diff options
author | Daniel Mueller <deso@posteo.net> | 2019-01-20 08:28:46 -0800 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2019-01-20 08:28:46 -0800 |
commit | e106613dbd94bf0580b873da0ad3c3751e156f24 (patch) | |
tree | 565bef9eccef10b9d49ed02a50b3c36cd3c4505c | |
parent | 01fb9e579de1c019ed718e04f9b592f2687f7040 (diff) | |
download | nitrocli-e106613dbd94bf0580b873da0ad3c3751e156f24.tar.gz nitrocli-e106613dbd94bf0580b873da0ad3c3751e156f24.tar.bz2 |
Make caching of secrets optional
Currently, when we enter a secret (i.e., a PIN) through the pinentry
module, this PIN will automatically be cached and not asked from the
user again on subsequent inquiries. However, caching may not always be
desired. For the upcoming support of passwords used in conjunction with
hidden volumes, we do not want any caching because different passwords
can be entered for different volumes and the user's intention is not
clear until a password has actually been entered.
To accommodate this use case, this change modifies the signature of the
SecretEntry trait's cache_id method to return an optional cache ID. If
none is returned, caching of the entered secret is disabled.
-rw-r--r-- | nitrocli/src/pinentry.rs | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/nitrocli/src/pinentry.rs b/nitrocli/src/pinentry.rs index 68cc4aa..1a3982e 100644 --- a/nitrocli/src/pinentry.rs +++ b/nitrocli/src/pinentry.rs @@ -38,7 +38,7 @@ Enum! {PinType, [ /// A trait representing a secret to be entered by the user. pub trait SecretEntry: fmt::Debug { /// The cache ID to use for this secret. - fn cache_id(&self) -> CowStr; + fn cache_id(&self) -> Option<CowStr>; /// The prompt to display when asking for the secret. fn prompt(&self) -> CowStr; /// The description to display when asking for the secret. @@ -72,15 +72,14 @@ impl PinEntry { } impl SecretEntry for PinEntry { - fn cache_id(&self) -> CowStr { + fn cache_id(&self) -> Option<CowStr> { let model = self.model.to_string().to_lowercase(); let suffix = format!("{}:{}", model, self.serial); - - match self.pin_type { + let cache_id = match self.pin_type { PinType::Admin => format!("nitrocli:admin:{}", suffix), PinType::User => format!("nitrocli:user:{}", suffix), - } - .into() + }; + Some(cache_id.into()) } fn prompt(&self) -> CowStr { @@ -173,7 +172,11 @@ pub fn inquire<E>(entry: &E, mode: Mode, error_msg: Option<&str>) -> crate::Resu where E: SecretEntry, { - let cache_id = entry.cache_id().into(); + let cache_id = entry + .cache_id() + // "X" is a sentinel value indicating that no caching is desired. + .unwrap_or_else(|| "X".into()) + .into(); let error_msg = error_msg .map(|msg| msg.replace(" ", "+")) .unwrap_or_else(|| String::from("+")); @@ -246,13 +249,17 @@ pub fn clear<E>(entry: &E) -> crate::Result<()> where E: SecretEntry, { - let command = format!("CLEAR_PASSPHRASE {}", entry.cache_id()); - let output = process::Command::new("gpg-connect-agent") - .arg(command) - .arg("/bye") - .output()?; - - parse_pinentry_response(str::from_utf8(&output.stdout)?) + if let Some(cache_id) = entry.cache_id() { + let command = format!("CLEAR_PASSPHRASE {}", cache_id); + let output = process::Command::new("gpg-connect-agent") + .arg(command) + .arg("/bye") + .output()?; + + parse_pinentry_response(str::from_utf8(&output.stdout)?) + } else { + Ok(()) + } } #[cfg(test)] |