.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man 5.0102 (Pod::Simple 3.45) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Mail::SpamAssassin::Plugin::AuthRes 3" .TH Mail::SpamAssassin::Plugin::AuthRes 3 2024-09-01 "perl v5.40.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME Mail::SpamAssassin::Plugin::AuthRes \- use Authentication\-Results header fields .SH SYNOPSIS .IX Header "SYNOPSIS" .SS "SpamAssassin configuration:" .IX Subsection "SpamAssassin configuration:" loadplugin Mail::SpamAssassin::Plugin::AuthRes .PP authres_trusted_authserv myserv.example.com authres_networks all .SH DESCRIPTION .IX Header "DESCRIPTION" This plugin parses Authentication-Results header fields and can supply the results obtained to other plugins, so as to avoid repeating checks that have been performed already. .SH "ADMINISTRATOR SETTINGS" .IX Header "ADMINISTRATOR SETTINGS" .IP "authres_networks internal/trusted/all (default: internal)" 4 .IX Item "authres_networks internal/trusted/all (default: internal)" Process Authenticated-Results headers set by servers from these networks (refers to SpamAssassin *_networks zones). Any header outside this is completely ignored (affects all module settings). .Sp .Vb 3 \& internal = internal_networks \& trusted = internal_networks + trusted_networks \& all = all above + all external .Ve .Sp Setting "all" is safe only if your MX servers filter properly all incoming A\-R headers, and you use authres_trusted_authserv to match your authserv-id. This is suitable for default OpenDKIM for example. These settings might also be required if your filters do not insert A\-R header to correct position above the internal Received header (some known offenders: OpenDKIM, OpenDMARC, amavisd-milter). .IP "authres_trusted_authserv authservid1 id2 ... (default: none)" 4 .IX Item "authres_trusted_authserv authservid1 id2 ... (default: none)" Trusted authentication server IDs (the domain-name-like first word of Authentication-Results field, also known as \f(CW\*(C`authserv\-id\*(C'\fR). .Sp Note that if set, ALL A\-R headers are ignored unless a match is found. .Sp Use strongly recommended, possibly along with authres_networks all. .IP "authres_ignored_authserv authservid1 id2 ... (default: none)" 4 .IX Item "authres_ignored_authserv authservid1 id2 ... (default: none)" Ignored authentication server IDs (the domain-name-like first word of Authentication-Results field, also known as \f(CW\*(C`authserv\-id\*(C'\fR). .Sp Any A\-R header is ignored if match is found. .SH METADATA .IX Header "METADATA" Parsed headers are stored in \f(CW$pms\fR\->{authres_parsed}, as a hash of array of hashes where results are collected by method. For example, the header field: .PP .Vb 4 \& Authentication\-Results: server.example.com; \& spf=pass smtp.mailfrom=bounce.example.org; \& dkim=pass header.i=@example.org; \& dkim=fail header.i=@another.signing.domain.example .Ve .PP Produces the following structure: .PP .Vb 10 \& $pms\->{authres_parsed} = { \& \*(Aqdkim\*(Aq => [ \& { \& \*(Aqproperties\*(Aq => { \& \*(Aqheader\*(Aq => { \& \*(Aqi\*(Aq => \*(Aq@example.org\*(Aq \& } \& }, \& \*(Aqauthserv\*(Aq => \*(Aqserver.example.com\*(Aq, \& \*(Aqresult\*(Aq => \*(Aqpass\*(Aq, \& \*(Aqversion\*(Aq => 1, \& \*(Aqreason\*(Aq => \*(Aq\*(Aq \& }, \& { \& \*(Aqproperties\*(Aq => { \& \*(Aqheader\*(Aq => { \& \*(Aqi\*(Aq => \*(Aq@another.signing.domain.example\*(Aq \& } \& }, \& \*(Aqresult\*(Aq => \*(Aqfail\*(Aq, \& \*(Aqauthserv\*(Aq => \*(Aqserver.example.com\*(Aq, \& \*(Aqversion\*(Aq => 1, \& \*(Aqreason\*(Aq => \*(Aq\*(Aq \& }, \& ], \& } .Ve .PP Within each array, the order of results is the original, which should be most recent results first. .PP For checking result of methods, \f(CW$pms\fR\->{authres_result} is available: .PP .Vb 4 \& $pms\->{authres_result} = { \& \*(Aqdkim\*(Aq => \*(Aqpass\*(Aq, \& \*(Aqspf\*(Aq => \*(Aqfail\*(Aq, \& } .Ve .SH "EVAL FUNCTIONS" .IX Header "EVAL FUNCTIONS" .IP "header RULENAME eval:check_authres_result(method, result)" 4 .IX Item "header RULENAME eval:check_authres_result(method, result)" Can be used to check results. .Sp Reference of valid result methods and values: \&\f(CW\*(C`https://www.iana.org/assignments/email\-auth/email\-auth.xhtml\*(C'\fR .Sp Additionally the result value of 'missing' can be used to check if there is no result at all. .Sp .Vb 12 \& ifplugin Mail::SpamAssassin::Plugin::AuthRes \& ifplugin !(Mail::SpamAssassin::Plugin::SPF) \& header SPF_PASS eval:check_authres_result(\*(Aqspf\*(Aq, \*(Aqpass\*(Aq) \& header SPF_FAIL eval:check_authres_result(\*(Aqspf\*(Aq, \*(Aqfail\*(Aq) \& header SPF_SOFTFAIL eval:check_authres_result(\*(Aqspf\*(Aq, \*(Aqsoftfail\*(Aq) \& header SPF_TEMPFAIL eval:check_authres_result(\*(Aqspf\*(Aq, \*(Aqtempfail\*(Aq) \& endif \& ifplugin !(Mail::SpamAssassin::Plugin::DKIM) \& header DKIM_VERIFIED eval:check_authres_result(\*(Aqdkim\*(Aq, \*(Aqpass\*(Aq) \& header DKIM_INVALID eval:check_authres_result(\*(Aqdkim\*(Aq, \*(Aqfail\*(Aq) \& endif \& endif .Ve