summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mueller <deso@posteo.net>2019-01-20 08:28:46 -0800
committerDaniel Mueller <deso@posteo.net>2019-01-20 08:28:46 -0800
commite106613dbd94bf0580b873da0ad3c3751e156f24 (patch)
tree565bef9eccef10b9d49ed02a50b3c36cd3c4505c
parent01fb9e579de1c019ed718e04f9b592f2687f7040 (diff)
downloadnitrocli-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.rs35
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)]