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; 
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
use Qpsmtpd::Constants;

sub hook_rcpt {
        my ($self, $transaction, $recipient) = @_;
        return Qpsmtpd::DSN->relaying_denied();
}

Reply via email to