The Authentication-Results: header field (RFC 8601), which tells the
next hop and the user's mail client what this server found out about
a message:
Authentication-Results: mx.example.org;
spf=pass smtp.mailfrom=alice@example.com;
dkim=pass header.d=example.com header.s=sel header.b=AbCdEf12The first value, the authserv-id, names the server that did the
checks. Results claiming to be ours that arrive with a message are
forged, so they must be removed before ours are added (RFC 8601 §5),
see strip/2.
A result is a map:
%{method: "spf", result: "pass", reason: nil, comment: nil,
properties: [{"smtp.mailfrom", "alice@example.com"}]}
Summary
Types
A property such as {"smtp.mailfrom", "a@example.com"} or {"header.d", "example.com"}.
Functions
Returns the authserv-id of a field value (the text after
Authentication-Results:), unquoted.
Returns the whole header field, ending in CRLF.
Parses a field value into its authserv-id and results.
Removes every Authentication-Results: field whose authserv-id is
authserv_id, compared without regard to case. Fields whose
authserv-id cannot be read are kept.
Returns the field value, without the field name and the final CRLF, one result per folded line.
Types
A property such as {"smtp.mailfrom", "a@example.com"} or {"header.d", "example.com"}.
Functions
Returns the authserv-id of a field value (the text after
Authentication-Results:), unquoted.
iex> Sovite.AuthResults.authserv_id(" (checked) mx.example.org 1; spf=pass")
{:ok, "mx.example.org"}
iex> Sovite.AuthResults.authserv_id(" ; spf=pass")
:error
Returns the whole header field, ending in CRLF.
iex> Sovite.AuthResults.field("mx.example.org", [])
"Authentication-Results: mx.example.org; none\r\n"
Parses a field value into its authserv-id and results.
Comments and the version after the authserv-id are dropped, and so is
a method version (dkim/1). Method, result and property names are
lower-cased; values are kept as written. Parsing is lenient about
what real servers send, such as unquoted base64 in header.b.
iex> Sovite.AuthResults.parse("mx.example.org; spf=pass (ok) smtp.mailfrom=a@example.com")
{:ok, "mx.example.org",
[%{method: "spf", result: "pass", reason: nil, properties: [{"smtp.mailfrom", "a@example.com"}]}]}
@spec strip([Sovite.Message.Headers.field()], String.t()) :: [ Sovite.Message.Headers.field() ]
Removes every Authentication-Results: field whose authserv-id is
authserv_id, compared without regard to case. Fields whose
authserv-id cannot be read are kept.
Returns the field value, without the field name and the final CRLF, one result per folded line.
iex> Sovite.AuthResults.value("mx.example.org", [
...> %{method: "spf", result: "pass", properties: [{"smtp.mailfrom", "a@example.com"}]}
...> ])
"mx.example.org;\r\n\tspf=pass smtp.mailfrom=a@example.com"
iex> Sovite.AuthResults.value("mx.example.org", [])
"mx.example.org; none"A :reason is always a quoted-string; a :comment follows the result
in parentheses. Property values that are not a plain token or
address are quoted. Control characters in them are replaced by
spaces, so no value can end the field early.