spf-discuss
[Top] [All Lists]

SPF aware userland mailfilter script

2005-01-04 07:04:46
Everyone, Hello, hope the holidays treated you all well! I've had this kicking around for a while and I recently updated it and realized I'd never posted it here so I'm doing so now. Its a "courier-maildrop" centric mailfilter script which facilitates per-user spam filtering ala 'maildrop' which affords a great deal of flexability as to how to behave based on the return values of single or multiple calls to various filtering agents etc.. etc.. Bear in mind, this was written with my setup in mind (qmail, sqwebmail, maildrop, and vpopmail (btw: if you have qmailadmin installed, your users have the ability to turn spam checking on and off using this method, without ever bothering you) however a few changes to binaries being called and perhaps it will do the trick for you. You can download the textual filter from here: http://6o4.ca/mailfilter.txt or provided it doesn't get all buggered in transit I'll paste it here:
#
# File:   /home/vpopmail/etc/mailfilter
# Author: James Couzens <jcouzens(_at_)codeshare(_dot_)ca>
# Date:   Feb 18, 2004
#
# Info:
#         'mailfilter' script for Courier-MTA's maildrop package.
#
# Desc:
#         Mailfilter to facilitate per-user spam checking with vPopMail.
# A user may place .mailfilter in their homedir (virtual ala vpopmail or
# otherwise) to supercede this"virtual" homedir to supercede calls to this
# script which is intended for global use, which facilitates individual per user # behaviour (such as automagically moving mail to specific folders as well as # perhaps making additional passes through various differing anti-spam filters).
#
# This script represents my interpretation of how per-user SpamAssassin
# functionality could be made available on a per user basis and is based on an
# original script I found through my good friend Google.
#
# Use:
# Add the following line to any users .qmail file, or any valid .qmail
# file for that matter.
#
# |/var/qmail/bin/preline /usr/local/bin/maildrop /home/vpopmail/etc/mailfilter
#
# Caveats:
# This script relies on the 'Courier-MTA' version of maildirmake which
# is present as part of the MailDrop package, but just in case you happen to
# change the 'maildirmake' binary path to use qmail's... change it back because
# this script calls maildirmake with the -f 'make a folder' option.
#
# Why when making the folders do I use the macro for the appropriate folder, but
# when referencing the same folder elsewhere in the file do I place a '.' in
# front?  This is because the '.' is added by maildirmake and you are not
# permitted to create directories that start with a '.'. Because a '.' is added
# when referencing the folder literally as a directory, it must be added.
#
# ---------------------------------------------------------------------------- --
# CHANGELOG
# ---------------------------------------------------------------------------- --
#
# 0.1 : February 18, 2004 - Initial Release
# 0.2 : November 21, 2004 - Major Update
#
# Added SPF header check for "Received-SPF: fail" headers which triggers
# a move to the user's ".Spam" folder identically to how the X-Spam header
# check works.
#
# For more information about SPF see http://spf.pobox.com.  For a C library
# with qmail, Sendmail, and Courier patches see http://libSPF.org
#
# 0.3 : January 1, 2005 - Added move to trash option
# 0.4 : January 3, 2005 - Added SPF supercede option
#
# ---------------------------------------------------------------------------- --

# ---------------------------------------------------------------------------- --
# Variables
# ---------------------------------------------------------------------------- --

VHOME="$PWD/Maildir"
USERNAME=`echo ${PWD##*/}`
USERHOST=`PWDTMP=${PWD%/*}; echo ${PWDTMP##*/}`
MAXMSG="262144" # ---------------------------------------------------------------------------- --
# Behaviour switch variables (0 - disable, 1 - enable)
# ---------------------------------------------------------------------------- --

# Enable checks for 'Recieved-SPF: fail'
ENABLE_SPF_CHECK=1
# If found move messages failing SPF checks to the Trash
TRASH_SPF=1
# If enabled (1), move messages to a special SPF Trash folder
SEPARATE_SPF_TRASH=1 # If enabled (1), checks matching as both Spam AND SPF, will be handled as if # they were only marked as SPF failures and moved appropriately. This is only
# of value if you wish to have SPF failures moved to their own special dir
# really.
SPF_SUPERCEDE=1
# If found move messages designated as Spam to the Trash
TRASH_SPAM=0
# ignore, delcared here for clarity
SPAM_DELIVERY=0 # ---------------------------------------------------------------------------- --
# Maildir subfolder name variables
# ---------------------------------------------------------------------------- --

TRASH_DIR="Trash"
SPAM_DIR="Spam"
SPF_TRASH_DIR="SPF-Trash"
# ignore, delcared here for clarity
TMP_DIR="$SPAM_DIR" # ---------------------------------------------------------------------------- --
# binary related variables (path and binary name)
# ---------------------------------------------------------------------------- --

