mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-08 22:12:56 +00:00
[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:
@@ -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(),
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user