diff options
Diffstat (limited to 'src/pinentry.rs')
-rw-r--r-- | src/pinentry.rs | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/src/pinentry.rs b/src/pinentry.rs index e1dec3e..510d7b0 100644 --- a/src/pinentry.rs +++ b/src/pinentry.rs @@ -19,12 +19,12 @@ use std::borrow; use std::fmt; -use std::io; use std::process; use std::str; +use anyhow::Context as _; + use crate::args; -use crate::error::Error; use crate::ExecCtx; type CowStr = borrow::Cow<'static, str>; @@ -49,12 +49,15 @@ pub struct PinEntry { } impl PinEntry { - pub fn from<'mgr, D>(pin_type: args::PinType, device: &D) -> crate::Result<Self> + pub fn from<'mgr, D>(pin_type: args::PinType, device: &D) -> anyhow::Result<Self> where D: nitrokey::Device<'mgr>, { let model = device.get_model(); - let serial = device.get_serial_number()?; + let serial = device + .get_serial_number() + .context("Failed to retrieve serial number")?; + Ok(Self { pin_type, model, @@ -122,12 +125,15 @@ pub struct PwdEntry { } impl PwdEntry { - pub fn from<'mgr, D>(device: &D) -> crate::Result<Self> + pub fn from<'mgr, D>(device: &D) -> anyhow::Result<Self> where D: nitrokey::Device<'mgr>, { let model = device.get_model(); - let serial = device.get_serial_number()?; + let serial = device + .get_serial_number() + .context("Failed to retrieve serial number")?; + Ok(Self { model, serial }) } } @@ -186,7 +192,7 @@ impl Mode { } } -fn parse_pinentry_pin<R>(response: R) -> crate::Result<String> +fn parse_pinentry_pin<R>(response: R) -> anyhow::Result<String> where R: AsRef<str>, { @@ -208,9 +214,9 @@ where // specially. if !lines.is_empty() && lines[0].starts_with("ERR ") { let (_, error) = lines[0].split_at(4); - return Err(Error::from(error)); + anyhow::bail!("{}", error); } - Err(Error::Error(format!("Unexpected response: {}", string))) + anyhow::bail!("Unexpected response: {}", string) } /// Inquire a secret from the user. @@ -226,7 +232,7 @@ pub fn inquire<E>( entry: &E, mode: Mode, error_msg: Option<&str>, -) -> crate::Result<String> +) -> anyhow::Result<String> where E: SecretEntry, { @@ -256,30 +262,28 @@ where .arg(command) .arg("/bye") .output() - .map_err(|err| match err.kind() { - io::ErrorKind::NotFound => { - io::Error::new(io::ErrorKind::NotFound, "gpg-connect-agent not found") - } - _ => err, - })?; - parse_pinentry_pin(str::from_utf8(&output.stdout)?) + .context("Failed to invoke gpg-connect-agent")?; + + let response = + str::from_utf8(&output.stdout).context("Failed to parse gpg-connect-agent output as UTF-8")?; + parse_pinentry_pin(response).context("Failed to parse pinentry secret") } -fn check<E>(entry: &E, secret: &str) -> crate::Result<()> +fn check<E>(entry: &E, secret: &str) -> anyhow::Result<()> where E: SecretEntry, { if secret.len() < usize::from(entry.min_len()) { - Err(Error::Error(format!( + anyhow::bail!( "The secret must be at least {} characters long", entry.min_len() - ))) + ) } else { Ok(()) } } -pub fn choose<E>(ctx: &mut ExecCtx<'_>, entry: &E) -> crate::Result<String> +pub fn choose<E>(ctx: &mut ExecCtx<'_>, entry: &E) -> anyhow::Result<String> where E: SecretEntry, { @@ -292,13 +296,13 @@ where clear(entry)?; if chosen != confirmed { - Err(Error::from("Entered secrets do not match")) + anyhow::bail!("Entered secrets do not match") } else { Ok(chosen) } } -fn parse_pinentry_response<R>(response: R) -> crate::Result<()> +fn parse_pinentry_response<R>(response: R) -> anyhow::Result<()> where R: AsRef<str>, { @@ -309,11 +313,11 @@ where // We got the only valid answer we accept. return Ok(()); } - Err(Error::Error(format!("Unexpected response: {}", string))) + anyhow::bail!("Unexpected response: {}", string) } /// Clear the cached secret represented by the given entry. -pub fn clear<E>(entry: &E) -> crate::Result<()> +pub fn clear<E>(entry: &E) -> anyhow::Result<()> where E: SecretEntry, { @@ -322,9 +326,13 @@ where let output = process::Command::new("gpg-connect-agent") .arg(command) .arg("/bye") - .output()?; + .output() + .context("Failed to invoke gpg-connect-agent")?; + + let response = str::from_utf8(&output.stdout) + .context("Failed to parse gpg-connect-agent output as UTF-8")?; - parse_pinentry_response(str::from_utf8(&output.stdout)?) + parse_pinentry_response(response).context("Failed to parse pinentry response") } else { Ok(()) } |