From 5cf4d7acfe04717ec345e197e9dc69a9ebbe2dee Mon Sep 17 00:00:00 2001 From: hashmap Date: Fri, 11 Jan 2019 00:58:37 +0100 Subject: [PATCH] Use ZeroingString for password and passpharse in wallet (#2285) --- src/bin/cmd/wallet_args.rs | 30 +++++++++++++++++------------- util/src/types.rs | 7 +++++++ wallet/src/command.rs | 12 ++++++------ wallet/src/types.rs | 2 +- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/bin/cmd/wallet_args.rs b/src/bin/cmd/wallet_args.rs index 54bab998f..92baa9e4f 100644 --- a/src/bin/cmd/wallet_args.rs +++ b/src/bin/cmd/wallet_args.rs @@ -14,7 +14,7 @@ use crate::api::TLSConfig; use crate::util::file::get_first_line; -use crate::util::Mutex; +use crate::util::{Mutex, ZeroingString}; /// Argument parsing and error handling for wallet commands use clap::ArgMatches; use failure::Fail; @@ -57,19 +57,23 @@ impl From for ParseError { } } -pub fn prompt_password(password: &Option) -> String { +fn prompt_password_stdout(prompt: &str) -> ZeroingString { + ZeroingString::from(rpassword::prompt_password_stdout(prompt).unwrap()) +} + +pub fn prompt_password(password: &Option) -> ZeroingString { match password { - None => rpassword::prompt_password_stdout("Password: ").unwrap(), - Some(p) => p.to_owned(), + None => prompt_password_stdout("Password: "), + Some(p) => p.clone(), } } -fn prompt_password_confirm() -> String { - let mut first = String::from("first"); - let mut second = String::from("second"); +fn prompt_password_confirm() -> ZeroingString { + let mut first = ZeroingString::from("first"); + let mut second = ZeroingString::from("second"); while first != second { - first = rpassword::prompt_password_stdout("Password: ").unwrap(); - second = rpassword::prompt_password_stdout("Confirm Password: ").unwrap(); + first = prompt_password_stdout("Password: "); + second = prompt_password_stdout("Confirm Password: "); } first } @@ -101,9 +105,9 @@ fn prompt_replace_seed() -> Result { } } -fn prompt_recovery_phrase() -> Result { +fn prompt_recovery_phrase() -> Result { let interface = Arc::new(Interface::new("recover")?); - let mut phrase = String::new(); + let mut phrase = ZeroingString::from(""); interface.set_report_signal(Signal::Interrupt, true); interface.set_prompt("phrase> ")?; loop { @@ -119,7 +123,7 @@ fn prompt_recovery_phrase() -> Result { } ReadResult::Input(line) => { if WalletSeed::from_mnemonic(&line).is_ok() { - phrase = line; + phrase = ZeroingString::from(line); break; } else { println!(); @@ -194,7 +198,7 @@ pub fn parse_global_args( let node_api_secret = get_first_line(config.node_api_secret_path.clone()); let password = match args.value_of("pass") { None => None, - Some(p) => Some(p.to_owned()), + Some(p) => Some(ZeroingString::from(p)), }; let tls_conf = match config.tls_certificate_file.clone() { diff --git a/util/src/types.rs b/util/src/types.rs index b5c792fef..b99d695a6 100644 --- a/util/src/types.rs +++ b/util/src/types.rs @@ -68,6 +68,7 @@ impl Default for LoggingConfig { use std::ops::Deref; use zeroize::Zeroize; /// Zeroing string, mainly useful for password +#[derive(Clone, PartialEq, PartialOrd)] pub struct ZeroingString(String); impl Drop for ZeroingString { @@ -82,6 +83,12 @@ impl From<&str> for ZeroingString { } } +impl From for ZeroingString { + fn from(s: String) -> Self { + ZeroingString(s) + } +} + impl Deref for ZeroingString { type Target = str; diff --git a/wallet/src/command.rs b/wallet/src/command.rs index 175308fcd..b717aa7ee 100644 --- a/wallet/src/command.rs +++ b/wallet/src/command.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::util::Mutex; +use crate::util::{Mutex, ZeroingString}; use std::collections::HashMap; /// Grin wallet command-line function implementations use std::fs::File; @@ -41,7 +41,7 @@ pub struct GlobalArgs { pub account: String, pub node_api_secret: Option, pub show_spent: bool, - pub password: Option, + pub password: Option, pub tls_conf: Option, } @@ -49,9 +49,9 @@ pub struct GlobalArgs { pub struct InitArgs { /// BIP39 recovery phrase length pub list_length: usize, - pub password: String, + pub password: ZeroingString, pub config: WalletConfig, - pub recovery_phrase: Option, + pub recovery_phrase: Option, pub restore: bool, } @@ -75,8 +75,8 @@ pub fn init(g_args: &GlobalArgs, args: InitArgs) -> Result<(), Error> { /// Argument for recover pub struct RecoverArgs { - pub recovery_phrase: Option, - pub passphrase: String, + pub recovery_phrase: Option, + pub passphrase: ZeroingString, } /// Check whether seed file exists diff --git a/wallet/src/types.rs b/wallet/src/types.rs index 4831a4230..65ca4c7a2 100644 --- a/wallet/src/types.rs +++ b/wallet/src/types.rs @@ -216,7 +216,7 @@ impl WalletSeed { pub fn init_file( wallet_config: &WalletConfig, seed_length: usize, - recovery_phrase: Option, + recovery_phrase: Option, password: &str, ) -> Result { // create directory if it doesn't exist