diff --git a/Cargo.lock b/Cargo.lock index 7c7e178..8e218d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,15 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -119,10 +128,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ba9b5e817f1bc1f2219b5a3474b69f838321b2a2ba8860d6a71c3bfe3d0fc1" dependencies = [ "backtrace", + "color-spantrace", "eyre", "indenter", "once_cell", "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a99aa4aa18448eef4c7d3f86d2720d2d8cad5c860fe9ff9b279293efdc8f5be" +dependencies = [ + "ansi_term 0.11.0", + "tracing-core", + "tracing-error", ] [[package]] @@ -966,7 +988,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82bb5079aa76438620837198db8a5c529fb9878c730bc2b28179b0241cf04c10" dependencies = [ - "ansi_term", + "ansi_term 0.12.1", "chrono", "lazy_static", "matchers", diff --git a/Cargo.toml b/Cargo.toml index 36c3e0d..b85c395 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -color-eyre = {version = "0.5.3", default-features =false} +color-eyre = "0.5.3" lazy_static = "1.4.0" cryptohelpers = {version = "1.1.2", features=["full", "async", "serialise"]} cfg-if = "0.1.10" diff --git a/src/args/error.rs b/src/args/error.rs index b79a1cc..0c749fe 100644 --- a/src/args/error.rs +++ b/src/args/error.rs @@ -57,6 +57,7 @@ impl From<(String, ParseErrorKind)> for Error #[non_exhaustive] pub enum ConstructError { + Dropped, NoGenerateKind, ExpectedNotPresent(&'static str), AlreadyExists(String), @@ -80,6 +81,7 @@ impl fmt::Display for ConstructError Self::ExpectedNotPresent(name) => write!(f, "expected a {}, one was not provided", name), Self::AlreadyExists(opt) => write!(f, "duplicate atom {}", opt), Self::Resolve(_) => write!(f, "error resolving autodetect"), + Self::Dropped => panic!("mpsc fatal: dropped rx shoudl've been handled not reported"), } } } diff --git a/src/args/mod.rs b/src/args/mod.rs index 81e71df..81a9dee 100644 --- a/src/args/mod.rs +++ b/src/args/mod.rs @@ -43,8 +43,8 @@ OPTIONS: Other options for `-k` -p Read a password from stdin for this key -P The next argument after the key file is a password for the key - -s This key is also a signing key - -S This key is only a signing key + -s This key is also a signing key (or verifying for decrypt) + -S This key is only a signing key (or verifying for decrypt, will fail on bad verification) EXAMPLE: {program} -kRP key.rsa "super secret password" -ka key.aes -te input_file output_encrypted file diff --git a/src/args/parse/generate.rs b/src/args/parse/generate.rs index 1a4ef89..a087d88 100644 --- a/src/args/parse/generate.rs +++ b/src/args/parse/generate.rs @@ -3,7 +3,7 @@ use super::*; use tokio::sync::mpsc::Receiver; use std::collections::HashSet; -#[instrument] +#[instrument(level="trace", err, skip(rx))] pub(super) async fn handle(mut rx: Receiver) -> Result { let mut had = smallmap::Map::new(); @@ -37,7 +37,10 @@ pub(super) async fn handle(mut rx: Receiver) -> Result val, + None => return Err(error::ConstructError::Dropped), + } { Atom::Generate(GenerateAtom::Type(ty)) => ty, _ => invalidate!("First atom is not type."), }), @@ -91,8 +94,8 @@ fn split<'a>(input: &'a str) -> (&'a str, Option<&'a str>) } } - -pub(super) async fn parse>(args: I, atoms: &mut mpsc::Sender) -> Result<(), error::Error> +#[instrument(level="trace", skip(args, atoms))] +pub(super) async fn parse>(args: I, mut atoms: mpsc::Sender) -> Result<(), error::Error> { let mut args = args.into_iter(); let mut reading = true; @@ -112,8 +115,9 @@ pub(super) async fn parse>(args: I, atoms: &mut mps _ => return Err(error::Error::ExpectedKind(arg)), } }; - + let mut had = HashSet::new(); + let mut hadv = HashSet::new(); while let Some(arg) = args.next() { macro_rules! take_one { @@ -124,15 +128,12 @@ pub(super) async fn parse>(args: I, atoms: &mut mps } } } - - let mut had = HashSet::new(); if reading && arg.starts_with("--") { let (key, value) = split(&arg); - if had.contains(&key[..]) { + if !had.insert(key.to_owned()) { return Err((error::ParseErrorKind::NotUniqueLong(Some(key.to_owned())), arg).swap().into()); - } else { - had.insert(key.to_owned()); } + match &key.to_lowercase().trim()[2..] { "input" => send!(GenerateAtom::Input(take_one!("--input: Expected filename"))).await?, "password" if value.is_some() => { @@ -155,12 +156,12 @@ pub(super) async fn parse>(args: I, atoms: &mut mps })).await?, _ => return Err((arg, error::ParseErrorKind::UnexpectedArg(None)).into()), } + } else if reading && arg == "-" { + reading= false; } else { - if had.contains(&arg[..]) { + if !hadv.insert(arg.to_owned()) { return Err((arg, error::ParseErrorKind::NotUniqueLong(None)).into()); - } else { - had.insert(arg.to_owned()); } reading=false; match sent_output diff --git a/src/args/parse/mod.rs b/src/args/parse/mod.rs index 4ad0fcb..6f69c3f 100644 --- a/src/args/parse/mod.rs +++ b/src/args/parse/mod.rs @@ -153,10 +153,10 @@ impl Atom } } -#[instrument] +#[instrument(level="debug", err, skip(args))] pub async fn parse + std::fmt::Debug>(args: I) -> Result { - let (mut tx, rx) = mpsc::channel(1); + let (tx, rx) = mpsc::channel(1); macro_rules! unwrap_handler { ($handler:expr) => ($handler.await @@ -170,8 +170,7 @@ pub async fn parse + std::fmt::Debug>(args: I) -> R match arg.to_lowercase().trim() { "--generate" => { let handler = tokio::spawn(generate::handle(rx)); - match generate::parse(std::iter::once(arg) - .chain(args.map(Into::into)), &mut tx).await + match generate::parse(args.map(Into::into), tx).await { // The `handler` has dropped `rx` and returned an error, let unwrap_handler down there handle this. Err(error::Error::AtomInternal) => Ok(()), @@ -186,7 +185,7 @@ pub async fn parse + std::fmt::Debug>(args: I) -> R _ => { let handler = tokio::spawn(normal::handle(rx)); match normal::parse(std::iter::once(arg) - .chain(args.map(Into::into)), &mut tx).await + .chain(args.map(Into::into)), tx).await { // The `handler` has dropped `rx` and returned an error, let unwrap_handler down there handle this. Err(error::Error::AtomInternal) => Ok(()), @@ -202,6 +201,9 @@ pub async fn parse + std::fmt::Debug>(args: I) -> R }; match unwrap_handler!(handler)? { + Err(d @ error::ConstructError::Dropped) => { + unreachable!("{}", d); + }, Err(error) => { return Err(error) .wrap_err_with(|| eyre!("Failed to construct operation from arguments")) diff --git a/src/args/parse/normal.rs b/src/args/parse/normal.rs index d1c2b23..2c74db9 100644 --- a/src/args/parse/normal.rs +++ b/src/args/parse/normal.rs @@ -2,7 +2,7 @@ use super::*; use tokio::sync::mpsc::Receiver; -#[instrument] +#[instrument(level="trace", err, skip(rx))] pub(super) async fn handle(mut rx: Receiver) -> Result { let mut output = op::Normal::default(); @@ -36,13 +36,15 @@ pub(super) async fn handle(mut rx: Receiver) -> Result output.aes.push((string, password)), - config::KeyKind::RsaPublic => output.rsa.push((string, password)), - config::KeyKind::RsaPrivate => output.rsa.push((string, password)) + if sign != IsSigning::Only { + match kind { + config::KeyKind::Aes => output.aes.push((string, password)), + config::KeyKind::RsaPublic => output.rsa.push((string, password)), + config::KeyKind::RsaPrivate => output.rsa.push((string, password)) + } } }, Atom::Generate(_) => unreachable!(), @@ -51,7 +53,8 @@ pub(super) async fn handle(mut rx: Receiver) -> Result>(args: I, atoms: &mut mpsc::Sender) -> Result<(), error::Error> +#[instrument(level="trace", skip(args, atoms))] +pub(super) async fn parse>(args: I, mut atoms: mpsc::Sender) -> Result<(), error::Error> { let mut args = args.into_iter(); let mut reading=true; @@ -59,7 +62,7 @@ pub(super) async fn parse>(args: I, atoms: &mut mps let mut mode_set=false; while let Some(arg) = args.next() { - + trace!("[Normal (parse)] opt string {:?}", arg); macro_rules! take_one { ($msg:literal $($tt:tt)*) => { match args.next() { @@ -131,8 +134,8 @@ pub(super) async fn parse>(args: I, atoms: &mut mps Aes, } let mut kind = KeySpec::Autodetect; - let mut password = Password::default(); - let mut signing = IsSigning::default(); + let mut password = Password::No; + let mut signing = IsSigning::No; let mut had = smallmap::Map::new(); while let Some(opt) = opt.next() { @@ -161,12 +164,12 @@ pub(super) async fn parse>(args: I, atoms: &mut mps check_combine!['r','R']; kind = KeySpec::Aes; }, - 'P' => { - check_combine!['p']; - password= Password::Yes; - }, 'p' => { check_combine!['P']; + password= Password::Yes; + }, + 'P' => { + check_combine!['p']; password = Password::Specific(take_one!("P: Expected a password")); }, 'S' => { diff --git a/src/main.rs b/src/main.rs index 57beee1..7e0869e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,7 +68,12 @@ fn install_tracing() { async fn work(op: config::Operation) -> Result<(), eyre::Report> { - todo!() + debug!("Got op: {:#?}", op); + match op { + config::Operation::Help => args::usage(), + _ => todo!(), + } + Ok(()) } #[instrument]