Spf.Context (Spfcheck v0.10.0) View Source
Functions to create, access and update an SPF evaluation context.
Many functions take and return an evaluation context whose purpose is to store information gathered during the evaluation. This includes a dns cache, an ip lookup table that maps prefixes to SPF terms that named them, a stack for recursive evaluations, as well as some statistics around DNS mechanisms seen and void DNS responses seen.
Link to this section Summary
Types
A {qualifier, nth, term}
tuple, where nth
is the nth SPF record where term
was
found.
An SPF evaluation context.
An SPF evaluation result.
Functions
Updates context
with given error
, reason
and verdict
.
Returns a previous SPF string given either its domain
of nth
-tracking number.
Updates context
's message queue and, if available, calls the user supplied log
function.
Returns true if new_domain
constitues a loop for given context
, false
otherwise.
Returns a new Spf.Context.t/0
for given sender
.
Pop the previous state of given context
from its stack.
Push the current state of given context
onto its stack and re-init the context.
Reinitializes current context
for given domain
of a redirect modifier.
Given a current context
and a range
, return the SPF term in that range.
Split an email address into a local and a domain part.
If test
is true, logs the given msg
with its facility
and severity
.
Adds delta
to counter
and returns updated context
.
Link to this section Types
Specs
iptval() :: {Spf.Lexer.q(), non_neg_integer(), binary()}
A {qualifier, nth, term}
tuple, where nth
is the nth SPF record where term
was
found.
The context's ip lookup table stores these tuples thus tracking which term in which SPF record provided a qualifier for a prefix. Since an evaluation may involve multiple SPF records, each prefix actually stores a list of these tuples.
Once the sender's ip has a longest prefix match, the qualifier will tell how the mechanism at hand matches.
Specs
prefix() :: Pfx.prefix()
A Pfx.prefix/0
.
Specs
t() :: %{ ast: list(), atype: :a | :aaaa, contact: binary(), depth: non_neg_integer(), dns: map(), dns_timeout: non_neg_integer(), domain: binary(), duration: non_neg_integer(), error: nil | atom(), explain: nil | tuple(), explain_string: binary(), explanation: binary(), helo: binary(), ip: binary(), ipt: Iptrie.t(), local: binary(), log: nil | function(), map: map(), max_dnsm: non_neg_integer(), max_dnsv: non_neg_integer(), msg: list(), nameservers: nil | list(), nth: non_neg_integer(), num_checks: non_neg_integer(), num_dnsm: non_neg_integer(), num_dnsq: non_neg_integer(), num_dnsv: non_neg_integer(), num_error: non_neg_integer(), num_spf: non_neg_integer(), num_warn: non_neg_integer(), owner: binary(), reason: binary(), sender: binary(), spf: binary(), spf_rest: binary(), spf_tokens: list(), stack: list(), t0: non_neg_integer(), traces: map(), verbosity: non_neg_integer(), verdict: verdict() }
An SPF evaluation context.
Field notes:
ast
is a list of SPF terms to be evaluated as produced bySpf.Parser
atype
is set according to the sender's IP addresscontact
is gleaned from the soa record fordomain
under evaluationdepth
is the nested depth during recursion, used to print a tree of log messagesdns
is the DNS cache, used to report on DNS information gathered during evaluationduration
is the time (in milliseconds) it took to evaluate the SPF policyerror
set by eitherSpf.Parser
orSpf.Eval
and halts evaluation if setexplain
is the token for theexp=
-modifier, if any (not needed for actual evaluation)explain_string
is the explanation after all expansions (when available and applicable)helo
as set by the:helo
option given toSpf.check/2
ip
is the sender IP, as set by the:ip
option given toSpf.check/2
(default127.0.0.1
)ipt
is anIptrie.t/0
used to record addresses and/or prefixes authorized to send mailslocal
is the local part of thesender
log
is the user callback log function as provided by the:log
option toSpf.check/2
map
is used to recordnth
=> domain and domain => spf-stringmax_dnsm
is the max of dns-mechanisms allowed (default 10), if it took more => permerrormax_dnsv
is the max of void dns-responses allowed (default 2), if it took more => permerrormsg
the list of logged messages by the Spf modulesnameservers
a list of nameservers to use or nil (uses system default)nth
is the nth SPF record being evaluatednum_checks
counts how many checks were performed during evaluationnum_dnsm
counts the number of dns-mechanisms seen during evaluationnum_dnsq
counts the number of dns queries performed during evaluationnum_dnsv
counts the number of void DNS responses seen during evaluationnum_error
counts the number of errors seen during evaluationnum_spf
counts the number of SPF records evaluatednum_warn
counts the number of warnings seen during evaluationowner
shows the SOA zone for the original SPF domain being evaluatedreason
shows the reason for the verdict, usually in the form of an SPF termsender
is the sender as given toSpf.check/2
spf
is the SPF string of thedomain
being evaluated (if any)spf_rest
is the remainder of the SPF string (should always by "")spf_tokens
is theSpf.Lexer
's result of lexing the SPF string (last seen)stack
is used to push/pop the evaluation state during recursive callst0
is the Unix Epoch time the evaluation startedtraces
is a map used to detect loops in an SPF policyverbosity
controls the level of logged messages to stderrverdict
is the final result of the SPF evaluation bySpf.check/2
Other notes:
max_dnsm
andmax_dnsv
are only checked after evaluating the entire policy- this allows to debug most of the SPF policy under consideration
Spf.Parser
may set an syntaxerror
, in which case the SPF record results in a permerror- the
ast
is produced by the parser by processing allspf_tokens
- whitespace tokens are used to report on repeated whitespace in an SPF string
- whitespace tokens donot end up in the AST
v=spf1
-modifier is checked and if not present, results in an error- by processing all tokens, any
error
set reflects the last error seen
- the
Spf.Eval
may set an evaluationerror
, which may result in an overall permerror- a void DNS response is either a
NXDOMAIN
orZERO ANSWERS
Specs
token() :: Spf.Lexer.token()
Specs
verdict() :: :fail | :neutral | :none | :pass | :permerror | :softfail | :temperror
An SPF evaluation result.
Link to this section Functions
Specs
Updates context.ipt
with one or more {prefix/0
, iptval/0
}-pairs.
When given a list op ip's, they all will be be updated with given
iptval/0
which records the SPF record and term (including the qualifier)
that attributed the ip or ip's.
The dual
parameter contains the dual-cidr lengths to apply to the given
ip addresses.
Specs
Updates context
with given error
, reason
and verdict
.
When verdict
is nil, context.verdict
is not updated. This
allows for setting error conditions whose impact is to be evaluated
at a later stage.
Specs
Returns a previous SPF string given either its domain
of nth
-tracking number.
Used for reporting rather than evalutation an SPF record.
Specs
Updates context
's message queue and, if available, calls the user supplied log
function.
The log/4
is called with:
context
the current context/state of the evalutionfacility
an atom denoting which part of the program emitted the eventseverity
an atom describing the severitymsg
a binary with event details
Specs
Returns true if new_domain
constitues a loop for given context
, false
otherwise.
Loops may occur when two SPF records (eventually) include or redirect to each other and is considered a permanent error.
Specs
Returns a new Spf.Context.t/0
for given sender
.
Options include:
:dns
, filepath or binary with zonedata (defaults to nil):helo
, sender's helo string to use (defaults tosender
):ip
, sender ip to use (defaults to127.0.0.1
):log
, user supplied log function (defaults to nil):verbosity
, log level0..5
to use (defaults to4
):nameserver
, IPv4 or IPv6 address of a nameserver to use instead of the default
The initial domain
is derived from given sender
. The default for
ip
is likely to traverse all SPF mechanisms during evaluation, gathering
as much information as possible. Set :ip
to a real IPv4 or IPv6 address
to check an SPF policy for that specific address.
The context is used for the entire SPF evaluation, including during any
recursive calls. When evaluating an include
mechanism, the current state (a
few selected context properties) is pushed onto an internal stack and a new
domain
is set. After evaluating the include
mechanism, the state if
popped and the results are processed according to the include
-mechanism's
qualifier.
When evaluating a redirect
modifier, the current state is altered for the
new domain specified by the modifier.
Specify more than one recursive nameserver by repeating the :nameserver
option in the Keyword list. They will be tried in the order listed. Mainly
useful when the local default recursive nameserver is having problems, or
when an external nameserver is to be used for checking an SPF policy instead
of an internal nameserver. As an example, use in opts [nameserver: "2001:4860:4860::8888", nameserver: "2001:4860:4860::8844"]
to use the IPv6
dns.google servers.
Specs
Pop the previous state of given context
from its stack.
Before evaluating an include mechanism, the current SPF's record state is pushed onto the stack. This function restores that state from the stack.
Specs
Push the current state of given context
onto its stack and re-init the context.
The details of the current SPF record are pushed onto a stack and the context
is re-initialized for retrieving, parsing and evaluate a new include
d
record.
Specs
Reinitializes current context
for given domain
of a redirect modifier.
When a redirect modifier is encountered it basically replaces the current SPF record and the context is modified accordingly.
Specs
Given a current context
and a range
, return the SPF term in that range.
Retrieves a slice of the current SPF record being evaluated. Used for logging events.
Specs
Split an email address into a local and a domain part.
The local part is left to the left-most @
, if there is no local
part it defaults to "postmaster". Note that splitting an empty
string yields {"postmaster", ""}
.
Specs
If test
is true, logs the given msg
with its facility
and severity
.
A convencience function to quickly check some test and, if true, log it as well in one go.
Specs
Adds delta
to counter
and returns updated context
.
Valid counters include:
:num_spf
, the number of SPF records seen:num_dnsm
the number of DNS mechanisms seen:num_dnsq
the number of DNS queries performed:num_dnsv
the number of void DNS queries seen:num_checks
the number of checks performed:num_warn
the number of warnings seen:num_error
the number of errors see (may not be fatal):depth
the current recursion depth