procmail
[Top] [All Lists]

Re: System-wide anti-spam .rc file

1997-08-21 15:48:16
Dan Smith wrote (his commenting octothorpes can double as citations),

# This file is designed to be used from the /etc/aliases file to
# filter mail destined for some other address.  Typical usages would
# be as follows
#   user: "| /path/to/procmail FILE=user FLAG=subject /this/file.rc"
#   fwd: "| /path/to/procmail MAIL=fwd(_at_)host FLAG=discard /this/file.rc"
#   prog: "| /path/to/procmail PIPE=/some/prog FLAG=header /this/file.rc"

One complication there is that the pipes will run as user "nobody" and the
original envelope recipient will be lost (that may not be a problem in the
"fwd" case, except that the downstream recipient may get 
nobody(_at_)your(_dot_)site
as the From_ address).  If you keep the original user with procmail's -d
option, procmail will disregard any command-line variable assignments.

Of course, I don't know whether the original recipient is significant to
/some/prog; perhaps that can run as "nobody" as well.  After all, it is
handling mail for prog(_at_)your(_dot_)site, which is not a username.

And I may be totally wrong about that if /path/to/procmail is setuid
root, in which case the pipes may run with ruid=nobody and euid=owner of
/this/file.rc?  I guess that's OS-dependent.  Oh bother.  Well, anyway,
back to Dan:

# The first option is [FILE|MAIL|PIPE], this determines what should be
# done with messages that aren't spam (or flaged as SPAM).  The FLAG
# variable determines what would be done with detected SPAM
#   subject - modify the Subject line to indicate SPAM was found
#   discard - send the message to /dev/null
#   header - add an X-This-Is-Spam: header to the message

You could use the -a option to pass "subject", "discard", or "header"
rather than the FLAG variable; that will survive the -d option.

This looks better to me as a way to set variables in the aliases file.  Note
that the possibility that /some/prog will have options or arguments means we
have to reverse the order of the parameters from Dan's original plan:

   user: "| /path/to/procmail -m /this/file.rc subject logname"
   fwd: "| /path/to/procmail -m /this/file.rc discard fwd(_at_)host"
   prog: "| /path/to/procmail -m /this/file.rc header /some/prog args"

Then /this/file.rc could have code like this:

IF_SPAM=$1 # subject, discard, or header
IF_KOSHER=$2 # local logname, remote address, or program without args

:0 # if it's a program, lose $1 so that "$@" will be what we need
* IF_KOSHER ?? ^^/
{ SHIFT=1 }

... and later, if spam detected

MATCH # unset it to start
:0h
* IF_SPAM ?? discard
/dev/null

:0Efwh
* IF_SPAM ?? header
| formail -A "X-This-Is-Spam: yessiree, Bob!"

:0Efwh # if set to "subject" make it work if there is a subject or not
* IF_SPAM ?? subject
* 1^0 ^Subject\/:.*
* 1^0
| formail -I"Subject: SPAM!$MATCH"

:0Efwh # otherwise
| formail -A "X-Spam-Handling: undefined"

... but if not detected as spam, we rely on $IF_KOSHER

:0 # remote address
* IF_KOSHER ?? [(_at_)!]
! $IF_KOSHER

:0E # local logname
* IF_KOSHER ?? ^^[^/]+^^
| /path/to/setuid_procmail -d $IF_KOSHER
# Conditions on the above may be made more stringent to be sure of matching
# acceptable patterns for local lognames.  For example,
# * IF_KOSHER ?? ^^[a-z]\
#   [0-9a-z][0-9a-z]?[0-9a-z]?[0-9a-z]?[0-9a-z]?[0-9a-z]?[0-9a-z]?^^
# or if you don't mind the fork,
# * ? grep ^$IF_KOSHER: /etc/passwd
# In such a case, you could even put the local logname test first, before
# the handling of remote addresses.

:0E # W perhaps? # to a program
* IF_KOSHER ?? ^^/
| "$@"

:0Efwh # IF_KOSHER is null or unset or improper.
| formail -A"X-Diagnostic: no handling specified for legitimate mail" 
 :0A # local lockfile if saved for, rather than forwarded to, the postmaster
 ! postmaster # or a folder for the postmaster writable by this process

<Prev in Thread] Current Thread [Next in Thread>