mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 16:33:47 +03:00
e7699708ef
in smtpserver, we store dmarc evaluations (under the right conditions). in dmarcdb, we periodically (hourly) send dmarc reports if there are evaluations. for failed deliveries, we deliver the dsn quietly to a submailbox of the postmaster mailbox. this is on by default, but can be disabled in mox.conf.
165 lines
4.8 KiB
Go
165 lines
4.8 KiB
Go
package dmarcrpt
|
|
|
|
import (
|
|
"encoding/xml"
|
|
)
|
|
|
|
// Initially generated by xsdgen, then modified.
|
|
|
|
// Feedback is the top-level XML field returned.
|
|
type Feedback struct {
|
|
XMLName xml.Name `xml:"feedback" json:"-"` // todo: removing the json tag triggers bug in sherpadoc, should fix.
|
|
Version string `xml:"version"`
|
|
ReportMetadata ReportMetadata `xml:"report_metadata"`
|
|
PolicyPublished PolicyPublished `xml:"policy_published"`
|
|
Records []ReportRecord `xml:"record"`
|
|
}
|
|
|
|
type ReportMetadata struct {
|
|
OrgName string `xml:"org_name"`
|
|
Email string `xml:"email"`
|
|
ExtraContactInfo string `xml:"extra_contact_info,omitempty"`
|
|
ReportID string `xml:"report_id"`
|
|
DateRange DateRange `xml:"date_range"`
|
|
Errors []string `xml:"error,omitempty"`
|
|
}
|
|
|
|
type DateRange struct {
|
|
Begin int64 `xml:"begin"`
|
|
End int64 `xml:"end"`
|
|
}
|
|
|
|
// PolicyPublished is the policy as found in DNS for the domain.
|
|
type PolicyPublished struct {
|
|
// Domain is where DMARC record was found, not necessarily message From. Reports we
|
|
// generate use unicode names, incoming reports may have either ASCII-only or
|
|
// Unicode domains.
|
|
Domain string `xml:"domain"`
|
|
ADKIM Alignment `xml:"adkim,omitempty"`
|
|
ASPF Alignment `xml:"aspf,omitempty"`
|
|
Policy Disposition `xml:"p"`
|
|
SubdomainPolicy Disposition `xml:"sp"`
|
|
Percentage int `xml:"pct"`
|
|
ReportingOptions string `xml:"fo"`
|
|
}
|
|
|
|
// Alignment is the identifier alignment.
|
|
type Alignment string
|
|
|
|
const (
|
|
AlignmentRelaxed Alignment = "r" // Subdomains match the DMARC from-domain.
|
|
AlignmentStrict Alignment = "s" // Only exact from-domain match.
|
|
)
|
|
|
|
// Disposition is the requested action for a DMARC fail as specified in the
|
|
// DMARC policy in DNS.
|
|
type Disposition string
|
|
|
|
const (
|
|
DispositionNone Disposition = "none"
|
|
DispositionQuarantine Disposition = "quarantine"
|
|
DispositionReject Disposition = "reject"
|
|
)
|
|
|
|
type ReportRecord struct {
|
|
Row Row `xml:"row"`
|
|
Identifiers Identifiers `xml:"identifiers"`
|
|
AuthResults AuthResults `xml:"auth_results"`
|
|
}
|
|
|
|
type Row struct {
|
|
// SourceIP must match the pattern ((1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]).){3}
|
|
// (1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])|
|
|
// ([A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}
|
|
SourceIP string `xml:"source_ip"`
|
|
Count int `xml:"count"`
|
|
PolicyEvaluated PolicyEvaluated `xml:"policy_evaluated"`
|
|
}
|
|
|
|
type PolicyEvaluated struct {
|
|
Disposition Disposition `xml:"disposition"`
|
|
DKIM DMARCResult `xml:"dkim"`
|
|
SPF DMARCResult `xml:"spf"`
|
|
Reasons []PolicyOverrideReason `xml:"reason,omitempty"`
|
|
}
|
|
|
|
// DMARCResult is the final validation and alignment verdict for SPF and DKIM.
|
|
type DMARCResult string
|
|
|
|
const (
|
|
DMARCPass DMARCResult = "pass"
|
|
DMARCFail DMARCResult = "fail"
|
|
)
|
|
|
|
type PolicyOverrideReason struct {
|
|
Type PolicyOverride `xml:"type"`
|
|
Comment string `xml:"comment,omitempty"`
|
|
}
|
|
|
|
// PolicyOverride is a reason the requested DMARC policy from the DNS record
|
|
// was not applied.
|
|
type PolicyOverride string
|
|
|
|
const (
|
|
PolicyOverrideForwarded PolicyOverride = "forwarded"
|
|
PolicyOverrideSampledOut PolicyOverride = "sampled_out"
|
|
PolicyOverrideTrustedForwarder PolicyOverride = "trusted_forwarder"
|
|
PolicyOverrideMailingList PolicyOverride = "mailing_list"
|
|
PolicyOverrideLocalPolicy PolicyOverride = "local_policy"
|
|
PolicyOverrideOther PolicyOverride = "other"
|
|
)
|
|
|
|
type Identifiers struct {
|
|
EnvelopeTo string `xml:"envelope_to,omitempty"`
|
|
EnvelopeFrom string `xml:"envelope_from"`
|
|
HeaderFrom string `xml:"header_from"`
|
|
}
|
|
|
|
type AuthResults struct {
|
|
DKIM []DKIMAuthResult `xml:"dkim,omitempty"`
|
|
SPF []SPFAuthResult `xml:"spf"`
|
|
}
|
|
|
|
type DKIMAuthResult struct {
|
|
Domain string `xml:"domain"`
|
|
Selector string `xml:"selector,omitempty"`
|
|
Result DKIMResult `xml:"result"`
|
|
HumanResult string `xml:"human_result,omitempty"`
|
|
}
|
|
|
|
type DKIMResult string
|
|
|
|
const (
|
|
DKIMNone DKIMResult = "none"
|
|
DKIMPass DKIMResult = "pass"
|
|
DKIMFail DKIMResult = "fail"
|
|
DKIMPolicy DKIMResult = "policy"
|
|
DKIMNeutral DKIMResult = "neutral"
|
|
DKIMTemperror DKIMResult = "temperror"
|
|
DKIMPermerror DKIMResult = "permerror"
|
|
)
|
|
|
|
type SPFAuthResult struct {
|
|
Domain string `xml:"domain"`
|
|
Scope SPFDomainScope `xml:"scope"`
|
|
Result SPFResult `xml:"result"`
|
|
}
|
|
|
|
type SPFDomainScope string
|
|
|
|
const (
|
|
SPFDomainScopeHelo SPFDomainScope = "helo" // SMTP EHLO
|
|
SPFDomainScopeMailFrom SPFDomainScope = "mfrom" // SMTP "MAIL FROM".
|
|
)
|
|
|
|
type SPFResult string
|
|
|
|
const (
|
|
SPFNone SPFResult = "none"
|
|
SPFNeutral SPFResult = "neutral"
|
|
SPFPass SPFResult = "pass"
|
|
SPFFail SPFResult = "fail"
|
|
SPFSoftfail SPFResult = "softfail"
|
|
SPFTemperror SPFResult = "temperror"
|
|
SPFPermerror SPFResult = "permerror"
|
|
)
|