Skip to content

Commit

Permalink
Fix dmg notarization
Browse files Browse the repository at this point in the history
Closes #131
  • Loading branch information
jan-br committed Jan 17, 2024
1 parent bfa3b00 commit 1c01cd7
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 15 deletions.
18 changes: 8 additions & 10 deletions crates/packager/src/codesign/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ pub fn delete_keychain() {
#[derive(Debug)]
pub struct SignTarget {
pub path: PathBuf,
pub is_an_executable: bool,
pub is_native_binary: bool,
}

#[tracing::instrument(level = "trace")]
Expand All @@ -170,7 +170,7 @@ pub fn try_sign(targets: Vec<SignTarget>, identity: &str, config: &Config) -> cr
&target.path,
identity,
config,
target.is_an_executable,
target.is_native_binary,
packager_keychain,
)?;
}
Expand All @@ -188,8 +188,8 @@ fn sign(
path_to_sign: &Path,
identity: &str,
config: &Config,
is_an_executable: bool,
pcakger_keychain: bool,
is_native_binary: bool,
packager_keychain: bool,
) -> crate::Result<()> {
tracing::info!(
"Codesigning {} with identity \"{}\"",
Expand All @@ -199,7 +199,7 @@ fn sign(

let mut args = vec!["--force", "-s", identity];

if pcakger_keychain {
if packager_keychain {
args.push("--keychain");
args.push(KEYCHAIN_ID);
}
Expand All @@ -209,14 +209,12 @@ fn sign(
args.push(entitlements_path);
}

if is_an_executable {
if is_native_binary {
args.push("--options");
args.push("runtime");
}

if path_to_sign.is_dir() {
args.push("--deep");
}
args.push("--timestamp");

Command::new("codesign")
.args(args)
Expand Down Expand Up @@ -275,7 +273,7 @@ pub fn notarize(
try_sign(
vec![SignTarget {
path: zip_path.clone(),
is_an_executable: false,
is_native_binary: false,
}],
identity,
config,
Expand Down
77 changes: 73 additions & 4 deletions crates/packager/src/package/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,75 @@ pub(crate) fn package(ctx: &Context) -> crate::Result<Vec<PathBuf>> {

tracing::debug!("Copying frameworks");
let framework_paths = copy_frameworks_to_bundle(&contents_directory, config)?;

// All dylib files and native executables should be signed manually
// It is highly discouraged by Apple to use the --deep codesign parameter in larger projects.
// https://developer.apple.com/forums/thread/129980
for framework_path in &framework_paths {
if let Some(framework_path) = framework_path.to_str() {

// Find all files in the current framework folder
let constructed_glob = format!("{}/**/*", framework_path);
let files = match glob::glob(&constructed_glob) {
Ok(res) => res,
Err(err) => {
tracing::warn!("Could not construct a glob for {}: {}, please make sure your path contains no *", framework_path, err);
tracing::warn!("This path will not be scanned for dylibs!");
continue;
}
};


let files = files.filter_map(|p| match p {
Ok(v) => Some(v),
Err(err) => {
tracing::warn!("Error while globbing for Mach-O files in {}: {}", framework_path, err);
None
}
});

// Filter all files for Mach-O headers. This will target all .dylib and native executable files
for file in files {
let Some(file) = file.to_str() else {
tracing::warn!("Failed to convert {} to a valid UTF-8 string, this path will not be scanned for Mach-O header!", file.display());
continue;
};

let Ok(metadata) = std::fs::metadata(file) else {
tracing::warn!("Failed to get metadata for {}, this file will not be scanned for Mach-O header!", file);
continue;
};

if !metadata.is_file() {
continue;
}

let Ok(mut open_file) = std::fs::File::open(file) else {
tracing::warn!("Failed to open {} for reading, this file will not be scanned for Mach-O header!", file);
continue;
};

let mut buffer = [0; 4];
std::io::Read::read_exact(&mut open_file, &mut buffer)?;

// Mach-O magic numbers
let magic_numbers = [0xfeedface, 0xfeedfacf, 0xcafebabe, 0xcefaedfe, 0xcffaedfe];

let magic = u32::from_be_bytes(buffer);

let is_mach = magic_numbers.contains(&magic);
if !is_mach {
continue;
}

sign_paths.push(SignTarget {
path: PathBuf::from(file),
is_native_binary: true,
});
};
}
}

sign_paths.extend(
framework_paths
.into_iter()
Expand All @@ -61,7 +130,7 @@ pub(crate) fn package(ctx: &Context) -> crate::Result<Vec<PathBuf>> {
})
.map(|path| SignTarget {
path,
is_an_executable: false,
is_native_binary: false,
}),
);

Expand All @@ -72,7 +141,7 @@ pub(crate) fn package(ctx: &Context) -> crate::Result<Vec<PathBuf>> {
let bin_paths = config.copy_external_binaries(&bin_dir)?;
sign_paths.extend(bin_paths.into_iter().map(|path| SignTarget {
path,
is_an_executable: true,
is_native_binary: true,
}));

tracing::debug!("Copying binaries");
Expand All @@ -82,7 +151,7 @@ pub(crate) fn package(ctx: &Context) -> crate::Result<Vec<PathBuf>> {
std::fs::copy(&bin_path, &dest_path)?;
sign_paths.push(SignTarget {
path: dest_path,
is_an_executable: true,
is_native_binary: true,
});
}

Expand All @@ -95,7 +164,7 @@ pub(crate) fn package(ctx: &Context) -> crate::Result<Vec<PathBuf>> {
// https://developer.apple.com/forums/thread/701514
sign_paths.push(SignTarget {
path: app_bundle_path.clone(),
is_an_executable: true,
is_native_binary: true,
});

// Remove extra attributes, which could cause codesign to fail
Expand Down
2 changes: 1 addition & 1 deletion crates/packager/src/package/dmg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ pub(crate) fn package(ctx: &Context) -> crate::Result<Vec<PathBuf>> {
codesign::try_sign(
vec![codesign::SignTarget {
path: dmg_path.clone(),
is_an_executable: false,
is_native_binary: false,
}],
identity,
config,
Expand Down

0 comments on commit 1c01cd7

Please sign in to comment.