Re: rctpto rejection based on smtp verify?
| Newsgroups | perl.qpsmtpd |
|---|---|
| Message-ID | <[email protected]> |
(ops, resent from the right address) On Fri, Jan 14, 2011 at 10:24:19PM +1300, Nicholas Lee wrote: > >>> Is there a plugin that will check rcpt addresses against a back end smtp > >>> server? I have a plug-in, ripped ad modified from some other plugin. (sorry, still no (c) info, please add some gpl header and credits[1] and manual before add to public repo - it was for internal use only.. my fault, i wanted to add headers/credits/manual and sumbit to public repo, but .. you known ..). Usage: rcpt_smtp xx.xx.xx.xx yy @domain.ext [@domain.ext ..] rcpt_deny For sample rcpt_smtp 127.0.0.1 26 @antani.it @pippotronic.com rcpt_deny You can have more than one rcpt_smtp entry, also should work for multiple lines/ip with the same domain (HA, etc). Remember to add rcpt_deny at the end (btw, there's a not so good behaviour, it responds with a relay denied also for valid domains/invalid users combinations). works ok for me, i use it with qpsmtpd-forkserver on a not so heavily loaded mailserver. ciao, Igor [1] I don't remember exactly which plugin i used as template, but should be easily identifiable;
rcpt_smtp
(text/plain, 2.2 KB)
use Qpsmtpd::Constants;
use Net::SMTP;
sub init {
my ($self, $qp, @args) = @_;
if (@args > 0) {
if ($args[0] =~ /^([\.\w_-]+)$/) {
$self->{_smtp_server} = $1
}
else {
die "Bad data in smtp server: $args[0]";
}
$self->{_smtp_port} = 25;
if (@args > 1 and $args[1] =~ /^(\d+)$/) {
$self->{_smtp_port} = $1;
}
if( @args > 2 ) {
shift(@args);
shift(@args);
$self->{_domains} = join( ",", @args );
}
} else {
die("No SMTP server specified in rcpt_smtp config");
}
}
sub hook_rcpt {
my ($self, $transaction, $recipient) = @_;
return (DECLINED) unless $recipient->host && $recipient->user;
my $rcpt = lc $recipient->user . '@' . $recipient->host;
my @domains;
if( defined( $self->{_domains} ) ) {
@domains = split( /,/, $self->{_domains} );
} else {
@domains = ( "ANY" );
}
foreach my $domain (@domains) {
if( $domain eq "ANY" || $rcpt =~ m/\Q$domain\E$/ ) {
$self->log(LOGDEBUG, "rcpt_smtp check $rcpt for domain: $domain -> $self->{_smtp_server}:$self->{_smtp_port} " );
my $smtp = Net::SMTP->new(
$self->{_smtp_server},
Port => $self->{_smtp_port},
Timeout => 60,
Hello => $self->qp->config("me"),
);
# check if smtp connection was successful, or return deny
if( !$smtp ) {
$self->log(LOGWARN, "WARNING: rcpt_smtp unable to connect ($self->{_smtp_server}:$self->{_smtp_port}:$!)" );
return Qpsmtpd::DSN->sys_not_accepting_mail();
}
# check address from/to
$smtp->mail( $transaction->sender->address );
$smtp->recipient($rcpt);
# store return code (eg: 5 for "550 Relaying denied (#5.7.1)"
my $smtp_code = substr( $smtp->code(), 0, 1 );
$self->log(LOGDEBUG, "rcpt_smtp check for $rcpt from $self->{_smtp_server}:$self->{_smtp_port}: " . $smtp->code() . " / " . $smtp->message() );
$smtp->quit();
if( $smtp_code eq "2" ) {
return Qpsmtpd::DSN->addr_rcpt_ok();
} elsif( $smtp_code eq "4" ) {
return Qpsmtpd::DSN->sys_not_accepting_mail( "Temporary error" );
} elsif( $smtp_code eq "5" ) {
return Qpsmtpd::DSN->relaying_denied();
}
}
}
return (DECLINED);
}
# vim: ts=4 sw=4 expandtab syn=perl
rcpt_deny
(text/plain, 128 B)
use Qpsmtpd::Constants;
sub hook_rcpt {
my ($self, $transaction, $recipient) = @_;
return Qpsmtpd::DSN->relaying_denied();
}