From ed120b277371be7b9bd61c825aa7d61b104d3ac6 Mon Sep 17 00:00:00 2001 From: Aaron Feickert <66188213+AaronFeickert@users.noreply.github.com> Date: Fri, 19 May 2023 08:07:13 -0500 Subject: [PATCH] fix: loop on mismatched passphrase entry (#5396) Description --- If the user enters a new or changed passphrase and fails to confirm it, an exit error is immediately returned. This PR updates to prompt the user to try again, up to a sanity limit. Closes [issue 5391](https://github.com/tari-project/tari/issues/5391). Motivation and Context --- The user is prompted to enter and confirm a new passphrase in two cases: when creating a new wallet, and when changing the passphrase of an existing wallet. In both cases, failure to confirm the new passphrase correctly returns an exit error. This PR prompts the user again if the new passphrase and its confirmation do not match. We probably don't want the user to get stuck in an infinite loop and go insane, so there is a sanity limit of three tries. If the user fails this many times, we return the exit error. How Has This Been Tested? --- Tested manually. What process can a PR reviewer use to test or verify this change? --- Test the following scenarios manually: - Create a new wallet. Fail to confirm a new passphrase three times. Confirm that the process exits. - Create a new wallet. Confirm a new passphrase within three tries. Confirm that the process succeeds. - Change an existing wallet's passphrase. Fail to confirm a new passphrase three times. Confirm that the process exits. - Change an existing wallet's passphrase. Confirm a new passphrase within three tries. Confirm that the process succeeds. --- .../tari_console_wallet/src/init/mod.rs | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/applications/tari_console_wallet/src/init/mod.rs b/applications/tari_console_wallet/src/init/mod.rs index 2a3964a88f..46b7fe43b8 100644 --- a/applications/tari_console_wallet/src/init/mod.rs +++ b/applications/tari_console_wallet/src/init/mod.rs @@ -71,6 +71,9 @@ use crate::{ pub const LOG_TARGET: &str = "wallet::console_wallet::init"; const TARI_WALLET_PASSWORD: &str = "TARI_WALLET_PASSWORD"; +// Maxmimum number of times we prompt for confirmation of a new passphrase, to avoid driving the user insane with an +// infinite loop +const PASSPHRASE_SANITY_LIMIT: u8 = 3; #[derive(Clone, Copy)] pub enum WalletBoot { @@ -98,11 +101,25 @@ pub enum WalletBoot { fn get_new_passphrase(prompt: &str, confirm: &str) -> Result { // We may need to prompt for a passphrase multiple times loop { - // Prompt the user for a passphrase and confirm it - let passphrase = prompt_password(prompt)?; - let confirmed = prompt_password(confirm)?; - if passphrase.reveal() != confirmed.reveal() { - return Err(ExitError::new(ExitCode::InputError, "Passphrases don't match!")); + // Prompt the user for a passphrase and confirm it, up to the defined limit + // This ensures an unlucky user doesn't get stuck + let mut tries = 0; + let mut passphrase = SafePassword::from(""); // initial value for scope + loop { + passphrase = prompt_password(prompt)?; + let confirmed = prompt_password(confirm)?; + + // If they match, continue the process + if passphrase.reveal() == confirmed.reveal() { + break; + } + + // If they don't match, keep prompting until we hit the sanity limit + tries += 1; + if tries == PASSPHRASE_SANITY_LIMIT { + return Err(ExitError::new(ExitCode::InputError, "Passphrases don't match!")); + } + println!("Passphrases don't match! Try again."); } // Score the passphrase and provide feedback