Trunk changed for mail:SPF. 1.08.1/debian tags updated for Ubuntu lessons learned.

This commit is contained in:
Scott Kitterman 2007-02-03 21:46:00 +00:00
commit 1d57e605d3
9 changed files with 204 additions and 102 deletions

15
CHANGES
View file

@ -4,6 +4,21 @@
# ! = Changed something significant, or removed a feature
# * = Fixed a bug, or made a minor improvement
--- 1.99 (2007-02-10 16:00)
postfix-policyd-spf-perl:
! Changed from Mail::SPF::Query to Mail::SPF for RFC 4408 compliance
! Removed Testing handler (usage was undocumented).
* Simplified logging. Policy server is less chatty. Logs are clearer.
Miscellaneous:
* Updated README file:
- Updated for new SPF library
- Added more detail on results/responses
- Explained how to get verbose logging
Debian:
--- 1.08.1 (2007-01-10 21:00)
postfix-policyd-spf-perl:

View file

@ -6,7 +6,7 @@ postfix-policyd-spf-perl:
Perl 5.6
version
Mail::SPF::Query
Mail::SPF (not Mail::SPF::Query)
Installing
----------
@ -31,5 +31,3 @@ Installing
4. Restart Postfix.
# $Id$
# vim:tw=79

20
README
View file

