move cli into module
This commit is contained in:
parent
7596019042
commit
ff509d75b0
@ -1,10 +1,10 @@
|
|||||||
|
use crate::cli::config::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
use structopt::clap::AppSettings;
|
use structopt::clap::AppSettings;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use failure::_core::fmt::{Display, Error, Formatter};
|
use std::fmt::{Display, Error, Formatter};
|
||||||
use failure::_core::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
pub struct HexEncoded(pub Vec<u8>);
|
pub struct HexEncoded(pub Vec<u8>);
|
||||||
@ -112,7 +112,7 @@ pub struct SecretParameters {
|
|||||||
env = "FIDO2LUKS_SALT",
|
env = "FIDO2LUKS_SALT",
|
||||||
default_value = "ask"
|
default_value = "ask"
|
||||||
)]
|
)]
|
||||||
pub salt: InputSalt,
|
pub salt: SecretInput,
|
||||||
/// Script used to obtain passwords, overridden by --interactive flag
|
/// Script used to obtain passwords, overridden by --interactive flag
|
||||||
#[structopt(
|
#[structopt(
|
||||||
name = "password-helper",
|
name = "password-helper",
|
@ -10,33 +10,33 @@ use std::process::Command;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum InputSalt {
|
pub enum SecretInput {
|
||||||
AskPassword,
|
AskPassword,
|
||||||
String(String),
|
String(String),
|
||||||
File { path: PathBuf },
|
File { path: PathBuf },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for InputSalt {
|
impl Default for SecretInput {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
InputSalt::AskPassword
|
SecretInput::AskPassword
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&str> for InputSalt {
|
impl From<&str> for SecretInput {
|
||||||
fn from(s: &str) -> Self {
|
fn from(s: &str) -> Self {
|
||||||
let mut parts = s.split(':');
|
let mut parts = s.split(':');
|
||||||
match parts.next() {
|
match parts.next() {
|
||||||
Some("ask") | Some("Ask") => InputSalt::AskPassword,
|
Some("ask") | Some("Ask") => SecretInput::AskPassword,
|
||||||
Some("file") => InputSalt::File {
|
Some("file") => SecretInput::File {
|
||||||
path: parts.collect::<Vec<_>>().join(":").into(),
|
path: parts.collect::<Vec<_>>().join(":").into(),
|
||||||
},
|
},
|
||||||
Some("string") => InputSalt::String(parts.collect::<Vec<_>>().join(":")),
|
Some("string") => SecretInput::String(parts.collect::<Vec<_>>().join(":")),
|
||||||
_ => Self::default(),
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for InputSalt {
|
impl FromStr for SecretInput {
|
||||||
type Err = Fido2LuksError;
|
type Err = Fido2LuksError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
@ -44,21 +44,42 @@ impl FromStr for InputSalt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for InputSalt {
|
impl fmt::Display for SecretInput {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
f.write_str(&match self {
|
f.write_str(&match self {
|
||||||
InputSalt::AskPassword => "ask".to_string(),
|
SecretInput::AskPassword => "ask".to_string(),
|
||||||
InputSalt::String(s) => ["string", s].join(":"),
|
SecretInput::String(s) => ["string", s].join(":"),
|
||||||
InputSalt::File { path } => ["file", path.display().to_string().as_str()].join(":"),
|
SecretInput::File { path } => ["file", path.display().to_string().as_str()].join(":"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputSalt {
|
impl SecretInput {
|
||||||
pub fn obtain(&self, password_helper: &PasswordHelper) -> Fido2LuksResult<[u8; 32]> {
|
pub fn obtain_string(&self, password_helper: &PasswordHelper) -> Fido2LuksResult<String> {
|
||||||
|
Ok(String::from_utf8(self.obtain(password_helper)?)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn obtain(&self, password_helper: &PasswordHelper) -> Fido2LuksResult<Vec<u8>> {
|
||||||
|
let mut secret = Vec::new();
|
||||||
|
match self {
|
||||||
|
SecretInput::File { path } => {
|
||||||
|
//TODO: replace with try_blocks
|
||||||
|
let mut do_io = || File::open(path)?.read_to_end(&mut secret);
|
||||||
|
do_io().map_err(|cause| Fido2LuksError::KeyfileError { cause })?;
|
||||||
|
}
|
||||||
|
SecretInput::AskPassword => {
|
||||||
|
secret.extend_from_slice(password_helper.obtain()?.as_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
SecretInput::String(s) => secret.extend_from_slice(s.as_bytes()),
|
||||||
|
}
|
||||||
|
Ok(secret)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn obtain_sha256(&self, password_helper: &PasswordHelper) -> Fido2LuksResult<[u8; 32]> {
|
||||||
let mut digest = digest::Context::new(&digest::SHA256);
|
let mut digest = digest::Context::new(&digest::SHA256);
|
||||||
match self {
|
match self {
|
||||||
InputSalt::File { path } => {
|
SecretInput::File { path } => {
|
||||||
let mut do_io = || {
|
let mut do_io = || {
|
||||||
let mut reader = File::open(path)?;
|
let mut reader = File::open(path)?;
|
||||||
let mut buf = [0u8; 512];
|
let mut buf = [0u8; 512];
|
||||||
@ -73,10 +94,7 @@ impl InputSalt {
|
|||||||
};
|
};
|
||||||
do_io().map_err(|cause| Fido2LuksError::KeyfileError { cause })?;
|
do_io().map_err(|cause| Fido2LuksError::KeyfileError { cause })?;
|
||||||
}
|
}
|
||||||
InputSalt::AskPassword => {
|
_ => digest.update(self.obtain(password_helper)?.as_slice()),
|
||||||
digest.update(password_helper.obtain()?.as_bytes());
|
|
||||||
}
|
|
||||||
InputSalt::String(s) => digest.update(s.as_bytes()),
|
|
||||||
}
|
}
|
||||||
let mut salt = [0u8; 32];
|
let mut salt = [0u8; 32];
|
||||||
salt.as_mut().copy_from_slice(digest.finish().as_ref());
|
salt.as_mut().copy_from_slice(digest.finish().as_ref());
|
||||||
@ -157,23 +175,29 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn input_salt_from_str() {
|
fn input_salt_from_str() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"file:/tmp/abc".parse::<InputSalt>().unwrap(),
|
"file:/tmp/abc".parse::<SecretInput>().unwrap(),
|
||||||
InputSalt::File {
|
SecretInput::File {
|
||||||
path: "/tmp/abc".into()
|
path: "/tmp/abc".into()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"string:abc".parse::<InputSalt>().unwrap(),
|
"string:abc".parse::<SecretInput>().unwrap(),
|
||||||
InputSalt::String("abc".into())
|
SecretInput::String("abc".into())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
"ask".parse::<SecretInput>().unwrap(),
|
||||||
|
SecretInput::AskPassword
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
"lol".parse::<SecretInput>().unwrap(),
|
||||||
|
SecretInput::default()
|
||||||
);
|
);
|
||||||
assert_eq!("ask".parse::<InputSalt>().unwrap(), InputSalt::AskPassword);
|
|
||||||
assert_eq!("lol".parse::<InputSalt>().unwrap(), InputSalt::default());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn input_salt_obtain() {
|
fn input_salt_obtain() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
InputSalt::String("abc".into())
|
SecretInput::String("abc".into())
|
||||||
.obtain(&PasswordHelper::Stdin)
|
.obtain(&PasswordHelper::Stdin)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
[
|
[
|
@ -1,25 +1,30 @@
|
|||||||
use crate::cli_args::*;
|
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::luks::{Fido2LuksToken, LuksDevice};
|
use crate::luks::{Fido2LuksToken, LuksDevice};
|
||||||
use crate::util::sha256;
|
use crate::util::sha256;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use cli_args::*;
|
||||||
|
use config::*;
|
||||||
|
|
||||||
use structopt::clap::Shell;
|
use structopt::clap::Shell;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use ctap::{FidoCredential, FidoErrorKind};
|
use ctap::{FidoCredential, FidoErrorKind};
|
||||||
|
|
||||||
use failure::_core::str::FromStr;
|
|
||||||
use failure::_core::time::Duration;
|
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::process::exit;
|
use std::str::FromStr;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
pub use cli_args::Args;
|
||||||
|
|
||||||
|
mod cli_args;
|
||||||
|
mod config;
|
||||||
|
|
||||||
fn read_pin(ap: &AuthenticatorParameters) -> Fido2LuksResult<String> {
|
fn read_pin(ap: &AuthenticatorParameters) -> Fido2LuksResult<String> {
|
||||||
if let Some(src) = ap.pin_source.as_ref() {
|
if let Some(src) = ap.pin_source.as_ref() {
|
||||||
let mut pin = String::new();
|
let mut pin = String::new();
|
||||||
@ -106,7 +111,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
let salt = if interactive || secret.password_helper == PasswordHelper::Stdin {
|
let salt = if interactive || secret.password_helper == PasswordHelper::Stdin {
|
||||||
util::read_password_hashed("Password", false)
|
util::read_password_hashed("Password", false)
|
||||||
} else {
|
} else {
|
||||||
secret.salt.obtain(&secret.password_helper)
|
secret.salt.obtain_sha256(&secret.password_helper)
|
||||||
}?;
|
}?;
|
||||||
let (secret, _cred) = derive_secret(
|
let (secret, _cred) = derive_secret(
|
||||||
credentials.ids.0.as_slice(),
|
credentials.ids.0.as_slice(),
|
||||||
@ -150,7 +155,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
if interactive || secret.password_helper == PasswordHelper::Stdin {
|
if interactive || secret.password_helper == PasswordHelper::Stdin {
|
||||||
util::read_password_hashed(q, verify)
|
util::read_password_hashed(q, verify)
|
||||||
} else {
|
} else {
|
||||||
secret.salt.obtain(&secret.password_helper)
|
secret.salt.obtain_sha256(&secret.password_helper)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let other_secret = |salt_q: &str,
|
let other_secret = |salt_q: &str,
|
||||||
@ -267,7 +272,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
if interactive || secret.password_helper == PasswordHelper::Stdin {
|
if interactive || secret.password_helper == PasswordHelper::Stdin {
|
||||||
util::read_password_hashed(q, verify)
|
util::read_password_hashed(q, verify)
|
||||||
} else {
|
} else {
|
||||||
secret.salt.obtain(&secret.password_helper)
|
secret.salt.obtain_sha256(&secret.password_helper)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1,5 +1,9 @@
|
|||||||
use ctap::FidoError;
|
use ctap::FidoError;
|
||||||
|
use libcryptsetup_rs::LibcryptErr;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::io::ErrorKind;
|
||||||
|
use std::string::FromUtf8Error;
|
||||||
|
use Fido2LuksError::*;
|
||||||
|
|
||||||
pub type Fido2LuksResult<T> = Result<T, Fido2LuksError>;
|
pub type Fido2LuksResult<T> = Result<T, Fido2LuksError>;
|
||||||
|
|
||||||
@ -81,11 +85,6 @@ impl From<LuksError> for Fido2LuksError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use libcryptsetup_rs::LibcryptErr;
|
|
||||||
use std::io::ErrorKind;
|
|
||||||
use std::string::FromUtf8Error;
|
|
||||||
use Fido2LuksError::*;
|
|
||||||
|
|
||||||
impl From<FidoError> for Fido2LuksError {
|
impl From<FidoError> for Fido2LuksError {
|
||||||
fn from(e: FidoError) -> Self {
|
fn from(e: FidoError) -> Self {
|
||||||
AuthenticatorError { cause: e }
|
AuthenticatorError { cause: e }
|
||||||
|
@ -4,7 +4,6 @@ extern crate ctap_hmac as ctap;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
use crate::cli::*;
|
use crate::cli::*;
|
||||||
use crate::config::*;
|
|
||||||
use crate::device::*;
|
use crate::device::*;
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -12,8 +11,6 @@ use std::path::PathBuf;
|
|||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
mod cli;
|
mod cli;
|
||||||
mod cli_args;
|
|
||||||
mod config;
|
|
||||||
mod device;
|
mod device;
|
||||||
mod error;
|
mod error;
|
||||||
mod luks;
|
mod luks;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user