mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Enable hardened runtime on macOS
This is needed for notarization
This commit is contained in:
parent
d1248f8260
commit
d6e8d00b52
@ -16,6 +16,7 @@ from bypy.utils import current_dir
|
||||
|
||||
CODESIGN_CREDS = os.path.expanduser('~/cert-cred')
|
||||
CODESIGN_CERT = os.path.expanduser('~/maccert.p12')
|
||||
path_to_entitlements = os.path.expanduser('~/calibre-entitlements.plist')
|
||||
|
||||
|
||||
def run(*args):
|
||||
@ -65,10 +66,21 @@ def codesign(items):
|
||||
items = [items]
|
||||
# If you get errors while codesigning that look like "A timestamp was
|
||||
# expected but not found" it means that codesign failed to contact Apple's time
|
||||
# servers, probably due to network congestion, so add --timestamp=none to
|
||||
# this command line. That means the signature will fail once your code
|
||||
# signing key expires and key revocation wont work, but...
|
||||
subprocess.check_call(['codesign', '-s', 'Kovid Goyal'] + list(items))
|
||||
# servers, probably due to network congestion
|
||||
#
|
||||
# --options=runtime enables the Hardened Runtime
|
||||
subprocess.check_call([
|
||||
'codesign', '--options=runtime', '--entitlements=' + path_to_entitlements,
|
||||
'--timestamp', '-s', 'Kovid Goyal'
|
||||
] + list(items))
|
||||
|
||||
|
||||
def notarize():
|
||||
# See
|
||||
# https://developer.apple.com/documentation/xcode/notarizing_your_app_before_distribution/customizing_the_notarization_workflow?language=objc
|
||||
# and
|
||||
# https://developer.apple.com/documentation/xcode/notarizing_your_app_before_distribution/resolving_common_notarization_issues?language=objc
|
||||
pass
|
||||
|
||||
|
||||
def files_in(folder):
|
||||
@ -77,12 +89,12 @@ def files_in(folder):
|
||||
yield os.path.join(record[0], f)
|
||||
|
||||
|
||||
def expand_dirs(items):
|
||||
def expand_dirs(items, exclude=lambda x: x.endswith('.so')):
|
||||
items = set(items)
|
||||
dirs = set(x for x in items if os.path.isdir(x))
|
||||
items.difference_update(dirs)
|
||||
for x in dirs:
|
||||
items.update(set(files_in(x)))
|
||||
items.update({y for y in files_in(x) if not exclude(y)})
|
||||
return items
|
||||
|
||||
|
||||
@ -91,6 +103,25 @@ def get_executable(info_path):
|
||||
return plistlib.load(f)['CFBundleExecutable']
|
||||
|
||||
|
||||
def create_entitlements_file():
|
||||
ans = {
|
||||
# MAP_JIT is used by libpcre which is bundled with Qt
|
||||
'com.apple.security.cs.allow-jit': True,
|
||||
|
||||
# v8 and therefore WebEngine need this as they dont use MAP_JIT
|
||||
'com.apple.security.cs.allow-unsigned-executable-memory': True,
|
||||
|
||||
# calibre itself does not use DYLD env vars, but dont know about its
|
||||
# dependencies.
|
||||
'com.apple.security.cs.allow-dyld-environment-variables': True,
|
||||
|
||||
# Allow loading of unsigned plugins or frameworks
|
||||
# 'com.apple.security.cs.disable-library-validation': True,
|
||||
}
|
||||
with open(path_to_entitlements, 'wb') as f:
|
||||
f.write(plistlib.dumps(ans))
|
||||
|
||||
|
||||
def find_sub_apps(contents_dir='.'):
|
||||
for app in glob(os.path.join(contents_dir, '*.app')):
|
||||
cdir = os.path.join(app, 'Contents')
|
||||
@ -121,12 +152,16 @@ def do_sign_app(appdir):
|
||||
sign_MacOS(os.path.join(sa, 'Contents'))
|
||||
codesign(sub_apps)
|
||||
|
||||
# Sign all .so files
|
||||
so_files = {x for x in files_in('.') if x.endswith('.so')}
|
||||
codesign(so_files)
|
||||
|
||||
# Sign everything in PlugIns
|
||||
with current_dir('PlugIns'):
|
||||
items = set(os.listdir('.'))
|
||||
codesign(expand_dirs(items))
|
||||
|
||||
# Sign everything in Frameworks
|
||||
# Sign everything else in Frameworks
|
||||
with current_dir('Frameworks'):
|
||||
fw = set(glob('*.framework'))
|
||||
codesign(fw)
|
||||
@ -136,12 +171,13 @@ def do_sign_app(appdir):
|
||||
# Now sign the main app
|
||||
codesign(appdir)
|
||||
# Verify the signature
|
||||
subprocess.check_call(['codesign', '--deep', '--verify', '-v', appdir])
|
||||
subprocess.check_call(['codesign', '-vvv', '--deep', '--strict', appdir])
|
||||
subprocess.check_call('spctl --verbose=4 --assess --type execute'.split() + [appdir])
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def sign_app(appdir):
|
||||
create_entitlements_file()
|
||||
with make_certificate_useable():
|
||||
do_sign_app(appdir)
|
||||
|
Loading…
x
Reference in New Issue
Block a user