2006-07-09 02:58:39 +02:00
|
|
|
sub hook_data_post {
|
|
|
|
use Mail::DomainKeys::Message;
|
|
|
|
use Mail::DomainKeys::Policy;
|
|
|
|
|
2006-07-11 19:41:48 +02:00
|
|
|
my ($self, $transaction) = @_;
|
2006-07-09 02:58:39 +02:00
|
|
|
|
2006-07-11 19:41:48 +02:00
|
|
|
# if this isn't signed, just move along
|
|
|
|
return DECLINED
|
|
|
|
unless $transaction->header->get('DomainKey-Signature');
|
|
|
|
|
2006-07-09 02:58:39 +02:00
|
|
|
my @body;
|
|
|
|
|
2006-07-11 19:41:48 +02:00
|
|
|
$transaction->body_resetpos;
|
2006-07-09 02:58:39 +02:00
|
|
|
|
2006-07-11 19:41:48 +02:00
|
|
|
$transaction->body_getline; # \r\n seperator is NOT part of the body
|
2006-07-09 02:58:39 +02:00
|
|
|
|
2006-07-11 19:41:48 +02:00
|
|
|
while (my $line = $transaction->body_getline) {
|
2006-07-09 02:58:39 +02:00
|
|
|
push @body, $line;
|
|
|
|
}
|
|
|
|
|
2006-07-11 19:41:48 +02:00
|
|
|
my $message = load Mail::DomainKeys::Message(
|
|
|
|
HeadString => $transaction->header->as_string,
|
2006-07-09 02:58:39 +02:00
|
|
|
BodyReference => \@body) or
|
|
|
|
$self->log(LOGWARN, "unable to load message"),
|
|
|
|
return DECLINED;
|
|
|
|
|
|
|
|
# no sender domain means no verification
|
2006-07-11 19:41:48 +02:00
|
|
|
$message->senderdomain or
|
2006-07-09 02:58:39 +02:00
|
|
|
return DECLINED;
|
|
|
|
|
|
|
|
my $status;
|
|
|
|
|
|
|
|
# key testing
|
2006-07-11 19:41:48 +02:00
|
|
|
if ( $message->testing ) {
|
2006-07-09 02:58:39 +02:00
|
|
|
# Don't do anything else
|
|
|
|
$status = "testing";
|
|
|
|
}
|
2006-07-11 19:41:48 +02:00
|
|
|
elsif ( $message->signed ) {
|
|
|
|
if ( $message->verify ) {
|
2006-07-09 02:58:39 +02:00
|
|
|
# verified: add good header
|
2006-07-11 19:41:48 +02:00
|
|
|
$status = $message->signature->status;
|
2006-07-09 02:58:39 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
# not verified, i.e. forged signature
|
|
|
|
$status = undef;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else { # not signed
|
2006-07-11 19:41:48 +02:00
|
|
|
my $policy = fetch Mail::DomainKeys::Policy(
|
2006-07-09 02:58:39 +02:00
|
|
|
Protocol => "dns",
|
2006-07-11 19:41:48 +02:00
|
|
|
Domain => $message->senderdomain
|
2006-07-09 02:58:39 +02:00
|
|
|
);
|
2006-07-11 19:41:48 +02:00
|
|
|
if ( $policy ) {
|
|
|
|
if ( $policy->testing ) {
|
2006-07-09 02:58:39 +02:00
|
|
|
# Don't do anything else
|
|
|
|
$status = "testing";
|
|
|
|
}
|
2006-07-11 19:41:48 +02:00
|
|
|
elsif ( $policy->signall ) {
|
2006-07-09 02:58:39 +02:00
|
|
|
# if policy requires all mail to be signed
|
|
|
|
$status = undef;
|
|
|
|
}
|
2006-07-11 19:41:48 +02:00
|
|
|
else { # $policy->signsome
|
2006-07-09 02:58:39 +02:00
|
|
|
# not signed and domain doesn't sign all
|
|
|
|
$status = "no signature";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$status = "no signature";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ( defined $status ) {
|
2006-07-11 19:41:48 +02:00
|
|
|
$transaction->header->replace("DomainKey-Status", $status);
|
2006-07-09 02:58:39 +02:00
|
|
|
return DECLINED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return DENY, "DomainKeys signature failed to verify";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Leave this in place until Mail::DomainKeys is patched
|
|
|
|
eval
|
|
|
|
q/
|
|
|
|
*Mail::DomainKeys::Message::header = sub {
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
$self->signed or
|
|
|
|
return new Mail::DomainKeys::Header(
|
|
|
|
Line => "DomainKey-Status: no signature");
|
|
|
|
|
|
|
|
$self->signature->status and
|
|
|
|
return new Mail::DomainKeys::Header(
|
|
|
|
Line => "DomainKey-Status: " . $self->signature->status);
|
|
|
|
};
|
|
|
|
/
|
|
|
|
unless Mail::DomainKeys::Message->can('header');
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
domainkeys: validate a DomainKeys signature on an incoming mail
|
|
|
|
|
2006-07-11 19:41:48 +02:00
|
|
|
Copyright (C) 2005-2006 John Peacock.
|
2006-07-09 02:58:39 +02:00
|
|
|
|
|
|
|
Portions Copyright (C) 2004 Anthony D. Urso. All rights reserved. This
|
|
|
|
program is free software; you can redistribute it and/or modify it under
|
|
|
|
the same terms as Perl itself.
|