refactor passkey/password prompts so they are always SecretString (#281)
This commit is contained in:
parent
d9261d0ac8
commit
df47ff1823
5 changed files with 42 additions and 30 deletions
|
@ -45,8 +45,7 @@ fn load_accounts_with_prompts(manager: &mut AccountManager) -> anyhow::Result<()
|
|||
if manager.has_passkey() {
|
||||
error!("Incorrect passkey");
|
||||
}
|
||||
let passkey = rpassword::prompt_password_stdout("Enter encryption passkey: ").ok();
|
||||
let passkey = passkey.map(SecretString::new);
|
||||
let passkey = Some(crate::tui::prompt_passkey()?);
|
||||
manager.submit_passkey(passkey);
|
||||
}
|
||||
Err(e) => {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use log::*;
|
||||
use secrecy::ExposeSecret;
|
||||
|
||||
use crate::{
|
||||
encryption::{EncryptionScheme, EntryEncryptor},
|
||||
|
@ -17,23 +18,22 @@ where
|
|||
{
|
||||
fn execute(&self, _transport: T, manager: &mut AccountManager) -> anyhow::Result<()> {
|
||||
if !manager.has_passkey() {
|
||||
let mut passkey;
|
||||
let passkey: Option<SecretString>;
|
||||
loop {
|
||||
passkey = rpassword::prompt_password_stdout("Enter encryption passkey: ").ok();
|
||||
if let Some(p) = passkey.as_ref() {
|
||||
if p.is_empty() {
|
||||
error!("Passkey cannot be empty, try again.");
|
||||
continue;
|
||||
}
|
||||
let passkey1 = tui::prompt_passkey()?;
|
||||
if passkey1.expose_secret().is_empty() {
|
||||
error!("Passkey cannot be empty, try again.");
|
||||
continue;
|
||||
}
|
||||
let passkey_confirm =
|
||||
rpassword::prompt_password_stdout("Confirm encryption passkey: ").ok();
|
||||
if passkey == passkey_confirm {
|
||||
rpassword::prompt_password_stdout("Confirm encryption passkey: ")
|
||||
.map(SecretString::new)?;
|
||||
if passkey1.expose_secret() == passkey_confirm.expose_secret() {
|
||||
passkey = Some(passkey1);
|
||||
break;
|
||||
}
|
||||
error!("Passkeys do not match, try again.");
|
||||
}
|
||||
let passkey = passkey.map(SecretString::new);
|
||||
|
||||
#[cfg(feature = "keyring")]
|
||||
{
|
||||
|
|
20
src/login.rs
20
src/login.rs
|
@ -1,6 +1,7 @@
|
|||
use std::io::Write;
|
||||
|
||||
use log::*;
|
||||
use secrecy::{ExposeSecret, SecretString};
|
||||
use steamguard::{
|
||||
protobufs::steammessages_auth_steamclient::{EAuthSessionGuardType, EAuthTokenPlatformType},
|
||||
refresher::TokenRefresher,
|
||||
|
@ -42,8 +43,8 @@ pub fn do_login<T: Transport + Clone>(
|
|||
account.account_name = tui::prompt();
|
||||
}
|
||||
let _ = std::io::stdout().flush();
|
||||
let password = rpassword::prompt_password_stdout("Password: ").unwrap();
|
||||
if !password.is_empty() {
|
||||
let password = tui::prompt_password()?;
|
||||
if !password.expose_secret().is_empty() {
|
||||
debug!("password is present");
|
||||
} else {
|
||||
debug!("password is empty");
|
||||
|
@ -65,8 +66,8 @@ pub fn do_login_raw<T: Transport + Clone>(
|
|||
username: String,
|
||||
) -> anyhow::Result<Tokens> {
|
||||
let _ = std::io::stdout().flush();
|
||||
let password = rpassword::prompt_password_stdout("Password: ").unwrap();
|
||||
if !password.is_empty() {
|
||||
let password = tui::prompt_password()?;
|
||||
if !password.expose_secret().is_empty() {
|
||||
debug!("password is present");
|
||||
} else {
|
||||
debug!("password is empty");
|
||||
|
@ -77,7 +78,7 @@ pub fn do_login_raw<T: Transport + Clone>(
|
|||
fn do_login_impl<T: Transport + Clone>(
|
||||
transport: T,
|
||||
username: String,
|
||||
password: String,
|
||||
password: SecretString,
|
||||
account: Option<&SteamGuardAccount>,
|
||||
) -> anyhow::Result<Tokens> {
|
||||
let mut login = UserLogin::new(transport.clone(), build_device_details());
|
||||
|
@ -85,7 +86,7 @@ fn do_login_impl<T: Transport + Clone>(
|
|||
let mut password = password;
|
||||
let confirmation_methods;
|
||||
loop {
|
||||
match login.begin_auth_via_credentials(&username, &password) {
|
||||
match login.begin_auth_via_credentials(&username, password.expose_secret()) {
|
||||
Ok(methods) => {
|
||||
confirmation_methods = methods;
|
||||
break;
|
||||
|
@ -95,11 +96,8 @@ fn do_login_impl<T: Transport + Clone>(
|
|||
return Err(LoginError::TooManyAttempts.into());
|
||||
}
|
||||
Err(LoginError::BadCredentials) => {
|
||||
error!("Incorrect password.");
|
||||
password = rpassword::prompt_password_stdout("Password: ")
|
||||
.unwrap()
|
||||
.trim()
|
||||
.to_owned();
|
||||
error!("Incorrect password for {username}");
|
||||
password = tui::prompt_password()?;
|
||||
continue;
|
||||
}
|
||||
Err(err) => {
|
||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -152,9 +152,7 @@ fn run(args: commands::Args) -> anyhow::Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
let raw =
|
||||
rpassword::prompt_password_stdout("Enter encryption passkey: ")?;
|
||||
passkey = Some(SecretString::new(raw));
|
||||
passkey = Some(tui::prompt_passkey()?);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to migrate manifest: {}", e);
|
||||
|
@ -208,8 +206,7 @@ fn run(args: commands::Args) -> anyhow::Result<()> {
|
|||
if manager.has_passkey() {
|
||||
error!("Incorrect passkey");
|
||||
}
|
||||
let raw = rpassword::prompt_password_stdout("Enter encryption passkey: ")?;
|
||||
passkey = Some(SecretString::new(raw));
|
||||
passkey = Some(tui::prompt_passkey()?);
|
||||
manager.submit_passkey(passkey);
|
||||
}
|
||||
Err(e) => {
|
||||
|
@ -253,8 +250,7 @@ fn run(args: commands::Args) -> anyhow::Result<()> {
|
|||
if manager.has_passkey() {
|
||||
error!("Incorrect passkey");
|
||||
}
|
||||
let raw = rpassword::prompt_password_stdout("Enter encryption passkey: ")?;
|
||||
passkey = Some(SecretString::new(raw));
|
||||
passkey = Some(tui::prompt_passkey()?);
|
||||
manager.submit_passkey(passkey);
|
||||
}
|
||||
Err(e) => {
|
||||
|
|
19
src/tui.rs
19
src/tui.rs
|
@ -6,6 +6,7 @@ use crossterm::{
|
|||
terminal::{Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
QueueableCommand,
|
||||
};
|
||||
use secrecy::SecretString;
|
||||
use std::collections::HashSet;
|
||||
use std::io::{stderr, stdout, Write};
|
||||
use steamguard::Confirmation;
|
||||
|
@ -244,6 +245,24 @@ pub(crate) fn pause() {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn prompt_passkey() -> std::io::Result<SecretString> {
|
||||
loop {
|
||||
let raw = rpassword::prompt_password_stdout("Enter encryption passkey: ")?;
|
||||
if !raw.is_empty() {
|
||||
return Ok(SecretString::new(raw));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn prompt_password() -> std::io::Result<SecretString> {
|
||||
loop {
|
||||
let raw = rpassword::prompt_password_stdout("Password: ")?;
|
||||
if !raw.is_empty() {
|
||||
return Ok(SecretString::new(raw));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod prompt_char_tests {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in a new issue