Page MenuHomePhorge

D5898.1779295862.diff
No OneTemporary

Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None

D5898.1779295862.diff

diff --git a/docker/postfix/rootfs/etc/postfix/main.cf b/docker/postfix/rootfs/etc/postfix/main.cf
--- a/docker/postfix/rootfs/etc/postfix/main.cf
+++ b/docker/postfix/rootfs/etc/postfix/main.cf
@@ -612,5 +612,10 @@
# to allow/deny sender access.
# We use this in place of reject_sender_login_mismatch to support e.g. delegation.
check_policy_service unix:private/policy_submission
+sieve_data_restrictions =
+ # Final hook for rate-limit request and decision
+ # to allow/deny sender access.
+ # We use this in place of reject_sender_login_mismatch to support e.g. delegation.
+ check_policy_service unix:private/policy_submission_sieve
rbl_reply_maps = texthash:/etc/postfix/rbl_reply_map
diff --git a/docker/postfix/rootfs/etc/postfix/master.cf b/docker/postfix/rootfs/etc/postfix/master.cf
--- a/docker/postfix/rootfs/etc/postfix/master.cf
+++ b/docker/postfix/rootfs/etc/postfix/master.cf
@@ -44,7 +44,7 @@
-o smtpd_sender_restrictions=$sieve_sender_restrictions
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=$submission_relay_restrictions
- -o smtpd_data_restrictions=
+ -o smtpd_data_restrictions=$sieve_data_restrictions
-o smtpd_helo_restrictions=$submission_helo_restrictions
-o smtpd_helo_required=yes
-o smtpd_peername_lookup=no
@@ -146,7 +146,10 @@
# Outbound
policy_submission unix - n n - - spawn
- user=nobody argv=/usr/libexec/postfix/kolab_policy_submission
+ user=nobody argv=/usr/libexec/postfix/kolab_policy_submission /api/webhooks/policy/submission
+
+policy_submission_sieve unix - n n - - spawn
+ user=nobody argv=/usr/libexec/postfix/kolab_policy_submission /api/webhooks/policy/submission-sieve
# Inbound
policy_reception unix - n n - - spawn
diff --git a/docker/postfix/rootfs/usr/libexec/postfix/kolab_policy_submission b/docker/postfix/rootfs/usr/libexec/postfix/kolab_policy_submission
--- a/docker/postfix/rootfs/usr/libexec/postfix/kolab_policy_submission
+++ b/docker/postfix/rootfs/usr/libexec/postfix/kolab_policy_submission
@@ -139,7 +139,8 @@
if __name__ == "__main__":
- URL = 'SERVICES_HOST/api/webhooks/policy/submission'
+ path = sys.argv[1]
+ URL = f"SERVICES_HOST{path}"
policy_requests = {}
diff --git a/src/app/Http/Controllers/API/V4/PolicyController.php b/src/app/Http/Controllers/API/V4/PolicyController.php
--- a/src/app/Http/Controllers/API/V4/PolicyController.php
+++ b/src/app/Http/Controllers/API/V4/PolicyController.php
@@ -154,4 +154,14 @@
return $response->jsonResponse();
}
+
+ /**
+ * Validate sender/recipients in an SMTP submission request from sieve.
+ */
+ public function submissionSieve(): JsonResponse
+ {
+ $response = SmtpAccess::submission(\request()->input(), true);
+
+ return $response->jsonResponse();
+ }
}
diff --git a/src/app/Policy/SmtpAccess.php b/src/app/Policy/SmtpAccess.php
--- a/src/app/Policy/SmtpAccess.php
+++ b/src/app/Policy/SmtpAccess.php
@@ -32,7 +32,7 @@
*
* @param array $data Input data
*/
- public static function submission($data): Response
+ public static function submission($data, bool $isSieve = false): Response
{
// TODO: The old SMTP access policy had an option ('empty_sender_hosts') to allow
// sending mail with no sender from configured networks.
@@ -59,7 +59,7 @@
return new Response(Response::ACTION_REJECT, "Could not find user {$data['user']}", 403);
}
- if (!self::verifySender($user, $sender)) {
+ if (!self::verifySender($user, $sender, $isSieve)) {
$reason = "{$sasl_user} is unauthorized to send mail as {$sender}";
return new Response(Response::ACTION_REJECT, $reason, 403);
}
@@ -86,7 +86,7 @@
* @param User $user Authenticated user
* @param string $email Email address
*/
- public static function verifySender(User $user, string $email): bool
+ public static function verifySender(User $user, string $email, bool $isSieve = false): bool
{
if ($user->isSuspended() || !str_contains($email, '@')) {
return false;
@@ -94,6 +94,12 @@
// TODO: Make sure the domain is not suspended
+ // Sieve redirects will have unknown sender addresses,
+ // so there is nothing to validate.
+ if ($isSieve) {
+ return true;
+ }
+
$email = \strtolower($email);
if ($user->email == $email) {
diff --git a/src/routes/api.php b/src/routes/api.php
--- a/src/routes/api.php
+++ b/src/routes/api.php
@@ -331,6 +331,7 @@
Route::post('policy/spf', [API\V4\PolicyController::class, 'senderPolicyFramework']);
Route::post('policy/reception', [API\V4\PolicyController::class, 'reception']);
Route::post('policy/submission', [API\V4\PolicyController::class, 'submission']);
+ Route::post('policy/submission-sieve', [API\V4\PolicyController::class, 'submissionSieve']);
Route::post('policy/mail/filter', [API\V4\PolicyController::class, 'mailfilter']);
Route::get('health/status', [API\V4\HealthController::class, 'status']);
}
diff --git a/src/tests/Feature/Policy/SmtpAccessTest.php b/src/tests/Feature/Policy/SmtpAccessTest.php
--- a/src/tests/Feature/Policy/SmtpAccessTest.php
+++ b/src/tests/Feature/Policy/SmtpAccessTest.php
@@ -126,4 +126,23 @@
$jack->suspend();
$this->assertFalse(SmtpAccess::verifySender($jack, $jack->email));
}
+
+ /**
+ * Test verifySender() method from sieve
+ */
+ public function testVerifySenderSieve(): void
+ {
+ $john = $this->getTestUser('john@kolab.org');
+ $jack = $this->getTestUser('jack@kolab.org');
+
+ // Test main email address
+ $this->assertTrue(SmtpAccess::verifySender($john, ucfirst($john->email), true));
+
+ // Test unknown address
+ $this->assertTrue(SmtpAccess::verifySender($jack, 'unknown@domain.tld', true));
+
+ // Test suspended user
+ $jack->suspend();
+ $this->assertFalse(SmtpAccess::verifySender($jack, $jack->email, true));
+ }
}

File Metadata

Mime Type
text/plain
Expires
Wed, May 20, 4:51 PM (1 d, 1 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18929192
Default Alt Text
D5898.1779295862.diff (6 KB)

Event Timeline