From f967132971d83b54517385d085b8973583774c2e Mon Sep 17 00:00:00 2001 From: Maurus Decimus <11444311+mdecimus@users.noreply.github.com> Date: Sun, 19 Jul 2026 15:44:06 +0200 Subject: [PATCH] Fix MTA: DMARC is skipped when MAIL FROM SPF is unavailable --- CHANGELOG.md | 1 + crates/smtp/src/inbound/data.rs | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 748905b8..5b07c6f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If - Web Push payloads with `Content-Encoding: aes128gcm` should not be base64-encoded but sent as raw bytes. - `Email/import` does not send push notifications for imported messages. - `CalendarEvent/set` silently ignores `ifInState`. +- MTA: DMARC is skipped when MAIL FROM SPF is unavailable. - Calendar: - Uppercase `MAILTO` calendar addresses become invalid SMTP recipients. - Scheduling invitations on a shared, non-owned calendar fail with `MAIL FROM unauthorized`. diff --git a/crates/smtp/src/inbound/data.rs b/crates/smtp/src/inbound/data.rs index 3bc6ded0..b00c24d8 100644 --- a/crates/smtp/src/inbound/data.rs +++ b/crates/smtp/src/inbound/data.rs @@ -29,6 +29,7 @@ use common::{ }; use mail_auth::{ AuthenticatedMessage, AuthenticationResults, Dkim2Result, DkimResult, DmarcResult, ReceivedSpf, + SpfOutput, SpfResult, common::{ crypto::Algorithm, headers::{Header, HeaderWriter}, @@ -349,8 +350,16 @@ impl Session { // Verify DMARC let is_report = !self.is_authenticated() && self.is_report(); - let (dmarc_result, dmarc_policy) = match &self.data.spf_mail_from { - Some(spf_output) if dmarc.verify() => { + let (dmarc_result, dmarc_policy) = if dmarc.verify() { + { + let synthetic_spf; + let spf_output = match &self.data.spf_mail_from { + Some(spf_output) => spf_output, + None => { + synthetic_spf = SpfOutput::new(String::new()).with_result(SpfResult::None); + &synthetic_spf + } + }; let time = Instant::now(); let dmarc_output = self.server @@ -432,7 +441,8 @@ impl Session { (dmarc_result.into(), dmarc_policy.into()) } - _ => (None, None), + } else { + (None, None) }; // Analyze reports