mirror of
https://github.com/mjl-/mox.git
synced 2025-07-10 07:54:40 +03:00
improvements to outgoing dmarc reports and displaying evaluations
- more eagerly report about overrides, so domain owners can better tell that switching from p=none to p=reject will not cause trouble for these messages. - report multiple reasons, e.g. mailing list and sampled out - in dmarc analysis for rejects from first-time senders (possibly spammers), fix the conditional check on nonjunk messages. - in evaluations view in admin, show unaligned spf pass in yellow too and a few more small tweaks.
This commit is contained in:
@ -2411,24 +2411,26 @@ func (c *conn) deliver(ctx context.Context, recvHdrFor func(string) string, msgW
|
||||
|
||||
// Any DMARC result override is stored in the evaluation for outgoing DMARC
|
||||
// aggregate reports, and added to the Authentication-Results message header.
|
||||
var dmarcOverride string
|
||||
if dmarcResult.Record != nil {
|
||||
if !dmarcUse {
|
||||
dmarcOverride = string(dmarcrpt.PolicyOverrideSampledOut)
|
||||
} else if a.dmarcOverrideReason != "" && (a.accept && !m.IsReject) == dmarcResult.Reject {
|
||||
dmarcOverride = a.dmarcOverrideReason
|
||||
}
|
||||
// We want to tell the sender that we have an override, e.g. for mailing lists, so
|
||||
// they don't overestimate the potential damage of switching from p=none to
|
||||
// p=reject.
|
||||
var dmarcOverrides []string
|
||||
if a.dmarcOverrideReason != "" {
|
||||
dmarcOverrides = []string{a.dmarcOverrideReason}
|
||||
}
|
||||
if dmarcResult.Record != nil && !dmarcUse {
|
||||
dmarcOverrides = append(dmarcOverrides, string(dmarcrpt.PolicyOverrideSampledOut))
|
||||
}
|
||||
|
||||
// Add per-recipient DMARC method to Authentication-Results. Each account can have
|
||||
// their own override rules, e.g. based on configured mailing lists/forwards.
|
||||
// ../rfc/7489:1486
|
||||
rcptDMARCMethod := dmarcMethod
|
||||
if dmarcOverride != "" {
|
||||
if len(dmarcOverrides) > 0 {
|
||||
if rcptDMARCMethod.Comment != "" {
|
||||
rcptDMARCMethod.Comment += ", "
|
||||
}
|
||||
rcptDMARCMethod.Comment += "override " + dmarcOverride
|
||||
rcptDMARCMethod.Comment += "override " + strings.Join(dmarcOverrides, ",")
|
||||
}
|
||||
rcptAuthResults := authResults
|
||||
rcptAuthResults.Methods = append([]message.AuthMethod{}, authResults.Methods...)
|
||||
@ -2477,7 +2479,7 @@ func (c *conn) deliver(ctx context.Context, recvHdrFor func(string) string, msgW
|
||||
// See if we received a non-junk message from this organizational domain.
|
||||
q := bstore.QueryTx[store.Message](tx)
|
||||
q.FilterNonzero(store.Message{MsgFromOrgDomain: m.MsgFromOrgDomain})
|
||||
q.FilterEqual("Notjunk", false)
|
||||
q.FilterEqual("Notjunk", true)
|
||||
exists, err := q.Exists()
|
||||
if err != nil {
|
||||
return fmt.Errorf("querying for non-junk message from organizational domain: %v", err)
|
||||
@ -2544,10 +2546,9 @@ func (c *conn) deliver(ctx context.Context, recvHdrFor func(string) string, msgW
|
||||
HeaderFrom: msgFrom.Domain.Name(),
|
||||
}
|
||||
|
||||
if dmarcOverride != "" {
|
||||
eval.OverrideReasons = []dmarcrpt.PolicyOverrideReason{
|
||||
{Type: dmarcrpt.PolicyOverride(dmarcOverride)},
|
||||
}
|
||||
for _, s := range dmarcOverrides {
|
||||
reason := dmarcrpt.PolicyOverrideReason{Type: dmarcrpt.PolicyOverride(s)}
|
||||
eval.OverrideReasons = append(eval.OverrideReasons, reason)
|
||||
}
|
||||
|
||||
// We'll include all signatures for the organizational domain, even if they weren't
|
||||
|
Reference in New Issue
Block a user