diff --git a/dracut/96luks-2fa/luks-2fa-generator.sh b/dracut/96luks-2fa/luks-2fa-generator.sh index a6b16ae..37b182c 100755 --- a/dracut/96luks-2fa/luks-2fa-generator.sh +++ b/dracut/96luks-2fa/luks-2fa-generator.sh @@ -32,13 +32,12 @@ generate_service () { printf -- "\n\n[Service]" printf -- "\nType=oneshot" printf -- "\nRemainAfterExit=yes" + printf -- "\nEnvironmentFile='%s'" "/etc/luks-2fa.conf" printf -- "\nEnvironment=FIDO2LUKS_CREDENTIAL_ID='%s'" "$credential_id" - printf -- "\nEnvironment=FIDO2LUKS_SALT='%s'" "Ask" - printf -- "\nEnvironment=FIDO2LUKS_PASSWORD_HELPER='%s'" "/usr/bin/systemd-ask-password Disk 2fa password" printf -- "\nKeyringMode=%s" "shared" - printf -- "\nExecStartPre=-/usr/bin/plymouth display-message --text \"${CON_MSG}\"" - printf -- "\nExecStartPre=-/bin/bash -c \"while ! ${FIDO2LUKS} connected; do /usr/bin/sleep 1; done\"" - printf -- "\nExecStartPre=-/usr/bin/plymouth hide-message --text \"${CON_MSG}\"" + printf -- "\nExecStartPre=-/usr/bin/plymouth display-message --text \"${CON_MSG}\"" + printf -- "\nExecStartPre=-/bin/bash -c \"while ! ${FIDO2LUKS} connected; do /usr/bin/sleep 1; done\"" + printf -- "\nExecStartPre=-/usr/bin/plymouth hide-message --text \"${CON_MSG}\"" printf -- "\nExecStart=/bin/bash -c \"${FIDO2LUKS} print-secret --bin | ${CRYPTSETUP} attach 'luks-%s' '/dev/disk/by-uuid/%s' '/dev/stdin'\"" "$target_uuid" "$target_uuid" printf -- "\nExecStop=${CRYPTSETUP} detach 'luks-%s'" "$target_uuid" } > "$sd_service" diff --git a/dracut/96luks-2fa/luks-2fa.conf b/dracut/96luks-2fa/luks-2fa.conf new file mode 100644 index 0000000..c34bd13 --- /dev/null +++ b/dracut/96luks-2fa/luks-2fa.conf @@ -0,0 +1 @@ +FIDO2LUKS_SALT=Ask \ No newline at end of file diff --git a/dracut/96luks-2fa/module-setup.sh b/dracut/96luks-2fa/module-setup.sh index d3eb8b0..8471076 100755 --- a/dracut/96luks-2fa/module-setup.sh +++ b/dracut/96luks-2fa/module-setup.sh @@ -18,6 +18,7 @@ depends () { install () { inst "$moddir/luks-2fa-generator.sh" "/etc/systemd/system-generators/luks-2fa-generator.sh" inst_simple "/usr/bin/fido2luks" "/usr/bin/fido2luks" + inst_simple "$moddir/luks-2fa.conf" "/etc/luks-2fa.conf" inst "$systemdutildir/systemd-cryptsetup" mkdir -p "$initdir/luks-2fa" diff --git a/src/cli.rs b/src/cli.rs index fa3ef5a..a716bb7 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -88,8 +88,13 @@ pub struct SecretGeneration { /// FIDO credential id, generate using fido2luks credential #[structopt(name = "credential-id", env = "FIDO2LUKS_CREDENTIAL_ID")] pub credential_id: String, - /// Salt for secret generation, defaults to Password - #[structopt(name = "salt", env = "FIDO2LUKS_SALT", default_value = "Ask")] + /// Salt for secret generation, defaults to 'ask' + /// + /// Options:{n} + /// - ask : Promt user using password helper{n} + /// - file: : Will read {n} + /// - string: : Will use , which will be handled like a password provided to the 'ask' option{n} + #[structopt(name = "salt", env = "FIDO2LUKS_SALT", default_value = "ask")] pub salt: InputSalt, /// Script used to obtain passwords, overridden by --interactive flag #[structopt( diff --git a/src/config.rs b/src/config.rs index a3dde17..5dcabdb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,11 +10,11 @@ use std::path::PathBuf; use std::process::Command; use std::str::FromStr; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum InputSalt { AskPassword, + String(String), File { path: PathBuf }, - Both { path: PathBuf }, } impl Default for InputSalt { @@ -25,10 +25,14 @@ impl Default for InputSalt { impl From<&str> for InputSalt { fn from(s: &str) -> Self { - if PathBuf::from(s).exists() && s != "Ask" { - InputSalt::File { path: s.into() } - } else { - InputSalt::AskPassword + let mut parts = s.split(":").into_iter(); + match parts.next() { + Some("ask") | Some("Ask") => InputSalt::AskPassword, + Some("file") => InputSalt::File { + path: parts.collect::>().join(":").into(), + }, + Some("string") => InputSalt::String(parts.collect::>().join(":")), + _ => Self::default(), } } } @@ -45,8 +49,8 @@ impl fmt::Display for InputSalt { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.write_str(&match self { InputSalt::AskPassword => "ask".to_string(), - InputSalt::File { path } => path.display().to_string(), - InputSalt::Both { path } => ["ask", path.display().to_string().as_str()].join(" + "), + InputSalt::String(s) => ["string", s].join(":"), + InputSalt::File { path } => ["file", path.display().to_string().as_str()].join(":"), }) } } @@ -73,10 +77,7 @@ impl InputSalt { InputSalt::AskPassword => { digest.input(password_helper.obtain()?.as_bytes()); } - InputSalt::Both { path } => { - digest.input(&InputSalt::AskPassword.obtain(password_helper)?); - digest.input(&InputSalt::File { path: path.clone() }.obtain(password_helper)?) - } + InputSalt::String(s) => digest.input(s.as_bytes()), } let mut salt = [0u8; 32]; digest.result(&mut salt); @@ -148,3 +149,25 @@ impl PasswordHelper { } } } + +#[cfg(test)] +mod test { + + use super::*; + + #[test] + fn input_salt_from_str() { + assert_eq!( + "file:/tmp/abc".parse::().unwrap(), + InputSalt::File { + path: "/tmp/abc".into() + } + ); + assert_eq!( + "string:abc".parse::().unwrap(), + InputSalt::String("abc".into()) + ); + assert_eq!("ask".parse::().unwrap(), InputSalt::AskPassword); + assert_eq!("lol".parse::().unwrap(), InputSalt::default()); + } +}