2012-04-29 10:35:59 +02:00
|
|
|
#!perl -w
|
2012-04-08 02:11:16 +02:00
|
|
|
|
2012-05-05 07:07:01 +02:00
|
|
|
=head1 NAME
|
2002-07-08 04:30:11 +02:00
|
|
|
|
2012-05-05 07:07:01 +02:00
|
|
|
check_relay
|
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
|
|
|
|
Checks the relayclients config file and $ENV{RELAYCLIENT} to see if relaying is allowed.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
use Qpsmtpd::Constants;
|
2007-05-18 00:16:27 +02:00
|
|
|
use Net::IP qw(:PROC);
|
|
|
|
|
2005-07-07 06:17:39 +02:00
|
|
|
sub hook_connect {
|
2004-09-22 18:01:16 +02:00
|
|
|
my ($self, $transaction) = @_;
|
|
|
|
my $connection = $self->qp->connection;
|
2003-01-20 12:03:15 +01:00
|
|
|
|
2003-11-02 12:14:44 +01:00
|
|
|
# Check if this IP is allowed to relay
|
|
|
|
my $client_ip = $self->qp->connection->remote_ip;
|
2007-05-18 00:16:27 +02:00
|
|
|
|
|
|
|
# @crelay... for comparing, @srelay... for stripping
|
|
|
|
my (@crelay_clients, @srelay_clients);
|
|
|
|
|
|
|
|
my @relay_clients = $self->qp->config("relayclients");
|
|
|
|
for (@relay_clients) {
|
|
|
|
my ($range_ip, $range_prefix) = ip_splitprefix($_);
|
|
|
|
if($range_prefix){
|
|
|
|
# has a prefix, so due for comparing
|
|
|
|
push @crelay_clients, $_;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
# has no prefix, so due for splitting
|
|
|
|
push @srelay_clients, $_;
|
2004-06-16 22:28:57 +02:00
|
|
|
}
|
2003-11-02 12:14:44 +01:00
|
|
|
}
|
|
|
|
|
2007-05-18 00:16:27 +02:00
|
|
|
if (@crelay_clients){
|
|
|
|
my ($range_ip, $range_prefix, $rversion, $begin, $end, $bin_client_ip);
|
|
|
|
my $cversion = ip_get_version($client_ip);
|
|
|
|
for (@crelay_clients) {
|
|
|
|
# Get just the IP from the CIDR range, to get the IP version, so we can
|
|
|
|
# get the start and end of the range
|
|
|
|
($range_ip, $range_prefix) = ip_splitprefix($_);
|
|
|
|
$rversion = ip_get_version($range_ip);
|
|
|
|
($begin, $end) = ip_normalize($_, $rversion);
|
|
|
|
|
|
|
|
# expand the client address (zero pad it) before converting to binary
|
|
|
|
$bin_client_ip = ip_iptobin(ip_expand_address($client_ip, $cversion), $cversion);
|
|
|
|
|
|
|
|
if (ip_bincomp($bin_client_ip, 'gt', ip_iptobin($begin, $rversion))
|
|
|
|
&& ip_bincomp($bin_client_ip, 'lt', ip_iptobin($end, $rversion)))
|
|
|
|
{
|
|
|
|
$connection->relay_client(1);
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# If relay_client is already set, no point checking again
|
|
|
|
if (@srelay_clients && !$connection->relay_client) {
|
|
|
|
my $more_relay_clients = $self->qp->config("morerelayclients", "map");
|
|
|
|
my %srelay_clients = map { $_ => 1 } @srelay_clients;
|
|
|
|
$client_ip =~ s/::/:/;
|
|
|
|
($connection->relay_client(1) && undef($client_ip)) if $client_ip eq ":1";
|
|
|
|
|
|
|
|
while ($client_ip) {
|
|
|
|
if (exists($ENV{RELAYCLIENT}) or
|
|
|
|
exists($srelay_clients{$client_ip}) or
|
|
|
|
exists($more_relay_clients->{$client_ip}))
|
|
|
|
{
|
|
|
|
$connection->relay_client(1);
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
$client_ip =~ s/(\d|\w)+(:|\.)?$//; # strip off another 8 bits
|
|
|
|
}
|
|
|
|
}
|
2004-09-22 18:01:16 +02:00
|
|
|
return (DECLINED);
|
2002-07-08 04:30:11 +02:00
|
|
|
}
|