From abcaafee042c6f2036b822e6f1c6c2683a526d92 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 30 Dec 2018 18:37:37 +0100 Subject: Add mode argument to pinentry::inquire_passphrase The mode argument is used to specify the context of the pinentry dialog: querying an existing passphrase or prompting the user to choose a new PIN. It is used to choose a description and to decide whether to show a quality bar that measures the password strength. --- nitrocli/src/commands.rs | 2 +- nitrocli/src/pinentry.rs | 45 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs index 47a955d..17c8c8c 100644 --- a/nitrocli/src/commands.rs +++ b/nitrocli/src/commands.rs @@ -131,7 +131,7 @@ where let mut retry = 3; let mut error_msg = None; loop { - let passphrase = match pinentry::inquire_passphrase(pin, error_msg) { + let passphrase = match pinentry::inquire_passphrase(pin, pinentry::Mode::Query, error_msg) { Ok(passphrase) => passphrase, Err(err) => return Err((data, err)), }; diff --git a/nitrocli/src/pinentry.rs b/nitrocli/src/pinentry.rs index 891de38..90986be 100644 --- a/nitrocli/src/pinentry.rs +++ b/nitrocli/src/pinentry.rs @@ -48,14 +48,35 @@ impl PinType { } } - fn description(self) -> &'static str { + fn description(self, mode: Mode) -> &'static str { match self { - PinType::Admin => "Please enter admin PIN", - PinType::User => "Please enter user PIN", + PinType::Admin => match mode { + Mode::Query => "Please enter the admin PIN", + }, + PinType::User => match mode { + Mode::Query => "Please enter the user PIN", + }, } } } +/// PIN entry mode for pinentry. +/// +/// This enum describes the context of the pinentry query, for example prompting for the current +/// PIN or requesting a new PIN. The mode may affect the pinentry description and whether a +/// quality bar is shown. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum Mode { + /// Query an existing PIN. + Query, +} + +impl Mode { + fn show_quality_bar(self) -> bool { + false + } +} + fn parse_pinentry_passphrase(response: Vec) -> Result, Error> { let string = String::from_utf8(response)?; let lines: Vec<&str> = string.lines().collect(); @@ -83,17 +104,27 @@ fn parse_pinentry_passphrase(response: Vec) -> Result, Error> { /// Inquire a PIN of the given type from the user. /// /// This function inquires a PIN of the given type from the user or returns the cached passphrase, -/// if available. If an error message is set, it is displayed in the passphrase dialog. -pub fn inquire_passphrase(pin_type: PinType, error_msg: Option<&str>) -> Result, Error> { +/// if available. If an error message is set, it is displayed in the passphrase dialog. The +/// mode describes the context of the pinentry dialog. It is used to choose an appropriate +/// description and to decide whether a quality bar is shown in the dialog. +pub fn inquire_passphrase( + pin_type: PinType, + mode: Mode, + error_msg: Option<&str>, +) -> Result, Error> { let cache_id = pin_type.cache_id(); let error_msg = error_msg .map(|msg| msg.replace(" ", "+")) .unwrap_or_else(|| String::from("+")); let prompt = pin_type.prompt().replace(" ", "+"); - let description = pin_type.description().replace(" ", "+"); + let description = pin_type.description(mode).replace(" ", "+"); let args = vec![cache_id, &error_msg, &prompt, &description].join(" "); - let command = "GET_PASSPHRASE --data ".to_string() + &args; + let mut command = "GET_PASSPHRASE --data ".to_string(); + if mode.show_quality_bar() { + command += "--qualitybar "; + } + command += &args; // We could also use the --data parameter here to have a more direct // representation of the passphrase but the resulting response was // considered more difficult to parse overall. It appears an error -- cgit v1.2.3