Skip to content

Instantly share code, notes, and snippets.

@flat235
Last active February 10, 2017 13:46
Show Gist options
  • Select an option

  • Save flat235/bc6ff1fb3fc8812675c72c527eb79039 to your computer and use it in GitHub Desktop.

Select an option

Save flat235/bc6ff1fb3fc8812675c72c527eb79039 to your computer and use it in GitHub Desktop.
diy mail delivery agent (especially for catch-all scenarios)
#!/usr/bin/perl
# assumed folderlayout: somwhere/domain/user
# configure the 'somewhere' in $basedir
# you may also configure the spamdir
#
# this will filter mail in the following way:
# 1. messages marked as spam by spamassassin will be put into the spam subfolder
# 2. messages mailed to an address(@domain), for which there exists a folder named address in the spamfolder
# will be put in there, i.e.: if the folder Spam/badcompany exists and a message is mailed to [email protected],
# the message will be placed in said folder. Use this to discard old aliases, which are being spammed, especially in
# a catch-all scenario, like the one this mda is written for
# 3. messages mailed to an address(@domain), for which there exists a folder outside of the spam/archive folder will be put in
# the corresponding folder, i.e. a mail to [email protected] will be put in the goodcompany folder if it exists.
# 4. everything else will be put into the default inbox
# installation for postfix:
# put it somewhere nice and cosy like /usr/local/bin
# make it executable
# don't forget to configure the variables below
# install use Mail::Box::Manager from cpan
# if you don't know how then just:
# bash$ curl -L https://cpanmin.us | perl - App::cpanminus
# bash$ cpanm Mail::Box::Manager
# in your /etc/postfix/master.cf: (change vmail to whatever user you are using for mail storage)
# diymda unix - n n - - pipe
# flags=ODRhu user=vmail argv=/usr/local/bin/diymda.pl $user $domain
# in your /etc/postfix/main.cf:
# virtual_transport = diymda
# diymda_destination_recipient_limit = 1
# restart postfix
# report bugs to me ;)
use strict;
use warnings;
use Mail::Message;
use Mail::Box::Manager;
my $basedir = '/var/vmail';
my $user = $ARGV[0];
my $domain = $ARGV[1];
my $userdir = "$basedir/$domain/$user";
my $spamdir = 'Spam';
my $archivedir = 'Archive';
my $mgr = Mail::Box::Manager->new;
my $msg = Mail::Message->read(\*STDIN);
if (! -d "$basedir/$domain/"){
mkdir "$basedir/$domain";
}
if (! -d "$userdir/"){
`maildirmake $userdir`;
}
if (! -d "$userdir/$spamdir"){
`maildirmake -f $spamdir $userdir`;
}
if ($msg->get('X-Spam-Flag') and $msg->get('X-Spam-Flag') =~ /YES/){
$mgr->appendMessage("$userdir/.$spamdir/", $msg);
exit 0;
}
if ($msg->get('X-Original-To')){
# explicitly get the first (top-most) header, this should be the one prepended by this server,
# not one added by a mailing list
if ($msg->head->get('X-Original-To', 0) =~ /\s*([^@]+)\@$domain/ and -d "$userdir/.$spamdir.$1"){
$mgr->appendMessage("$userdir/.$spamdir.$1/", $msg);
exit 0;
}
if (-d "$userdir/.$1" and $1 ne $archivedir){
$mgr->appendMessage("$userdir/.$1/", $msg);
exit 0;
}
}
$mgr->appendMessage("$userdir/", $msg);
exit 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment