1. easier to update 2. it's readable on github
2.4 KiB
Advanced Playground
Discarding messages
If you want to make the client think a message has been regularily accepted,
but in real you delete it or send it to /dev/null
, ..., use something
like the following plugin and load it before your default queue plugin.
sub hook_queue {
my ($self, $transaction) = @_;
if ($transaction->notes('discard_mail')) {
my $msg_id = $transaction->header->get('Message-Id') || '';
$msg_id =~ s/[\r\n].*//s;
return(OK, "Queued! $msg_id");
}
return(DECLINED);
}
Changing return values
This is an example how to use the isa_plugin
method.
The rcpt_ok_maxrelay
plugin wraps the rcpt_ok
plugin. The rcpt_ok
plugin checks the rcpthosts
and morercpthosts
config files for
domains, which we accept mail for. If not found it tells the
client that relaying is not allowed. Clients which are marked as
relay clients
are excluded from this rule. This plugin counts the
number of unsuccessfull relaying attempts and drops the connection if
too many were made.
The optional parameter MAX_RELAY_ATTEMPTS
configures this plugin to drop
the connection after MAX_RELAY_ATTEMPTS
unsuccessful relaying attempts.
Set to 0
to disable, default is 5
.
Note: Do not load both (rcpt_ok
and rcpt_ok_maxrelay
). This plugin
should be configured to run last
, like rcpt_ok
.
use Qpsmtpd::DSN;
sub init {
my ($self, $qp, @args) = @_;
die "too many arguments"
if @args > 1;
$self->{_count_relay_max} = defined $args[0] ? $args[0] : 5;
$self->isa_plugin("rcpt_ok");
}
sub hook_rcpt {
my ($self, $transaction, $recipient) = @_;
my ($rc, @msg) = $self->SUPER::hook_rcpt($transaction, $recipient);
return ($rc, @msg)
unless (($rc == DENY) and $self->{_count_relay_max});
my $count =
($self->connection->notes('count_relay_attempts') || 0) + 1;
$self->connection->notes('count_relay_attempts', $count);
return ($rc, @msg) unless ($count > $self->{_count_relay_max});
return Qpsmtpd::DSN->relaying_denied(DENY_DISCONNECT,
"Too many relaying attempts");
}
Results of other hooks
If we're in a transaction, the results of a callback are stored in
$self->transaction->notes($code->{name})->{"hook_$hook"}->{return}
If we're in a connection, store things in the connection notes instead.