Discussion:
[courier-users] Can courier sort mail for one user into multiple subfolders for imap
David Niklas
2016-09-02 00:57:50 UTC
Permalink
Hello,
I wanted to know if courier could read the subject/from metadata so that
it could place courier mailing list mail into one folder and so on with
other mail received.
I'm talking about doing this after the part where courier figures out
that the email message it just received/retrieved is for a local user and
after deciding to place the email in the inbox of said user.

Thanks,
David

------------------------------------------------------------------------------
Lindsay Haisley
2016-09-02 04:34:21 UTC
Permalink
Post by David Niklas
Hello,
I wanted to know if courier could read the subject/from metadata so that
it could place courier mailing list mail into one folder and so on with
other mail received.
I'm talking about doing this after the part where courier figures out
that the email message it just received/retrieved is for a local user and
after deciding to place the email in the inbox of said user.
You can use use maildrop to do this in a ~/.mailfilter script, or you
can, as I do, use a special address for your mailing list subscription.
I have, for instance, all mail addressed to 
fmouse-***@fmp.com delivered to ./Maildir/.postmaster as
instructed in the file ~/.courier-postmaster. I could do the same for
my courier-users address, fmouse-***@fmp.com except that I have a
null ~/.courier-courier file, which says simply that the address is
valid, and I let my MUA do the filtering. 
--
Lindsay Haisley | "UNIX is user-friendly, it just
FMP Computer Services | chooses its friends."
512-259-1190 | -- Andreas Bogk
http://www.fmp.com |



------------------------------------------------------------------------------
Alessandro Vesely
2016-09-02 09:01:12 UTC
Permalink
Post by David Niklas
I wanted to know if courier could read the subject/from metadata so
that it could place courier mailing list mail into one folder and so
on with other mail received.
simplest method would be using maildrop recipe for this user. It comes
into play after determining mailbox/home directory for mail being
delivered if configured so. Maildrop recipes are easy to read
resembling common programming languages or scripts.
You nead just configure courier to use it, either with .courier if
maildrop should be used only for said user, or setting DEFAULTDELIVERY
in courierd config file for all users.
If you would like to sort mails from this mailing list into defined
if (/^List-Id:.*courier-users.lists.sourceforge.net/)
to "$HOME/Maildir/$FOLDER/"
(use desired folder name instead on $FOLDER, I use - for this list -
.Software.Courier.courier-users).
An obvious generalization, to avoid editing $HOME/.mailfilter on every new subscription:

if (/^List-ID:[^<]*<([-_A-Za-z0-9]*)/)
{
DEST=`sed -nr 's/^INBOX(\\.'"$MATCH1"')$/\\1/ip' ./Maildir/courierimapsubscribed`
if ("$DEST")
{
`test -d "./Maildir/$DEST"`
if ($RETURNCODE == 0)
to "./Maildir/$DEST";
}
}


Note that the regex only collects characters up to but excluding the first dot (or semicolon, in case of malice), so the 2nd arg to sed would actually be "s/^INBOX(\.courier-users)$/\1/ip" for messages in this list.

Ale
--
------------------------------------------------------------------------------
l***@datenritter.de
2017-03-29 19:16:42 UTC
Permalink
Post by Alessandro Vesely
If you would like to sort mails from this mailing list into defined
if (/^List-Id:.*courier-users.lists.sourceforge.net/)
to "$HOME/Maildir/$FOLDER/"
(use desired folder name instead on $FOLDER, I use - for this list -
.Software.Courier.courier-users).
if (/^List-ID:[^<]*<([-_A-Za-z0-9]*)/)
{
DEST=`sed -nr 's/^INBOX(\\.'"$MATCH1"')$/\\1/ip' ./Maildir/courierimapsubscribed`
if ("$DEST")
{
`test -d "./Maildir/$DEST"`
if ($RETURNCODE == 0)
to "./Maildir/$DEST";
}
}
Below is how I did it. Unfortunately the script stopped working a few
months ago writing hundreds of mails to (mbox?-)files with useful names
like ".@".

My debug version with some extra logging needs more input, so I'll send
it to this list... ["Yo dawg, I heard you like mail filters..."]

Anyway, it's meant to make everything maintenance free. When the first
mail from a list you subscribed to is received, a maildir
"***@some_domain_tld" is created and added to courierimapsubscribed.


