Skip to content

Commit 901f834

Browse files
committed
feat: support signing pkgs
1 parent 48c476e commit 901f834

File tree

4 files changed

+68
-5
lines changed

4 files changed

+68
-5
lines changed

cargo-dist/src/backend/installer/macpkg.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ use axoprocess::Cmd;
77
use camino::Utf8PathBuf;
88
use serde::Serialize;
99
use temp_dir::TempDir;
10-
use tracing::info;
10+
use tracing::{info, warn};
1111

12-
use crate::{create_tmp, DistResult};
12+
use crate::{
13+
create_tmp,
14+
sign::macos::{Codesign, Keychain},
15+
DistResult, TargetTriple,
16+
};
1317

1418
use super::ExecutableZipFragment;
1519

@@ -30,13 +34,36 @@ pub struct PkgInstallerInfo {
3034
pub version: String,
3135
/// Executable aliases
3236
pub bin_aliases: BTreeMap<String, Vec<String>>,
37+
/// Whether to sign package artifacts
38+
pub macos_sign: bool,
39+
/// The target we're building from
40+
pub host_target: TargetTriple,
41+
}
42+
43+
struct SigningEnv {
44+
pub keychain: Keychain,
45+
pub identity: String,
3346
}
3447

3548
impl PkgInstallerInfo {
3649
/// Build the pkg installer
3750
pub fn build(&self) -> DistResult<()> {
3851
info!("building a pkg: {}", self.identifier);
3952

53+
let signing_env = if self.macos_sign {
54+
if let Some(signer) = Codesign::new(&self.host_target)? {
55+
Some(SigningEnv {
56+
keychain: signer.create_keychain()?,
57+
identity: signer.identity().to_owned(),
58+
})
59+
} else {
60+
warn!("Signing was requested, but we weren't able to construct the signing environment - config may be missing");
61+
None
62+
}
63+
} else {
64+
None
65+
};
66+
4067
// We can't build directly from dist_dir because the
4168
// package installer wants the directory we feed it
4269
// to have the final package layout, which in this case
@@ -81,6 +108,14 @@ impl PkgInstallerInfo {
81108
pkgcmd.arg("--install-location").arg(&self.install_location);
82109
pkgcmd.arg("--version").arg(&self.version);
83110
pkgcmd.arg(&pkg_path);
111+
112+
// If we've been asked to sign, and we have the required
113+
// environment, do that here.
114+
if let Some(signing_env) = &signing_env {
115+
pkgcmd.arg("--sign").arg(&signing_env.identity);
116+
pkgcmd.arg("--keychain").arg(&signing_env.keychain.path);
117+
}
118+
84119
// Ensures stdout from the build process doesn't taint the dist-manifest
85120
pkgcmd.stdout_to_stderr();
86121
pkgcmd.run()?;
@@ -89,6 +124,13 @@ impl PkgInstallerInfo {
89124
let mut productcmd = Cmd::new("/usr/bin/productbuild", "create final product .pkg");
90125
productcmd.arg("--package").arg(&pkg_path);
91126
productcmd.arg(&product_path);
127+
128+
// We also need to sign the product .pkg.
129+
if let Some(signing_env) = &signing_env {
130+
productcmd.arg("--sign").arg(&signing_env.identity);
131+
productcmd.arg("--keychain").arg(&signing_env.keychain.path);
132+
}
133+
92134
productcmd.stdout_to_stderr();
93135
productcmd.run()?;
94136

cargo-dist/src/sign/macos.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ use tracing::warn;
2727

2828
use crate::{create_tmp, DistError, DistResult, TargetTriple};
2929

30-
struct Keychain {
30+
/// Represents a temporary macOS keychain database. The database object will be created within `_root`, and deleted once this struct is dropped.
31+
pub struct Keychain {
3132
_root: TempDir,
3233
root_path: Utf8PathBuf,
3334
password: String,
35+
/// The path to the keychain database.
3436
pub path: Utf8PathBuf,
3537
}
3638

@@ -156,6 +158,7 @@ impl std::fmt::Debug for CodesignEnv {
156158
}
157159

158160
impl Codesign {
161+
/// Creates a new Codesign instance, if the host is darwin and the required information is in the environment
159162
pub fn new(host_target: &TargetTriple) -> DistResult<Option<Self>> {
160163
if !host_target.contains("darwin") {
161164
return Ok(None);
@@ -182,11 +185,20 @@ impl Codesign {
182185
val
183186
}
184187

185-
pub fn sign(&self, file: &Utf8Path) -> DistResult<()> {
188+
/// Creates a Keychain with this signer's certificate imported,
189+
/// then returns it.
190+
pub fn create_keychain(&self) -> DistResult<Keychain> {
186191
let password = uuid::Uuid::new_v4().as_hyphenated().to_string();
187192
let keychain = Keychain::create(password)?;
188193
keychain.import_certificate(&self.env.certificate, &self.env.password)?;
189194

195+
Ok(keychain)
196+
}
197+
198+
/// Signs a binary using `codesign`.
199+
pub fn sign(&self, file: &Utf8Path) -> DistResult<()> {
200+
let keychain = self.create_keychain()?;
201+
190202
let mut cmd = Cmd::new("/usr/bin/codesign", "sign macOS artifacts");
191203
cmd.arg("--sign").arg(&self.env.identity);
192204
cmd.arg("--keychain").arg(&keychain.path);
@@ -196,4 +208,9 @@ impl Codesign {
196208

197209
Ok(())
198210
}
211+
212+
/// Returns the signing identity represented by this signer.
213+
pub fn identity(&self) -> &str {
214+
&self.env.identity
215+
}
199216
}

cargo-dist/src/sign/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use camino::Utf8Path;
88

99
use crate::{config::ProductionMode, DistResult, TargetTriple};
1010

11-
mod macos;
11+
pub mod macos;
1212
mod ssldotcom;
1313

1414
/// Code/artifact signing providers

cargo-dist/src/tasks.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2274,6 +2274,8 @@ impl<'pkg_graph> DistGraphBuilder<'pkg_graph> {
22742274
};
22752275

22762276
let bin_aliases = bin_aliases.for_target(&variant.target);
2277+
let macos_sign = self.inner.config.builds.macos_sign;
2278+
let host_target = self.inner.tools.cargo.host_target.clone();
22772279

22782280
// Gather up the bundles the installer supports
22792281
let installer_artifact = Artifact {
@@ -2297,6 +2299,8 @@ impl<'pkg_graph> DistGraphBuilder<'pkg_graph> {
22972299
install_location: config.install_location.clone(),
22982300
version: version.to_string(),
22992301
bin_aliases,
2302+
macos_sign,
2303+
host_target,
23002304
})),
23012305
is_global: false,
23022306
};

0 commit comments

Comments
 (0)