qpsmtpd/plugins/sender_permitted_from

86 lines
2.2 KiB
Plaintext
Raw Normal View History

=head1 NAME
SPF - plugin to implement Sender Permitted From
=head1 SYNOPSIS
# in config/plugins
sender_permitted_from
Or if you wish to issue 5xx on SPF fail:
sender_permitted_from spf_deny 1
=cut
use Mail::SPF::Query;
sub register {
my ($self, $qp, @args) = @_;
%{$self->{_args}} = @args;
$self->register_hook("mail", "mail_handler");
$self->register_hook("rcpt", "rcpt_handler");
$self->register_hook("data_post", "data_handler");
}
sub mail_handler {
my ($self, $transaction, $sender) = @_;
return (DECLINED) unless ($sender->format ne "<>"
and $sender->host && $sender->user);
my $host = lc $sender->host;
my $from = $sender->user . '@' . $host;
my $ip = $self->qp->connection->remote_ip;
my $query = Mail::SPF::Query->new(ip => $ip, sender => $from)
|| die "Couldn't construct Mail::SPF::Query object";
$transaction->notes('spfquery', $query);
return (DECLINED);
}
sub rcpt_handler {
my ($self, $transaction, $rcpt) = @_;
my $query = $transaction->notes('spfquery');
my ($result, $comment) = $query->result();
$self->qp->connection->notes('spf_result', $result);
$self->qp->connection->notes('spf_comment', $comment);
if ($result eq "fail" and $self->{_args}{spf_deny}) {
return (DENY, "SPF forgery ($comment)");
}
return (DECLINED);
}
sub data_handler {
my ($self, $transaction) = @_;
my $spf = $self->qp->connection->notes('spf_result');
my $host = $self->qp->connection->remote_host;
my $ip = $self->qp->connection->remote_ip;
my $sender = $transaction->sender;
my $details = '';
if ($spf eq 'fail') {
$details = "fail (client $host[$ip] is not a designated mailer for domain of sender $sender)";
}
elsif ($spf eq 'softfail') {
$details = "error (temporary failure while resolving designated mailer status for domain of sender $sender)";
}
elsif ($spf eq 'pass') {
$details = "pass (client $host[$ip] is designated mailer for domain of sender $sender)";
}
else {
$details = "unknown (domain of sender $sender does not designate mailers)";
}
$transaction->header->add('Received-SPF' => $details);
return DECLINED;
}