From 48f7ed5d9e8d6deebb0cee98469f2eddc5df991b Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 28 Oct 2020 23:22:03 +0000 Subject: [PATCH] start resolve --- Cargo.lock | 11 +++++ Cargo.toml | 3 +- TODO | 1 + src/bytes.rs | 7 +--- src/config.rs | 24 +++++++++++ src/main.rs | 13 ++++-- src/resolve.rs | 89 +++++++++++++++++++++++++++++++++++++++- src/work/generate/aes.rs | 1 + 8 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 TODO diff --git a/Cargo.lock b/Cargo.lock index 10fd74f..4660ba7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -835,6 +835,7 @@ dependencies = [ "once_cell", "pin-project", "recolored", + "rpassword", "rustc_version", "serde", "serde_cbor", @@ -927,6 +928,16 @@ version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" +[[package]] +name = "rpassword" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d755237fc0f99d98641540e66abac8bc46a0652f19148ac9e21de2da06b326c9" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "rustc-demangle" version = "0.1.16" diff --git a/Cargo.toml b/Cargo.toml index a3431b0..38e8fd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,8 @@ async-trait = "0.1.40" hex-literal = "0.3.1" once_cell = "1.4.1" getrandom = "0.2.0" +rpassword = "5.0.0" [build-dependencies] rustc_version = "0.2" -config_struct = "0.5.0" \ No newline at end of file +config_struct = "0.5.0" diff --git a/TODO b/TODO new file mode 100644 index 0000000..cf84a09 --- /dev/null +++ b/TODO @@ -0,0 +1 @@ +resolve::find_key_format::check_pem() diff --git a/src/bytes.rs b/src/bytes.rs index 06838ab..7654fa8 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -1,6 +1,3 @@ -use libc::{ - c_void, -}; /// Copy slice of bytes only /// /// # Notes @@ -9,7 +6,7 @@ pub fn copy_slice(dst: &mut [u8], src: &[u8]) -> usize { let sz = std::cmp::min(dst.len(),src.len()); unsafe { - libc::memcpy(&mut dst[0] as *mut u8 as *mut c_void, &src[0] as *const u8 as *const c_void, sz); + std::ptr::copy(&src[0] as *const u8, &mut dst[0] as *mut u8, sz); } sz } @@ -22,7 +19,7 @@ pub fn move_slice(dst: &mut [u8], src: &[u8]) -> usize { let sz = std::cmp::min(dst.len(),src.len()); unsafe { - libc::memmove(&mut dst[0] as *mut u8 as *mut c_void, &src[0] as *const u8 as *const c_void, sz); + std::ptr::copy(&src[0] as *const u8, &mut dst[0] as *mut u8, sz); } sz } diff --git a/src/config.rs b/src/config.rs index 085fff9..ed5df3c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -113,3 +113,27 @@ pub enum KeyKind RsaPrivate, Aes, } + +pub use op::Password; + +impl Password +{ + /// Consume into real password + #[instrument] + pub fn into_password(self) -> eyre::Result> + { + Ok(match self { + Self::No => None, + Self::Yes => Some(read_password()?), + Self::Specific(passwd) => Some(passwd), + }) + } +} + +/// Read password from stdin +#[instrument(err)] +fn read_password() -> eyre::Result +{ + rpassword::read_password() + .wrap_err(eyre!("Failed to read password from stdin")) +} diff --git a/src/main.rs b/src/main.rs index fa5e997..dbc4551 100644 --- a/src/main.rs +++ b/src/main.rs @@ -189,7 +189,14 @@ async fn work(op: config::Operation) -> Result<(), eyre::Report> match op { config::Operation::Help => args::usage(), config::Operation::GenerateKey(config::op::GenerateKey::Aes(aes)) => { - + let input_aes = match aes.input { + Some((path, passwd)) => { + let passwd = passwd.into_password()?; + // read from `path` + + }, + _ => None, + }; }, config::Operation::GenerateKey(config::op::GenerateKey::Rsa(rsa)) => { @@ -205,8 +212,8 @@ async fn main() -> Result<(), eyre::Report> { install_tracing(); color_eyre::install()?; - fuck().await?; - return Ok(()); + //fuck().await?; + //return Ok(()); trace!("Parsing args"); let args = args::parse_args().await?; diff --git a/src/resolve.rs b/src/resolve.rs index 58bfc97..a58e0d5 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -6,7 +6,84 @@ use std::{ }, error, fmt, + io, }; +use tokio::{ + prelude::*, + fs::{ + OpenOptions, + File, + }, + io::{ + BufReader, + }, +}; + +use config::op::KeyFormat; + +/// Find the format (Binary, Text, PEM) of this key file. +/// +/// # Note +/// This isn't an infallible test as it only parses parts of headers, if it detects a type it doesn't guarantee that the file *actually* is that type. It is just a hint or best-guess. +#[instrument(err, skip(path), fields(path = ?path.as_ref()))] +pub async fn find_key_format(path: impl AsRef, can_pem: bool) -> eyre::Result +{ + async fn check_bin(file: &mut File) -> Result + { + let mut buffer = [0u8; 4]; + file.read_exact(&mut buffer[..]).await?; + Ok(&buffer[..] == format::RAE_HEADER_BIT) + } + async fn check_text(file: &mut File) -> Result + { + let mut buffer = [0u8; 4]; + file.read_exact(&mut buffer[..]).await?; + if &buffer[..] != b"--- " { + return Ok(false); + } + file.read_exact(&mut buffer[..]).await?; + Ok(&buffer[..] == format::RAE_HEADER_BIT) + } + async fn check_pem(file: &mut File) -> Result + { + todo!("I don't remember the PEM format right now") + } + let mut file = { + let path = path.as_ref(); + OpenOptions::new() + .read(true) + .open(path).await + .wrap_err(eyre::eyre!("Failed to open file to check")) + .with_section(|| format!("{:?}", path).header("Path was"))? + }; + + macro_rules! reset { + () => { + file.seek(std::io::SeekFrom::Start(0)).await? + } + } + + if can_pem { + if check_pem(&mut file).await + .with_note(|| "With check for PEM")? { + return Ok(KeyFormat::PEM); + } else { + reset!(); + } + } + if check_bin(&mut file).await + .with_note(|| "With check for binary")? { + return Ok(KeyFormat::Bin); + } else { + reset!(); + } + if check_text(&mut file).await + .with_note(|| "With check for text")? { + return Ok(KeyFormat::Text); + } + + return Err(Error::UnknownFormat)?; +} pub async fn find_file_mode>(path: P) -> Result { @@ -26,7 +103,9 @@ pub async fn find_key_mode>(path: P) -> Result for Error +{ + #[inline] fn from(from: io::Error) -> Self + { + Self::IO(from) + } +} diff --git a/src/work/generate/aes.rs b/src/work/generate/aes.rs index a8e58d4..57e400a 100644 --- a/src/work/generate/aes.rs +++ b/src/work/generate/aes.rs @@ -1,2 +1,3 @@ //! Generate aes key operations use super::*; +