@@ -20,9 +20,50 @@ specifically (all resolved) and are not duplicated here.
2020- ** RFC 9989 ` t= ` /` pct= ` ** : ` t= ` parsing, fetch accessor, and enforcement
2121 step-down (reject->quarantine->none). ` pct= ` deliberately kept for POLA,
2222 with ` DMARCbisIgnorePct ` for operators who want strict compliance. (#434 )
23+ - ** ` !NNNk ` RUA size-suffix syntax** : RFC 9989's ABNF marks this obsolete
24+ (` obs-dmarc-uri ` /` obs-dmarc-report-size ` ) and says reporters MUST ignore
25+ it. Unlike the ` pct= ` POLA call above, ` opendmarc-reports ` now drops the
26+ enforcement PR #392 had restored -- the suffix is still stripped from
27+ the destination address so delivery isn't broken, but it no longer
28+ overrides ` report_maxbytes ` .
2329- ** RFC 9990 aggregate reporting** : ` np ` /` testing ` /` discovery_method ` in
2430 ` policy_published ` , namespace bumped to ` dmarc-2.0 ` , ` <pct> ` removed
2531 (branch ` feat/rfc9990-aggregate-reporting ` ).
32+ - ** RFC 9990 ` generator ` element** (S3.1.1.3): ` report_metadata ` now
33+ includes ` <generator> ` identifying the report-generating software
34+ (` $progname v$version ` ), matching the string already used for
35+ ` --version ` output and the ` X-Mailer ` header. (Unrelated: the separate
36+ ` contrib/dmarc-report-totext.pl ` * consumer* tool already parses this
37+ field from other senders' reports — that's reading, not writing.)
38+ - ** ` rf= ` /` ri= ` cleanup** : both tags were removed from the DMARC record
39+ format by RFC 9989. Removed the parsing (` opendmarc_policy.c ` ), the
40+ now-dead ` DMARC_POLICY_T ` fields (` rf ` , ` ri ` ), the orphaned
41+ ` opendmarc_policy_fetch_rf() ` (never declared in the public header, so
42+ unreachable by consumers anyway) and its stale doc page, and the
43+ ` RF= ` /` RI= ` lines from ` opendmarc_policy_to_buf() ` 's dump. Unrecognized
44+ tags are already silently ignored by the parser per spec, so ` rf= ` /` ri= `
45+ now fall through to that same path rather than being validated.
46+ Verified via a real ` ./configure && make check ` on quark (this sandbox
47+ lacks milter headers) — all 10 ` libopendmarc ` tests pass, including
48+ ` test_dmarc_parse ` 's negative cases updated to expect ` DMARC_PARSE_OKAY `
49+ now that these are unknown tags rather than validated ones.
50+ - ** ` pass ` disposition value** (S3.1.1.9): ` ActionDispositionType ` now
51+ emits ` pass ` alongside ` none ` /` quarantine ` /` reject ` . New
52+ ` DMARC_RESULT_PASS ` (` opendmarc.h ` ) is set in ` opendmarc.c ` 's
53+ ` enforce_policy ` switch specifically when alignment passed * and* the
54+ unadjusted published ` p ` /` sp ` (whichever applies) was ` reject ` or
55+ ` quarantine ` -- under ` p=none ` /` sp=none ` the disposition stays ` none ` ,
56+ since RFC 9990 reserves ` pass ` for "passing DMARC w/enforcing policy".
57+ Deliberately keyed off the unadjusted policy rather than the
58+ ` t=y ` -downgraded ` enforce_policy ` , matching the existing rule that ` t= `
59+ doesn't affect report generation. Also added a ` dis=pass ` case to the
60+ Authentication-Results ` dis= ` tag mapping for consistency with the
61+ existing ` dmarc=pass ` ` aresult ` . Flows through ` messages.disp ` (a plain
62+ unconstrained ` TINYINT ` , so no schema migration) into
63+ ` opendmarc-reports.in ` 's disposition mapping. Verified with a clean
64+ ` ./configure && make check ` on quark: full project builds with no
65+ warnings, ` libopendmarc ` suite still 10/10 (unaffected, but a good
66+ regression signal since this touches the same enforcement path).
2667- ** RFC 9991 failure reporting** : ` Identity-Alignment ` and
2768 ` DKIM-Domain ` /` -Identity ` /` -Selector ` ARF headers, ` ruf= ` external
2869 destination verification + rate-limiting in `opendmarc-reports
@@ -56,18 +97,10 @@ specifically (all resolved) and are not duplicated here.
5697
5798### RFC 9990 aggregate reporting
5899
59- - ** ` pass ` disposition value** (S3.1.1.9): ` ActionDispositionType ` now
60- includes ` pass ` (message passed DMARC under an * enforcing* policy)
61- alongside ` none ` /` quarantine ` /` reject ` . Current code only ever emits the
62- original three. Not touched by the ` np ` /` testing ` /` discovery_method ` work.
63100- ** ` policy_test_mode ` reason type** (S3.1.6): a ` <reason><type> ` value a
64101 report record should carry when ` t=y ` caused a policy step-down. Directly
65102 adjacent to work already done — ` t= ` enforcement and ` <testing> ` in
66103 ` policy_published ` both shipped, but this per-record annotation didn't.
67- - ** ` generator ` element** (S3.1.1.3): identifies the report-generating
68- software. Not implemented in ` opendmarc-reports ` . (Unrelated: the
69- separate ` contrib/dmarc-report-totext.pl ` * consumer* tool already parses
70- this field from other senders' reports — that's reading, not writing.)
71104- ** ` error ` element** (S3.1.1.3/S3.1.5): describes processing errors
72105 encountered while evaluating the DMARC Policy Record. Not implemented.
73106- ** DKIM signature priority + 100-signature cap** (S3.1.3): defines which
@@ -77,10 +110,6 @@ specifically (all resolved) and are not duplicated here.
77110- ** Extension mechanism** (S3.2, S5): ` <extension> ` at file level,
78111 namespaced elements at record level. Low priority — only matters if
79112 extensions are actually adopted by report consumers.
80- - ** ` rf= ` /` ri= ` cleanup** : both tags were removed from the DMARC record
81- format by RFC 9989. OpenDMARC still parses them into unused
82- ` DMARC_POLICY_T ` fields (` rf ` , ` ri ` ). Minor; safe to remove.
83-
84113### RFC 9991 failure reporting
85114
86115Both RFC 6591 fields originally tracked here (` DKIM-Canonicalized-Header ` /
@@ -135,14 +164,3 @@ in this section.
135164 startup instead of a compile error until someone actually parses a
136165 config file containing it, which apparently hadn't happened for three
137166 of these four since they were introduced.
138-
139- ### Open decision, not just missing code
140-
141- - ** ` !NNNk ` RUA size-suffix syntax** : RFC 9990 Appendix C says this syntax
142- is obsolete and receivers (i.e. OpenDMARC, acting as report generator)
143- MUST ignore it. The restored PR #392 code (` check_size_restriction ` )
144- actively parses and enforces it, faithfully reproducing pre-regression
145- behavior rather than the RFC 9990 text. Same shape of question as the
146- ` pct= ` POLA decision: keep honoring it for senders who rely on it, or
147- drop it now that it's back in front of you. Needs an explicit call, not
148- a default.
0 commit comments