Reads DMARC aggregate reports (RFC 9990), as mail providers send them: XML, gzip or zip. Reports in the older RFC 7489 format read the same way.
{:ok, report} = MailAuth.DMARC.Report.parse(File.read!("report.xml.gz"))
report.policy_published.domain
for record <- report.records, do: {record.source_ip, record.count, record.disposition}Reports come from strangers, so the input is bounded: at most 50 MB once
uncompressed, and no DTD (<!DOCTYPE), which rules out entity expansion
attacks. Element names never become atoms.
Fields
:version: the report format version, when given:metadata::org_name,:email,:extra_contact_info,:report_id,:beginand:end(asDateTime),:generator,:errors:policy_published: the record the reporter found::domain,:p,:sp,:np,:adkim,:aspf,:testing,:discovery_method,:fo,:pct, as written:records: one map per row::source_ip,:count,:disposition,:dkim,:spf(the policy evaluation),:reasons,:header_from,:envelope_from,:envelope_to, and:auth_resultswith:dkimand:spflists
Values are strings as written, except :count and the dates.
Summary
Functions
Parses a report: XML, or XML in gzip or zip.