# Check X-BeenThere which every good list server sets.
# List-ID is okay, too.
if ( /^X-BeenThere:\s+(.*)@(.*)/ )
{
# Pick local part and domain part, replace the dots with
# underscores.
### BUG: This leaves LPART and DPART empty. :( ###
LPART=`echo $MATCH1 | sed "s/\./_/g"`
DPART=`echo $MATCH2 | sed "s/\./_/g"`

PREFIX=""
FOLDER=".$LPART@$DPART"

# I want subfolders for organizations with more than one list:
if ( /^X-BeenThere:.*specialorg.*/ )
{
PREFIX=".specialorg"
FOLDER=".$LPART"
}

NEWDIR=$HOME/Maildir/$PREFIX$FOLDER

# create the maildir if it doesn't exist:
`test -d "$NEWDIR"`
if( $RETURNCODE == 1 )
{
`maildirmake $NEWDIR`
`echo "INBOX$PREFIX$FOLDER" \
Post by Alessandro Vesely
$HOME/Maildir/courierimapsubscribed`
}

to $NEWDIR
}



Maybe additional quotation marks are required around "$MATCH[1|2]"?

d.
Sam Varshavchik
2017-03-30 00:46:47 UTC
Permalink
Post by l***@datenritter.de
Below is how I did it. Unfortunately the script stopped working a few
months ago writing hundreds of mails to (mbox?-)files with useful names
My debug version with some extra logging needs more input, so I'll send
it to this list... ["Yo dawg, I heard you like mail filters..."]
Anyway, it's meant to make everything maintenance free. When the first
mail from a list you subscribed to is received, a maildir
# Check X-BeenThere which every good list server sets.
# List-ID is okay, too.
{
# Pick local part and domain part, replace the dots with
# underscores.
### BUG: This leaves LPART and DPART empty. :( ###
LPART=`echo $MATCH1 | sed "s/\./_/g"`
If someone were to send an email with a carefully crafted header that reads:
"X-BeenThere: ; rm -rf $HOME" you'll have a lot of cleanup to do.
Post by l***@datenritter.de
Maybe additional quotation marks are required around "$MATCH[1|2]"?
Maybe scrap the whole thing. Use backticks to feed the email to a Perl
script that safely parses headers.

At the very least use an additional =~ operator to verify that matched
pattern is sane:

LOCALPART=$MATCH1

if ($LOCALPART =~ /^[A-Za-z0-9\.\-]+$/)


Then you can proceed and safely substitute $LOCALPART into an executed
command.
l***@datenritter.de
2017-03-30 10:45:03 UTC
Permalink
Post by Sam Varshavchik
Post by l***@datenritter.de
### BUG: This leaves LPART and DPART empty. :( ###
LPART=`echo $MATCH1 | sed "s/\./_/g"`
"X-BeenThere: ; rm -rf $HOME" you'll have a lot of cleanup to do.
Ouch. I had this bad feeling all the time... Fixed it. Thank you.


Still, at the moment, there should be nothing to worry about, as even:

BLABLA=`echo hallo >> /tmp/test.txt`

doesn't have any effect. (I.e. no file "test.txt" appears in /tmp.)

Filling variables with backtick-commands doesn't seem to work in my
setup. They are empty afterwards, while the very exact statements work
on the command line.
Post by Sam Varshavchik
Maybe scrap the whole thing. Use backticks to feed the email to a Perl
script that safely parses headers.
Okay... the beforementioned problems left aside, what is the advantage?
It's all about a simple regex. IMHO, the beauty of all solutions
discussed here is that they use maildropfiler and nothing else.
Post by Sam Varshavchik
At the very least use an additional =~ operator to verify that matched
LOCALPART=$MATCH1
if ($LOCALPART =~ /^[A-Za-z0-9\.\-]+$/)
"At the very least"? Does an external perl script have any security
advantage over this?

d.
Sam Varshavchik
2017-03-30 11:00:42 UTC
Permalink
Post by l***@datenritter.de
Post by Sam Varshavchik
Maybe scrap the whole thing. Use backticks to feed the email to a Perl
script that safely parses headers.
Okay... the beforementioned problems left aside, what is the advantage?
You can safely implement the same functionality in Perl itself, instead of
executing shell commands, which is difficult to do right without creating
security holes.
Post by l***@datenritter.de
It's all about a simple regex. IMHO, the beauty of all solutions
discussed here is that they use maildropfiler and nothing else.
maildropfilter is fine for simple mail filtering tasks. But it's not Perl.
Post by l***@datenritter.de
"At the very least"? Does an external perl script have any security
advantage over this?
See above. A Perl script can validate and do a lot more things, all without
shelling out to external commands.
l***@datenritter.de
2017-03-30 11:47:15 UTC
Permalink
Post by Sam Varshavchik
See above. A Perl script can validate and do a lot more things, all without
shelling out to external commands.
Convincing.

Still, to run that script I either need xfilter (which doesn't look like
the right choice to me here) or backtick-commands, which don't seem to
work for some strange reason. (Returncode for a simple echo-line is 1.)

Could there be anything wrong with my maildrops environment?
l***@datenritter.de
2017-03-30 20:23:49 UTC
Permalink
Post by l***@datenritter.de
Could there be anything wrong with my maildrops environment?
I just figured, the user maildrop is beeing executed as, has no shell...
Loading...