From b874441a4742fb445a41d6ae344d3fe16d1ba9f2 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 22:42:42 -0500 Subject: [PATCH] Prevent passphrase mistakes with confirmation prompt (#7207) --- clap-utils/src/keypair.rs | 16 ++++++++++++++-- keygen/src/keygen.rs | 6 +++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/clap-utils/src/keypair.rs b/clap-utils/src/keypair.rs index 2046c5a4ff..e149ca3df5 100644 --- a/clap-utils/src/keypair.rs +++ b/clap-utils/src/keypair.rs @@ -41,6 +41,18 @@ impl KeypairWithSource { } } +/// Prompts user for a passphrase and then asks for confirmirmation to check for mistakes +pub fn prompt_passphrase(prompt: &str) -> Result> { + let passphrase = prompt_password_stderr(&prompt)?; + if !passphrase.is_empty() { + let confirmed = rpassword::prompt_password_stderr("Enter same passphrase again: ")?; + if confirmed != passphrase { + return Err("Passphrases did not match".into()); + } + } + Ok(passphrase) +} + /// Reads user input from stdin to retrieve a seed phrase and passphrase for keypair derivation pub fn keypair_from_seed_phrase( keypair_name: &str, @@ -54,11 +66,11 @@ pub fn keypair_from_seed_phrase( ); if skip_validation { - let passphrase = prompt_password_stderr(&passphrase_prompt)?; + let passphrase = prompt_passphrase(&passphrase_prompt)?; keypair_from_seed_phrase_and_passphrase(&seed_phrase, &passphrase) } else { let mnemonic = Mnemonic::from_phrase(seed_phrase, Language::English)?; - let passphrase = prompt_password_stderr(&passphrase_prompt)?; + let passphrase = prompt_passphrase(&passphrase_prompt)?; let seed = Seed::new(&mnemonic, &passphrase); keypair_from_seed(seed.as_bytes()) } diff --git a/keygen/src/keygen.rs b/keygen/src/keygen.rs index 10fc7c1597..3c840f2873 100644 --- a/keygen/src/keygen.rs +++ b/keygen/src/keygen.rs @@ -5,7 +5,7 @@ use clap::{ }; use num_cpus; use solana_clap_utils::keypair::{ - keypair_from_seed_phrase, ASK_KEYWORD, SKIP_SEED_PHRASE_VALIDATION_ARG, + keypair_from_seed_phrase, prompt_passphrase, ASK_KEYWORD, SKIP_SEED_PHRASE_VALIDATION_ARG, }; use solana_sdk::{ pubkey::write_pubkey_file, @@ -236,8 +236,8 @@ fn main() -> Result<(), Box> { NO_PASSPHRASE.to_string() } else { eprintln!("Generating a new keypair"); - rpassword::prompt_password_stderr( - "For added security, enter a passphrase (empty for no passphrase):", + prompt_passphrase( + "For added security, enter a passphrase (empty for no passphrase): ", )? }; let seed = Seed::new(&mnemonic, &passphrase);