|
38 | 38 | logger = logging.getLogger(__name__) |
39 | 39 |
|
40 | 40 |
|
| 41 | +# Mach-O binaries start with magic bytes. |
| 42 | +# Definitions: |
| 43 | +# * https://github.com/apple-oss-distributions/xnu/blob/main/EXTERNAL_HEADERS/mach-o/loader.h |
| 44 | +# * https://github.com/apple-oss-distributions/xnu/blob/main/EXTERNAL_HEADERS/mach-o/fat.h |
| 45 | +# For now, only include little-endian 64-bit and fat binaries |
| 46 | +MACHO_MAGIC_BYTES = ( |
| 47 | + b"\xcf\xfa\xed\xfe", # 64-bit |
| 48 | + b"\xbe\xba\xfe\xca", # universal binary |
| 49 | +) |
| 50 | + |
| 51 | + |
| 52 | +def is_macho_binary(file: Path) -> bool: |
| 53 | + if not file.is_file(): |
| 54 | + return False |
| 55 | + with file.open(mode="rb") as f: |
| 56 | + magic = f.read(4) |
| 57 | + return magic in MACHO_MAGIC_BYTES |
| 58 | + |
| 59 | + |
41 | 60 | def calculate_install_dir(yaml_file, subdir=None): |
42 | 61 | contents = parse(yaml_file, subdir or conda_context.subdir) |
43 | 62 | if contents.get("installer_type") == "sh": |
@@ -88,6 +107,24 @@ def _detect_mimetype(path: str): |
88 | 107 | return "text/plain" |
89 | 108 |
|
90 | 109 |
|
| 110 | +def sign_standalone_binary( |
| 111 | + exe_path: Path, |
| 112 | + codesigner: CodeSign, |
| 113 | +): |
| 114 | + entitlements = { |
| 115 | + "com.apple.security.cs.allow-jit": True, |
| 116 | + "com.apple.security.cs.allow-unsigned-executable-memory": True, |
| 117 | + "com.apple.security.cs.disable-executable-page-protection": True, |
| 118 | + "com.apple.security.cs.disable-library-validation": True, |
| 119 | + "com.apple.security.cs.allow-dyld-environment-variables": True, |
| 120 | + } |
| 121 | + codesigner.sign_bundle(exe_path, entitlements=entitlements) |
| 122 | + internal_dir = exe_path.parent / "_internal" |
| 123 | + for file in internal_dir.glob("**"): |
| 124 | + if is_macho_binary(file): |
| 125 | + codesigner.sign_bundle(file, entitlements=entitlements) |
| 126 | + |
| 127 | + |
91 | 128 | def modify_xml(xml_path, info): |
92 | 129 | # See |
93 | 130 | # http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html#//apple_ref/doc/uid/TP40005370-CH100-SW20 |
@@ -449,16 +486,16 @@ def pkgbuild_prepare_installation(info): |
449 | 486 | shutil.rmtree(f"{pkg}.expanded") |
450 | 487 |
|
451 | 488 |
|
452 | | -def create_plugins(pages: list = None, codesigner: CodeSign = None): |
453 | | - def _build_xcode_projects(xcodeporj_dirs: list[Path]): |
| 489 | +def create_plugins(pages: list[str] | str | None = None, codesigner: CodeSign | None = None): |
| 490 | + def _build_xcode_projects(xcodeproj_dirs: list[Path]): |
454 | 491 | xcodebuild = shutil.which("xcodebuild") |
455 | 492 | if not xcodebuild: |
456 | 493 | raise RuntimeError( |
457 | 494 | "Plugin directory contains an uncompiled project, but xcodebuild is not available." |
458 | 495 | ) |
459 | 496 | try: |
460 | 497 | subprocess.run([xcodebuild, "--help"], check=True, capture_output=True) |
461 | | - except subprocess.CalledSubprocessError: |
| 498 | + except subprocess.CalledProcessError: |
462 | 499 | raise RuntimeError( |
463 | 500 | "Plugin directory contains an uncompiled project, " |
464 | 501 | "but xcodebuild requires XCode to compile plugins." |
@@ -608,14 +645,7 @@ def create(info, verbose=False): |
608 | 645 | codesigner = CodeSign( |
609 | 646 | notarization_identity_name, prefix=info.get("reverse_domain_identifier", info["name"]) |
610 | 647 | ) |
611 | | - entitlements = { |
612 | | - "com.apple.security.cs.allow-jit": True, |
613 | | - "com.apple.security.cs.allow-unsigned-executable-memory": True, |
614 | | - "com.apple.security.cs.disable-executable-page-protection": True, |
615 | | - "com.apple.security.cs.disable-library-validation": True, |
616 | | - "com.apple.security.cs.allow-dyld-environment-variables": True, |
617 | | - } |
618 | | - codesigner.sign_bundle(join(prefix, exe_name), entitlements=entitlements) |
| 648 | + sign_standalone_binary(Path(prefix, exe_name), codesigner) |
619 | 649 |
|
620 | 650 | # This script checks to see if the install location already exists and/or contains spaces |
621 | 651 | # Not to be confused with the user-provided pre_install! |
|
0 commit comments