summaryrefslogtreecommitdiff
path: root/crates/smtp
diff options
context:
space:
mode:
authormdecimus <mauro@stalw.art>2024-09-12 17:42:14 +0200
committermdecimus <mauro@stalw.art>2024-09-12 17:42:14 +0200
commitd214468c54415f3048f0246eb176f6d25a3acdd2 (patch)
treeadc9eaefdbd9c7a57f5c7a83fed41c92fe5d590b /crates/smtp
parentfbcf55d8e1891b72499fed7d5ff54964c8a2f256 (diff)
Roles and multi-tenancy - part 1
Diffstat (limited to 'crates/smtp')
-rw-r--r--crates/smtp/src/inbound/auth.rs44
1 files changed, 38 insertions, 6 deletions
diff --git a/crates/smtp/src/inbound/auth.rs b/crates/smtp/src/inbound/auth.rs
index d7ff8c24..419b4dab 100644
--- a/crates/smtp/src/inbound/auth.rs
+++ b/crates/smtp/src/inbound/auth.rs
@@ -5,11 +5,11 @@
*/
use common::listener::SessionStream;
-use directory::backend::internal::PrincipalField;
+use directory::{backend::internal::PrincipalField, Permission};
use mail_parser::decoders::base64::base64_decode;
use mail_send::Credentials;
use smtp_proto::{IntoString, AUTH_LOGIN, AUTH_OAUTHBEARER, AUTH_PLAIN, AUTH_XOAUTH2};
-use trc::{AuthEvent, SmtpEvent};
+use trc::{AddContext, AuthEvent, SmtpEvent};
use crate::core::Session;
@@ -165,7 +165,9 @@ impl<T: SessionStream> Session<T> {
| Credentials::XOauth2 { username, .. }
| Credentials::OAuthBearer { token: username } => username.to_string(),
};
- match self
+
+ // Authenticate
+ let mut result = self
.core
.core
.authenticate(
@@ -175,10 +177,35 @@ impl<T: SessionStream> Session<T> {
self.data.remote_ip,
false,
)
- .await
- {
+ .await;
+
+ // Validate permissions
+ if let Ok(principal) = &result {
+ match self
+ .core
+ .core
+ .get_cached_access_token(principal.id())
+ .await
+ .caused_by(trc::location!())
+ {
+ Ok(access_token) => {
+ if let Err(err) = access_token
+ .assert_has_permission(Permission::EmailSend)
+ .and_then(|_| {
+ access_token.assert_has_permission(Permission::Authenticate)
+ })
+ {
+ result = Err(err);
+ }
+ }
+ Err(err) => {
+ result = Err(err);
+ }
+ }
+ }
+
+ match result {
Ok(principal) => {
- let todo = "check smtp auth permissions";
self.data.authenticated_as = authenticated_as.to_lowercase();
self.data.authenticated_emails = principal
.iter_str(PrincipalField::Emails)
@@ -207,6 +234,11 @@ impl<T: SessionStream> Session<T> {
)
.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")
+ .await?;
+ return Ok(false);
+ }
trc::EventType::Security(_) => {
return Err(());
}