SPF: use $conn->relay_client instead of duplicated

is_in_relayclients method. Expects relay plugin to have set relay_client, a reasonable assumption.
This commit is contained in:
Matt Simerson 2012-11-14 23:21:20 -05:00
parent eb154f2069
commit 78cab52582
4 changed files with 27 additions and 47 deletions

View File

@ -1,12 +1,14 @@
# used by plugins/relay # used by plugins/relay
# Format is IP, or IP part with trailing dot # IPv4 format is IP, or IP part with trailing dot
# e.g. "127.0.0.1", or "192.168." # e.g. "127.0.0.1", or "192.168."
127.0.0.1 127.0.0.1
# leading/trailing whitespace is ignored # leading/trailing whitespace is ignored
192.0. 192.0.
# #
# IPv6 formats ends in a nibble (not a netmask, prefixlen, or colon) # IPv6 formats can be compressed or expanded, may include a prefixlen,
# RFC 3849 example # and can end on any nibble boundary. Nibble boundaries must be expressed
2001:DB8 # in expanded format. (RFC 3849 example)
2001:0DB8
2001:DB8::1 2001:DB8::1
2001:DB8::1/32
2001:0DB8:0000:0000:0000:0000:0000:0001 2001:0DB8:0000:0000:0000:0000:0000:0001

View File

@ -37,12 +37,12 @@ Each line in I<relayclients> is one of:
- partial IP address terminated by a dot or colon for matching whole networks - partial IP address terminated by a dot or colon for matching whole networks
192.168.42. 192.168.42.
fdda:b13d:e431:ae06: 2001:db8:e431:ae06:
... ...
- a network/mask, aka a CIDR block - a network/mask, aka a CIDR block
10.1.0.0/24 10.1.0.0/24
fdda:b13d:e431:ae06::/64 2001:db8:e431:ae06::/64
... ...
=head2 morerelayclients =head2 morerelayclients
@ -175,15 +175,20 @@ sub is_octet_match {
my $self = shift; my $self = shift;
my $ip = $self->qp->connection->remote_ip; my $ip = $self->qp->connection->remote_ip;
$ip =~ s/::/:/;
if ( $ip eq ':1' ) { if ( $ip eq '::1' ) {
$self->log(LOGINFO, "pass, octet matched localhost ($ip)"); $self->log(LOGINFO, "pass, octet matched localhost ($ip)");
return 1; return 1;
}; };
my $more_relay_clients = $self->qp->config('morerelayclients', 'map'); my $more_relay_clients = $self->qp->config('morerelayclients', 'map');
my $ipv6 = $ip =~ /:/ ? 1 : 0;
if ( $ipv6 && $ip =~ /::/ ) { # IPv6 compressed notation
$ip = Net::IP::ip_expand_address($ip,6);
};
while ($ip) { while ($ip) {
if ( exists $self->{_octets}{$ip} ) { if ( exists $self->{_octets}{$ip} ) {
$self->log(LOGINFO, "pass, octet match in relayclients ($ip)"); $self->log(LOGINFO, "pass, octet match in relayclients ($ip)");
@ -194,7 +199,15 @@ sub is_octet_match {
$self->log(LOGINFO, "pass, octet match in morerelayclients ($ip)"); $self->log(LOGINFO, "pass, octet match in morerelayclients ($ip)");
return 1; return 1;
}; };
$ip =~ s/(\d|\w)+(:|\.)?$// or last; # strip off another 8 bits
# added IPv6 support (Michael Holzt - 2012-11-14)
if ( $ipv6 ) {
$ip =~ s/[0-9a-f]:?$//; # strip off another nibble
chop $ip if ':' eq substr($ip, -1, 1);
}
else {
$ip =~ s/\d+\.?$// or last; # strip off another 8 bits
}
} }
$self->log(LOGDEBUG, "no octet match" ); $self->log(LOGDEBUG, "no octet match" );

View File

@ -59,8 +59,6 @@ use warnings;
#use Mail::SPF 2.000; # eval'ed in ->register #use Mail::SPF 2.000; # eval'ed in ->register
use Qpsmtpd::Constants; use Qpsmtpd::Constants;
use Net::IP;
sub register { sub register {
my ($self, $qp, %args) = @_; my ($self, $qp, %args) = @_;
eval 'use Mail::SPF'; eval 'use Mail::SPF';
@ -92,8 +90,8 @@ sub mail_handler {
return (DECLINED, "SPF - null sender"); return (DECLINED, "SPF - null sender");
}; };
if ( $self->is_in_relayclients() ) { if ( $self->qp->connection->relay_client ) {
$self->log( LOGINFO, "skip, in relayclients" ); $self->log( LOGINFO, "skip, relay_client" );
return (DECLINED, "SPF - relaying permitted"); return (DECLINED, "SPF - relaying permitted");
}; };
@ -231,39 +229,6 @@ sub data_post_handler {
return DECLINED; return DECLINED;
} }
sub is_in_relayclients {
my $self = shift;
my $client_ip = $self->qp->connection->remote_ip;
my @relay_clients = $self->qp->config('relayclients');
my $more_relay_clients = $self->qp->config('morerelayclients', 'map');
my %relay_clients = map { $_ => 1 } @relay_clients;
my $ipv6 = $client_ip =~ /:/ ? 1 : 0;
if ( $ipv6 && $client_ip =~ /::/ ) { # IPv6 compressed notation
$client_ip = Net::IP::ip_expand_address($client_ip,6);
};
while ($client_ip) {
if ( exists $relay_clients{$client_ip} ||
exists $more_relay_clients->{$client_ip} ) {
$self->log( LOGDEBUG, "skip, IP in relayclients" );
return 1;
};
# added IPv6 support (Michael Holzt - 2012-11-14)
if ( $ipv6 ) {
$client_ip =~ s/[0-9a-f]:*$//; # strip off another nibble
chop $client_ip if ':' eq substr($client_ip, -1, 1);
}
else {
$client_ip =~ s/\d+\.?$// or last; # strip off another 8 bits
}
}
return;
};
sub is_special_recipient { sub is_special_recipient {
my ($self, $rcpt) = @_; my ($self, $rcpt) = @_;

View File

@ -26,7 +26,7 @@ is($smtpd->config('me'), 'some.host.example.org', 'config("me")');
# line with both) # line with both)
my $relayclients = join ",", sort $smtpd->config('relayclients'); my $relayclients = join ",", sort $smtpd->config('relayclients');
is($relayclients, is($relayclients,
'127.0.0.1,192.0.,2001:0DB8:0000:0000:0000:0000:0000:0001,2001:DB8,2001:DB8::1', '127.0.0.1,192.0.,2001:0DB8:0000:0000:0000:0000:0000:0001,2001:DB8::1/32,2001:DB8,2001:DB8::1',
'config("relayclients") are trimmed'); 'config("relayclients") are trimmed');
foreach my $f ( @mes ) { foreach my $f ( @mes ) {