aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-05-28 03:12:09 -0400
committerJesse Luehrs <doy@tozt.net>2020-05-28 03:19:45 -0400
commit3ab2da1595da8b1b596f256a26c9e65ab35bc24c (patch)
tree5400a00a8c341582a7d93f9d06bce732f9c81d39 /src
parent3efe6a2b304c0c63bd2ce86adcd23a3647634008 (diff)
downloadrbw-3ab2da1595da8b1b596f256a26c9e65ab35bc24c.tar.gz
rbw-3ab2da1595da8b1b596f256a26c9e65ab35bc24c.zip
display the server's error message for incorrect password
Diffstat (limited to 'src')
-rw-r--r--src/actions.rs6
-rw-r--r--src/api.rs41
-rw-r--r--src/bin/rbw-agent/actions.rs57
-rw-r--r--src/error.rs4
4 files changed, 71 insertions, 37 deletions
diff --git a/src/actions.rs b/src/actions.rs
index c63191f..f77378e 100644
--- a/src/actions.rs
+++ b/src/actions.rs
@@ -52,7 +52,11 @@ pub async fn unlock(
crate::cipherstring::CipherString::new(protected_key)?;
let key = match protected_key.decrypt_locked_symmetric(&identity.keys) {
Ok(master_keys) => crate::locked::Keys::new(master_keys),
- Err(Error::InvalidMac) => return Err(Error::IncorrectPassword),
+ Err(Error::InvalidMac) => {
+ return Err(Error::IncorrectPassword {
+ message: "Password is incorrect. Try again.".to_string(),
+ })
+ }
Err(e) => return Err(e),
};
diff --git a/src/api.rs b/src/api.rs
index 813043a..aec1398 100644
--- a/src/api.rs
+++ b/src/api.rs
@@ -901,24 +901,26 @@ fn classify_login_error(error_res: &ConnectErrorRes, code: u16) -> Error {
match error_res.error.as_str() {
"invalid_grant" => match error_res.error_description.as_str() {
"invalid_username_or_password" => {
- return Error::IncorrectPassword;
+ if let Some(error_model) = error_res.error_model.as_ref() {
+ let message = error_model.message.as_str().to_string();
+ return Error::IncorrectPassword { message };
+ }
}
"Two factor required." => {
- match error_res.two_factor_providers.as_ref() {
- Some(providers) => {
- let providers: Result<_> = providers
- .iter()
- .copied()
- .map(std::convert::TryInto::try_into)
- .collect();
- return match providers {
- Ok(providers) => {
- Error::TwoFactorRequired { providers }
- }
- Err(e) => e,
- };
- }
- _ => {}
+ if let Some(providers) =
+ error_res.two_factor_providers.as_ref()
+ {
+ let providers: Result<_> = providers
+ .iter()
+ .copied()
+ .map(std::convert::TryInto::try_into)
+ .collect();
+ return match providers {
+ Ok(providers) => {
+ Error::TwoFactorRequired { providers }
+ }
+ Err(e) => e,
+ };
}
}
_ => {}
@@ -928,16 +930,17 @@ fn classify_login_error(error_res: &ConnectErrorRes, code: u16) -> Error {
// this case, for some reason
if error_res.error_description == "" {
if let Some(error_model) = error_res.error_model.as_ref() {
- match error_model.message.as_str() {
+ let message = error_model.message.as_str().to_string();
+ match message.as_str() {
"Username or password is incorrect. Try again"
| "TOTP code is not a number" => {
- return Error::IncorrectPassword;
+ return Error::IncorrectPassword { message };
}
s => {
if s.starts_with(
"Invalid TOTP code! Server time: ",
) {
- return Error::IncorrectPassword;
+ return Error::IncorrectPassword { message };
}
}
}
diff --git a/src/bin/rbw-agent/actions.rs b/src/bin/rbw-agent/actions.rs
index 0062067..a01f510 100644
--- a/src/bin/rbw-agent/actions.rs
+++ b/src/bin/rbw-agent/actions.rs
@@ -22,9 +22,12 @@ pub async fn login(
let email = config_email().await?;
+ let mut err_msg = None;
for i in 1_u8..=3 {
let err = if i > 1 {
- Some(format!("Incorrect password (attempt {}/3)", i))
+ // this unwrap is safe because we only ever continue the loop
+ // if we have set err_msg
+ Some(format!("{} (attempt {}/3)", err_msg.unwrap(), i))
} else {
None
};
@@ -91,13 +94,14 @@ pub async fn login(
return Err(anyhow::anyhow!("TODO"));
}
}
- Err(rbw::error::Error::IncorrectPassword) => {
+ Err(rbw::error::Error::IncorrectPassword { message }) => {
if i == 3 {
- return Err(rbw::error::Error::IncorrectPassword)
- .context(
- "failed to log in to bitwarden instance",
- );
+ return Err(rbw::error::Error::IncorrectPassword {
+ message,
+ })
+ .context("failed to log in to bitwarden instance");
} else {
+ err_msg = Some(message);
continue;
}
}
@@ -120,9 +124,12 @@ async fn two_factor(
password: &rbw::locked::Password,
provider: rbw::api::TwoFactorProviderType,
) -> anyhow::Result<(String, String, u32, String)> {
+ let mut err_msg = None;
for i in 1_u8..=3 {
let err = if i > 1 {
- Some(format!("Incorrect code (attempt {}/3)", i))
+ // this unwrap is safe because we only ever continue the loop if
+ // we have set err_msg
+ Some(format!("{} (attempt {}/3)", err_msg.unwrap(), i))
} else {
None
};
@@ -158,13 +165,27 @@ async fn two_factor(
protected_key,
))
}
- Err(rbw::error::Error::IncorrectPassword)
+ Err(rbw::error::Error::IncorrectPassword { message }) => {
+ if i == 3 {
+ return Err(rbw::error::Error::IncorrectPassword {
+ message,
+ })
+ .context("failed to log in to bitwarden instance");
+ } else {
+ err_msg = Some(message);
+ continue;
+ }
+ }
// can get this if the user passes an empty string
- | Err(rbw::error::Error::TwoFactorRequired { .. }) => {
+ Err(rbw::error::Error::TwoFactorRequired { .. }) => {
+ let message = "TOTP code is not a number".to_string();
if i == 3 {
- return Err(rbw::error::Error::IncorrectPassword)
- .context("failed to log in to bitwarden instance");
+ return Err(rbw::error::Error::IncorrectPassword {
+ message,
+ })
+ .context("failed to log in to bitwarden instance");
} else {
+ err_msg = Some(message);
continue;
}
}
@@ -262,9 +283,12 @@ pub async fn unlock(
let email = config_email().await?;
+ let mut err_msg = None;
for i in 1u8..=3 {
let err = if i > 1 {
- Some(format!("Incorrect password (attempt {}/3)", i))
+ // this unwrap is safe because we only ever continue the loop
+ // if we have set err_msg
+ Some(format!("{} (attempt {}/3)", err_msg.unwrap(), i))
} else {
None
};
@@ -290,11 +314,14 @@ pub async fn unlock(
unlock_success(state, keys, org_keys).await?;
break;
}
- Err(rbw::error::Error::IncorrectPassword) => {
+ Err(rbw::error::Error::IncorrectPassword { message }) => {
if i == 3 {
- return Err(rbw::error::Error::IncorrectPassword)
- .context("failed to unlock database");
+ return Err(rbw::error::Error::IncorrectPassword {
+ message,
+ })
+ .context("failed to unlock database");
} else {
+ err_msg = Some(message);
continue;
}
}
diff --git a/src/error.rs b/src/error.rs
index 5a6eef4..5a95fec 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -34,8 +34,8 @@ pub enum Error {
#[snafu(display("failed to expand with hkdf"))]
HkdfExpand,
- #[snafu(display("username or password incorrect"))]
- IncorrectPassword,
+ #[snafu(display("{}", message))]
+ IncorrectPassword { message: String },
#[snafu(display("invalid base64"))]
InvalidBase64 { source: base64::DecodeError },