forked from lix-project/lix-installer
Allow disabling signature checking for testing
This commit is contained in:
parent
0de55cce78
commit
78af1e1d88
|
@ -31,6 +31,8 @@ use crate::{
|
||||||
/// * NarHash must be sha256
|
/// * NarHash must be sha256
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct FetchAndUnpackNixSubstituter {
|
pub struct FetchAndUnpackNixSubstituter {
|
||||||
|
/// Whether to require valid signatures when checking narinfo
|
||||||
|
require_sigs: bool,
|
||||||
/// Map from key name (e.g. cache.nixos.org-1) to parsed ed25519 key
|
/// Map from key name (e.g. cache.nixos.org-1) to parsed ed25519 key
|
||||||
trusted_keys: HashMap<String, VerifyingKey>,
|
trusted_keys: HashMap<String, VerifyingKey>,
|
||||||
/// Base URLs for substituters, e.g. https://cache.nixos.org/
|
/// Base URLs for substituters, e.g. https://cache.nixos.org/
|
||||||
|
@ -59,6 +61,7 @@ impl FetchAndUnpackNixSubstituter {
|
||||||
targets: Vec<PathBuf>,
|
targets: Vec<PathBuf>,
|
||||||
dest: PathBuf,
|
dest: PathBuf,
|
||||||
trusted_keys: Vec<String>,
|
trusted_keys: Vec<String>,
|
||||||
|
require_sigs: bool,
|
||||||
substituters: Vec<Url>,
|
substituters: Vec<Url>,
|
||||||
proxy: Option<Url>,
|
proxy: Option<Url>,
|
||||||
ssl_cert_file: Option<PathBuf>,
|
ssl_cert_file: Option<PathBuf>,
|
||||||
|
@ -86,7 +89,12 @@ impl FetchAndUnpackNixSubstituter {
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
.map_err(Self::error)?;
|
.map_err(Self::error)?;
|
||||||
|
|
||||||
|
if !require_sigs {
|
||||||
|
tracing::warn!("Signatures are not required during substitution. This is insecure.");
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
require_sigs,
|
||||||
targets,
|
targets,
|
||||||
trusted_keys: trusted_keys_parsed,
|
trusted_keys: trusted_keys_parsed,
|
||||||
dest,
|
dest,
|
||||||
|
@ -122,6 +130,7 @@ impl FetchAndUnpackNixSubstituter {
|
||||||
}
|
}
|
||||||
|
|
||||||
let narinfo = NarInfo::parse_and_verify(
|
let narinfo = NarInfo::parse_and_verify(
|
||||||
|
self.require_sigs,
|
||||||
&self.trusted_keys,
|
&self.trusted_keys,
|
||||||
substituter,
|
substituter,
|
||||||
&output,
|
&output,
|
||||||
|
@ -458,7 +467,7 @@ struct NarInfo {
|
||||||
/// Other store paths referenced by the nar
|
/// Other store paths referenced by the nar
|
||||||
pub references: Vec<StorePath>,
|
pub references: Vec<StorePath>,
|
||||||
/// Signature of the nar, used to sign other items
|
/// Signature of the nar, used to sign other items
|
||||||
pub sig: (String, Vec<u8>),
|
pub sig: Option<(String, Vec<u8>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NarInfo {
|
impl NarInfo {
|
||||||
|
@ -527,7 +536,7 @@ impl NarInfo {
|
||||||
nar_hash: nar_hash.ok_or_else(|| SubstitutionError::BadNarInfo)?,
|
nar_hash: nar_hash.ok_or_else(|| SubstitutionError::BadNarInfo)?,
|
||||||
nar_size: nar_size.ok_or_else(|| SubstitutionError::BadNarInfo)?,
|
nar_size: nar_size.ok_or_else(|| SubstitutionError::BadNarInfo)?,
|
||||||
references: references.ok_or_else(|| SubstitutionError::BadNarInfo)?,
|
references: references.ok_or_else(|| SubstitutionError::BadNarInfo)?,
|
||||||
sig: sig.ok_or_else(|| SubstitutionError::BadNarInfo)?,
|
sig,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +544,11 @@ impl NarInfo {
|
||||||
&self,
|
&self,
|
||||||
trusted_keys: &HashMap<String, VerifyingKey>,
|
trusted_keys: &HashMap<String, VerifyingKey>,
|
||||||
) -> Result<(), SubstitutionError> {
|
) -> Result<(), SubstitutionError> {
|
||||||
let Some(key) = trusted_keys.get(&self.sig.0) else {
|
let Some(sig) = &self.sig else {
|
||||||
|
return Err(SubstitutionError::BadSignature);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(key) = trusted_keys.get(&sig.0) else {
|
||||||
return Err(SubstitutionError::BadSignature);
|
return Err(SubstitutionError::BadSignature);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -556,8 +569,7 @@ impl NarInfo {
|
||||||
key.verify_strict(
|
key.verify_strict(
|
||||||
fingerprint.as_bytes(),
|
fingerprint.as_bytes(),
|
||||||
&ed25519_dalek::Signature::from_bytes(
|
&ed25519_dalek::Signature::from_bytes(
|
||||||
self.sig
|
sig.1
|
||||||
.1
|
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| SubstitutionError::BadSignature)?,
|
.map_err(|_| SubstitutionError::BadSignature)?,
|
||||||
|
@ -567,6 +579,7 @@ impl NarInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_and_verify(
|
pub fn parse_and_verify(
|
||||||
|
require_sigs: bool,
|
||||||
trusted_keys: &HashMap<String, VerifyingKey>,
|
trusted_keys: &HashMap<String, VerifyingKey>,
|
||||||
substituter_url: &Url,
|
substituter_url: &Url,
|
||||||
expected_store_path: &StorePath,
|
expected_store_path: &StorePath,
|
||||||
|
@ -578,7 +591,9 @@ impl NarInfo {
|
||||||
return Err(SubstitutionError::BadSignature);
|
return Err(SubstitutionError::BadSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed.verify(trusted_keys)?;
|
if require_sigs {
|
||||||
|
parsed.verify(trusted_keys)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(parsed)
|
Ok(parsed)
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ impl ProvisionNix {
|
||||||
settings.substitution_targets.clone(),
|
settings.substitution_targets.clone(),
|
||||||
PathBuf::from(SCRATCH_DIR),
|
PathBuf::from(SCRATCH_DIR),
|
||||||
settings.substituter_trusted_keys.clone(),
|
settings.substituter_trusted_keys.clone(),
|
||||||
|
settings.substituter_require_sigs,
|
||||||
settings.substituters.clone(),
|
settings.substituters.clone(),
|
||||||
settings.proxy.clone(),
|
settings.proxy.clone(),
|
||||||
settings.ssl_cert_file.clone(),
|
settings.ssl_cert_file.clone(),
|
||||||
|
|
|
@ -192,7 +192,7 @@ pub struct CommonSettings {
|
||||||
)]
|
)]
|
||||||
pub substituter_trusted_keys: Vec<String>,
|
pub substituter_trusted_keys: Vec<String>,
|
||||||
|
|
||||||
/// Output to download when use_substituters is set
|
/// Store paths to download when use_substituters is set. Should include lix and cacert
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "cli",
|
feature = "cli",
|
||||||
clap(long, env = "NIX_INSTALLER_SUBSTITUTION_TARGETS",)
|
clap(long, env = "NIX_INSTALLER_SUBSTITUTION_TARGETS",)
|
||||||
|
@ -223,6 +223,19 @@ pub struct CommonSettings {
|
||||||
)]
|
)]
|
||||||
pub substitution_targets: Vec<PathBuf>,
|
pub substitution_targets: Vec<PathBuf>,
|
||||||
|
|
||||||
|
/// Require trusted signatures when downloading from substituters
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "cli",
|
||||||
|
clap(
|
||||||
|
action(ArgAction::SetFalse),
|
||||||
|
default_value = "true",
|
||||||
|
global = true,
|
||||||
|
env = "NIX_INSTALLER_REQUIRE_SIGS",
|
||||||
|
long = "no-require-sigs"
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub substituter_require_sigs: bool,
|
||||||
|
|
||||||
/// Download Lix from a substituter instead of an install tarball
|
/// Download Lix from a substituter instead of an install tarball
|
||||||
#[cfg_attr(feature = "cli", clap(long, env = "NIX_INSTALLER_USE_SUBSTITUTER"))]
|
#[cfg_attr(feature = "cli", clap(long, env = "NIX_INSTALLER_USE_SUBSTITUTER"))]
|
||||||
pub use_substituters: bool,
|
pub use_substituters: bool,
|
||||||
|
@ -387,6 +400,7 @@ impl CommonSettings {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| PathBuf::from(*s))
|
.map(|s| PathBuf::from(*s))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
substituter_require_sigs: true,
|
||||||
use_substituters: false,
|
use_substituters: false,
|
||||||
nix_package_url: url.parse()?,
|
nix_package_url: url.parse()?,
|
||||||
proxy: Default::default(),
|
proxy: Default::default(),
|
||||||
|
@ -409,6 +423,7 @@ impl CommonSettings {
|
||||||
substituters,
|
substituters,
|
||||||
substituter_trusted_keys,
|
substituter_trusted_keys,
|
||||||
substitution_targets,
|
substitution_targets,
|
||||||
|
substituter_require_sigs,
|
||||||
use_substituters,
|
use_substituters,
|
||||||
nix_package_url,
|
nix_package_url,
|
||||||
proxy,
|
proxy,
|
||||||
|
@ -443,7 +458,6 @@ impl CommonSettings {
|
||||||
"nix_build_user_count".into(),
|
"nix_build_user_count".into(),
|
||||||
serde_json::to_value(nix_build_user_count)?,
|
serde_json::to_value(nix_build_user_count)?,
|
||||||
);
|
);
|
||||||
map.insert("substituters".into(), serde_json::to_value(substituters)?);
|
|
||||||
map.insert(
|
map.insert(
|
||||||
"substituter_trusted_keys".into(),
|
"substituter_trusted_keys".into(),
|
||||||
serde_json::to_value(substituter_trusted_keys)?,
|
serde_json::to_value(substituter_trusted_keys)?,
|
||||||
|
@ -452,6 +466,10 @@ impl CommonSettings {
|
||||||
"substitution_targets".into(),
|
"substitution_targets".into(),
|
||||||
serde_json::to_value(substitution_targets)?,
|
serde_json::to_value(substitution_targets)?,
|
||||||
);
|
);
|
||||||
|
map.insert(
|
||||||
|
"substituter_require_sigs".into(),
|
||||||
|
serde_json::to_value(substituter_require_sigs)?,
|
||||||
|
);
|
||||||
map.insert(
|
map.insert(
|
||||||
"use_substituters".into(),
|
"use_substituters".into(),
|
||||||
serde_json::to_value(use_substituters)?,
|
serde_json::to_value(use_substituters)?,
|
||||||
|
@ -460,6 +478,7 @@ impl CommonSettings {
|
||||||
"nix_package_url".into(),
|
"nix_package_url".into(),
|
||||||
serde_json::to_value(nix_package_url)?,
|
serde_json::to_value(nix_package_url)?,
|
||||||
);
|
);
|
||||||
|
map.insert("substituters".into(), serde_json::to_value(substituters)?);
|
||||||
map.insert("proxy".into(), serde_json::to_value(proxy)?);
|
map.insert("proxy".into(), serde_json::to_value(proxy)?);
|
||||||
map.insert("ssl_cert_file".into(), serde_json::to_value(ssl_cert_file)?);
|
map.insert("ssl_cert_file".into(), serde_json::to_value(ssl_cert_file)?);
|
||||||
map.insert("extra_conf".into(), serde_json::to_value(extra_conf)?);
|
map.insert("extra_conf".into(), serde_json::to_value(extra_conf)?);
|
||||||
|
|
1
tests/fixtures/linux/linux.json
vendored
1
tests/fixtures/linux/linux.json
vendored
|
@ -422,6 +422,7 @@
|
||||||
"substitution_targets": [
|
"substitution_targets": [
|
||||||
"/nix/store/rp7y16q2py2n9y19jvxkjr83lp77bh7y-lix-2.90.0"
|
"/nix/store/rp7y16q2py2n9y19jvxkjr83lp77bh7y-lix-2.90.0"
|
||||||
],
|
],
|
||||||
|
"substituter_require_sigs": true,
|
||||||
"use_substituters": false,
|
"use_substituters": false,
|
||||||
"nix_package_url": {
|
"nix_package_url": {
|
||||||
"Url": "https://releases.nixos.org/nix/nix-2.17.0/nix-2.17.0-x86_64-linux.tar.xz"
|
"Url": "https://releases.nixos.org/nix/nix-2.17.0/nix-2.17.0-x86_64-linux.tar.xz"
|
||||||
|
|
1
tests/fixtures/linux/steam-deck.json
vendored
1
tests/fixtures/linux/steam-deck.json
vendored
|
@ -406,6 +406,7 @@
|
||||||
"substitution_targets": [
|
"substitution_targets": [
|
||||||
"/nix/store/rp7y16q2py2n9y19jvxkjr83lp77bh7y-lix-2.90.0"
|
"/nix/store/rp7y16q2py2n9y19jvxkjr83lp77bh7y-lix-2.90.0"
|
||||||
],
|
],
|
||||||
|
"substituter_require_sigs": true,
|
||||||
"use_substituters": false,
|
"use_substituters": false,
|
||||||
"nix_package_url": {
|
"nix_package_url": {
|
||||||
"Url": "https://releases.nixos.org/nix/nix-2.17.0/nix-2.17.0-x86_64-linux.tar.xz"
|
"Url": "https://releases.nixos.org/nix/nix-2.17.0/nix-2.17.0-x86_64-linux.tar.xz"
|
||||||
|
|
1
tests/fixtures/macos/macos.json
vendored
1
tests/fixtures/macos/macos.json
vendored
|
@ -433,6 +433,7 @@
|
||||||
"substitution_target": [
|
"substitution_target": [
|
||||||
"/nix/store/rp7y16q2py2n9y19jvxkjr83lp77bh7y-lix-2.90.0"
|
"/nix/store/rp7y16q2py2n9y19jvxkjr83lp77bh7y-lix-2.90.0"
|
||||||
],
|
],
|
||||||
|
"substituter_require_sigs": true,
|
||||||
"use_substituters": false,
|
"use_substituters": false,
|
||||||
"nix_package_url": {
|
"nix_package_url": {
|
||||||
"Url": "https://releases.nixos.org/nix/nix-2.17.0/nix-2.17.0-x86_64-darwin.tar.xz"
|
"Url": "https://releases.nixos.org/nix/nix-2.17.0/nix-2.17.0-x86_64-darwin.tar.xz"
|
||||||
|
|
Loading…
Reference in a new issue