#!/bin/bash # A wrapper for SpamAssassin suitable for calling from a dot-qmail file # Version: 0.1 # # Usage: # |ifspamloop mail-address spam-address virus-address spamc-user # # spamc-user is the user ID passed to spamc. It controls selection of # the user's black/white lists, bayes rules, etc. Not used if you # don't use the -u option to spamc. # # mail-address is an address that is sent to THIS mailbox. Emails that # are scanned by Spamassassin will be forwarded to this address to be # reprocessed. # # spam-address is an email address that you want all spam forwarded to. # It may be the same as mail-address. # # virus-address is an email address that you want all virus-infected # emails to be forwarded to. It may be the same as email-address. # # Mail that has already been scanned by Spamasssassin, or is to large # for Spamassassin to deal with, will be passed to the rest of the # .qmail file for further processing. # # This script is based on James Grinter's ifspamh script. # www.gbnet.net/~jrg/qmail/ifspamh/ # # I want to have the scanned and annotated email available to the # entire .qmail file. I also want emails that contan viruses to be # forwarded to a quarantine box. In my installation, the non-virus # spams are left in the box for the MUA to filter. The scanned # emails my also be forwarded to other addresses, some of which are # on my server. I want an email to be presented to Spamassassin # only once, no matter how many boxes it goes to. # # A typical .qmail file might look like this: # |ifspamloop mark@example.com mark@example.com sharps@example.com example.com # ./Maildir/ # &alterego@example.com # # You should set Spamassassin to insert a custom header to indicate # that the email has been scanned by YOUR server. I use the following # in my configuration: # add_header all ScannedBy DataHelper, Inc. # # For more details on SpamAssassin, how to set preferences, whitelists, # etc, see 'Mail::SpamAssassin::Conf(3)' - and put the preferences # in ~/.spamassassin/user_prefs # # For more detail on .qmail files, see dot-qmail(5) and qmail-command(8) # # Author of ifspamh: James R Grinter # jrg (at) watching.org 24/03/2002 # Last Update: 28/02/2003 # URL: http://www.gbnet.net/~jrg/qmail/ifspamh/ # # Requires: spamc, spamd, qmail and 822field (from DJB's mess822 package) # to be installed and working. # # Also requires your /bin/sh to have a "printf" available # (most do, if yours doesn't then consider fetching ksh-93 # from http://www.research.att.com/sw/download/, or using bash) # # N.B. # If you are using vpopmail, make sure you are using at least # version 5.3.6. # # If you want to run SpamAssassin globally for every email, see the # qmail-spamc/qmail-scanner approach in the qmail/ subdirectory of the # SpamAssassin distribution # # Author of ifspamloop: Mark Willcox # willcox (at) datahelper.com # Last Update: 02/27/2005 # http://datahelper.com/download/ifspamloop/ ###### Change these values! ###### # The custom header and value that identify your spamassassin CUSTOMHEAD=ScannedBy CUSTOMVALUE="Your Message Here" # spamc - client location - followed by "-u " if you specify a user. SPAMC="/usr/bin/spamc -u" # qmail's forward program location FORWARDBIN=/var/qmail/bin/forward # mess822 822field location M822FIELD=/usr/local/bin/822field ################################################################# # nothing beyond here should require adjustment ################################################################# LOOPADDR="$1" SPAMADDR="$2" VIRUSADDR="$3" USERID="$4" if [ -z "$VIRUSADDR" ]; then echo "Usage: ifspamloop this-box's-address spam-address virus-address [userID] " exit 111 fi output="`head -c250100`" # spamc will not process a "large email" msize=`echo "$output" | wc -c` # there's also a sizelimit with some shells that triggers around the 512kB mark # with an external printf and arguments size so we stop at this point if [ $msize -gt 250000 ]; then # probably deemed too large anyway .. let it through exit 0 fi # Have we seen this email before? Is it already scanned? flagvalue=`printf "%s\n" "$output" | $M822FIELD X-Spam-$CUSTOMHEAD` flgvalue=`echo $flagvalue | grep "$CUSTOMVALUE"` if [ -n "$flagvalue" ]; then # Regardless of this email's spammness or infectedness, let it be processed by the # rest of the .qmail file. If there is an email address to send spam and viruses # to, it's already been sent there. exit 0 fi output="`echo "$output" | $SPAMC $USERID`" exitcode=$? # We've gotten this far and called spamc. We will NOT exit with 0 below here. # We will either forward the email to one of the supplied addresses or exit # with 111 to try it again. # Virus found? flagvalue=`printf "%s\n" "$output" | $M822FIELD X-Spam-Virus | sed -e 's/^ //' -e 's/ .*//'` echo "$flagvalue" > /tmp/ifspamloop if [ "$flagvalue" = "Yes" ]; then export DTLINE= printf "%s\n" "$output" | $FORWARDBIN $VIRUSADDR if [ $? -eq 0 ]; then # so qmail will not do any further deliveries in .qmail file exit 99 fi # problem calling inject - temp failure exit 111 fi # Spam found? flagvalue=`printf "%s\n" "$output" | $M822FIELD X-Spam-Flag | sed 's/^ //'` if [ "$flagvalue" = "YES" ]; then export DTLINE= printf "%s\n" "$output" | $FORWARDBIN $SPAMADDR if [ $? -eq 0 ]; then # so qmail will not do any further deliveries in .qmail file exit 99 fi # problem calling inject - temp failure exit 111 fi # Neither spam nor virus. Sen it to the address that's supposed to # deliver it back here. export DTLINE= printf "%s\n" "$output" | $FORWARDBIN $LOOPADDR if [ $? -eq 0 ]; then # so qmail will not do any further deliveries in .qmail file exit 99 fi # problem calling inject - temp failure exit 111