verbose
This commit is contained in:
parent
8e98bf024e
commit
2ed7f8141f
83
src/cli.rs
83
src/cli.rs
@ -17,7 +17,7 @@ use structopt::clap::Shell;
|
|||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
fn read_pin() -> Fido2LuksResult<String> {
|
fn read_pin() -> Fido2LuksResult<String> {
|
||||||
util::read_password("Authenticator PIN", false)
|
util::read_password_tty("Authenticator PIN", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_secret(
|
fn derive_secret(
|
||||||
@ -98,14 +98,11 @@ pub fn get_input(
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
salt.obtain_sha256(Some(|| util::read_password(q, verify)))?,
|
salt.obtain_sha256(Some(|| util::read_password_tty(q, verify)))?,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
match (authenticator.pin, authenticator.pin_prefixed) {
|
match (authenticator.pin, authenticator.pin_prefixed) {
|
||||||
(true, false) => (
|
(true, false) => (Some(read_pin()?), salt.obtain_sha256(password_helper)?),
|
||||||
Some(read_pin()?),
|
|
||||||
salt.obtain_sha256(password_helper)?,
|
|
||||||
),
|
|
||||||
(true, true) => read_password_pin_prefixed(|| {
|
(true, true) => read_password_pin_prefixed(|| {
|
||||||
salt.obtain(password_helper).and_then(|secret| {
|
salt.obtain(password_helper).and_then(|secret| {
|
||||||
String::from_utf8(secret).map_err(|e| Fido2LuksError::from(e))
|
String::from_utf8(secret).map_err(|e| Fido2LuksError::from(e))
|
||||||
@ -143,6 +140,11 @@ pub fn parse_cmdline() -> Args {
|
|||||||
pub fn run_cli() -> Fido2LuksResult<()> {
|
pub fn run_cli() -> Fido2LuksResult<()> {
|
||||||
let mut stdout = io::stdout();
|
let mut stdout = io::stdout();
|
||||||
let args = parse_cmdline();
|
let args = parse_cmdline();
|
||||||
|
let log = |message: &dyn Fn() -> String| {
|
||||||
|
if args.verbose {
|
||||||
|
eprintln!("{}", message());
|
||||||
|
}
|
||||||
|
};
|
||||||
match &args.command {
|
match &args.command {
|
||||||
Command::Credential {
|
Command::Credential {
|
||||||
authenticator,
|
authenticator,
|
||||||
@ -168,7 +170,10 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
} => {
|
} => {
|
||||||
let (pin, salt) =
|
let (pin, salt) =
|
||||||
get_input(&secret, &authenticator, args.interactive, "Password", false)?;
|
get_input(&secret, &authenticator, args.interactive, "Password", false)?;
|
||||||
let credentials = if let Some(dev) = device {
|
let credentials = if let Some(path) = device {
|
||||||
|
let mut dev = LuksDevice::load(path)?;
|
||||||
|
let luks2 = dev.is_luks2()?;
|
||||||
|
log(&|| format!("luks2 supported: {}", luks2));
|
||||||
extend_creds_device(
|
extend_creds_device(
|
||||||
credentials
|
credentials
|
||||||
.ids
|
.ids
|
||||||
@ -176,17 +181,28 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
.map(|cs| cs.0)
|
.map(|cs| cs.0)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.as_slice(),
|
.as_slice(),
|
||||||
&mut LuksDevice::load(dev)?,
|
&mut dev,
|
||||||
)?
|
)?
|
||||||
} else {
|
} else {
|
||||||
credentials.ids.clone().map(|cs| cs.0).unwrap_or_default()
|
credentials.ids.clone().map(|cs| cs.0).unwrap_or_default()
|
||||||
};
|
};
|
||||||
let (secret, _cred) = derive_secret(
|
log(&|| {
|
||||||
|
format!(
|
||||||
|
"credentials: {}",
|
||||||
|
credentials
|
||||||
|
.iter()
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
)
|
||||||
|
});
|
||||||
|
let (secret, cred) = derive_secret(
|
||||||
credentials.as_slice(),
|
credentials.as_slice(),
|
||||||
&salt,
|
&salt,
|
||||||
authenticator.await_time,
|
authenticator.await_time,
|
||||||
pin.as_deref(),
|
pin.as_deref(),
|
||||||
)?;
|
)?;
|
||||||
|
log(&|| format!("credential used: {}", hex::encode(&cred.id)));
|
||||||
if *binary {
|
if *binary {
|
||||||
stdout.write_all(&secret[..])?;
|
stdout.write_all(&secret[..])?;
|
||||||
} else {
|
} else {
|
||||||
@ -216,6 +232,8 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
|
|
||||||
let luks2 = luks_dev.is_luks2()?;
|
let luks2 = luks_dev.is_luks2()?;
|
||||||
|
|
||||||
|
log(&|| format!("luks2 supported: {}", luks2));
|
||||||
|
|
||||||
let credentials = if !luks.disable_token && luks2 {
|
let credentials = if !luks.disable_token && luks2 {
|
||||||
extend_creds_device(
|
extend_creds_device(
|
||||||
credentials
|
credentials
|
||||||
@ -229,7 +247,16 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
} else {
|
} else {
|
||||||
credentials.ids.clone().map(|cs| cs.0).unwrap_or_default()
|
credentials.ids.clone().map(|cs| cs.0).unwrap_or_default()
|
||||||
};
|
};
|
||||||
|
log(&|| {
|
||||||
|
format!(
|
||||||
|
"credentials: {}",
|
||||||
|
credentials
|
||||||
|
.iter()
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
)
|
||||||
|
});
|
||||||
let inputs = |q: &str, verify: bool| -> Fido2LuksResult<(Option<String>, [u8; 32])> {
|
let inputs = |q: &str, verify: bool| -> Fido2LuksResult<(Option<String>, [u8; 32])> {
|
||||||
get_input(&secret, &authenticator, args.interactive, q, verify)
|
get_input(&secret, &authenticator, args.interactive, q, verify)
|
||||||
};
|
};
|
||||||
@ -255,7 +282,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
.map(|(secret, cred)| (secret[..].to_vec(), Some(cred)))?)
|
.map(|(secret, cred)| (secret[..].to_vec(), Some(cred)))?)
|
||||||
}
|
}
|
||||||
_ => Ok((
|
_ => Ok((
|
||||||
util::read_password(salt_q, verify)?.as_bytes().to_vec(),
|
util::read_password_tty(salt_q, verify)?.as_bytes().to_vec(),
|
||||||
None,
|
None,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
@ -284,6 +311,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
} else {
|
} else {
|
||||||
secret(true, &credentials)
|
secret(true, &credentials)
|
||||||
}?;
|
}?;
|
||||||
|
log(&|| format!("credential used: {}", hex::encode(&cred.id)));
|
||||||
let added_slot = luks_dev.add_key(
|
let added_slot = luks_dev.add_key(
|
||||||
&new_secret,
|
&new_secret,
|
||||||
&existing_secret[..],
|
&existing_secret[..],
|
||||||
@ -341,6 +369,9 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
}
|
}
|
||||||
Ok(slot)
|
Ok(slot)
|
||||||
}?;
|
}?;
|
||||||
|
if let Some(cred) = cred {
|
||||||
|
log(&|| format!("credential used: {}", hex::encode(&cred.id)));
|
||||||
|
}
|
||||||
println!(
|
println!(
|
||||||
"Added to password to device {}, slot: {}",
|
"Added to password to device {}, slot: {}",
|
||||||
luks.device.display(),
|
luks.device.display(),
|
||||||
@ -377,21 +408,38 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
|
|
||||||
let mut retries = *retries;
|
let mut retries = *retries;
|
||||||
let mut luks_dev = LuksDevice::load(&luks.device)?;
|
let mut luks_dev = LuksDevice::load(&luks.device)?;
|
||||||
|
let luks2 = luks_dev.is_luks2()?;
|
||||||
|
log(&|| format!("luks2 supported: {}", luks2));
|
||||||
loop {
|
loop {
|
||||||
let slot = if let Some(ref credentials) = credentials.ids {
|
let slot = if let Some(ref credentials) = credentials.ids {
|
||||||
secret(Cow::Borrowed(&credentials.0)).and_then(|(secret, _cred)| {
|
log(&|| {
|
||||||
|
format!(
|
||||||
|
"credentials: {}",
|
||||||
|
credentials
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
)
|
||||||
|
});
|
||||||
|
secret(Cow::Borrowed(&credentials.0)).and_then(|(secret, cred)| {
|
||||||
|
log(&|| format!("credential used: {}", hex::encode(&cred.id)));
|
||||||
luks_dev.activate(&name, &secret, luks.slot, *dry_run)
|
luks_dev.activate(&name, &secret, luks.slot, *dry_run)
|
||||||
})
|
})
|
||||||
} else if luks_dev.is_luks2()? && !luks.disable_token {
|
} else if luks2 && !luks.disable_token {
|
||||||
luks_dev.activate_token(
|
luks_dev.activate_token(
|
||||||
&name,
|
&name,
|
||||||
Box::new(|credentials: Vec<String>| {
|
Box::new(|credentials: Vec<String>| {
|
||||||
|
log(&|| format!("credentials: {}", credentials.join(", ")));
|
||||||
let creds = credentials
|
let creds = credentials
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|cred| HexEncoded::from_str(cred.as_ref()).ok())
|
.flat_map(|cred| HexEncoded::from_str(cred.as_ref()).ok())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
secret(Cow::Owned(creds))
|
secret(Cow::Owned(creds)).map(|(secret, cred)| {
|
||||||
.map(|(secret, cred)| (secret, hex::encode(&cred.id)))
|
log(&|| format!("credential used: {}", hex::encode(&cred.id)));
|
||||||
|
(secret, hex::encode(&cred.id))
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
luks.slot,
|
luks.slot,
|
||||||
*dry_run,
|
*dry_run,
|
||||||
@ -414,7 +462,10 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
retries -= 1;
|
retries -= 1;
|
||||||
eprintln!("{}", e);
|
eprintln!("{}", e);
|
||||||
}
|
}
|
||||||
res => break res.map(|_| ()),
|
Ok(slot) => {
|
||||||
|
log(&|| format!("keyslot: {}", slot));
|
||||||
|
break Ok(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ impl PasswordHelper {
|
|||||||
use PasswordHelper::*;
|
use PasswordHelper::*;
|
||||||
match self {
|
match self {
|
||||||
Systemd => unimplemented!(),
|
Systemd => unimplemented!(),
|
||||||
Stdin => Ok(util::read_password("Password", true)?),
|
Stdin => Ok(util::read_password("Password", true, false)?),
|
||||||
Script(password_helper) => {
|
Script(password_helper) => {
|
||||||
let password = Command::new("sh")
|
let password = Command::new("sh")
|
||||||
.arg("-c")
|
.arg("-c")
|
||||||
|
@ -147,6 +147,8 @@ pub struct Args {
|
|||||||
/// Request passwords via Stdin instead of using the password helper
|
/// Request passwords via Stdin instead of using the password helper
|
||||||
#[structopt(short = "i", long = "interactive")]
|
#[structopt(short = "i", long = "interactive")]
|
||||||
pub interactive: bool,
|
pub interactive: bool,
|
||||||
|
#[structopt(short = "v", long = "verbose")]
|
||||||
|
pub verbose: bool,
|
||||||
#[structopt(subcommand)]
|
#[structopt(subcommand)]
|
||||||
pub command: Command,
|
pub command: Command,
|
||||||
}
|
}
|
||||||
|
18
src/util.rs
18
src/util.rs
@ -13,9 +13,17 @@ pub fn sha256(messages: &[&[u8]]) -> [u8; 32] {
|
|||||||
secret.as_mut().copy_from_slice(digest.finish().as_ref());
|
secret.as_mut().copy_from_slice(digest.finish().as_ref());
|
||||||
secret
|
secret
|
||||||
}
|
}
|
||||||
|
pub fn read_password_tty(q: &str, verify: bool) -> Fido2LuksResult<String> {
|
||||||
pub fn read_password(q: &str, verify: bool) -> Fido2LuksResult<String> {
|
read_password(q, verify, true)
|
||||||
match rpassword::read_password_from_tty(Some(&[q, ": "].join("")))? {
|
}
|
||||||
|
pub fn read_password(q: &str, verify: bool, tty: bool) -> Fido2LuksResult<String> {
|
||||||
|
let res = if tty {
|
||||||
|
rpassword::read_password_from_tty(Some(&[q, ": "].join("")))
|
||||||
|
} else {
|
||||||
|
print!("{}: ", q);
|
||||||
|
rpassword::read_password()
|
||||||
|
}?;
|
||||||
|
match res {
|
||||||
ref pass
|
ref pass
|
||||||
if verify
|
if verify
|
||||||
&& &rpassword::read_password_from_tty(Some(&[q, "(again): "].join(" ")))?
|
&& &rpassword::read_password_from_tty(Some(&[q, "(again): "].join(" ")))?
|
||||||
@ -29,10 +37,6 @@ pub fn read_password(q: &str, verify: bool) -> Fido2LuksResult<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_password_hashed(q: &str, verify: bool) -> Fido2LuksResult<[u8; 32]> {
|
|
||||||
read_password(q, verify).map(|pass| sha256(&[pass.as_bytes()]))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_keyfile<P: Into<PathBuf>>(path: P) -> Fido2LuksResult<Vec<u8>> {
|
pub fn read_keyfile<P: Into<PathBuf>>(path: P) -> Fido2LuksResult<Vec<u8>> {
|
||||||
let mut file = File::open(path.into())?;
|
let mut file = File::open(path.into())?;
|
||||||
let mut key = Vec::new();
|
let mut key = Vec::new();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user