SHELL="/bin/sh"
SPAMC="/usr/local/bin/spamc"
MAILDIRMAKE="/usr/local/bin/maildirmake"
VUSERINFO="/home/vpopmail/bin/vuserinfo"
DELIVERQUOTA="/usr/local/bin/deliverquota"
BOUNCESAYING="/var/qmail/bin/bouncesaying" # ---------------------------------------------------------------------------- --
# logging related variables
# ---------------------------------------------------------------------------- --

LOGGING=1
LOGFILE="/home/vpopmail/maildrop.log"

# ---------------------------------------------------------------------------- -- # If Logging is enabled, logfile path should be writable by the user vpopmail
# is running as (in most cases this will be vpopmail:vchkpw)
# ---------------------------------------------------------------------------- --

if ($LOGGING == 1)
{
logfile "$LOGFILE"
log $VMAILDIR
log $USERNAME
log $USERHOST
log $SPAMFOLDER
log "$VMAILDIR$SPAMFOLDER"
} # ---------------------------------------------------------------------------- --
# Perform 'message size' evaluation and if successful, pass off to 'spamc'
# ---------------------------------------------------------------------------- --

if ($SIZE < $MAXMSG)
{
# pass the message through SpamAssassin
exception {
  xfilter "$SPAMC -p 1025 -f -u $USERNAME(_at_)$USERHOST"
}
} # ---------------------------------------------------------------------------- --
# Look for 'maildirsize', if it doesn't exist, create it
# ---------------------------------------------------------------------------- --

`test -e $VHOME/maildirsize`
if ($RETURNCODE == 1)
{
`$VUSERINFO -q $USERNAME(_at_)$USERHOST > $VHOME/maildirsize`
}

# ---------------------------------------------------------------------------- --
# include user's personal mailfilter
# ---------------------------------------------------------------------------- --

`test -e $VHOME/.mailfilter`
if ($RETURNCODE == 1)
{
exception {
  include $VHOME/.mailfilter
}
}

# ---------------------------------------------------------------------------- --
# if spam folder doesn't exist, create
# ---------------------------------------------------------------------------- --

`test -d $VHOME/.$SPAM_DIR`
if ($RETURNCODE == 1)
{
`$MAILDIRMAKE -f $SPAM_DIR $VHOME`
}

# ---------------------------------------------------------------------------- -- # Parse headers (2821/2822 possibly entire message + body) for the SpamAssassin
# 'X-Spam-Flag' header to be set with a value of "YES".  You will need to
# configure SpamAssassin to tag headers with this option.  RTFM.
# ---------------------------------------------------------------------------- --

if (/^X-Spam-Flag: *YES/)
{
if ($TRASH_SPAM == 1)
{
  TMP_DIR="$TRASH_DIR"
}
else
{
  TMP_DIR=".$SPAM_DIR"
}

SPAM_DELIVERY=1
}

# ---------------------------------------------------------------------------- -- # Parse headers (2821/2822 possibly entire message + body) for a 'Received-SPF' # header to be set with a value of 'fail'. Don't be a tard and apply positive
# reactions to SPF values such as 'pass'.
# ---------------------------------------------------------------------------- --

if ($ENABLE_SPF_CHECK == 1)
{
if (/^Received-SPF: fail/)
{
  if ($TRASH_SPF == 1)
  {
    if ($SEPARATE_SPF_TRASH == 1)
    {
`test -d $VHOME/.$SPF_TRASH_DIR`
      if ($RETURNCODE == 1)
      {
        `$MAILDIRMAKE -f $SPF_TRASH_DIR $VHOME`
      }

      TMP_DIR=".$SPF_TRASH_DIR"
    }
    else
    {
      TMP_DIR=".$TRASH_DIR"
    }
  }
  else
  {
    TMP_DIR=".$SPAM_DIR"
}
#    exception {
#        xfilter "$DELIVERQUOTA -w 90 $VHOME/$TMP_DIR"
#    }
}
SPAM_DELIVERY=1
}

# ---------------------------------------------------------------------------- --
# Deliver the mail normally
# ---------------------------------------------------------------------------- --

if ($SPAM_DELIVERY == 0)
{
exception {
  xfilter "$DELIVERQUOTA -w 90 $VHOME"
}
}
else
{
if ($SPF_SUPERCEDE == 0)
{
  TMP_DIR="$SPF_TRASH_DIR"
}
exception {
  xfilter "$DELIVERQUOTA -w 90 $VHOME/$TMP_DIR"
}
}

# ---------------------------------------------------------------------------- --
# returncode 77 means Maildir over-quota, so bounce the mail
# ---------------------------------------------------------------------------- --

if ($RETURNCODE == 77)
{
to "|$BOUNCESAYING 'user is over quota'"
} # end of mailfilter Cheers, James
James Couzens,
Programmer
-----------------------------------------------------------------
http://libspf.org -- ANSI C Sender Policy Framework library
http://libsrs.org -- ANSI C Sender Rewriting Scheme library
-----------------------------------------------------------------


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