#!/bin/sh # Post.Office Spam Sorting Solution # Copyright by Joe Savelberg -- jmsc@euregio.net # version 0.21 -- 2004-11-29 @ 16:00 GMT # Use at own risk. Moved messages are deleted from SpamFolder # # Install this script in your root home directory # chmod 755 to make it executable # chown root:wheel to allow it to read/write files # install a cron job to run this script every minute # example for /etc/crontab: # * */1 * * * root ~root/spamsort.sh > /dev/null 2>&1 # Show your support by donating something through PayPal # https://www.paypal.com/xclick/business=jmsc%40euregio.net&item_name=Post.Office+Tools&cn=Comments+or+Suggestions&tax=0¤cy_code=USD # General Options # sortspam=[yes|no] -- enable or disable the script # usespamassassin=[yes|no] -- instead of rewriting just the subject, you can process the message by SpamAssassin again to rewrite headers # deletefiles=[yes|no] -- delete original files in spamchecker directory after copying them to the user directory # debugon=[yes|no] -- writes more information to the log file to see what's going on. sortspam="yes" usespamassassin="yes" deletefiles="yes" debugon="yes" # Location and name of this script spamscript="/var/root/spamsortnew.sh" # Setting up the correct paths to logs and temporary files # Normally, you don't have to change these spamsortlog="/var/log/spamsort.log" tmpmessage="/tmp/satmp.txt" # Location of your Post.Office program directory folder (auto-detect): # programdir="/usr/local/post.office" programdir=`grep "ProgramDir" /etc/post.office.conf | cut -d "=" -f 2` # Filtering Options # spamaddress is the e-mail address of the local mailbox where you receive spam messages from SpamAssassin # if you don't copy spam messages to a local mailbox then this script won't work. spamaddress="spamchecker@domain.com" # List users that you'd like to include or exclude in the filtering. # You can use extended regular expressions. includeusers="jmsc@euregio.net|postmaster@domain.com|localuser1|user2" excludeusers="user3|info@domain.com" # Set the folder name where you'd like to sort the files into. # If your users access their mail by POP3 then you should set this to "/in" # If your users access their mail by IMAP4 then you can set this to anything # you'd like -- e.g. to automatically put the spam into a Junk/Spam folder # then you should set it to "/junk" or "/spam" junkfolder="/INBOX.Junk" cleanfolder="/in" # Location of SpamAssassin -- only necessary when usespammassin="yes" # Spamc is the client half of the spamc/spamd pair. It should be used in place of spamassassin in scripts to process mail. # It will read the mail from STDIN, and spool it to its connection to spamd, then read the result back and print it to STDOUT. # Spamc has extremely low overhead in loading, so it should be much faster to load than the whole spamassassin program. spamc="/usr/bin/spamc" # AutoRemoveSpam if score is over a certain threshold which is a multiple of the "required_hits" variable # if you set the required_hits in SpamAssassin to 5.0, and the maximum score multiplier to 3 # then all spam with a score higher than 5.0 x 3 = 15 will be removed # spamquarantine can be any directory on your server. Leave the variable empty if you don't want to put the spam into the quarantine # when you test this script, you might want to move spam to the quarantine when it's autoremoved to make sure everything works as # expected. # autoremoverules contains a grep pattern of SpamAssassin rules that you always want to remove (such as RCVD_IN_CBL|RCVD_IN_SBL) # This can be useful if you want to delete any spam that is matched by certain RBL's (SpamHaus, SpamCop, etc.) # Leave this variable empty if you don't want to remove messages that contain any speficied SpamAssasin rules. autoremovespam="yes" maxscoremultiplier="3" spamquarantine="/spamquarantine" autoremoverules="RCVD_IN_CBL|RCVD_IN_SBL" # ################################################################################ # # The real script starts here. Normally there is nothing to change below this line # # ################################################################################ echo "`date` [Start] spamsort" >> $spamsortlog # Setting start time of the execution startdate=`date "+%m%d%H%M.00"` if [ "$sortspam" != "yes" ] ; then echo "`date` [End] spamsort - set spamsort=yes to run the script" >> $spamsortlog exit fi spamcheck=`${programdir}/cmdutils/getuid ${spamaddress}` spamcheck=`${programdir}/cmdutils/getpopmbox ${spamcheck}` spamcheck="${spamcheck}/in/" #echo $spamcheck # Checking if the spamsort script is already running to prevent too many simultaneous executions grepproc=$(ps -ax | grep "sh $spamscript" | grep -v "grep sh $spamscript" | wc -l) if [ $grepproc -gt 2 ] ; then echo $grepproc echo "`date` [End] too many spamsort processes: ${grepproc}" >> $spamsortlog exit fi # Now getting all local mailboxes # only users with a valid local mailbox are added accountinfo=`${programdir}/cmdutils/listacct -s ":" -i POP-Address,SMTP-Address,Local-Delivery | grep ":Mailbox"` # Applying the include and exclude filters to the list # of available local accounts (exclude users egrep -i -v) if [ -n "${includeusers}" ] ; then accountinfo=`echo "${accountinfo}" | tr " " "\n" | egrep -i "${includeusers}"` if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] Step 1 including accounts ${includeusers}" >> $spamsortlog fi fi if [ -n "${excludeusers}" ] ; then accountinfo=`echo "${accountinfo}" | tr " " "\n" | egrep -i -v "${excludeusers}"` if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] Step 2 excluding accounts ${excludeusers}" >> $spamsortlog fi fi if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] List of Accounts that will be used:" echo "`date` [Debug] ${accountinfo}" echo "`date` [Debug] List of Accounts that will be used:" >> $spamsortlog echo "`date` [Debug] ${accountinfo}" >> $spamsortlog fi deletelist="" for i in ${accountinfo} do uid=`echo ${i} | cut -d ":" -f 1` uiddir=`${programdir}/cmdutils/getuid ${uid}` uiddir=`${programdir}/cmdutils/getpopmbox ${uiddir}` #currentdate=`date +%Y%m%d` #userjunkfolder="${uiddir}${junkfolder}-${currentdate}" userjunkfolder="${uiddir}${junkfolder}" usercleanfolder="${uiddir}${cleanfolder}" if [ ! -d ${userjunkfolder} ] ; then mkdir -p ${userjunkfolder} chown "mta:mail" ${userjunkfolder} chmod 770 ${userjunkfolder} echo -n "" > "${uiddir}/.mailboxlist" chown "mta:mail" "${uiddir}/.mailboxlist" chmod 660 "${uiddir}/.mailboxlist" echo -n "" > ${userjunkfolder}/__cache__ chown "mta:mail" ${userjunkfolder}/__cache__ chmod 600 ${userjunkfolder}/__cache__ echo -n "" > ${userjunkfolder}/__size__ chown "mta:mail" ${userjunkfolder}/__size__ chmod 600 ${userjunkfolder}/__size__ fi if [ "$debugon" = "yes" ] ; then echo "" echo "`date` [Debug] Processing: ${uiddir}" echo "`date` [Debug] Processing: ${uiddir}" >> $spamsortlog fi smtpid=`echo ${i} | cut -d ":" -f 2| tr "," "|"` messages=`egrep -l -i -r "for <${smtpid}>;" ${spamcheck}` for x in ${messages} do if [ "$debugon" = "yes" ] ; then echo "" echo "`date` [Debug] Working on: ${x}" echo "`date` [Debug] Working on: ${x}" >> $spamsortlog fi if [ "$usespamassassin" != "yes" ] ; then tmp=`grep "Subject: \[*** Spam ***\] " ${x}` if [ -z "${tmp}" ] ; then mytmp=`sed 's/Subject: /Subject: [*** Spam ***] /g' ${x}` echo -n "${mytmp}" > ${x} if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] Copying ${x} to ${userjunkfolder}/" echo "`date` [Debug] Copying ${x} to ${userjunkfolder}/" >> $spamsortlog fi cp -p ${x} ${userjunkfolder}/ fi else if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] Starting SpamAssassin for ${x}" echo "`date` [Debug] Starting SpamAssassin for ${x}" >> $spamsortlog fi $spamc -u ${uid} < ${x} > ${tmpmessage} cat ${tmpmessage} | awk '{sub(/\r$/,"");print}' | awk '{sub(/$/,"\r");print}' > ${x} if [ `grep -c "X-Spam-Flag: YES" ${x}` -eq 1 ] ; then # -- new auto remove feature start -- if [ "$autoremovespam" = "yes" ] ; then sascores=`grep "X-Spam-Status:" ${x} | cut -d " " -f "3 4"` if [ -n "$sascores" ] ; then sahits=`echo $sascores | cut -d " " -f 1 | cut -d "=" -f 2 | tr -d "."` sarequired=`echo $sascores | cut -d " " -f 2 | cut -d "=" -f 2 | tr -d "."` let samax="sarequired*maxscoremultiplier" if [ -n "$autoremoverules" ] ; then containsrules=`egrep -i "${autoremoverules}" ${x}` if [ -n "$containsrules" ] ; then let sahits="1000" fi fi if [ "$sahits" -gt "$samax" ] ; then if [ -z "$spamquarantine" ] ; then if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] AutoRemoving ${x} (${sahits}>${samax})" echo "`date` [Debug] AutoRemoving ${x} (${sahits}>${samax})" >> $spamsortlog fi rm "${x}" else if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] Copying ${x} to ${spamquarantine}/ (${sahits}>${samax})" echo "`date` [Debug] Copying ${x} to ${spamquarantine}/ (${sahits}>${samax})" >> $spamsortlog fi cp -p ${x} ${spamquarantine}/ fi else if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] Copying ${x} to ${userjunkfolder}/" echo "`date` [Debug] Copying ${x} to ${userjunkfolder}/" >> $spamsortlog fi cp -p ${x} ${userjunkfolder}/ fi fi else if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] Copying ${x} to ${userjunkfolder}/" echo "`date` [Debug] Copying ${x} to ${userjunkfolder}/" >> $spamsortlog fi cp -p ${x} ${userjunkfolder}/ fi # -- new auto remove feature end -- else if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] Copying ${x} to ${usercleanfolder}/" echo "`date` [Debug] Copying ${x} to ${usercleanfolder}/" >> $spamsortlog fi cp -p ${x} ${usercleanfolder}/ fi rm ${tmpmessage} fi done deletelist="${deletelist} ${messages}" done if [ "$deletefiles" = "yes" ] ; then if [ "$debugon" = "yes" ] ; then echo "`date` [Debug] Deleting message files from $spamcheck" echo "`date` [Debug] Deleting message files from $spamcheck" >> $spamsortlog fi for q in ${deletelist} do if [ -f "${q}" ] ; then echo "Deleting ${q}" rm ${q} fi done fi echo "`date` [End] spamsort - started at $startdate" >> $spamsortlog #end