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 ( AlignmentAbsent Alignment = "" 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 ( DispositionAbsent Disposition = "" 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 ( DMARCAbsent DMARCResult = "" 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 ( PolicyOverrideAbsent PolicyOverride = "" 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 ( DKIMAbsent DKIMResult = "" 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 ( SPFDomainScopeAbsent SPFDomainScope = "" SPFDomainScopeHelo SPFDomainScope = "helo" // SMTP EHLO SPFDomainScopeMailFrom SPFDomainScope = "mfrom" // SMTP "MAIL FROM". ) type SPFResult string const ( SPFAbsent SPFResult = "" SPFNone SPFResult = "none" SPFNeutral SPFResult = "neutral" SPFPass SPFResult = "pass" SPFFail SPFResult = "fail" SPFSoftfail SPFResult = "softfail" SPFTemperror SPFResult = "temperror" SPFPermerror SPFResult = "permerror" )