@ -1,4 +1,4 @@
postfix-policyd-spf-perl 1.08.1
postfix-policyd-spf-perl 1.99
A Postfix SMTPd policy server for SPF checking
(C) 2007 Scott Kitterman <scott@kitterman.com>
2003-2004 Meng Weng Wong <mengwong@pobox.com>
@ -7,7 +7,19 @@ Contributions by various members of the SPF project
==============================================================================
postfix-policyd-spf-perl is a Postfix SMTPd policy daemon for SPF checking.
It is implemented in pure Perl and uses the Mail::SPF::Query CPAN module.
It is implemented in pure Perl and uses the Mail::SPF CPAN module. Note that
Mail::SPF is a complete re-implementation of SPF based on the final SPF RFC,
RFC 4408. It shares no code with the older Mail::SPF::Query that was the
original SPF development implementation. If you are upgrading from on older
version of this policy server you will need to install Mail::SPF.
This version of the policy server will reject mail that fails either Mail From
or HELO SPF checks. It always checks HELO (older versions just checked HELO if
Mail From was null). It will defer mail if there is a temporary SPF error and
the message would othersise be permitted (DEFER_IF_PERMIT). Otherwise, it will
PREPEND the appropriate SPF Received header. In the case of multi-recipient
mail, multiple headers will get appended. Error conditions within the policy
server (that don't result in a crash) or from Mail::SPF will return DUNNO.
See INSTALL or README.Debian for installation instructions.
@ -57,11 +69,11 @@ followed by a empty line:
action=dunno
[empty line]
If you want more detail in the system logs change $VERBOSE to 1.
License
-------
postfix-policyd-spf-perl is free software. You may use, modify, and distribute
it under the GNU GPL (version 2 or later); see the LICENSE file.
# $Id$
# vim:tw=79

View file

@ -4,7 +4,7 @@ Installing
1. Add the following to /etc/postfix/master.cf:
policy unix - n n - - spawn
user=nobody argv=/usr/bin/perl /usr/lib/postfix/policyd-spf-perl
user=nobody argv=/usr/bin/perl /usr/sbin/postfix-policyd-spf-perl
2. Configure the Postfix policy service in /etc/postfix/main.cf:
@ -19,5 +19,3 @@ Installing
3. Restart Postfix.
# $Id: README 167 2005-01-17 18:26:45Z julian $
# vim:tw=79

30
debian/changelog vendored
View file

@ -1,23 +1,17 @@
postfix-policyd-spf-perl (1.08.1) unstable; urgency=low
postfix-policyd-spf-perl (1.99-0ubuntu1) feisty; urgency=low
Debian:
* New maintainer: Scott Kitterman <scott@kitterman.com>
* Priority: extra (was: optional)
* Removed Build-Depends-Indep: perl, as there really is no need for it.
* Depends: libversion-perl
* Updated debian/copyright.
* New upstream release for RFC compliant SPF checking.
* Updated control to use libmail-spf-perl instead of the unmaintained
libmail-spf-query-perl and changed maintainer to Scott Kitterman (was
MOTU).
* Updated man pages for new library and upstream documentation udpates.
postfix-policyd-spf-perl:
* Minor and purely cosmetic code clean-up.
-- Scott Kitterman <scott@kitterman.com> Sat, 03 Feb 2007 16:33:08 -0500
Miscellaneous:
* Updated README file with new website URL and copyright.
* Added LICENSE file as an explicit copy of the GPLv2.
postfix-policyd-spf-perl (1.08.1-0ubuntu1) feisty; urgency=low
-- Scott Kitterman <scott@kitterman.com> Wed, 10 Jan 2007 21:00:00 +0000
* Initial debianization of the package.
* Removed upstream provided /debian directory
* Modified documentation for Debian specific file locations
postfix-policyd-spf-perl (1.08) unstable; urgency=low
* Initial release as a Debian package.
-- Julian Mehnle <julian@mehnle.net> Sat, 17 Jun 2006 19:32:31 +0000
-- Scott Kitterman <scott@kitterman.com> Thu, 11 Jan 2007 04:59:08 -0500

6
debian/control vendored
View file

@ -7,8 +7,10 @@ Standards-Version: 3.7.2
Package: postfix-policyd-spf-perl
Architecture: all
Depends: libversion-perl, libmail-spf-query-perl
Depends: libversion-perl, libmail-spf-perl, ${perl:Depends}
Recommends: postfix
Description: pure-Perl Postfix policy daemon for SPF checking
postfix-policyd-spf-perl is a Postfix SMTPd policy daemon for SPF checking.
It is implemented in pure Perl and uses the Mail::SPF::Query module.
It is implemented in pure Perl and uses the Mail::SPF module. The SPF web
site is http://www.openspf.org/. The Postfix configuration must be changed to
check SPF. See README.Debian or man 8 postfix-policyd-spf-perl for details.

75
debian/copyright vendored
View file

@ -1,14 +1,77 @@
This is the Debian package for postfix-policyd-spf-perl, which is available
from <http://www.openspf.org/Software#postfix-policyd-spf-perl>.
This package was debianized by Scott Kitterman <scott@kitterman.com> on
Thu, 11 Jan 2007 04:29:13 -0500.
It was downloaded from <http://www.openspf.org/Software#postfix-policyd-spf-perl>.
Upstream authors Meng Weng Wong <mengwong@pobox.com> and Scott Kitterman
<scott@kitterman.com>
Copyright:
(C) 2007 Scott Kitterman <scott@kitterman.com>
2003-2004 Meng Weng Wong <mengwong@pobox.com>
Contributions by various members of the SPF project
Scott Kitterman is the maintainer of the Debian package.
(C) 2003-2004 Meng Weng Wong <mengwong@pobox.com>
This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License (version 2 or later).
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
On Debian systems, the complete text of the GPL v2 can be found here:
/usr/share/common-licenses/GPL-2

11
debian/rules vendored
View file

@ -22,8 +22,7 @@ install-stamp:
dh_testroot
dh_clean -k
install -D postfix-policyd-spf-perl $(TMP)/usr/lib/postfix/policyd-spf-perl
install -D postfix-policyd-spf-perl $(TMP)/usr/sbin/postfix-policyd-spf-perl
touch install-stamp
# Build architecture-independent files here:
@ -31,13 +30,9 @@ binary-indep: build install
dh_testdir
dh_testroot
dh_install
dh_installdirs
dh_installdocs README
dh_installdocs
dh_installman debian/postfix-policyd-spf-perl.8
dh_installchangelogs CHANGES
#dh_installexamples examples/*
#dh_installman
#dh_link
dh_compress
dh_fixperms

View file

@ -2,24 +2,40 @@
# postfix-policyd-spf-perl
# http://www.openspf.org/Software
# version 1.08.1
# version 1.99
# $Id$
#(C) 2007 Scott Kitterman <scott@kitterman.com>
#(C) 2003-2004 Meng Weng Wong <mengwong@pobox.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# 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.08.1');
use version; our $VERSION = qv('1.99');
use strict;
use Fcntl;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Mail::SPF::Query;
use Mail::SPF;
# ----------------------------------------------------------
# configuration
# ----------------------------------------------------------
my $spf_server = Mail::SPF::Server->new();
my @HANDLERS;
push @HANDLERS, "testing";
push @HANDLERS, "sender_permitted_from";
push @HANDLERS, "sender_policy_framework";
#Leaving this to make it easier to add others later.
my $VERBOSE = 0;
@ -88,14 +104,17 @@ while (<STDIN>) {
foreach my $handler (@HANDLERS) {
no strict 'refs';
my $response = $handler->(attr=>\%attr);
syslog(debug => "handler %s: %s", $handler, $response);
if ($VERBOSE) {
syslog(debug => "handler %s: %s", $handler, $response);
}
#Picks whatever response is not dunno
if ($response and $response !~ /^dunno/i) {
syslog(info => "handler %s: %s is decisive.", $handler, $response);
syslog(info => "handler %s: is decisive.", $handler);
$action = $response; last;
}
}
syslog(info => "decided action=%s", $action);
syslog(info => "Policy action=%s", $action);
print STDOUT "action=$action\n\n";
%attr = ();
@ -104,65 +123,71 @@ while (<STDIN>) {
# ----------------------------------------------------------
# plugin: SPF
# ----------------------------------------------------------
sub sender_permitted_from {
sub sender_policy_framework {
local %_ = @_;
my %attr = %{ $_{attr} };
my $query = eval {
Mail::SPF::Query->new(
ip => $attr{client_address},
sender => $attr{sender},
helo => $attr{helo_name}
)
#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'
identity => $attr{helo_name},
ip_address => $attr{client_address},
helo_identity # optional,
=> $attr{helo_name}
);
};
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;
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.
my $mfrom_request = eval {
Mail::SPF::Request->new(
scope => 'mfrom', # 'mfrom' or 'helo', 'pra'
identity => $attr{sender},
ip_address => $attr{client_address},
helo_identity # optional,
=> $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::Query->new(%s, %s, %s) failed: %s",
info => "%s: Mail::SPF->new(%s, %s, %s) failed: %s",
$attr{queue_id}, $attr{client_address}, $attr{sender}, $attr{helo_name}, $@
);
return "DUNNO";
}
my ($result, $smtp_comment, $header_comment) = $query->result();
syslog(
info => "%s: SPF %s: smtp_comment=%s, header_comment=%s",
$attr{queue_id}, $result, $smtp_comment, $header_comment
info => "%s: SPF %s: Envelope-from: %s, IP Address: %s, Recipient: %s",
$attr{queue_id}, $mfrom_result, $attr{sender}, $attr{client_address}, $attr{recipient}
);
if ($result eq "fail") { return "REJECT $smtp_comment"; }
elsif ($result eq "error") { return "DEFER_IF_PERMIT $smtp_comment"; }
else { return "PREPEND Received-SPF: $result ($header_comment)"; }
}
# ----------------------------------------------------------
# plugin: testing
# ----------------------------------------------------------
sub testing {
local %_ = @_;
my %attr = %{ $_{attr} };
if (
lc(address_stripped($attr{sender})) eq lc(address_stripped($attr{recipient})) and
$attr{recipient} =~ /policyblock/
) {
syslog(info => "%s: testing: will block as requested", $attr{queue_id});
return "REJECT smtpd-policy blocking $attr{recipient}";
}
else {
syslog(
info => "%s: testing: stripped sender=%s, stripped rcpt=%s",
$attr{queue_id},
address_stripped($attr{sender}),
address_stripped($attr{recipient}),
);
}
return "DUNNO";
}
# my $foo = address_stripped('foo+bar@baz.com'); # returns 'foo@baz.com'
sub address_stripped {
my $string = shift;
$string =~ s/[+-].*\@/\@/;
return $string;
#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"; }
}