78 lines
2.2 KiB
Plaintext
78 lines
2.2 KiB
Plaintext
|
=head1 NAME
|
||
|
|
||
|
dkim_sigh: attach a DKIM or DomainKeys signature to incoming mail before it is queued.
|
||
|
Currently we sign all authenticated and allowed relay email.
|
||
|
|
||
|
written by Shad L. Lords
|
||
|
|
||
|
=cut
|
||
|
|
||
|
require Mail::DKIM::Signer;
|
||
|
require Mail::DKIM::DkSignature;
|
||
|
|
||
|
sub register {
|
||
|
my ($self, $qp, @args) = @_;
|
||
|
%{$self->{_dkim}} = @args;
|
||
|
}
|
||
|
|
||
|
sub hook_data_post {
|
||
|
my $self = shift;
|
||
|
my $trns = shift;
|
||
|
|
||
|
return DECLINED unless $self->qp->connection->relay_client() || ( $self->qp->auth_mechanism() && $self->qp->auth_user() );
|
||
|
|
||
|
my $sender = (Qpsmtpd::Address->parse($trns->sender))[0];
|
||
|
return DECLINED unless $sender;
|
||
|
|
||
|
my $dkim = new Mail::DKIM::Signer(
|
||
|
Policy => sub {
|
||
|
my $dkim = shift;
|
||
|
|
||
|
my $headers = $self->{_dkim}->{dkim_headers} || "received:from:subject:date:message-id";
|
||
|
$headers = $dkim->headers if $headers eq 'all';
|
||
|
|
||
|
my $keys = $self->{_dkim}->{keys} || 'both';
|
||
|
|
||
|
$dkim->add_signature(new Mail::DKIM::DkSignature(
|
||
|
Algorithm => $self->{_dkim}->{algorithm} || "rsa-sha1",
|
||
|
Method => $self->{_dkim}->{dk_method} || "nofws",
|
||
|
Selector => $self->{_dkim}->{selector} || "default",
|
||
|
Domain => $dkim->message_sender->host,
|
||
|
Headers => $headers,
|
||
|
)) if $keys eq 'both' || $keys eq 'dk' || $keys eq 'domainkeys';
|
||
|
|
||
|
$dkim->add_signature(new Mail::DKIM::Signature(
|
||
|
Algorithm => $self->{_dkim}->{algorithm} || "rsa-sha1",
|
||
|
Method => $self->{_dkim}->{dkim_method} || "relaxed",
|
||
|
Selector => $self->{_dkim}->{selector} || "default",
|
||
|
Domain => $dkim->message_sender->host,
|
||
|
Headers => $headers,
|
||
|
)) if $keys eq 'both' || $keys eq 'dkim';
|
||
|
|
||
|
return 1;
|
||
|
},
|
||
|
KeyFile => "config/dkimkeys/".$sender->host.".private"
|
||
|
);
|
||
|
return DECLINED unless $dkim;
|
||
|
|
||
|
$trns->body_resetpos;
|
||
|
foreach my $line (split /\n/, $trns->header->as_string) {
|
||
|
chomp $line;
|
||
|
$dkim->PRINT("$line\015\012");
|
||
|
}
|
||
|
while (my $line = $trns->body_getline) {
|
||
|
chomp $line;
|
||
|
$dkim->PRINT("$line\015\012");
|
||
|
}
|
||
|
$dkim->CLOSE;
|
||
|
|
||
|
foreach my $sig ($dkim->signatures) {
|
||
|
if ( (my $sig_string = $sig->as_string) =~ /^([^:]+):\s*(.*)$/) {
|
||
|
$self->log(LOGINFO, "Added $1 for domain ".$sender->host);
|
||
|
$trns->header->add("$1:", $2, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return DECLINED;
|
||
|
}
|