diff --git a/src/config.rs b/src/config.rs index 884a2f4ef2..a26a18709a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -33,6 +33,41 @@ impl Display for OverrideReason { } } +#[derive(Debug)] +pub enum PgpPublicKey { + Builtin(&'static [u8]), + FromEnvironment(PathBuf, Vec), + FromConfiguration(PathBuf, Vec), +} + +impl PgpPublicKey { + /// Retrieve the key data for this key + /// + /// This key might be ASCII Armored or may not, we make no + /// guarantees. + pub fn key_data(&self) -> &[u8] { + match self { + Self::Builtin(k) => k, + Self::FromEnvironment(_, k) => &k, + Self::FromConfiguration(_, k) => &k, + } + } +} + +impl Display for PgpPublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Builtin(_) => write!(f, "builtin Rust release key"), + Self::FromEnvironment(p, _) => { + write!(f, "key specified in RUST_PGP_KEY ({})", p.display()) + } + Self::FromConfiguration(p, _) => { + write!(f, "key specified in configuration file ({})", p.display()) + } + } + } +} + pub struct Cfg { pub profile_override: Option, pub rustup_dir: PathBuf, @@ -41,7 +76,7 @@ pub struct Cfg { pub update_hash_dir: PathBuf, pub download_dir: PathBuf, pub temp_cfg: temp::Cfg, - pub gpg_key: Cow<'static, str>, + pgp_keys: Vec, pub toolchain_override: Option, pub env_override: Option, pub dist_root_url: String, @@ -62,13 +97,22 @@ impl Cfg { let update_hash_dir = rustup_dir.join("update-hashes"); let download_dir = rustup_dir.join("downloads"); - // GPG key - let gpg_key = - if let Some(path) = env::var_os("RUSTUP_GPG_KEY").and_then(utils::if_not_empty) { - Cow::Owned(utils::read_file("public key", Path::new(&path))?) - } else { - Cow::Borrowed(include_str!("rust-key.gpg.ascii")) - }; + // PGP keys + let mut pgp_keys: Vec = + vec![PgpPublicKey::Builtin(include_bytes!("rust-key.pgp.ascii"))]; + if let Some(s_path) = env::var_os("RUSTUP_PGP_KEY") { + let path = PathBuf::from(s_path); + let content = utils::read_file_bytes("RUSTUP_PGP_KEY", &path)?; + pgp_keys.push(PgpPublicKey::FromEnvironment(path, content)); + } + settings_file.with(|s| { + if let Some(s) = &s.pgp_keys { + let path = PathBuf::from(s); + let content = utils::read_file_bytes("PGP Key from config", &path)?; + pgp_keys.push(PgpPublicKey::FromConfiguration(path, content)); + } + Ok(()) + })?; // Environment override let env_override = env::var("RUSTUP_TOOLCHAIN") @@ -105,7 +149,7 @@ impl Cfg { update_hash_dir, download_dir, temp_cfg, - gpg_key, + pgp_keys, notify_handler, toolchain_override: None, env_override, @@ -122,6 +166,10 @@ impl Cfg { Ok(cfg) } + pub fn get_pgp_keys(&self) -> &[PgpPublicKey] { + &self.pgp_keys + } + pub fn set_profile_override(&mut self, profile: dist::Profile) { self.profile_override = Some(profile); } diff --git a/src/rust-key.gpg.ascii b/src/rust-key.pgp.ascii similarity index 100% rename from src/rust-key.gpg.ascii rename to src/rust-key.pgp.ascii diff --git a/src/settings.rs b/src/settings.rs index 89f688edb2..0c2687d0e5 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -69,6 +69,7 @@ pub struct Settings { pub default_toolchain: Option, pub profile: Option, pub overrides: BTreeMap, + pub pgp_keys: Option, } impl Default for Settings { @@ -79,6 +80,7 @@ impl Default for Settings { default_toolchain: None, profile: Some("default".to_owned()), overrides: BTreeMap::new(), + pgp_keys: None, } } } @@ -142,6 +144,7 @@ impl Settings { default_toolchain: get_opt_string(&mut table, "default_toolchain", path)?, profile: get_opt_string(&mut table, "profile", path)?, overrides: Self::table_to_overrides(&mut table, path)?, + pgp_keys: get_opt_string(&mut table, "pgp_keys", path)?, }) } pub fn into_toml(self) -> toml::value::Table { @@ -161,6 +164,10 @@ impl Settings { result.insert("profile".to_owned(), toml::Value::String(v)); } + if let Some(v) = self.pgp_keys { + result.insert("pgp_keys".to_owned(), toml::Value::String(v)); + } + let overrides = Self::overrides_to_table(self.overrides); result.insert("overrides".to_owned(), toml::Value::Table(overrides)); diff --git a/src/utils/utils.rs b/src/utils/utils.rs index d5288765ed..1cee0dc810 100644 --- a/src/utils/utils.rs +++ b/src/utils/utils.rs @@ -37,6 +37,13 @@ where }) } +pub fn read_file_bytes(name: &'static str, path: &Path) -> Result> { + fs::read(path).chain_err(|| ErrorKind::ReadingFile { + name, + path: PathBuf::from(path), + }) +} + pub fn read_file(name: &'static str, path: &Path) -> Result { fs::read_to_string(path).chain_err(|| ErrorKind::ReadingFile { name,