Re: rctpto rejection based on smtp verify?

[email protected]
Newsgroups perl.qpsmtpd
Message-ID <[email protected]>
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();
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.