Sovite.DMARC.Report (sovite v0.6.0)

Copy Markdown View Source

DMARC aggregate reports (RFC 7489 §7.2 and Appendix C, with the <version> and <np> elements of the DMARCbis aggregate reporting draft).

xml = Sovite.DMARC.Report.aggregate(report)
name = Sovite.DMARC.Report.filename("mx.example.net", "example.com", from, to, id)
#=> "mx.example.net!example.com!1700000000!1700086400!id.xml.gz"

The caller gzips the document and sends it to the rua destinations that Sovite.DMARC.report_authorized?/3 allows.

Summary

Types

A DKIM result in a report row.

The policy published by the domain, as it was applied.

Why a receiver applied a disposition other than the policy's.

One row: the messages from one source with the same results.

An SPF result in a report row.

Functions

Builds the XML document of an aggregate report. The output depends only on report, and every value is escaped.

The file name of an aggregate report (RFC 7489 §7.2.1.1): receiver!policy-domain!begin!end!unique-id.xml.gz, with the times as Unix timestamps. An empty unique_id is left out.

Types

dkim_auth()

@type dkim_auth() :: %{domain: String.t(), selector: String.t() | nil, result: atom()}

A DKIM result in a report row.

policy()

@type policy() :: %{
  :domain => String.t(),
  :adkim => :relaxed | :strict,
  :aspf => :relaxed | :strict,
  :p => :none | :quarantine | :reject,
  :sp => :none | :quarantine | :reject,
  :pct => 0..100,
  optional(:np) => :none | :quarantine | :reject | nil
}

The policy published by the domain, as it was applied.

reason()

@type reason() :: %{type: String.t(), comment: String.t() | nil}

Why a receiver applied a disposition other than the policy's.

report()

@type report() :: %{
  org_name: String.t(),
  email: String.t(),
  extra_contact_info: String.t() | nil,
  report_id: String.t(),
  begin: DateTime.t(),
  end: DateTime.t(),
  policy: policy(),
  records: [row()]
}

row()

@type row() :: %{
  source_ip: :inet.ip_address(),
  count: non_neg_integer(),
  disposition: :none | :quarantine | :reject,
  dkim: :pass | :fail,
  spf: :pass | :fail,
  reasons: [reason()],
  header_from: String.t(),
  envelope_from: String.t() | nil,
  envelope_to: String.t() | nil,
  dkim_auth: [dkim_auth()],
  spf_auth: [spf_auth()]
}

One row: the messages from one source with the same results.

spf_auth()

@type spf_auth() :: %{domain: String.t(), scope: :mfrom | :helo, result: atom()}

An SPF result in a report row.

Functions

aggregate(report)

@spec aggregate(report()) :: binary()

Builds the XML document of an aggregate report. The output depends only on report, and every value is escaped.

filename(receiver, policy_domain, begin, finish, unique_id)

@spec filename(String.t(), String.t(), DateTime.t(), DateTime.t(), String.t()) ::
  String.t()

The file name of an aggregate report (RFC 7489 §7.2.1.1): receiver!policy-domain!begin!end!unique-id.xml.gz, with the times as Unix timestamps. An empty unique_id is left out.