Here is a clean plugin which I have tested on a standalone server with a newly installed SQlGrey.
#!/usr/bin/perl -Tw
#############################################################################
#
# Scandinavian Mail eXchange
#
# Copyright Scandinavian Mail eXchange - all rights reserved
##############################################################################
sub register {
my ($self, $qp, @args) = @_;
}
sub hook_rcpt {
my ($self, $transaction, $recipient) = @_;
$self->{_to} = $recipient;
my ($retcode,$retmsg) = $self->check_sqlgrey($transaction);
if ($retcode != DECLINED) {
return ($retcode,$retmsg);
}
return DECLINED;
}
sub hook_mail {
my ($self,$transaction, $sender) = @_;
$self->{_from} = lc($sender->user) . '@' . lc($sender->host);
$self->{_client_name} = lc($sender->host);
return DECLINED;
}
#############################################################################
#
#
#############################################################################
sub check_sqlgrey {
my ( $self, $transaction ) = (@_);
my $host = "localhost";
my $port = 2501;
my $client_name = $self->{_client_name};
my $client_address = $self->connection->remote_ip;
if (not $client_address) {
$self->log( LOGWARN,"SQLGrey: No Client IP address" );
return DECLINED;
}
my $from_addr = $self->{_from};
if (not $from_addr) {
$self->log( LOGWARN,"SQLGrey: No From address" );
return DECLINED;
}
my $to_addr = $self->{_to};
if (not $to_addr) {
$self->log( LOGWARN,"SQLGrey: No TO address" );
return DECLINED;
}
my %connect_args = (
PeerAddr => $host,
PeerPort => $port,
Proto => 'tcp',
Timeout => 5
);
$self->log( LOGWARN,"SQLGrey: Connecting to $host:$port");
my $sock = IO::Socket::INET->new(%connect_args);
if (not $sock) {
$self->log( LOGWARN,"SQLGrey: Connect to SQLGrey failed ($@)" );
return DECLINED;
}
$sock->print("request=smtpd_access_policy
protocol_state=RCPT
protocol_name=SMTP
client_address=$client_address
client_name=$client_name
sender=$from_addr
recipient=$to_addr
");
my $answer = $sock->getline();
# make sure we got an answer
if (not defined($answer)) {
return DECLINED;
}
$answer =~ s/[\n\r]//;
if ($answer =~ m/action=defer_if_permit/) {
my ($msg) = $answer =~ m/action=defer_if_permit (.*)/;
$self->log(LOGWARN,"SQLGrey: $from_addr $msg");
return (DENYSOFT, "Temporarily rejected: $from_addr $msg");
} else {
$answer =~ s/action=//;
$self->log( LOGWARN,"SQLGrey: OK ($answer)" );
}
return DECLINED;
}