/[smeserver]/rpms/qpsmtpd/sme8/0014-rewrote-sender_permitted_from.patch
ViewVC logotype

Annotation of /rpms/qpsmtpd/sme8/0014-rewrote-sender_permitted_from.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Sun Nov 14 20:50:20 2010 UTC (14 years ago) by slords
Branch: MAIN
CVS Tags: qpsmtpd-0_84-3_el5_sme, qpsmtpd-0_84-6_el5_sme, qpsmtpd-0_84-2_el5_sme, qpsmtpd-0_84-5_el5_sme, qpsmtpd-0_84-8_el5_sme, qpsmtpd-0_84-9_el5_sme, qpsmtpd-0_84-4_el5_sme, qpsmtpd-0_84-7_el5_sme, HEAD
* Sun Nov 14 2010 <slords@mail.com> 0.84-2.sme
- Sync with upstream git repo.
- Fix require_resolvable_fromhost doesn't work [SME: 6369]
- Fix TLS security defaults [SME: 6366]
- Fix fatal errors when mail has no headers [SME: 6345]

1 slords 1.1 From 02912602842a5b2251b1455cf7206cfee3d18553 Mon Sep 17 00:00:00 2001
2     From: Matt Simerson <matt@tnpi.net>
3     Date: Tue, 11 May 2010 01:41:08 -0400
4     Subject: rewrote sender_permitted_from
5    
6     rewrote the plugin using Mail::SPF, which is the replacement for Mail::SPF::Query (by the same author). The two plugins are mutually exclusive and SpamAssassin expects to have Mail::SPF available.
7    
8     Signed-off-by: Robert <rspier@pobox.com>
9     ---
10     plugins/sender_permitted_from | 193 ++++++++++++++++++++++------------------
11     1 files changed, 106 insertions(+), 87 deletions(-)
12    
13     diff --git a/plugins/sender_permitted_from b/plugins/sender_permitted_from
14     index 287847e..a6d833b 100644
15     --- a/plugins/sender_permitted_from
16     +++ b/plugins/sender_permitted_from
17     @@ -5,119 +5,138 @@ SPF - plugin to implement Sender Permitted From
18    
19     =head1 SYNOPSIS
20    
21     - # in config/plugins
22     - sender_permitted_from
23     +Prevents email sender address spoofing by checking the SPF policy of the purported senders domain.
24    
25     -Or if you wish to issue 5xx on SPF fail:
26     +=head1 DESCRIPTION
27    
28     - sender_permitted_from spf_deny 1
29     +Sender Policy Framework (SPF) is an e-mail validation system designed to prevent spam by addressing source address spoofing. SPF allows administrators to specify which hosts are allowed to send e-mail from a given domain by creating a specific SPF record in the public DNS. Mail exchangers then use the DNS to check that mail from a given domain is being sent by a host sanctioned by that domain's administrators. -- http://en.wikipedia.org/wiki/Sender_Policy_Framework
30     +
31     +=head1 CONFIGURATION
32    
33     -Other arguments are 'trust 0' and 'guess 0'. These turn off processing of
34     -spf.trusted-forwarders.org and the best_guess functionality. It is unlikely
35     -that you want to turn these off.
36     +In config/plugins, add arguments to the sender_permitted_from line.
37    
38     -Adding 'spf_deny 2' will also issue a 5xx on a softfail response.
39     + sender_permitted_from spf_deny 1
40    
41     -You can also specify local SPF policy with
42     +=head2 spf_deny
43    
44     - include '<spf mechanism list>'
45     +Setting spf_deny to 0 will prevent emails from being rejected, even if they fail SPF checks. sfp_deny 1 is the default, and a reasonable setting. It temporarily defers connections (4xx) that have soft SFP failures and only rejects (5xx) messages when the sending domains policy suggests it. Settings spf_deny to 2 is more aggressive and will cause soft failures to be rejected permanently.
46    
47     See also http://spf.pobox.com/
48    
49     +=head1 AUTHOR
50     +
51     +Matt Simerson <msimerson@cpan.org>
52     +
53     +=head1 ACKNOWLEDGEMENTS
54     +
55     +whomever wrote the original SPF plugin, upon which I based this.
56     +
57     =cut
58    
59     -use Mail::SPF::Query 1.991;
60     +use strict;
61     +use Mail::SPF 2.000;
62     +use Data::Dumper;
63    
64     sub register {
65     - my ($self, $qp, @args) = @_;
66     - %{$self->{_args}} = @args;
67     + my ($self, $qp, @args) = @_;
68     + %{$self->{_args}} = @args;
69     }
70    
71     sub hook_mail {
72     - my ($self, $transaction, $sender, %param) = @_;
73     -
74     - return (DECLINED) unless ($sender->format ne "<>"
75     - and $sender->host && $sender->user);
76     -
77     - # If we are receving from a relay permitted host, then we are probably
78     - # not the delivery system, and so we shouldn't check
79     -
80     - return (DECLINED) if $self->qp->connection->relay_client();
81     - my @relay_clients = $self->qp->config("relayclients");
82     - my $more_relay_clients = $self->qp->config("morerelayclients", "map");
83     - my %relay_clients = map { $_ => 1 } @relay_clients;
84     - my $client_ip = $self->qp->connection->remote_ip;
85     - while ($client_ip) {
86     - return (DECLINED) if exists $relay_clients{$client_ip};
87     - return (DECLINED) if exists $more_relay_clients->{$client_ip};
88     - $client_ip =~ s/\d+\.?$//; # strip off another 8 bits
89     - }
90     -
91     - my $host = lc $sender->host;
92     - my $from = $sender->user . '@' . $host;
93     -
94     - my $ip = $self->qp->connection->remote_ip;
95     - my $helo = $self->qp->connection->hello_host;
96     -
97     - my $query = Mail::SPF::Query->new(ip => $ip, sender => $from, helo => $helo,
98     - sanitize => 1,
99     - local => $self->{_args}{local},
100     - guess => defined($self->{_args}{guess}) ? $self->{_args}{guess} : 1,
101     - trusted => defined($self->{_args}{trust}) ? $self->{_args}{trust} : 1)
102     - || die "Couldn't construct Mail::SPF::Query object";
103     - $transaction->notes('spfquery', $query);
104     -
105     - return (DECLINED);
106     + my ($self, $transaction, $sender, %param) = @_;
107     +
108     + my $format = $sender->format;
109     + my $host = lc $sender->host;
110     + my $user = $sender->user;
111     + my $client_ip = $self->qp->connection->remote_ip;
112     + my $from = $sender->user . '@' . $host;
113     + my $helo = $self->qp->connection->hello_host;
114     +
115     + return (DECLINED, "SPF - null sender")
116     + unless ($format ne "<>" && $host && $user);
117     +
118     + # If we are receving from a relay permitted host, then we are probably
119     + # not the delivery system, and so we shouldn't check
120     + return (DECLINED, "SPF - relaying permitted")
121     + if $self->qp->connection->relay_client();
122     +
123     + my @relay_clients = $self->qp->config("relayclients");
124     + my $more_relay_clients = $self->qp->config("morerelayclients", "map");
125     + my %relay_clients = map { $_ => 1 } @relay_clients;
126     + while ($client_ip) {
127     + return (DECLINED, "SPF - relaying permitted")
128     + if exists $relay_clients{$client_ip};
129     + return (DECLINED, "SPF - relaying permitted")
130     + if exists $more_relay_clients->{$client_ip};
131     + $client_ip =~ s/\d+\.?$//; # strip off another 8 bits
132     + }
133     +
134     + my $scope = $from ? 'mfrom' : 'helo';
135     + $client_ip = $self->qp->connection->remote_ip;
136     + my %req_params = (
137     + versions => [1, 2], # optional
138     + scope => $scope,
139     + ip_address => $client_ip,
140     + );
141     +
142     + if ($scope =~ /mfrom|pra/) {
143     + $req_params{identity} = $from;
144     + $req_params{helo_identity} = $helo if $helo;
145     + }
146     + elsif ($scope eq 'helo') {
147     + $req_params{identity} = $helo;
148     + $req_params{helo_identity} = $helo;
149     + }
150     +
151     + my $spf_server = Mail::SPF::Server->new();
152     + my $request = Mail::SPF::Request->new(%req_params);
153     + my $result = $spf_server->process($request);
154     +
155     + $transaction->notes('spfquery', $result);
156     +
157     + return (OK) if $result->code eq 'pass'; # this test passed
158     + return (DECLINED, "SPF - $result->code");
159     }
160    
161     sub hook_rcpt {
162     - my ($self, $transaction, $rcpt, %param) = @_;
163     -
164     - # special addresses don't get SPF-tested.
165     - return DECLINED if $rcpt and $rcpt->user and $rcpt->user =~ /^(?:postmaster|abuse|mailer-daemon|root)$/i;
166     -
167     - my $query = $transaction->notes('spfquery');
168     -
169     - return DECLINED if !$query;
170     - my ($result, $smtp_comment, $comment) = $query->result2($rcpt->address);
171     -
172     - if ($result eq "error") {
173     - return (DENYSOFT, "SPF error: $smtp_comment");
174     - }
175     -
176     - if ($result eq "fail" and $self->{_args}{spf_deny}) {
177     - return (DENY, "SPF forgery: $smtp_comment");
178     - }
179     -
180     - if ($result eq "softfail" and $self->{_args}{spf_deny} > 1) {
181     - return (DENY, "SPF probable forgery: $smtp_comment");
182     - }
183     -
184     - if ($result eq 'fail' or $result eq 'softfail') {
185     - $self->log(LOGDEBUG, "result for $rcpt->address was $result: $comment");
186     - }
187     -
188     - return DECLINED;
189     -}
190     + my ($self, $transaction, $rcpt, %param) = @_;
191     +
192     + # special addresses don't get SPF-tested.
193     + return DECLINED
194     + if $rcpt
195     + and $rcpt->user
196     + and $rcpt->user =~ /^(?:postmaster|abuse|mailer-daemon|root)$/i;
197     +
198     + my $result = $transaction->notes('spfquery') or return DECLINED;
199     + my $code = $result->code;
200     + my $why = $result->local_explanation;
201     + my $deny = $self->{_args}{spf_deny};
202     +
203     + return (DECLINED, "SPF - $code: $why") if $code eq "pass";
204     + return (DECLINED, "SPF - $code, $why") if !$deny;
205     + return (DENYSOFT, "SPF - $code: $why") if $code eq "error";
206     + return (DENY, "SPF - forgery: $why") if $code eq 'fail';
207    
208     -sub _uri_escape {
209     - my $str = shift;
210     - $str =~ s/([^A-Za-z0-9\-_.!~*\'()])/sprintf "%%%X", ord($1)/eg;
211     - return $str;
212     + if ($code eq "softfail") {
213     + return (DENY, "SPF probable forgery: $why") if $deny > 1;
214     + return (DENYSOFT, "SPF probable forgery: $why");
215     + }
216     +
217     + $self->log(LOGDEBUG, "result for $rcpt->address was $code: $why");
218     +
219     + return (DECLINED, "SPF - $code, $why");
220     }
221    
222     sub hook_data_post {
223     - my ($self, $transaction) = @_;
224     -
225     - my $query = $transaction->notes('spfquery');
226     - return DECLINED if !$query;
227     + my ($self, $transaction) = @_;
228    
229     - my ($result, $smtp_comment, $comment) = $query->message_result2();
230     + my $result = $transaction->notes('spfquery') or return DECLINED;
231    
232     - $self->log(LOGDEBUG, "result was $result: $comment") if ($result);
233     + $self->log(LOGDEBUG, "result was $result->code");
234    
235     - $transaction->header->add('Received-SPF' => "$result ($comment)", 0);
236     + $transaction->header->add('Received-SPF' => $result->received_spf_header,
237     + 0);
238    
239     - return DECLINED;
240     + return DECLINED;
241     }
242    
243     --
244     1.7.2.2
245    

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed