=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; }