File Coverage

blib/lib/Mail/SPF/Mod/Exp.pm
Criterion Covered Total %
statement 34 50 68.0
branch 0 6 0.0
condition n/a
subroutine 11 17 64.7
pod 2 3 66.6
total 47 76 61.8


line stmt bran cond sub pod time code
1             #
2             # Mail::SPF::Mod::Exp
3             # SPF record "exp" modifier class.
4             #
5             # (C) 2005-2012 Julian Mehnle
6             # 2005 Shevek
7             # $Id: Exp.pm 57 2012-01-30 08:15:31Z julian $
8             #
9             ##############################################################################
10              
11             package Mail::SPF::Mod::Exp;
12              
13             =head1 NAME
14              
15             Mail::SPF::Mod::Exp - SPF record C modifier class
16              
17             =head1 VERSION
18              
19             version 3.20250505
20              
21             =cut
22              
23 1     1   1649 use warnings;
  1         3  
  1         82  
24 1     1   9 use strict;
  1         4  
  1         31  
25              
26 1     1   6 use Mail::SPF::Mod;
  1         2  
  1         77  
27 1     1   8 use base 'Mail::SPF::GlobalMod';
  1         4  
  1         673  
28              
29 1     1   10 use Error ':try';
  1         3  
  1         13  
30              
31 1     1   309 use Mail::SPF::MacroString;
  1         3  
  1         40  
32              
33 1     1   6 use constant TRUE => (0 == 0);
  1         2  
  1         139  
34 1     1   8 use constant FALSE => not TRUE;
  1         4  
  1         69  
35              
36 1     1   7 use constant name => 'exp';
  1         3  
  1         93  
37 1     1   7 use constant name_pattern => qr/${\name}/i;
  1         4  
  1         3  
  1         114  
38              
39 1     1   10 use constant precedence => 0.2;
  1         2  
  1         611  
40              
41             =head1 DESCRIPTION
42              
43             An object of class B represents an SPF record modifier of
44             type C.
45              
46             =head2 Constructors
47              
48             The following constructors are provided:
49              
50             =over
51              
52             =item B: returns I
53              
54             Creates a new SPF record C modifier object.
55              
56             %options is a list of key/value pairs representing any of the following
57             options:
58              
59             =over
60              
61             =item B
62              
63             See L.
64              
65             =back
66              
67             =item B: returns I;
68             throws I, I
69              
70             Creates a new SPF record C modifier object by parsing the string and
71             any options given.
72              
73             =back
74              
75             =head2 Class methods
76              
77             The following class methods are provided:
78              
79             =over
80              
81             =item B: returns I
82              
83             Returns B<'exp'>.
84              
85             =item B: returns I
86              
87             Returns a regular expression that matches a modifier name of B<'exp'>.
88              
89             =item B: returns I
90              
91             Returns a precedence value of B<0.2>. See L.
92              
93             =back
94              
95             =head2 Instance methods
96              
97             The following instance methods are provided:
98              
99             =over
100              
101             =cut
102              
103             sub parse_params {
104 0     0 0   my ($self) = @_;
105 0           $self->parse_domain_spec(TRUE);
106 0           return;
107             }
108              
109             =item B
110              
111             See L.
112              
113             =cut
114              
115             sub params {
116 0     0 1   my ($self) = @_;
117 0           return $self->{domain_spec};
118             }
119              
120             =item B: returns I
121              
122             Returns the C parameter of the modifier.
123              
124             =cut
125              
126             # Make read-only accessor:
127             __PACKAGE__->make_accessor('domain_spec', TRUE);
128              
129             =item B
130              
131             If the given SPF result is a C result, retrieves the authority domain's
132             explanation string from the modifier's target domain and attaches it to the SPF
133             result. If an error occurs during the retrieval of the explanation string,
134             does nothing, as if the modifier was not present. See RFC 4408, 6.2, for
135             details.
136              
137             =cut
138              
139             sub process {
140 0     0 1   my ($self, $server, $request, $result) = @_;
141              
142             try {
143 0     0     my $exp_domain = $self->{domain_spec}->new(server => $server, request => $request);
144 0           my $txt_packet = $server->dns_lookup($exp_domain, 'TXT');
145 0           my @txt_rrs = grep($_->type eq 'TXT', $txt_packet->answer);
146 0 0         @txt_rrs > 0
147             or $server->throw_result('permerror', $request,
148             "No authority explanation string available at domain '$exp_domain'"); # RFC 4408, 6.2/4
149 0 0         @txt_rrs == 1
150             or $server->throw_result('permerror', $request,
151             "Redundant authority explanation strings found at domain '$exp_domain'"); # RFC 4408, 6.2/4
152              
153             # char_str_list method is 'historical', use as a fallback for Net::DNS prior to 0.69
154             # where txtdata is not available.
155             # join with no intervening spaces, RFC 6376
156             # must call txtdata() in a list context
157 0 0         my $text = $txt_rrs[0]->can('txtdata')
158             ? join('', $txt_rrs[0]->txtdata)
159             : join('', $txt_rrs[0]->char_str_list);
160 0           my $explanation = Mail::SPF::MacroString->new(
161             text => $text,
162             server => $server,
163             request => $request,
164             is_explanation => TRUE
165             );
166              
167 0           $request->state('authority_explanation', $explanation);
168             }
169             # Ignore DNS and other errors:
170       0     catch Mail::SPF::EDNSError with {}
171 0     0     catch Mail::SPF::Result::Error with {};
172              
173 0           return;
174             }
175              
176             =back
177              
178             See L for other supported instance methods.
179              
180             =head1 SEE ALSO
181              
182             L, L, L, L
183              
184             L
185              
186             For availability, support, and license information, see the README file
187             included with Mail::SPF.
188              
189             =head1 AUTHORS
190              
191             Julian Mehnle , Shevek
192              
193             =cut
194              
195             TRUE;