Given following the following example the DMARC check is wrong.
From: hello@sub.example.org
If there is no DNS DMARC record for sub.example.org (i.e. TXT _dmarc.sub.example.org), then the organizational domain should be used (i.e. _dmarc.example.org). If the organizational domain contains a subdomain policy (tag sp) such as "v=DMARC1; p=reject; sp=none; pct=100" then this policy should be applied.
Unfortunately, the policy (p=reject) of the organizational domain is currently applied instead of sp=none.
This fix also solves another issue. Namely, the evaluation of the tag "pct" (i.e. percentage). Otherwise always pct=100 is assumed (see Mail/DMARC/PurePerl.pm#validate, because $result->disposition considers the pct, whereas $result->published->p only contains the parsed policy of the DNS record.
Fixed in commit d5a393aecad89a86901d449579f2baa7d4bf0198
Most updated code will always be in https://github.com/apache/spamassassin now that this code has been imported into official Apache repository.
Bug report
Given following the following example the DMARC check is wrong.
From: hello@sub.example.org
If there is no DNS DMARC record for sub.example.org (i.e. TXT _dmarc.sub.example.org), then the organizational domain should be used (i.e. _dmarc.example.org). If the organizational domain contains a subdomain policy (tag sp) such as "v=DMARC1; p=reject; sp=none; pct=100" then this policy should be applied.
Unfortunately, the policy (p=reject) of the organizational domain is currently applied instead of sp=none.
How to fix
https://github.com/bigio/spamassassin-dmarc/blob/7b13622cd105c002fad2105d685fc15272caf67f/DMARC.pm#L346
Replace with:
$pms->{dmarc_policy} = $result->disposition;
This fix also solves another issue. Namely, the evaluation of the tag "pct" (i.e. percentage). Otherwise always pct=100 is assumed (see Mail/DMARC/PurePerl.pm#validate, because
$result->disposition
considers the pct, whereas$result->published->p
only contains the parsed policy of the DNS record.