Merge pull request #17 from blitz/appease-clippy

Lanzatool: appease clippy
This commit is contained in:
Julian Stecklina 2022-11-26 23:36:15 +01:00 committed by GitHub
commit 452e558e40
9 changed files with 78 additions and 59 deletions

View File

@ -159,13 +159,11 @@
}; };
in in
{ {
# TODO Will be enabled by nikstur. lanzatool-unwrapped-clippy = craneLib.cargoClippy {
# src = lanzatool-unwrapped-src;
# lanzatool-unwrapped-clippy = craneLib.cargoClippy { cargoArtifacts = lanzatool-unwrapped-deps;
# src = lanzatool-unwrapped-src; cargoClippyExtraArgs = "--all-targets -- --deny warnings";
# cargoArtifacts = lanzatool-unwrapped-deps; };
# cargoClippyExtraArgs = "--all-targets -- --deny warnings";
# };
# TODO: user mode: OK # TODO: user mode: OK
# TODO: how to get in: {deployed, audited} mode ? # TODO: how to get in: {deployed, audited} mode ?

View File

@ -4,6 +4,7 @@ use anyhow::{Context, Result};
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use crate::install; use crate::install;
use crate::signature::KeyPair;
#[derive(Parser)] #[derive(Parser)]
pub struct Cli { pub struct Cli {
@ -60,11 +61,12 @@ fn install(args: InstallCommand) -> Result<()> {
let initrd_stub = std::env::var("LANZABOOTE_INITRD_STUB") let initrd_stub = std::env::var("LANZABOOTE_INITRD_STUB")
.context("Failed to read LANZABOOTE_INITRD_STUB env variable")?; .context("Failed to read LANZABOOTE_INITRD_STUB env variable")?;
let key_pair = KeyPair::new(&args.public_key, &args.private_key);
install::Installer::new( install::Installer::new(
PathBuf::from(lanzaboote_stub), PathBuf::from(lanzaboote_stub),
PathBuf::from(initrd_stub), PathBuf::from(initrd_stub),
args.public_key, key_pair,
args.private_key,
args.pki_bundle, args.pki_bundle,
args.auto_enroll, args.auto_enroll,
args.esp, args.esp,

View File

@ -32,7 +32,7 @@ impl EspPaths {
kernel: esp_nixos.join(nixos_path(&bootspec.kernel, "bzImage")?), kernel: esp_nixos.join(nixos_path(&bootspec.kernel, "bzImage")?),
initrd: esp_nixos.join(nixos_path(&bootspec.initrd, "initrd")?), initrd: esp_nixos.join(nixos_path(&bootspec.initrd, "initrd")?),
linux: esp_linux.clone(), linux: esp_linux.clone(),
lanzaboote_image: esp_linux.join(generation_path(&generation)), lanzaboote_image: esp_linux.join(generation_path(generation)),
efi_fallback_dir: esp_efi_fallback_dir.clone(), efi_fallback_dir: esp_efi_fallback_dir.clone(),
efi_fallback: esp_efi_fallback_dir.join("BOOTX64.EFI"), efi_fallback: esp_efi_fallback_dir.join("BOOTX64.EFI"),
systemd: esp_systemd.clone(), systemd: esp_systemd.clone(),
@ -42,12 +42,17 @@ impl EspPaths {
} }
fn nixos_path(path: impl AsRef<Path>, name: &str) -> Result<PathBuf> { fn nixos_path(path: impl AsRef<Path>, name: &str) -> Result<PathBuf> {
let resolved = path.as_ref().read_link().unwrap_or(path.as_ref().into()); let resolved = path
.as_ref()
.read_link()
.unwrap_or_else(|_| path.as_ref().into());
let parent = resolved.parent().ok_or(anyhow::anyhow!(format!( let parent = resolved.parent().ok_or_else(|| {
anyhow::anyhow!(format!(
"Path: {} does not have a parent", "Path: {} does not have a parent",
resolved.display() resolved.display()
)))?; ))
})?;
let without_store = parent.strip_prefix("/nix/store").with_context(|| { let without_store = parent.strip_prefix("/nix/store").with_context(|| {
format!( format!(

View File

@ -16,7 +16,7 @@ impl Generation {
pub fn from_toplevel(toplevel: impl AsRef<Path>) -> Result<Self> { pub fn from_toplevel(toplevel: impl AsRef<Path>) -> Result<Self> {
let bootspec_path = toplevel.as_ref().join("bootspec/boot.v1.json"); let bootspec_path = toplevel.as_ref().join("bootspec/boot.v1.json");
let bootspec: Bootspec = serde_json::from_slice( let bootspec: Bootspec = serde_json::from_slice(
&fs::read(&bootspec_path).context("Failed to read bootspec file")?, &fs::read(bootspec_path).context("Failed to read bootspec file")?,
) )
.context("Failed to parse bootspec json")?; .context("Failed to parse bootspec json")?;
@ -34,18 +34,19 @@ impl fmt::Display for Generation {
} }
fn parse_version(toplevel: impl AsRef<Path>) -> Result<u64> { fn parse_version(toplevel: impl AsRef<Path>) -> Result<u64> {
let file_name = toplevel.as_ref().file_name().ok_or(anyhow::anyhow!( let file_name = toplevel
"Failed to extract file name from generation" .as_ref()
))?; .file_name()
.ok_or_else(|| anyhow::anyhow!("Failed to extract file name from generation"))?;
let file_name_str = file_name let file_name_str = file_name
.to_str() .to_str()
.with_context(|| "Failed to convert file name of generation to string")?; .with_context(|| "Failed to convert file name of generation to string")?;
let generation_version = file_name_str let generation_version = file_name_str
.split("-") .split('-')
.nth(1) .nth(1)
.ok_or(anyhow::anyhow!("Failed to extract version from generation"))?; .ok_or_else(|| anyhow::anyhow!("Failed to extract version from generation"))?;
let parsed_generation_version = generation_version let parsed_generation_version = generation_version
.parse() .parse()

View File

@ -10,13 +10,12 @@ use tempfile::tempdir;
use crate::esp::EspPaths; use crate::esp::EspPaths;
use crate::generation::Generation; use crate::generation::Generation;
use crate::pe; use crate::pe;
use crate::signer::Signer; use crate::signature::KeyPair;
pub struct Installer { pub struct Installer {
lanzaboote_stub: PathBuf, lanzaboote_stub: PathBuf,
initrd_stub: PathBuf, initrd_stub: PathBuf,
public_key: PathBuf, key_pair: KeyPair,
private_key: PathBuf,
_pki_bundle: Option<PathBuf>, _pki_bundle: Option<PathBuf>,
_auto_enroll: bool, _auto_enroll: bool,
esp: PathBuf, esp: PathBuf,
@ -27,8 +26,7 @@ impl Installer {
pub fn new( pub fn new(
lanzaboote_stub: PathBuf, lanzaboote_stub: PathBuf,
initrd_stub: PathBuf, initrd_stub: PathBuf,
public_key: PathBuf, key_pair: KeyPair,
private_key: PathBuf,
_pki_bundle: Option<PathBuf>, _pki_bundle: Option<PathBuf>,
_auto_enroll: bool, _auto_enroll: bool,
esp: PathBuf, esp: PathBuf,
@ -37,8 +35,7 @@ impl Installer {
Self { Self {
lanzaboote_stub, lanzaboote_stub,
initrd_stub, initrd_stub,
public_key, key_pair,
private_key,
_pki_bundle, _pki_bundle,
_auto_enroll, _auto_enroll,
esp, esp,
@ -96,15 +93,13 @@ impl Installer {
let initrd_location = secure_temp_dir.path().join("initrd"); let initrd_location = secure_temp_dir.path().join("initrd");
copy(&bootspec.initrd, &initrd_location)?; copy(&bootspec.initrd, &initrd_location)?;
if let Some(initrd_secrets_script) = &bootspec.initrd_secrets { if let Some(initrd_secrets_script) = &bootspec.initrd_secrets {
append_initrd_secrets(&initrd_secrets_script, &initrd_location)?; append_initrd_secrets(initrd_secrets_script, &initrd_location)?;
} }
let wrapped_initrd = pe::wrap_initrd(&secure_temp_dir, &self.initrd_stub, &initrd_location) let wrapped_initrd = pe::wrap_initrd(&secure_temp_dir, &self.initrd_stub, &initrd_location)
.context("Failed to assemble stub")?; .context("Failed to assemble stub")?;
println!("Sign and copy files to EFI system partition..."); println!("Sign and copy files to EFI system partition...");
let signer = Signer::new(&self.public_key, &self.private_key);
let systemd_boot = bootspec let systemd_boot = bootspec
.toplevel .toplevel
.join("systemd/lib/systemd/boot/efi/systemd-bootx64.efi"); .join("systemd/lib/systemd/boot/efi/systemd-bootx64.efi");
@ -121,7 +116,7 @@ impl Installer {
println!("Signing {}...", to.display()); println!("Signing {}...", to.display());
ensure_parent_dir(to); ensure_parent_dir(to);
signer.sign_and_copy(&from, &to).with_context(|| { self.key_pair.sign_and_copy(from, to).with_context(|| {
format!("Failed to copy and sign file from {:?} to {:?}", from, to) format!("Failed to copy and sign file from {:?} to {:?}", from, to)
})?; })?;
// Call sync to improve the likelihood that file is actually written to disk // Call sync to improve the likelihood that file is actually written to disk
@ -149,8 +144,7 @@ pub fn append_initrd_secrets(
return Err(anyhow::anyhow!( return Err(anyhow::anyhow!(
"Failed to append initrd secrets with args `{:?}`", "Failed to append initrd secrets with args `{:?}`",
vec![append_initrd_secrets_path, initrd_path] vec![append_initrd_secrets_path, initrd_path]
) ));
.into());
} }
Ok(()) Ok(())

View File

@ -4,7 +4,7 @@ mod esp;
mod generation; mod generation;
mod install; mod install;
mod pe; mod pe;
mod signer; mod signature;
mod utils; mod utils;
use anyhow::Result; use anyhow::Result;

View File

@ -1,7 +1,7 @@
use std::fs; use std::fs;
use std::io::Write; use std::io::Write;
use std::os::unix::prelude::OpenOptionsExt;
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
use std::os::unix::prelude::OpenOptionsExt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
@ -23,18 +23,21 @@ pub fn lanzaboote_image(
) -> Result<PathBuf> { ) -> Result<PathBuf> {
// objcopy copies files into the PE binary. That's why we have to write the contents // objcopy copies files into the PE binary. That's why we have to write the contents
// of some bootspec properties to disk // of some bootspec properties to disk
let (kernel_cmdline_file, _) = write_to_tmp(&target_dir, let (kernel_cmdline_file, _) =
"kernel-cmdline", write_to_tmp(target_dir, "kernel-cmdline", kernel_cmdline.join(" "))?;
kernel_cmdline.join(" "))?; let (kernel_path_file, _) = write_to_tmp(
let (kernel_path_file, _) = write_to_tmp(&target_dir, target_dir,
"kernel-esp-path", "kernel-esp-path",
esp_relative_path_string(esp, kernel_path))?; esp_relative_path_string(esp, kernel_path),
let (initrd_path_file, _) = write_to_tmp(&target_dir, )?;
let (initrd_path_file, _) = write_to_tmp(
target_dir,
"initrd-esp-path", "initrd-esp-path",
esp_relative_path_string(esp, initrd_path))?; esp_relative_path_string(esp, initrd_path),
)?;
let os_release_offs = stub_offset(lanzaboote_stub)?; let os_release_offs = stub_offset(lanzaboote_stub)?;
let kernel_cmdline_offs = os_release_offs + file_size(&os_release)?; let kernel_cmdline_offs = os_release_offs + file_size(os_release)?;
let initrd_path_offs = kernel_cmdline_offs + file_size(&kernel_cmdline_file)?; let initrd_path_offs = kernel_cmdline_offs + file_size(&kernel_cmdline_file)?;
let kernel_path_offs = initrd_path_offs + file_size(&initrd_path_file)?; let kernel_path_offs = initrd_path_offs + file_size(&initrd_path_file)?;
@ -45,7 +48,7 @@ pub fn lanzaboote_image(
s(".kernelp", kernel_path_file, kernel_path_offs), s(".kernelp", kernel_path_file, kernel_path_offs),
]; ];
wrap_in_pe(&target_dir, "lanzaboote-stub.efi", &lanzaboote_stub, sections) wrap_in_pe(target_dir, "lanzaboote-stub.efi", lanzaboote_stub, sections)
} }
pub fn wrap_initrd(target_dir: &TempDir, initrd_stub: &Path, initrd: &Path) -> Result<PathBuf> { pub fn wrap_initrd(target_dir: &TempDir, initrd_stub: &Path, initrd: &Path) -> Result<PathBuf> {
@ -54,7 +57,12 @@ pub fn wrap_initrd(target_dir: &TempDir, initrd_stub: &Path, initrd: &Path) -> R
wrap_in_pe(target_dir, "wrapped-initrd.exe", initrd_stub, sections) wrap_in_pe(target_dir, "wrapped-initrd.exe", initrd_stub, sections)
} }
fn wrap_in_pe(target_dir: &TempDir, filename: &str, stub: &Path, sections: Vec<Section>) -> Result<PathBuf> { fn wrap_in_pe(
target_dir: &TempDir,
filename: &str,
stub: &Path,
sections: Vec<Section>,
) -> Result<PathBuf> {
let image_path = target_dir.path().join(filename); let image_path = target_dir.path().join(filename);
let _ = fs::OpenOptions::new() let _ = fs::OpenOptions::new()
.create(true) .create(true)
@ -64,7 +72,10 @@ fn wrap_in_pe(target_dir: &TempDir, filename: &str, stub: &Path, sections: Vec<S
.context("Failed to generate named temp file")?; .context("Failed to generate named temp file")?;
let mut args: Vec<String> = sections.iter().flat_map(Section::to_objcopy).collect(); let mut args: Vec<String> = sections.iter().flat_map(Section::to_objcopy).collect();
let extra_args = vec![utils::path_to_string(stub), utils::path_to_string(&image_path)]; let extra_args = vec![
utils::path_to_string(stub),
utils::path_to_string(&image_path),
];
args.extend(extra_args); args.extend(extra_args);
let status = Command::new("objcopy") let status = Command::new("objcopy")
@ -72,7 +83,10 @@ fn wrap_in_pe(target_dir: &TempDir, filename: &str, stub: &Path, sections: Vec<S
.status() .status()
.context("Failed to run objcopy command")?; .context("Failed to run objcopy command")?;
if !status.success() { if !status.success() {
return Err(anyhow::anyhow!("Failed to wrap in pe with args `{:?}`", &args).into()); return Err(anyhow::anyhow!(
"Failed to wrap in pe with args `{:?}`",
&args
));
} }
Ok(image_path) Ok(image_path)
@ -103,7 +117,11 @@ fn s(name: &'static str, file_path: impl AsRef<Path>, offset: u64) -> Section {
} }
} }
fn write_to_tmp(secure_temp: &TempDir, filename: &str, contents: impl AsRef<[u8]>) -> Result<(PathBuf, fs::File)> { fn write_to_tmp(
secure_temp: &TempDir,
filename: &str,
contents: impl AsRef<[u8]>,
) -> Result<(PathBuf, fs::File)> {
let mut tmpfile = fs::OpenOptions::new() let mut tmpfile = fs::OpenOptions::new()
.create(true) .create(true)
.write(true) .write(true)
@ -125,7 +143,7 @@ fn esp_relative_path_string(esp: &Path, path: &Path) -> String {
.into_os_string() .into_os_string()
.into_string() .into_string()
.expect("Failed to convert path '{}' to a relative string path") .expect("Failed to convert path '{}' to a relative string path")
.replace("/", "\\"); .replace('/', "\\");
format!("\\{}", &relative_path_string) format!("\\{}", &relative_path_string)
} }
@ -140,7 +158,7 @@ fn stub_offset(binary: &Path) -> Result<u64> {
Ok(u64::from( Ok(u64::from(
pe.sections pe.sections
.last() .last()
.and_then(|s| Some(s.virtual_size + s.virtual_address)) .map(|s| s.virtual_size + s.virtual_address)
.expect("Failed to calculate offset"), .expect("Failed to calculate offset"),
) + image_base) ) + image_base)
} }

View File

@ -5,12 +5,12 @@ use anyhow::Result;
use crate::utils; use crate::utils;
pub struct Signer { pub struct KeyPair {
pub private_key: PathBuf, pub private_key: PathBuf,
pub public_key: PathBuf, pub public_key: PathBuf,
} }
impl Signer { impl KeyPair {
pub fn new(public_key: &Path, private_key: &Path) -> Self { pub fn new(public_key: &Path, private_key: &Path) -> Self {
Self { Self {
public_key: public_key.into(), public_key: public_key.into(),
@ -36,8 +36,7 @@ impl Signer {
return Err(anyhow::anyhow!( return Err(anyhow::anyhow!(
"Failed to sign file using sbsign with args `{:?}`", "Failed to sign file using sbsign with args `{:?}`",
&args &args
) ));
.into());
} }
Ok(()) Ok(())

View File

@ -2,8 +2,10 @@ use std::path::Path;
// All Linux file paths should be convertable to strings // All Linux file paths should be convertable to strings
pub fn path_to_string(path: impl AsRef<Path>) -> String { pub fn path_to_string(path: impl AsRef<Path>) -> String {
String::from(path.as_ref().to_str().expect(&format!( String::from(path.as_ref().to_str().unwrap_or_else(|| {
panic!(
"Failed to convert path '{}' to a string", "Failed to convert path '{}' to a string",
path.as_ref().display() path.as_ref().display()
))) )
}))
} }