To add to Peter's flurry of plugins + patches - here's a plugin I've been
using in production for about 3 months that simply makes a copy (adds a
recipient, hence bcc) for all/all incoming/all outgoing mail. I use it on
a couple of client sites for archiving all their incoming and outgoing mail
for a couple of weeks, in case of end-user loss.
Also available at http://www.openfusion.com.au/labs/qpsmtpd/.
Cheers,
Gavin
--
Open Fusion P/L - Open Source Business Solutions [ Linux - Perl - Apache ]
ph: 02 9875 5032 fax: 02 9875 4317
web: http://www.openfusion.com.au mob: 0403 171712
- Fashion is a variable, but style is a constant - Programming Perl
=head1 NAME
bcc
=head1 DESCRIPTION
Forwards a copy of all mail (or incoming and/or outgoing mail) to the
given email address (useful for archiving etc.). Checks config files
'bcc_ignore_mailfrom' and 'bcc_ignore_rcptto' for exceptions - these
support bare username and '@domain' entries as wildcards as well as
normal addresses.
'bcc' should be called before the 'check_relay' plugin, since
'incoming' processing uses a RCPT hook.
=head1 CONFIG
The following parameters can be passed to bcc:
=over 4
=item all <email>
Send a copy of all email to the given address.
=item incoming <email>
Send a copy of all incoming email to the given address. Mail is considered
incoming if it is going to a recipient with a domain in 'rcpthosts'.
=item outgoing <email>
Send a copy of all outgoing email to the given address. Mail is considered
outgoing if it is sent from a relay client i.e. the RELAYCLIENT environment
variable is set.
=back
=head1 BUGS
Note that the definitions of incoming and outgoing mail mean that relayed
mail to a local domain is considered both incoming and outgoing, and will
be copied twice. This is a feature, not a bug. :-)
=head1 AUTHOR
Written by Gavin Carr <[EMAIL PROTECTED]>.
=cut
use Mail::Address;
sub register {
my ($self, $qp, %arg) = @_;
$self->{_bcc_all} = $arg{all};
$self->{_bcc_incoming} = $arg{incoming};
$self->{_bcc_outgoing} = $arg{outgoing};
$self->register_hook("mail", "mail_handler");
$self->register_hook("rcpt", "rcpt_handler") if $self->{_bcc_incoming};
$self->register_hook("data_post", "bcc");
}
sub mail_handler {
my ($self, $transaction, $sender) = @_;
my $ignore = 0;
for ($self->qp->config("bcc_ignore_mailfrom")) {
$_ = lc;
$ignore = 1,last if $_ eq lc $sender->address;
$ignore = 1,last if substr($_,0,1) eq '@' && substr($_,1) eq lc $sender->host;
$ignore = 1,last if index($_,'@') < 0 && $_ eq lc $sender->user;
}
$transaction->notes("bcc_ignore",1) if $ignore;
return (DECLINED);
}
sub rcpt_handler {
my ($self, $transaction, $rcpt) = @_;
# Only copy once for multiple recipients
return (DECLINED)
if $transaction->notes("bcc_ignore") || $transaction->notes('bcc_incoming');
# Ignore only if *all* recipients are so marked
my $ignore = 0;
for ($self->qp->config("bcc_ignore_rcptto")) {
$_ = lc;
$ignore = 1,last if $_ eq lc $rcpt->address;
$ignore = 1,last if substr($_,0,1) eq '@' && substr($_,1) eq lc $rcpt->host;
$ignore = 1,last if index($_,'@') < 0 && $_ eq lc $rcpt->user;
}
if ($ignore) {
$transaction->notes("bcc_ignore",1);
return (DECLINED);
}
my $host = lc $rcpt->host;
my @rcpthosts = ($self->qp->config("me"),$self->qp->config("rcpthosts"));
for my $allowed (@rcpthosts) {
($allowed) =~ s/^\s*(\S+)/\L$1\E/;
if ($host eq $allowed ||
(substr($allowed,0,1) eq '.' && $host =~ m/\Q$allowed\E$/)) {
$transaction->notes('bcc_incoming',1);
last;
}
}
return (DECLINED);
}
# Actual copying is deferred to data_post so as not to mess up the rcpt list
sub bcc
{
my ($self, $transaction) = @_;
return (DECLINED) if $transaction->notes("bcc_ignore");
if ($self->{_bcc_all}) {
my $rcpt = (Mail::Address->parse($self->{_bcc_all}))[0];
$transaction->add_recipient($rcpt);
$self->log(3,"message copied to " . $self->{_bcc_all});
}
if ($self->{_bcc_outgoing} && exists $ENV{RELAYCLIENT}) {
my $rcpt = (Mail::Address->parse($self->{_bcc_outgoing}))[0];
$transaction->add_recipient($rcpt);
$self->log(3,"outgoing message copied to " . $self->{_bcc_outgoing});
}
if ($transaction->notes('bcc_incoming')) {
my $rcpt = (Mail::Address->parse($self->{_bcc_incoming}))[0];
$transaction->add_recipient($rcpt);
$self->log(3,"incoming message copied to " . $self->{_bcc_incoming});
}
return (DECLINED);
}
# tag: bcc plugin to copy mails to additional recipients