diff --git a/Changes b/Changes index 61d9358..ced6384 100644 --- a/Changes +++ b/Changes @@ -25,6 +25,17 @@ + initial "awkward silence" period now configurable (Mark Powell) + DENY/DENYSOFT now configurable + Move relay flag to connection object (John Peacock): + + add relay_client() method to Connection.pm + + change SMTP.pm to copy relay_client() flag to transaction relaying + flag (for compatibility purposes) - should deprecate instead + + Update Auth.pm module to set $connection->relay_client() + + Split check_relay plugin into two plugins (John Peacock): + + check_relay now fires on connect and sets relay_client() flag + + rcpt_ok runs last of rcpt plugins and performs final OK/DENY + + change default config/plugins to reflect new order + 0.28 - 2004/06/05 Don't keep adding ip addresses to the process status line ($0) when running under PPerl. diff --git a/config.sample/plugins b/config.sample/plugins index e461707..91e8e9b 100644 --- a/config.sample/plugins +++ b/config.sample/plugins @@ -10,6 +10,7 @@ quit_fortune check_earlytalker count_unrecognized_commands 4 +check_relay require_resolvable_fromhost @@ -22,7 +23,7 @@ check_spamhelo # sender_permitted_from # this plugin needs to run after all other "rcpt" plugins -check_relay +rcpt_ok # content filters virus/klez_filter diff --git a/lib/Qpsmtpd/Auth.pm b/lib/Qpsmtpd/Auth.pm index 72c0c24..d1de77f 100644 --- a/lib/Qpsmtpd/Auth.pm +++ b/lib/Qpsmtpd/Auth.pm @@ -319,7 +319,7 @@ sub SASL { $msg = "Authentication successful" . ( defined $msg ? " - " . $msg : "" ); $session->respond( 235, $msg ); - $ENV{RELAYCLIENT} = 1; + $session->connection->relay_client(1); $session->log( LOGINFO, $msg ); return OK; } diff --git a/lib/Qpsmtpd/Connection.pm b/lib/Qpsmtpd/Connection.pm index ea6ec07..8fe3180 100644 --- a/lib/Qpsmtpd/Connection.pm +++ b/lib/Qpsmtpd/Connection.pm @@ -59,6 +59,12 @@ sub remote_info { $self->{_remote_info}; } +sub relay_client { + my $self = shift; + @_ and $self->{_relay_client} = shift; + $self->{_relay_client}; +} + sub hello { my $self = shift; @_ and $self->{_hello} = shift; diff --git a/lib/Qpsmtpd/SMTP.pm b/lib/Qpsmtpd/SMTP.pm index d0d6180..dcb72cc 100644 --- a/lib/Qpsmtpd/SMTP.pm +++ b/lib/Qpsmtpd/SMTP.pm @@ -116,7 +116,9 @@ sub transaction { sub reset_transaction { my $self = shift; $self->run_hooks("reset_transaction") if $self->{_transaction}; - return $self->{_transaction} = Qpsmtpd::Transaction->new(); + $self->{_transaction} = Qpsmtpd::Transaction->new(); + $self->{_transaction}->relaying($self->{_connection}->{_relay_client}); + return $self->{_transaction}; } diff --git a/plugins/check_relay b/plugins/check_relay index e2e19ca..9f96812 100644 --- a/plugins/check_relay +++ b/plugins/check_relay @@ -1,26 +1,15 @@ -# this plugin checks the standard rcpthosts config and +# this plugin checks the relayclients config file and # $ENV{RELAYCLIENT} to see if relaying is allowed. # -# It should be configured to be run _LAST_! -# sub register { my ($self, $qp) = @_; - $self->register_hook("rcpt", "check_relay"); + $self->register_hook("connect", "check_relay"); } sub check_relay { - my ($self, $transaction, $recipient) = @_; - my $host = lc $recipient->host; - - my @rcpt_hosts = ($self->qp->config("me"), $self->qp->config("rcpthosts")); - - # Allow 'no @' addresses for 'postmaster' and 'abuse' - # qmail-smtpd will do this for all users without a domain, but we'll - # be a bit more picky. Maybe that's a bad idea. - my $user = $recipient->user; - $host = $self->qp->config("me") - if ($host eq "" && (lc $user eq "postmaster" || lc $user eq "abuse")); + my ($self, $transaction) = @_; + my $connection = $self->qp->connection; # Check if this IP is allowed to relay my @relay_clients = $self->qp->config("relayclients"); @@ -32,21 +21,11 @@ sub check_relay { exists($relay_clients{$client_ip}) or exists($more_relay_clients->{$client_ip})) { - $transaction->relaying(1); - return (OK); + $connection->relay_client(1); + last; } $client_ip =~ s/\d+\.?$//; # strip off another 8 bits } - # Check if this recipient host is allowed - for my $allowed (@rcpt_hosts) { - $allowed =~ s/^\s*(\S+)/$1/; - return (OK) if $host eq lc $allowed; - return (OK) if substr($allowed,0,1) eq "." and $host =~ m/\Q$allowed\E$/i; - } - - my $more_rcpt_hosts = $self->qp->config('morercpthosts', 'map'); - return (OK) if exists $more_rcpt_hosts->{$host}; - - return (DENY); + return (DECLINED); } diff --git a/plugins/rcpt_ok b/plugins/rcpt_ok new file mode 100644 index 0000000..a8c51cc --- /dev/null +++ b/plugins/rcpt_ok @@ -0,0 +1,40 @@ +# this plugin checks the standard rcpthosts config +# +# It should be configured to be run _LAST_! +# + +sub register { + my ($self, $qp) = @_; + $self->register_hook("rcpt", "rcpt_ok"); +} + +sub rcpt_ok { + my ($self, $transaction, $recipient) = @_; + my $host = lc $recipient->host; + + my @rcpt_hosts = ($self->qp->config("me"), $self->qp->config("rcpthosts")); + + # Allow 'no @' addresses for 'postmaster' and 'abuse' + # qmail-smtpd will do this for all users without a domain, but we'll + # be a bit more picky. Maybe that's a bad idea. + my $user = $recipient->user; + $host = $self->qp->config("me") + if ($host eq "" && (lc $user eq "postmaster" || lc $user eq "abuse")); + + # Check if this recipient host is allowed + for my $allowed (@rcpt_hosts) { + $allowed =~ s/^\s*(\S+)/$1/; + return (OK) if $host eq lc $allowed; + return (OK) if substr($allowed,0,1) eq "." and $host =~ m/\Q$allowed\E$/i; + } + + my $more_rcpt_hosts = $self->qp->config('morercpthosts', 'map'); + return (OK) if exists $more_rcpt_hosts->{$host}; + + if ( $self->qp->connection->relay_client ) { # failsafe + return (OK); + } + else { + return (DENY); + } +}