postfix-policyd-spf-perl/trunk/postfix-policyd-spf-perl

* use NetAddr::IP
* Added another handler (sub exempt_localhost) at the front that exempts
  localhost (IPv4 and IPv6) addresses from further processing.  Dropped
  special-cased localhost exemption.
* Changed localhost message header from 'X-SPF' to 'X-Comment', and adjusted
  the header text slightly.
* Various minor clean-ups.

postfix-policyd-spf-perl/trunk/INSTALL
postfix-policyd-spf-perl/trunk/debian/control
* Note that NetAddr-IP 4 is required.
This commit is contained in:
Julian Mehnle 2007-02-07 23:13:46 +00:00
commit 0e669aacca
3 changed files with 44 additions and 24 deletions

View file

@ -6,6 +6,7 @@ postfix-policyd-spf-perl:
Perl 5.6 Perl 5.6
version version
NetAddr-IP 4
Mail-SPF (not Mail-SPF-Query) Mail-SPF (not Mail-SPF-Query)
Installing Installing

2
debian/control vendored
View file

@ -7,7 +7,7 @@ Standards-Version: 3.7.2
Package: postfix-policyd-spf-perl Package: postfix-policyd-spf-perl
Architecture: all Architecture: all
Depends: libversion-perl, libmail-spf-perl, ${perl:Depends} Depends: libversion-perl, libnetaddr-ip-perl (>= 4), libmail-spf-perl, ${perl:Depends}
Recommends: postfix Recommends: postfix
Description: pure-Perl Postfix policy daemon for RFC 4408 compliant SPF checking Description: pure-Perl Postfix policy daemon for RFC 4408 compliant SPF checking
postfix-policyd-spf-perl is a Postfix SMTPd policy server for SPF checking. postfix-policyd-spf-perl is a Postfix SMTPd policy server for SPF checking.

View file

@ -27,6 +27,7 @@ use strict;
use IO::Handle; use IO::Handle;
use Sys::Syslog qw(:DEFAULT setlogsock); use Sys::Syslog qw(:DEFAULT setlogsock);
use NetAddr::IP;
use Mail::SPF; use Mail::SPF;
# ---------------------------------------------------------- # ----------------------------------------------------------
@ -37,6 +38,10 @@ my $spf_server = Mail::SPF::Server->new();
# Leaving this to make it easier to add more handlers later: # Leaving this to make it easier to add more handlers later:
my @HANDLERS = ( my @HANDLERS = (
{
name => 'exempt_localhost',
code => \&exempt_localhost
},
{ {
name => 'sender_policy_framework', name => 'sender_policy_framework',
code => \&sender_policy_framework code => \&sender_policy_framework
@ -58,6 +63,11 @@ my $syslog_facility = 'mail';
my $syslog_options = 'pid'; my $syslog_options = 'pid';
my $syslog_ident = 'postfix/policy-spf'; my $syslog_ident = 'postfix/policy-spf';
use constant localhost_addresses => map(
NetAddr::IP->new($_),
qw( 127.0.0.0/8 ::ffff:127.0.0.0/104 ::1 )
); # Does Postfix ever say "client_address=::ffff:<ipv4-address>"?
# ---------------------------------------------------------- # ----------------------------------------------------------
# initialization # initialization
# ---------------------------------------------------------- # ----------------------------------------------------------
@ -115,26 +125,21 @@ while (<STDIN>) {
my %responses; my %responses;
# Skip SPF check for local connections # Skip SPF check for local connections
if ($attr{client_address}=~ /^127\./) { foreach my $handler (@HANDLERS) {
$action = "PREPEND X-SPF skipped - localhost is always allowed." my $handler_name = $handler->{name};
} my $handler_code = $handler->{code};
else {
foreach my $handler (@HANDLERS) {
my $handler_name = $handler->{name};
my $handler_code = $handler->{code};
my $response = $handler_code->(attr => \%attr); my $response = $handler_code->(attr => \%attr);
if ($VERBOSE) { if ($VERBOSE) {
syslog(debug => "handler %s: %s", $handler_name, $response); syslog(debug => "handler %s: %s", $handler_name, $response);
} }
# Picks whatever response is not dunno # Picks whatever response is not 'DUNNO'
if ($response and $response !~ /^dunno/i) { if ($response and $response !~ /^DUNNO/i) {
syslog(info => "handler %s: is decisive.", $handler_name); syslog(info => "handler %s: is decisive.", $handler_name);
$action = $response; $action = $response;
last; last;
}
} }
} }
@ -145,8 +150,22 @@ while (<STDIN>) {
} }
# ---------------------------------------------------------- # ----------------------------------------------------------
# plugin: SPF # handler: localhost exemption
# ---------------------------------------------------------- # ----------------------------------------------------------
sub exempt_localhost {
my %options = @_;
my $attr = $options{attr};
my $client_address = NetAddr::IP->new($attr->{client_address});
return 'PREPEND X-Comment SPF not applicable to localhost connection, skipped check'
if grep($_->contains($client_address), localhost_addresses);
return 'DUNNO';
}
# ----------------------------------------------------------
# handler: SPF
# ----------------------------------------------------------
sub sender_policy_framework { sub sender_policy_framework {
my %options = @_; my %options = @_;
my $attr = $options{attr}; my $attr = $options{attr};
@ -169,7 +188,7 @@ sub sender_policy_framework {
info => "%s:HELO check failed - Mail::SPF->new(%s, %s, %s) failed: %s", info => "%s:HELO check failed - Mail::SPF->new(%s, %s, %s) failed: %s",
$attr->{queue_id}, $attr->{client_address}, $attr->{sender}, $attr->{helo_name}, $errmsg $attr->{queue_id}, $attr->{client_address}, $attr->{sender}, $attr->{helo_name}, $errmsg
); );
return "DUNNO"; return 'DUNNO';
} }
else { else {
my $helo_result = $spf_server->process($helo_request); my $helo_result = $spf_server->process($helo_request);
@ -217,7 +236,7 @@ sub sender_policy_framework {
info => "%s: Mail From (sender) check failed - Mail::SPF->new(%s, %s, %s) failed: %s", info => "%s: Mail From (sender) check failed - Mail::SPF->new(%s, %s, %s) failed: %s",
$attr->{queue_id}, $attr->{client_address}, $attr->{sender}, $attr->{helo_name}, $errmsg $attr->{queue_id}, $attr->{client_address}, $attr->{sender}, $attr->{helo_name}, $errmsg
); );
return "DUNNO"; return 'DUNNO';
} }
else { else {
my $mfrom_result = $spf_server->process($mfrom_request); my $mfrom_result = $spf_server->process($mfrom_request);