74 lines · 2.3 KB · JavaScript
RawDownload
// Mach-O detection and codesign invocations shared by the runtime staging// scripts (Synara and Open Slide).import { chmodSync, closeSync, openSync, readSync } from "node:fs";import { run, walkFiles } from "./util.mjs"; const MACH_O_MAGICS = new Set([  "feedface", // 32-bit  "cefaedfe",  "feedfacf", // 64-bit  "cffaedfe",  "cafebabe", // universal  "bebafeca",  "cafebabf", // universal 64-bit  "bfbafeca",]); export function isMachO(path) {  const descriptor = openSync(path, "r");  try {    const magic = Buffer.allocUnsafe(4);    if (readSync(descriptor, magic, 0, magic.length, 0) !== magic.length) return false;    return MACH_O_MAGICS.has(magic.toString("hex"));  } finally {    closeSync(descriptor);  }} /** * Every Mach-O file below `root`, sorted. Packages can introduce extensionless * binaries such as esbuild, so detect native code rather than maintain a * filename list. Links are not followed: pnpm's point back into the same tree, * and following them would sign one binary twice. */export function findMachOBinaries(root) {  return walkFiles(root).filter(isMachO).sort();} /** The Developer ID from APPLE_SIGNING_IDENTITY, or null when unset or ad hoc ("-"). */export function signingIdentity() {  const identity = process.env.APPLE_SIGNING_IDENTITY?.trim();  return identity && identity !== "-" ? identity : null;} /** Sign with the hardened runtime. An ad-hoc ("-") signature cannot carry a timestamp. */export function codesign(path, { identity, entitlements }) {  run("/usr/bin/codesign", [    "--force",    "--options",    "runtime",    ...(identity === "-" ? [] : ["--timestamp"]),    ...(entitlements ? ["--entitlements", entitlements] : []),    "--sign",    identity,    path,  ]);} function verifySignature(path, ...flags) {  run("/usr/bin/codesign", ["--verify", ...flags, path]);} /** * Sign and strictly verify every Mach-O file below `root`, making each one * executable first (package installs can drop the bit). Returns how many it signed. */export function signMachOTree(root, { identity, entitlements }) {  const binaries = findMachOBinaries(root);  for (const path of binaries) {    chmodSync(path, 0o755);    codesign(path, { identity, entitlements });    verifySignature(path, "--strict");  }  return binaries.length;}