use shared libs, enabling openssl in init
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
use eyre::{Result, format_err};
|
||||
use eyre::{format_err, Result};
|
||||
use log::{error, info, warn};
|
||||
use std::collections::BTreeSet as Set;
|
||||
use std::os::unix::fs::symlink;
|
||||
@ -220,6 +220,8 @@ async fn extract_cpio_entry<R: std::io::Read>(
|
||||
fs::create_dir_all(parent).await?;
|
||||
}
|
||||
|
||||
let _ = fs::remove_file(path).await;
|
||||
|
||||
let mode = entry.mode();
|
||||
let uid = entry.uid();
|
||||
let gid = entry.gid();
|
||||
@ -259,30 +261,26 @@ async fn mount(src: Option<&str>, dst: &str, fstype: &str, opts: Option<&str>) {
|
||||
error!("failed to create dir {dst}: {e}");
|
||||
}
|
||||
|
||||
let mut is_file = false;
|
||||
retry_or_ignore(async || {
|
||||
let mut is_file = false;
|
||||
|
||||
if let Some(src) = src {
|
||||
retry_or_ignore(async || {
|
||||
if let Some(src) = src {
|
||||
is_file = (fs::metadata(src).await)
|
||||
.map_err(|e| format_err!("stat {src} failed: {e}"))?
|
||||
.is_file();
|
||||
Ok(())
|
||||
})
|
||||
.await;
|
||||
match fstype {
|
||||
"ext4" => {
|
||||
exec("fsck.ext4", &["-p", src]).await;
|
||||
match fstype {
|
||||
"ext4" => {
|
||||
exec("fsck.ext4", &["-p", src]).await;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let mut args = vec![src.unwrap_or("none"), dst, "-t", fstype];
|
||||
if let Some(opts) = opts {
|
||||
args.extend(["-o", opts]);
|
||||
}
|
||||
let mut args = vec![src.unwrap_or("none"), dst, "-t", fstype];
|
||||
if let Some(opts) = opts {
|
||||
args.extend(["-o", opts]);
|
||||
}
|
||||
|
||||
retry_or_ignore(async || {
|
||||
// if it's a file, we need to use a loopdev
|
||||
if is_file {
|
||||
// loopdev crate has annoying dependencies, just use the normal mount program
|
||||
@ -392,9 +390,9 @@ fn cmd_str(prog: &str, args: &[&str]) -> (String, Command) {
|
||||
|
||||
#[allow(unused)]
|
||||
async fn child_reaper() {
|
||||
use nix::sys::wait::{WaitPidFlag, waitpid};
|
||||
use nix::sys::wait::{waitpid, WaitPidFlag};
|
||||
use nix::unistd::Pid;
|
||||
use tokio::signal::unix::{SignalKind, signal};
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
let Ok(mut sigs) =
|
||||
signal(SignalKind::child()).inspect_err(|e| warn!("failed to setup SIGCHLD handler: {e}"))
|
||||
@ -418,7 +416,7 @@ async fn switch_root(root: &str) -> Result<()> {
|
||||
info!("killing all processes and switching root");
|
||||
dklog::LOG.close().await;
|
||||
|
||||
use nix::sys::signal::{SIGKILL, kill};
|
||||
use nix::sys::signal::{kill, SIGKILL};
|
||||
use nix::unistd::Pid;
|
||||
|
||||
if let Err(e) = kill(Pid::from_raw(-1), SIGKILL) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
use eyre::{Result, format_err};
|
||||
use eyre::{format_err, Result};
|
||||
use log::{info, warn};
|
||||
use tokio::{
|
||||
fs,
|
||||
io::{AsyncBufReadExt, BufReader},
|
||||
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
|
||||
};
|
||||
|
||||
use dkl::{
|
||||
@ -77,42 +77,36 @@ impl Verifier {
|
||||
return Ok(Self { pubkey: None });
|
||||
};
|
||||
|
||||
use base64::{Engine, prelude::BASE64_STANDARD};
|
||||
use base64::{prelude::BASE64_STANDARD, Engine};
|
||||
let pubkey = BASE64_STANDARD.decode(pubkey)?;
|
||||
let pubkey = Some(pubkey);
|
||||
|
||||
return Ok(Self { pubkey });
|
||||
}
|
||||
|
||||
async fn verify_path(&self, path: &str) -> Result<()> {
|
||||
async fn verify_path(&self, path: &str) -> Result<Vec<u8>> {
|
||||
let data = (fs::read(path).await).map_err(|e| format_err!("failed to read {path}: {e}"))?;
|
||||
|
||||
let Some(ref pubkey) = self.pubkey else {
|
||||
return Ok(());
|
||||
return Ok(data);
|
||||
};
|
||||
|
||||
info!("verifying {path}");
|
||||
|
||||
let mut pubkey = std::io::Cursor::new(pubkey);
|
||||
let sig = &format!("{path}.sig");
|
||||
let sig = (fs::read(sig).await).map_err(|e| format_err!("failed to read {sig}: {e}"))?;
|
||||
|
||||
let sig = format!("{path}.sig");
|
||||
use openssl::{hash::MessageDigest, pkey::PKey, sign::Verifier};
|
||||
let pubkey = PKey::public_key_from_der(pubkey)?;
|
||||
|
||||
use std::process::Stdio;
|
||||
use tokio::process::Command;
|
||||
let sig_ok = Verifier::new(MessageDigest::sha512(), &pubkey)?
|
||||
.verify_oneshot(&sig, &data)
|
||||
.map_err(|e| format_err!("verify failed: {e}"))?;
|
||||
|
||||
let mut openssl = Command::new("openssl")
|
||||
.stdin(Stdio::piped())
|
||||
.args(&["dgst", "-sha512", "-verify", "/dev/stdin"])
|
||||
.args(&["-signature", &sig, path])
|
||||
.spawn()?;
|
||||
|
||||
tokio::io::copy(&mut pubkey, openssl.stdin.as_mut().unwrap()).await?;
|
||||
|
||||
let status = openssl.wait().await?;
|
||||
if status.success() {
|
||||
Ok(())
|
||||
if sig_ok {
|
||||
Ok(data)
|
||||
} else {
|
||||
Err(format_err!(
|
||||
"signature verification failed for {path}: {status}"
|
||||
))
|
||||
Err(format_err!("signature verification failed for {path}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,9 +139,7 @@ async fn seed_config(
|
||||
return Err(format_err!("{cfg_path} does not exist after seeding"));
|
||||
}
|
||||
|
||||
verifier.verify_path(&cfg_path).await?;
|
||||
|
||||
Ok(fs::read(cfg_path).await?)
|
||||
verifier.verify_path(&cfg_path).await
|
||||
}
|
||||
|
||||
async fn fetch_bootstrap(seed_url: &str, output_file: &str) -> Result<()> {
|
||||
@ -186,19 +178,24 @@ async fn mount_system(cfg: &dkl::Config, bs_dir: &str, verifier: &Verifier) {
|
||||
let mut lower_dir = String::new();
|
||||
|
||||
for layer in &cfg.layers {
|
||||
let src = if layer == "modules" {
|
||||
"/modules.sqfs".to_string()
|
||||
} else {
|
||||
let p = format!("{bs_dir}/{layer}.fs");
|
||||
retry(async || verifier.verify_path(&p).await).await;
|
||||
p
|
||||
};
|
||||
let src = retry(async || {
|
||||
if layer == "modules" {
|
||||
(fs::read("/modules.sqfs").await)
|
||||
.map_err(|e| format_err!("read /modules.sqfs failed: {e}"))
|
||||
} else {
|
||||
verifier.verify_path(&format!("{bs_dir}/{layer}.fs")).await
|
||||
}
|
||||
})
|
||||
.await;
|
||||
|
||||
let tgt = &format!("{mem_dir}/{layer}.fs");
|
||||
retry(async || {
|
||||
info!("copying layer {layer} from {src}");
|
||||
fs::copy(&src, tgt).await?;
|
||||
Ok(())
|
||||
info!("copying layer {layer}");
|
||||
|
||||
let mut out = (fs::File::create(tgt).await)
|
||||
.map_err(|e| format_err!("create {tgt} failed: {e}"))?;
|
||||
(out.write_all(&src).await).map_err(|e| format_err!("write failed: {e}"))?;
|
||||
(out.flush().await).map_err(|e| format_err!("write failed: {e}"))
|
||||
})
|
||||
.await;
|
||||
|
||||
|
Reference in New Issue
Block a user