mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-25 00:50:36 +00:00
## Problem PGLB/Neonkeeper needs to separate the concerns of connecting to compute, and authenticating to compute. Additionally, the code within `connect_to_compute` is rather messy, spending effort on recovering the authentication info after wake_compute. ## Summary of changes Split `ConnCfg` into `ConnectInfo` and `AuthInfo`. `wake_compute` only returns `ConnectInfo` and `AuthInfo` is determined separately from the `handshake`/`authenticate` process. Additionally, `ConnectInfo::connect_raw` is in-charge or establishing the TLS connection, and the `postgres_client::Config::connect_raw` is configured to use `NoTls` which will force it to skip the TLS negotiation. This should just work.
57 lines
2.1 KiB
Rust
57 lines
2.1 KiB
Rust
use tokio::io::{AsyncRead, AsyncWrite};
|
|
use tracing::{debug, info, warn};
|
|
|
|
use super::{ComputeCredentials, ComputeUserInfo};
|
|
use crate::auth::backend::ComputeCredentialKeys;
|
|
use crate::auth::{self, AuthFlow};
|
|
use crate::config::AuthenticationConfig;
|
|
use crate::context::RequestContext;
|
|
use crate::control_plane::AuthSecret;
|
|
use crate::stream::{PqStream, Stream};
|
|
use crate::{compute, sasl};
|
|
|
|
pub(super) async fn authenticate(
|
|
ctx: &RequestContext,
|
|
creds: ComputeUserInfo,
|
|
client: &mut PqStream<Stream<impl AsyncRead + AsyncWrite + Unpin>>,
|
|
config: &'static AuthenticationConfig,
|
|
secret: AuthSecret,
|
|
) -> auth::Result<ComputeCredentials> {
|
|
let scram_keys = match secret {
|
|
AuthSecret::Scram(secret) => {
|
|
debug!("auth endpoint chooses SCRAM");
|
|
|
|
let auth_outcome = tokio::time::timeout(
|
|
config.scram_protocol_timeout,
|
|
AuthFlow::new(client, auth::Scram(&secret, ctx)).authenticate(),
|
|
)
|
|
.await
|
|
.inspect_err(|_| warn!("error processing scram messages error = authentication timed out, execution time exceeded {} seconds", config.scram_protocol_timeout.as_secs()))
|
|
.map_err(auth::AuthError::user_timeout)?
|
|
.inspect_err(|error| warn!(?error, "error processing scram messages"))?;
|
|
|
|
let client_key = match auth_outcome {
|
|
sasl::Outcome::Success(key) => key,
|
|
sasl::Outcome::Failure(reason) => {
|
|
// TODO: warnings?
|
|
// TODO: should we get rid of this because double logging?
|
|
info!("auth backend failed with an error: {reason}");
|
|
return Err(auth::AuthError::password_failed(&*creds.user));
|
|
}
|
|
};
|
|
|
|
compute::ScramKeys {
|
|
client_key: client_key.as_bytes(),
|
|
server_key: secret.server_key.as_bytes(),
|
|
}
|
|
}
|
|
};
|
|
|
|
Ok(ComputeCredentials {
|
|
info: creds,
|
|
keys: ComputeCredentialKeys::AuthKeys(postgres_client::config::AuthKeys::ScramSha256(
|
|
scram_keys,
|
|
)),
|
|
})
|
|
}
|