1Mail::SPF::Iterator(3)User Contributed Perl DocumentationMail::SPF::Iterator(3)
2
3
4
6 Mail::SPF::Iterator - iterative SPF lookup
7
9 use Net::DNS;
10 use Mail::SPF::Iterator;
11 use Mail::SPF::Iterator Debug =>1; # enable debugging
12 my $spf = Mail::SPF::Iterator->new(
13 $ip, # IP4|IP6 of client
14 $mailfrom, # from MAIL FROM:
15 $helo, # from HELO|EHLO
16 $myname, # optional: my hostname
17 {
18 default_spf => 'mx/24 ?all', # in case no record was found in DNS
19 pass_all => SPF_SoftFail, # treat records like '+all' as error
20 # rfc4408 => 1, # for compatibility only
21 }
22 );
23
24 # could be other resolvers too
25 my $resolver = Net::DNS::Resolver->new;
26
27 ### with nonblocking, but still in loop
28 ### (callbacks are preferred with non-blocking)
29 my ($result,@ans) = $spf->next; # initial query
30 while ( ! $result ) {
31 my @query = @ans;
32 die "no queries" if ! @query;
33 for my $q (@query) {
34 # resolve query
35 my $socket = $resolver->bgsend( $q );
36 ... wait...
37 my $answer = $resolver->bgread($socket);
38 ($result,@ans) = $spf->next(
39 $answer # valid answer
40 || [ $q, $resolver->errorstring ] # or DNS problem
41 );
42 last if $result; # got final result
43 last if @ans; # got more DNS queries
44 }
45 }
46
47 ### OR with blocking:
48 ### ($result,@ans) = $spf->lookup_blocking( undef,$resolver );
49
50 ### print mailheader
51 print "Received-SPF: ".$spf->mailheader;
52
53 # $result = Fail|Pass|...
54 # $ans[0] = comment for Received-SPF
55 # $ans[1] = %hash with infos for Received-SPF
56 # $ans[2] = explanation in case of Fail
57
59 This module provides an iterative resolving of SPF records. Contrary to
60 Mail::SPF, which does blocking DNS lookups, this module just returns
61 the DNS queries and later expects the responses.
62
63 Lookup of the DNS records will be done outside of the module and can be
64 done in a event driven way. It is also possible to do many parallel SPF
65 checks in parallel without needing multiple threads or processes.
66
67 This module can also make use of SenderID records for checking the
68 "mfrom" part, but it will prefer SPF. It will only use DNS TXT records
69 for looking up SPF policies unless compatibility with RFC 4408 is
70 explicitly enabled.
71
72 See RFC 7208 (old RFC 4408) for SPF and RFC 4406 for SenderID.
73
75 new( IP, MAILFROM, HELO, [ MYNAME ], [ \%OPT ] )
76 Construct a new Mail::SPF::Iterator object, which maintains the
77 state between the steps of the iteration. For each new SPF check a
78 new object has to be created.
79
80 IP is the IP if the client as string (IP4 or IP6).
81
82 MAILFROM is the user@domain part from the MAIL FROM handshake, e.g.
83 '<','>' and any parameters removed. If only '<>' was given (like in
84 bounces) the value is empty.
85
86 HELO is the string send within the HELO|EHLO dialog which should be
87 a domain according to the RFC but often is not.
88
89 MYNAME is the name of the local host. It's only used if required by
90 macros inside the SPF record.
91
92 OPT is used for additional arguments. Currently default_spf can be
93 used to set a default SPF record in case no SPF/TXT records are
94 returned from DNS (useful values are for example 'mx ?all' or
95 'mx/24 ?all'). rfc4408 can be set to true in case stricter
96 compatibility is needed with RFC 4408 instead of RFC 7208, i.e.
97 lookup of DNS SPF records, no limit on void DNS lookups etc.
98 pass_all can be set to the expected outcome in case a SPF policy
99 gets found, which would pass everything. Such policies are common
100 used domains used by spammers.
101
102 Returns the new object.
103
104 next([ ANSWER ])
105 "next" will be initially called with no arguments to get initial
106 DNS queries and then will be called with the DNS answers.
107
108 ANSWER is either a DNS packet with the response to a former query
109 or "[ QUERY, REASON ]" on failures, where QUERY is the DNS packet
110 containing the failed query and REASON the reason, why the query
111 failed (like TIMEOUT).
112
113 If a final result was achieved it will return "( RESULT, COMMENT,
114 HASH, EXPLAIN )". RESULT is the result, e.g. "Fail", "Pass",....
115 COMMENT is the comment for the Received-SPF header. HASH contains
116 information about problem, mechanism for the Received-SPF header.
117 EXPLAIN will be set to the explain string if RESULT is Fail.
118
119 If no final result was achieved yet it will either return
120 "(undef,@QUERIES)" with a list of new queries to continue, "('')"
121 in case the ANSWER produced an error but got ignored, because there
122 are other queries open, or "()" in case the ANSWER was ignored
123 because it did not match any open queries.
124
125 mailheader
126 Creates value for Received-SPF header based on the final answer
127 from next(). Returns header as string (one line, no folding) or
128 undef, if no final result was found. This creates only the value,
129 not the 'Received-SPF' prefix.
130
131 result
132 Returns ( RESULT, COMMENT, HASH, EXPLAIN ) like the final "next"
133 does or () if the final result wasn't found yet.
134
135 If the SPF record had an explain modifier, which needed DNS lookups
136 to resolve this method might return the result (although with
137 incomplete explain) before "next" does it.
138
139 explain_default ( [ EXPLAIN ] )
140 Sets default explanation string if EXPLAIN is given. If it's
141 called as a class method the default explanation string for the
142 class will be set, otherwise the default explanation string for the
143 object.
144
145 Returns the current default explanation string for the object or if
146 non given or if called as a class method the default explanation
147 string for the class.
148
149 lookup_blocking ( [ TIMEOUT, RESOLVER ] )
150 Quick way to get the SPF status. This will simply call "next"
151 until it gets a final result.
152
153 TIMEOUT limits the lookup time and defaults to 20. RESOLVER is a
154 Net::DNS::Resolver object (or similar) and defaults to
155 "Net::DNS::Resolver->new". Returns ( RESULT, COMMENT, HASH ) like
156 the final "next" does.
157
158 This is not the preferred way to use this module, because it's
159 blocking, so no lookups can be done in parallel in a single
160 process/thread.
161
163 For convenience the constants SPF_TempError, SPF_PermError, SPF_Pass,
164 SPF_Fail, SPF_SoftFail, SPF_Neutral, SPF_None are by default exported,
165 which have the values "TempError", "PermError" ...
166
167 Arguments to "use"/"import"
168 The "SPF_*" symbols are available for import and are exported if no
169 arguments are given to "use" or "import". Same effect with adding
170 ":DEFAULT" as an argument. Additionally the following arguments are
171 supported:
172
173 DebugFunc => \&coderef
174 Sets a custom debug function, which just takes on argument. If
175 given it will be called on all debug messages when debugging is
176 active. This function takes as the only argument the debug message.
177
178 Debug => 1|0
179 Switches debugging on/off.
180
182 Steffen Ullrich <sullr@cpan.org>
183
185 Copyright by Steffen Ullrich.
186
187 This module is free software; you can redistribute it and/or modify it
188 under the same terms as Perl itself.
189
190
191
192perl v5.32.0 2020-07-28 Mail::SPF::Iterator(3)