[proxy] Propagate SASL/SCRAM auth errors to the user

This will replace the vague (and incorrect) "Internal error" with a nice
and helpful authentication error, e.g. "password doesn't match".
This commit is contained in:
Dmitry Ivanov
2022-05-26 20:39:33 +03:00
parent 5d813f9738
commit b3ec6e0661
5 changed files with 22 additions and 2 deletions

View File

@@ -75,6 +75,7 @@ impl UserFacingError for AuthError {
match self.0.as_ref() {
Console(e) => e.to_string_client(),
GetAuthInfo(e) => e.to_string_client(),
Sasl(e) => e.to_string_client(),
MalformedPassword => self.to_string(),
_ => "Internal error".to_string(),
}

View File

@@ -2,6 +2,7 @@ use crate::url::ApiUrl;
use anyhow::{bail, ensure, Context};
use std::{str::FromStr, sync::Arc};
#[derive(Debug)]
pub enum AuthBackendType {
/// Legacy Cloud API (V1).
LegacyConsole,

View File

@@ -126,6 +126,7 @@ async fn main() -> anyhow::Result<()> {
}));
println!("Version: {GIT_VERSION}");
println!("Authentication backend: {:?}", config.auth_backend);
// Check that we can bind to address before further initialization
println!("Starting http on {}", http_address);

View File

@@ -10,6 +10,7 @@ mod channel_binding;
mod messages;
mod stream;
use crate::error::UserFacingError;
use std::io;
use thiserror::Error;
@@ -36,6 +37,20 @@ pub enum Error {
Io(#[from] io::Error),
}
impl UserFacingError for Error {
fn to_string_client(&self) -> String {
use Error::*;
match self {
// This constructor contains the reason why auth has failed.
AuthenticationFailed(s) => s.to_string(),
// TODO: add support for channel binding
ChannelBindingFailed(_) => "channel binding is not supported yet".to_string(),
ChannelBindingBadMethod(m) => format!("unsupported channel binding method {m}"),
_ => "authentication protocol violation".to_string(),
}
}
}
/// A convenient result type for SASL exchange.
pub type Result<T> = std::result::Result<T, Error>;

View File

@@ -106,7 +106,9 @@ impl sasl::Mechanism for Exchange<'_> {
}
if client_final_message.nonce != server_first_message.nonce() {
return Err(SaslError::AuthenticationFailed("bad nonce"));
return Err(SaslError::AuthenticationFailed(
"combined nonce doesn't match",
));
}
let signature_builder = SignatureBuilder {
@@ -120,7 +122,7 @@ impl sasl::Mechanism for Exchange<'_> {
.derive_client_key(&client_final_message.proof);
if client_key.sha256() != self.secret.stored_key {
return Err(SaslError::AuthenticationFailed("keys don't match"));
return Err(SaslError::AuthenticationFailed("password doesn't match"));
}
let msg = client_final_message