request password only once if possible
This commit is contained in:
parent
0ba77963d2
commit
bb7ee7c1ce
41
src/cli.rs
41
src/cli.rs
@ -12,7 +12,9 @@ use std::io::Write;
|
|||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
use crate::util::read_password;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
pub struct HexEncoded(Vec<u8>);
|
pub struct HexEncoded(Vec<u8>);
|
||||||
|
|
||||||
@ -73,19 +75,38 @@ pub struct SecretGeneration {
|
|||||||
default_value = "15"
|
default_value = "15"
|
||||||
)]
|
)]
|
||||||
pub await_authenticator: u64,
|
pub await_authenticator: u64,
|
||||||
|
|
||||||
|
/// Request the password twice to ensure it being correct
|
||||||
|
#[structopt(
|
||||||
|
long = "verify-password",
|
||||||
|
env = "FIDO2LUKS_VERIFY_PASSWORD",
|
||||||
|
hidden = true
|
||||||
|
)]
|
||||||
|
pub verify_password: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SecretGeneration {
|
impl SecretGeneration {
|
||||||
pub fn patch(&self, args: &Args) -> Self {
|
pub fn patch(&self, args: &Args, verify_password: Option<bool>) -> Self {
|
||||||
let mut me = self.clone();
|
let mut me = self.clone();
|
||||||
if args.interactive {
|
if args.interactive {
|
||||||
me.password_helper = PasswordHelper::Stdin;
|
me.password_helper = PasswordHelper::Stdin;
|
||||||
}
|
}
|
||||||
|
me.verify_password = me.verify_password.or(verify_password);
|
||||||
me
|
me
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn obtain_secret(&self) -> Fido2LuksResult<[u8; 32]> {
|
pub fn obtain_secret(&self, password_query: &str) -> Fido2LuksResult<[u8; 32]> {
|
||||||
let salt = self.salt.obtain(&self.password_helper)?;
|
let mut salt = [0u8; 32];
|
||||||
|
match self.password_helper {
|
||||||
|
PasswordHelper::Stdin if !self.verify_password.unwrap_or(true) => {
|
||||||
|
salt.copy_from_slice(
|
||||||
|
read_password(password_query, self.verify_password.unwrap_or(true))?.as_bytes(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
salt = self.salt.obtain(&self.password_helper)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
let timeout = Duration::from_secs(self.await_authenticator);
|
let timeout = Duration::from_secs(self.await_authenticator);
|
||||||
let start = SystemTime::now();
|
let start = SystemTime::now();
|
||||||
|
|
||||||
@ -187,7 +208,9 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
binary,
|
binary,
|
||||||
ref secret_gen,
|
ref secret_gen,
|
||||||
} => {
|
} => {
|
||||||
let secret = secret_gen.patch(&args).obtain_secret()?;
|
let secret = secret_gen
|
||||||
|
.patch(&args, Some(false))
|
||||||
|
.obtain_secret("Password")?;
|
||||||
if *binary {
|
if *binary {
|
||||||
stdout.write(&secret[..])?;
|
stdout.write(&secret[..])?;
|
||||||
} else {
|
} else {
|
||||||
@ -201,12 +224,12 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
keyfile,
|
keyfile,
|
||||||
ref secret_gen,
|
ref secret_gen,
|
||||||
} => {
|
} => {
|
||||||
let secret = secret_gen.patch(&args).obtain_secret()?;
|
|
||||||
let old_secret = if let Some(keyfile) = keyfile.clone() {
|
let old_secret = if let Some(keyfile) = keyfile.clone() {
|
||||||
util::read_keyfile(keyfile.clone())
|
util::read_keyfile(keyfile.clone())
|
||||||
} else {
|
} else {
|
||||||
util::read_password("Old password", false).map(|p| p.as_bytes().to_vec())
|
util::read_password("Old password", false).map(|p| p.as_bytes().to_vec())
|
||||||
}?;
|
}?;
|
||||||
|
let secret = secret_gen.patch(&args, None).obtain_secret("Password")?;
|
||||||
let added_slot = luks::add_key(device.clone(), &secret, &old_secret[..], Some(10))?;
|
let added_slot = luks::add_key(device.clone(), &secret, &old_secret[..], Some(10))?;
|
||||||
if *exclusive {
|
if *exclusive {
|
||||||
let destroyed = luks::remove_keyslots(&device, &[added_slot])?;
|
let destroyed = luks::remove_keyslots(&device, &[added_slot])?;
|
||||||
@ -231,12 +254,14 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
keyfile,
|
keyfile,
|
||||||
ref secret_gen,
|
ref secret_gen,
|
||||||
} => {
|
} => {
|
||||||
let secret = secret_gen.patch(&args).obtain_secret()?;
|
|
||||||
let new_secret = if let Some(keyfile) = keyfile.clone() {
|
let new_secret = if let Some(keyfile) = keyfile.clone() {
|
||||||
util::read_keyfile(keyfile.clone())
|
util::read_keyfile(keyfile.clone())
|
||||||
} else {
|
} else {
|
||||||
util::read_password("Password to add", *add_password).map(|p| p.as_bytes().to_vec())
|
util::read_password("Password to add", *add_password).map(|p| p.as_bytes().to_vec())
|
||||||
}?;
|
}?;
|
||||||
|
let secret = secret_gen
|
||||||
|
.patch(&args, Some(false))
|
||||||
|
.obtain_secret("Password")?;
|
||||||
let slot = if *add_password {
|
let slot = if *add_password {
|
||||||
luks::add_key(device, &new_secret[..], &secret, None)
|
luks::add_key(device, &new_secret[..], &secret, None)
|
||||||
} else {
|
} else {
|
||||||
@ -257,7 +282,9 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
} => {
|
} => {
|
||||||
let mut retries = *retries;
|
let mut retries = *retries;
|
||||||
loop {
|
loop {
|
||||||
let secret = secret_gen.patch(&args).obtain_secret()?;
|
let secret = secret_gen
|
||||||
|
.patch(&args, Some(false))
|
||||||
|
.obtain_secret("Password")?;
|
||||||
match luks::open_container(&device, &name, &secret) {
|
match luks::open_container(&device, &name, &secret) {
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
Fido2LuksError::WrongSecret if retries > 0 => {
|
Fido2LuksError::WrongSecret if retries > 0 => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user