Correct error trapping so policy server won't crash on bad input.

This commit is contained in:
Scott Kitterman 2007-02-04 02:25:39 +00:00
commit 9c264c3867
5 changed files with 57 additions and 56 deletions

View file

@ -2,7 +2,7 @@
# postfix-policyd-spf-perl
# http://www.openspf.org/Software
# version 1.99
# version 1.990
# $Id$
#(C) 2007 Scott Kitterman <scott@kitterman.com>
#(C) 2003-2004 Meng Weng Wong <mengwong@pobox.com>
@ -21,7 +21,7 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use version; our $VERSION = qv('1.99');
use version; our $VERSION = qv('1.990');
use strict;
@ -96,9 +96,7 @@ while (<STDIN>) {
syslog(debug => "Attribute: %s=%s", $_, $attr{$_});
}
}
fatal_exit("unrecognized request type: '$attr{request}'") unless $attr{request} eq "smtpd_access_policy";
my $action = $DEFAULT_RESPONSE;
my %responses;
foreach my $handler (@HANDLERS) {
@ -107,7 +105,7 @@ while (<STDIN>) {
if ($VERBOSE) {
syslog(debug => "handler %s: %s", $handler, $response);
}
#Picks whatever response is not dunno
# Picks whatever response is not dunno
if ($response and $response !~ /^dunno/i) {
syslog(info => "handler %s: is decisive.", $handler);
$action = $response; last;
@ -127,8 +125,8 @@ sub sender_policy_framework {
local %_ = @_;
my %attr = %{ $_{attr} };
#Always do HELO check first. If no HELO policy it's only one lookup.
#Avoids the need to do any Mail From processing for null sender.
# Always do HELO check first. If no HELO policy it's only one lookup.
# Avoids the need to do any Mail From processing for null sender.
my $helo_request = eval {
Mail::SPF::Request->new(
scope => 'helo', # 'mfrom' or 'helo', 'pra'
@ -138,26 +136,35 @@ sub sender_policy_framework {
=> $attr{helo_name}
);
};
my $helo_result = $spf_server->process($helo_request);
# If initializing helo_request throws an error, don't use it.
if ($@) {
syslog(
info => "%s: Mail::SPF->new(%s, %s, %s) failed: %s",
$attr{queue_id}, $attr{client_address}, $attr{sender}, $attr{helo_name}, $@
);
return "DUNNO";
}
else {
my $helo_result = $spf_server->process($helo_request);
my $helo_result_code = $helo_result->code; # 'pass', 'fail', etc.
my $helo_local_exp = $helo_result->local_explanation;
my $helo_authority_exp = $helo_result->authority_explanation
if $helo_result->is_code('fail');
my $helo_spf_header = $helo_result->received_spf_header;
my $helo_result_code = $helo_result->code; # 'pass', 'fail', etc.
my $helo_local_exp = $helo_result->local_explanation;
my $helo_authority_exp = $helo_result->authority_explanation
if $helo_result->is_code('fail');
my $helo_spf_header = $helo_result->received_spf_header;
syslog(
info => "%s: SPF %s: HELO/EHLO: %s, IP Address: %s, Recipient: %s",
$attr{queue_id}, $helo_result, $attr{helo_name}, $attr{client_address}, $attr{recipient}
);
syslog(
info => "%s: SPF %s: HELO/EHLO: %s, IP Address: %s, Recipient: %s",
$attr{queue_id}, $helo_result, $attr{helo_name}, $attr{client_address}, $attr{recipient}
);
# Reject on HELO fail. Defer on HELO temperror if message would otherwis
# be accepted. Use the HELO result and return for null sender.
if ($helo_result_code eq "fail") { return "REJECT $helo_authority_exp"; }
elsif ($helo_result_code eq "temperror") { return "DEFER_IF_PERMIT SPF-Result=$helo_local_exp"; }
elsif ($attr{sender} eq '') { return "PREPEND $helo_spf_header"; }
#Do mail from is HELO doesn't give a definitive result.
# Reject on HELO fail. Defer on HELO temperror if message would otherwis
# be accepted. Use the HELO result and return for null sender.
if ($helo_result_code eq "fail") { return "REJECT $helo_authority_exp"; }
elsif ($helo_result_code eq "temperror") { return "DEFER_IF_PERMIT SPF-Result=$helo_local_exp"; }
elsif ($attr{sender} eq '') { return "PREPEND $helo_spf_header"; }
};
# Do mail from is HELO doesn't give a definitive result.
my $mfrom_request = eval {
Mail::SPF::Request->new(
scope => 'mfrom', # 'mfrom' or 'helo', 'pra'
@ -167,27 +174,29 @@ sub sender_policy_framework {
=> $attr{helo_name} # for %{h} macro expansion
);
};
my $mfrom_result = $spf_server->process($mfrom_request);
my $mfrom_result_code = $mfrom_result->code; # 'pass', 'fail', etc.
my $mfrom_local_exp = $mfrom_result->local_explanation;
my $mfrom_authority_exp = $mfrom_result->authority_explanation
if $mfrom_result->is_code('fail');
my $mfrom_spf_header = $mfrom_result->received_spf_header;
if ($@) {
syslog(
info => "%s: Mail::SPF->new(%s, %s, %s) failed: %s",
$attr{queue_id}, $attr{client_address}, $attr{sender}, $attr{helo_name}, $@
);
return "DUNNO";
}
syslog(
info => "%s: SPF %s: Envelope-from: %s, IP Address: %s, Recipient: %s",
$attr{queue_id}, $mfrom_result, $attr{sender}, $attr{client_address}, $attr{recipient}
);
}
else {
my $mfrom_result = $spf_server->process($mfrom_request);
my $mfrom_result_code = $mfrom_result->code; # 'pass', 'fail', etc.
my $mfrom_local_exp = $mfrom_result->local_explanation;
my $mfrom_authority_exp = $mfrom_result->authority_explanation
if $mfrom_result->is_code('fail');
my $mfrom_spf_header = $mfrom_result->received_spf_header;
syslog(
info => "%s: SPF %s: Envelope-from: %s, IP Address: %s, Recipient: %s",
$attr{queue_id}, $mfrom_result, $attr{sender}, $attr{client_address}, $attr{recipient}
);
#Same approach as HELO....
if ($mfrom_result_code eq "fail") { return "REJECT $mfrom_authority_exp"; }
elsif ($mfrom_result_code eq "mfrom_temperror") { return "DEFER_IF_PERMIT SPF-Result=$mfrom_local_exp"; }
else { return "PREPEND $mfrom_spf_header"; }
# Same approach as HELO....
if ($mfrom_result_code eq "fail") { return "REJECT $mfrom_authority_exp"; }
elsif ($mfrom_result_code eq "mfrom_temperror") { return "DEFER_IF_PERMIT SPF-Result=$mfrom_local_exp"; }
else { return "PREPEND $mfrom_spf_header"; }
}
}