TLA Line data Source code
1 : use super::AuthSuccess;
2 : use crate::{
3 : auth::{self, AuthFlow, ClientCredentials},
4 : console::{
5 : self,
6 : provider::{CachedNodeInfo, ConsoleReqExtra},
7 : },
8 : stream,
9 : };
10 : use tokio::io::{AsyncRead, AsyncWrite};
11 : use tracing::{info, warn};
12 :
13 : /// Compared to [SCRAM](crate::scram), cleartext password auth saves
14 : /// one round trip and *expensive* computations (>= 4096 HMAC iterations).
15 : /// These properties are benefical for serverless JS workers, so we
16 : /// use this mechanism for websocket connections.
17 UBC 0 : pub async fn cleartext_hack(
18 0 : api: &impl console::Api,
19 0 : extra: &ConsoleReqExtra<'_>,
20 0 : creds: &mut ClientCredentials<'_>,
21 0 : client: &mut stream::PqStream<impl AsyncRead + AsyncWrite + Unpin>,
22 0 : ) -> auth::Result<AuthSuccess<CachedNodeInfo>> {
23 0 : warn!("cleartext auth flow override is enabled, proceeding");
24 0 : let password = AuthFlow::new(client)
25 0 : .begin(auth::CleartextPassword)
26 0 : .await?
27 0 : .authenticate()
28 0 : .await?;
29 :
30 0 : let mut node = api.wake_compute(extra, creds).await?;
31 0 : node.config.password(password);
32 0 :
33 0 : // Report tentative success; compute node will check the password anyway.
34 0 : Ok(AuthSuccess {
35 0 : reported_auth_ok: false,
36 0 : value: node,
37 0 : })
38 0 : }
39 :
40 : /// Workaround for clients which don't provide an endpoint (project) name.
41 : /// Very similar to [`cleartext_hack`], but there's a specific password format.
42 CBC 3 : pub async fn password_hack(
43 3 : api: &impl console::Api,
44 3 : extra: &ConsoleReqExtra<'_>,
45 3 : creds: &mut ClientCredentials<'_>,
46 3 : client: &mut stream::PqStream<impl AsyncRead + AsyncWrite + Unpin>,
47 3 : ) -> auth::Result<AuthSuccess<CachedNodeInfo>> {
48 3 : warn!("project not specified, resorting to the password hack auth flow");
49 3 : let payload = AuthFlow::new(client)
50 3 : .begin(auth::PasswordHack)
51 UBC 0 : .await?
52 CBC 3 : .authenticate()
53 3 : .await?;
54 :
55 2 : info!(project = &payload.endpoint, "received missing parameter");
56 2 : creds.project = Some(payload.endpoint);
57 :
58 2 : let mut node = api.wake_compute(extra, creds).await?;
59 2 : node.config.password(payload.password);
60 2 :
61 2 : // Report tentative success; compute node will check the password anyway.
62 2 : Ok(AuthSuccess {
63 2 : reported_auth_ok: false,
64 2 : value: node,
65 2 : })
66 3 : }
|