LCOV - differential code coverage report
Current view: top level - proxy/src/auth/backend - hacks.rs (source / functions) Coverage Total Hit UBC CBC
Current: cd44433dd675caa99df17a61b18949c8387e2242.info Lines: 48.8 % 41 20 21 20
Current Date: 2024-01-09 02:06:09 Functions: 16.7 % 24 4 20 4
Baseline: 66c52a629a0f4a503e193045e0df4c77139e344b.info
Baseline Date: 2024-01-08 15:34:46

           TLA  Line data    Source code
       1                 : use super::{
       2                 :     ComputeCredentialKeys, ComputeCredentials, ComputeUserInfo, ComputeUserInfoNoEndpoint,
       3                 : };
       4                 : use crate::{
       5                 :     auth::{self, AuthFlow},
       6                 :     console::AuthSecret,
       7                 :     metrics::LatencyTimer,
       8                 :     sasl,
       9                 :     stream::{self, Stream},
      10                 : };
      11                 : use tokio::io::{AsyncRead, AsyncWrite};
      12                 : use tracing::{info, warn};
      13                 : 
      14                 : /// Compared to [SCRAM](crate::scram), cleartext password auth saves
      15                 : /// one round trip and *expensive* computations (>= 4096 HMAC iterations).
      16                 : /// These properties are benefical for serverless JS workers, so we
      17                 : /// use this mechanism for websocket connections.
      18 UBC           0 : pub async fn authenticate_cleartext(
      19               0 :     info: ComputeUserInfo,
      20               0 :     client: &mut stream::PqStream<Stream<impl AsyncRead + AsyncWrite + Unpin>>,
      21               0 :     latency_timer: &mut LatencyTimer,
      22               0 :     secret: AuthSecret,
      23               0 : ) -> auth::Result<ComputeCredentials<ComputeCredentialKeys>> {
      24               0 :     warn!("cleartext auth flow override is enabled, proceeding");
      25                 : 
      26                 :     // pause the timer while we communicate with the client
      27               0 :     let _paused = latency_timer.pause();
      28                 : 
      29               0 :     let auth_outcome = AuthFlow::new(client)
      30               0 :         .begin(auth::CleartextPassword(secret))
      31               0 :         .await?
      32               0 :         .authenticate()
      33               0 :         .await?;
      34                 : 
      35               0 :     let keys = match auth_outcome {
      36               0 :         sasl::Outcome::Success(key) => key,
      37               0 :         sasl::Outcome::Failure(reason) => {
      38               0 :             info!("auth backend failed with an error: {reason}");
      39               0 :             return Err(auth::AuthError::auth_failed(&*info.inner.user));
      40                 :         }
      41                 :     };
      42                 : 
      43               0 :     Ok(ComputeCredentials { info, keys })
      44               0 : }
      45                 : 
      46                 : /// Workaround for clients which don't provide an endpoint (project) name.
      47                 : /// Similar to [`authenticate_cleartext`], but there's a specific password format,
      48                 : /// and passwords are not yet validated (we don't know how to validate them!)
      49 CBC           3 : pub async fn password_hack_no_authentication(
      50               3 :     info: ComputeUserInfoNoEndpoint,
      51               3 :     client: &mut stream::PqStream<Stream<impl AsyncRead + AsyncWrite + Unpin>>,
      52               3 :     latency_timer: &mut LatencyTimer,
      53               3 : ) -> auth::Result<ComputeCredentials<Vec<u8>>> {
      54               3 :     warn!("project not specified, resorting to the password hack auth flow");
      55                 : 
      56                 :     // pause the timer while we communicate with the client
      57               3 :     let _paused = latency_timer.pause();
      58                 : 
      59               3 :     let payload = AuthFlow::new(client)
      60               3 :         .begin(auth::PasswordHack)
      61 UBC           0 :         .await?
      62 CBC           3 :         .get_password()
      63               3 :         .await?;
      64                 : 
      65               2 :     info!(project = &*payload.endpoint, "received missing parameter");
      66                 : 
      67                 :     // Report tentative success; compute node will check the password anyway.
      68               2 :     Ok(ComputeCredentials {
      69               2 :         info: ComputeUserInfo {
      70               2 :             inner: info,
      71               2 :             endpoint: payload.endpoint,
      72               2 :         },
      73               2 :         keys: payload.password,
      74               2 :     })
      75               3 : }
        

Generated by: LCOV version 2.1-beta