smeserver-qpsmtpd/root/usr/share/qpsmtpd/plugins/disclaimer

125 lines
3.7 KiB
Plaintext
Raw Normal View History

use MIME::Parser;
use MIME::Entity;
sub register {
my ($self, $qp, @args) = @_;
$self->log(LOGERROR, "Bad parameters for the disclaimer plugin")
if @_ % 2;
%{$self->{_args}} = @args;
}
sub read_disclaimer {
my ($self, $disclaimer_file) = @_;
my $disclaimer_dir = $self->{_args}->{disclaimer_dir} || "/service/qpsmtpd/config/";
return () unless open DISCLAIMER, "<$disclaimer_dir/$disclaimer_file";
my @lines = <DISCLAIMER>;
chomp @lines;
close DISCLAIMER;
return @lines;
}
sub hook_data_post {
my ($self, $transaction) = @_;
if ( $transaction->header->get('X-Qpsmtp-Disclaimer') ) {
$self->log(LOGNOTICE, "Message already has disclaimer attached");
return DECLINED;
}
$self->qp->version =~ m/([\.\d]+).*/;
my $versionnum = $1;
my @rcpt_hosts = ($self->qp->config("me"), $self->qp->config("rcpthosts"));
my $fromhost = $transaction->sender->host;
unless ( $self->{_args}->{tag_all} ) {
my $fromlocal = 0;
for my $allowed (@rcpt_hosts) {
$allowed =~ s/^\s*(\S+)/$1/;
($fromlocal = 1, last) if (($fromhost eq lc $allowed) or (substr($allowed,0,1) eq "." and
$fromhost =~ m/\Q$allowed\E$/i));
}
if (($versionnum >= 0.26) and ($fromlocal == 0)) {
my $more_rcpt_hosts = $self->qp->config('morercpthosts', 'map');
$fromlocal = 1 if exists $more_rcpt_hosts->{$fromhost};
}
unless ($fromlocal) {
$self->log(LOGDEBUG, "Not from local domain");
return DECLINED;
}
}
my $specific = 0;
my @lines;
if ( @lines = $self->read_disclaimer("disclaimer_$fromhost") ) {
$self->log(LOGDEBUG, "Found disclaimer for domain: $fromhost");
$specific = 1;
} elsif ( @lines = $self->read_disclaimer("disclaimer") ) {
$self->log(LOGDEBUG, "Found general disclaimer");
} else {
$self->log(LOGERROR, "No disclaimer found for domain: $fromhost");
return DECLINED;
}
unless ( $self->{_args}->{tag_all} ) {
my $toexternal=0;
foreach my $rcpt ( $transaction->recipients ) {
my $local = 0;
my $host = $rcpt->host;
($toexternal = 1, last) if ( $specific && $host ne $fromhost);
for my $allowed (@rcpt_hosts) {
$allowed =~ s/^\s*(\S+)/$1/;
($local = 1, last) if (($host eq lc $allowed) or (substr($allowed,0,1) eq "." and
$host =~ m/\Q$allowed\E$/i));
}
if (($versionnum >= 0.26) and ($local == 0)) {
my $more_rcpt_hosts = $self->qp->config('morercpthosts', 'map');
$local = 1 if exists $more_rcpt_hosts->{$host};
}
($toexternal = 1, last) unless $local;
}
unless ($toexternal) {
$self->log(LOGDEBUG, "Not to any external domain");
return DECLINED;
}
}
my $parser = new MIME::Parser;
$parser->output_under( $self->spool_dir() );
$parser->extract_uuencode(1);
my $ent = $parser->parse_open( $transaction->body_filename() );
$ent->make_multipart( 'mixed', Force => 1 ) if $ent->mime_type ne 'multipart/mixed';
$ent->attach( Data => join("\n", @lines),
Encoding => $self->{_args}->{mime_encoding} || '-SUGGEST',
Filename => $self->{_args}->{mime_filename} || 'disclaimer.txt',
Type => $self->{_args}->{mime_type} || 'text/plain');
if ($ent->parts <= 2) {
$transaction->header->empty();
$transaction->header($ent->head());
}
$transaction->header->replace( 'X-Qpsmtp-Disclaimer', $fromhost );
$self->log(LOGNOTICE, "Attached disclaimer for domain: $fromhost");
open BFN, ">" . $transaction->body_filename();
$ent->print(\*BFN);
close BFN;
$transaction->body_resetpos();
$ent->purge();
rmdir( $parser->output_dir );
return DECLINED;
}
# vi: ft=perl ts=4