refactor passkey/password prompts so they are always SecretString (#281)

This commit is contained in:
Carson McManus 2023-07-05 08:35:32 -04:00 committed by GitHub
parent d9261d0ac8
commit df47ff1823
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 30 deletions

View file

@ -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) => {

View file

@ -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() {
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")]
{

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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::*;