build, deploy, inbound, dmarc, backup, e2e: cite the source of what they rely on (assumptions part C)
Comments only, no behaviour changed. Each main.cf/master.cf parameter the
build sets, the wrapper's and the reload hook's reliance on Postfix 3.7.11
(postfix-script, master.5, postconf.5, cleanup_init.c, smtpd_peer.c,
README_FILES), supervisor 4.2.5 (process.py, options.py, events.rst),
logrotate 3.21.0, OpenDKIM's config, Cyrus SASL's sasldb, rspamd 3.11.1
(milter_headers.lua, multimap, the map watcher), Docker Compose, CoreDNS
and certbot now say where that is written. Measurements already there stay
measurements ("date not recorded" where none was); hand-composed fixtures
say so.
Contradictions left for their own commits: C-P31 cleanup's size limit,
C-P42 master outside supervisor's signal, C-V5/V6 startsecs, C-V10,
C-S3/Q3 sasldb written in place, C-Q4/A1 certbot's symlinks, C-R7 rspamd
skips local clients but the signature routine does not, C-P8, C-R4, C-R12,
C-M7, C-E2, C-K8/K9, C-D1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -154,6 +154,10 @@ func extractAggregatePayload(raw []byte) ([]byte, error) {
|
||||
return readEncodedBody(textproto.MIMEHeader(msg.Header), msg.Body)
|
||||
}
|
||||
|
||||
// looksLikeAggregate takes a part by its file name or Content-Type. RFC 7489
|
||||
// § 7.2.1.1: the report is "application/gzip" if compressed and "text/xml"
|
||||
// otherwise, its name ending ".xml" or ".xml.gz"; zip is outside the RFC and
|
||||
// is what some reporters send (see decompress).
|
||||
func looksLikeAggregate(name string) bool {
|
||||
name = strings.ToLower(name)
|
||||
return strings.Contains(name, "xml") || strings.Contains(name, "gzip") || strings.Contains(name, "zip")
|
||||
|
||||
+10
-1
@@ -40,6 +40,11 @@ type ParsedRecord struct {
|
||||
HeaderFrom string
|
||||
}
|
||||
|
||||
// feedbackXML follows RFC 7489, Appendix C. The schema's targetNamespace is
|
||||
// "http://dmarc.org/dmarc-xml/0.1"; a tag without a namespace matches the
|
||||
// local name in any namespace (Go, src/encoding/xml/read.go: the namespace is
|
||||
// compared only when the tag names one), so a report that declares one is
|
||||
// read the same.
|
||||
type feedbackXML struct {
|
||||
XMLName xml.Name `xml:"feedback"`
|
||||
Metadata struct {
|
||||
@@ -160,6 +165,9 @@ func ParseAggregate(raw []byte) (ParsedReport, error) {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// dmarcRecordPasses: RFC 7489, Appendix C, PolicyEvaluatedType - dkim and spf
|
||||
// are "The DMARC-aligned authentication result"; § 4.2: DMARC passes when one
|
||||
// supported mechanism passes aligned.
|
||||
func dmarcRecordPasses(r ParsedRecord) bool {
|
||||
return strings.EqualFold(r.SPFResult, "pass") || strings.EqualFold(r.DKIMResult, "pass")
|
||||
}
|
||||
@@ -170,7 +178,8 @@ const maxAggregateXML = 8 << 20
|
||||
|
||||
// decompress unwraps the container the reporter used. Both are seen in the
|
||||
// wild: most senders gzip the XML, some (notably several Microsoft and Yahoo
|
||||
// endpoints) ship it as a single-entry zip.
|
||||
// endpoints) ship it as a single-entry zip. (A sighting: where and when not
|
||||
// recorded. RFC 7489 § 7.2.1.1 names gzip only.)
|
||||
func decompress(raw []byte) ([]byte, error) {
|
||||
switch {
|
||||
case len(raw) >= 2 && raw[0] == 0x1f && raw[1] == 0x8b:
|
||||
|
||||
@@ -11,6 +11,9 @@ import (
|
||||
"github.com/mixeme/selfpost/internal/store"
|
||||
)
|
||||
|
||||
// sampleXML and the messages in this file are composed by hand, in the shape
|
||||
// RFC 7489 gives (Appendix C, the schema; § 7.2.1.1, application/gzip and the
|
||||
// .xml.gz name). The org name is any reporter's; no report was copied.
|
||||
const sampleXML = `<?xml version="1.0"?>
|
||||
<feedback>
|
||||
<report_metadata>
|
||||
|
||||
Reference in New Issue
Block a user