From 1fed40a926b7070ad59fc69cb57ee1b67d53502f Mon Sep 17 00:00:00 2001 From: mdecimus Date: Sat, 28 Sep 2024 17:45:16 +0200 Subject: RFC7662 - OAuth 2.0 Token Introspection --- crates/smtp/src/inbound/auth.rs | 85 +++++++++++------------------------------ 1 file changed, 22 insertions(+), 63 deletions(-) (limited to 'crates/smtp') diff --git a/crates/smtp/src/inbound/auth.rs b/crates/smtp/src/inbound/auth.rs index 88b32d64..3a728f1a 100644 --- a/crates/smtp/src/inbound/auth.rs +++ b/crates/smtp/src/inbound/auth.rs @@ -5,7 +5,12 @@ */ use common::{ - auth::{oauth::extract_oauth_bearer, AuthRequest}, + auth::{ + sasl::{ + sasl_decode_challenge_oauth, sasl_decode_challenge_plain, sasl_decode_challenge_xoauth, + }, + AuthRequest, + }, listener::SessionStream, }; use directory::Permission; @@ -74,30 +79,9 @@ impl Session { } } else if let Some(response) = base64_decode(response) { match (token.mechanism, &mut token.credentials) { - (AUTH_PLAIN, Credentials::Plain { username, secret }) => { - let mut b_username = Vec::new(); - let mut b_secret = Vec::new(); - let mut arg_num = 0; - for ch in response { - if ch != 0 { - if arg_num == 1 { - b_username.push(ch); - } else if arg_num == 2 { - b_secret.push(ch); - } - } else { - arg_num += 1; - } - } - match (String::from_utf8(b_username), String::from_utf8(b_secret)) { - (Ok(s_username), Ok(s_secret)) if !s_username.is_empty() => { - *username = s_username; - *secret = s_secret; - return self - .authenticate(std::mem::take(&mut token.credentials)) - .await; - } - _ => (), + (AUTH_PLAIN, _) => { + if let Some(credentials) = sasl_decode_challenge_plain(&response) { + return self.authenticate(credentials).await; } } (AUTH_LOGIN, Credentials::Plain { username, secret }) => { @@ -111,45 +95,14 @@ impl Session { .await }; } - (AUTH_OAUTHBEARER, Credentials::OAuthBearer { token: token_ }) => { - if let Some(bearer) = extract_oauth_bearer(&response) { - *token_ = bearer.to_string(); - return self - .authenticate(std::mem::take(&mut token.credentials)) - .await; + (AUTH_OAUTHBEARER, _) => { + if let Some(credentials) = sasl_decode_challenge_oauth(&response) { + return self.authenticate(credentials).await; } } - (AUTH_XOAUTH2, Credentials::XOauth2 { username, secret }) => { - let mut b_username = Vec::new(); - let mut b_secret = Vec::new(); - let mut arg_num = 0; - let mut in_arg = false; - - for ch in response { - if in_arg { - if ch != 1 { - if arg_num == 1 { - b_username.push(ch); - } else if arg_num == 2 { - b_secret.push(ch); - } - } else { - in_arg = false; - } - } else if ch == b'=' { - arg_num += 1; - in_arg = true; - } - } - match (String::from_utf8(b_username), String::from_utf8(b_secret)) { - (Ok(s_username), Ok(s_secret)) if !s_username.is_empty() => { - *username = s_username; - *secret = s_secret; - return self - .authenticate(std::mem::take(&mut token.credentials)) - .await; - } - _ => (), + (AUTH_XOAUTH2, _) => { + if let Some(credentials) = sasl_decode_challenge_xoauth(&response) { + return self.authenticate(credentials).await; } } @@ -210,7 +163,13 @@ impl Session { .await; } trc::EventType::Security(trc::SecurityEvent::Unauthorized) => { - self.write(b"550 5.7.1 Your account is not authorized to use this service.\r\n") + self.write( + concat!( + "550 5.7.1 Your account is not authorized ", + "to use this service.\r\n" + ) + .as_bytes(), + ) .await?; return Ok(false); } -- cgit v1.2.3-70-g09d2