4882l2 Listing 2. scanmail Script #!/bin/sh ### Variable declarations---------------------- tstamp=`date` export date=`date '+%m%d%Y'` export METAMAIL_TMPDIR="." mailto="admin@domain.com" quarantine="/var/spool/smtpd/quarantine" outgoing="/var/spool/smtpd/outgoing" matchesbad="/var/spool/smtpd/etc/matches.bad" matchesdoc="/var/spool/smtpd/etc/matches.doc" export etc="/var/spool/smtpd/etc" outqthresh=25 maxsize=35000000 # Maximum email size to allow through export email_total=`cat $etc/email-log.$date` export virus_total=`cat $etc/virus-log.$date` ### See if there's any mail to scan------------ pushd . > /dev/null cd /var/spool/smtpd/incoming echo "The time is $tstamp" count=`ls --ignore=smtpd*_d -1 | wc -l` # See how many email there are export email_total=$((email_total+count)) # Increment the total daily email counter if [ $count -eq 0 ]; then # Only continue if there is mail to scan echo "" echo "No e-mails to scan." echo "" echo "There have been $email_total e-mails processed today." echo "There have been $virus_total viruses found today." echo "" exit 0 fi emails=(`ls --ignore=smtpd*_d *`) # Load email list into an array echo "Scanning ${emails[*]} for viruses..." echo "" max=$count # Set the max amount for our while loop count=0 while [ $count -lt $max ] # The main loop. One iteration per email do echo "+------------------------------------------------------------------+" echo "Scanning ${emails[$count]} now..." echo "+------------------------------------------------------------------+" echo "" ### Check and make sure email isn't too big---- filesize=`ls -lap ${emails[$count]} | awk '{print $5}'` # Check filesize echo "This email is $filesize bytes long" echo "The maximum allowable email size is $maxsize bytes." if [ $filesize -gt $maxsize ]; then echo "File ${emails[$count]} exceeds the email size limit of $maxsize bytes." echo "Moving it to $quarantine." mv ${emails[$count]} $quarantine mail -s "OVERSIZED E-MAIL ALERT" $mailto <<endofinput0 File ${emails[$count]} exceeded the maximum allowable email size of $maxsize bytes and has been quarantined in $quarantine for your inspection. The time is $tstamp. endofinput0 break # If email is too large, break and don't scan it fi ### Load up email specific information---- respondto=`/bin/awk '/^FROM.*/ {print $2}' ${emails[$count]}` # Get sender address goingto=`/bin/awk '/^RCPT.*/ {print $2}' ${emails[$count]}` # Get recipient address attachment=`/bin/awk '/filename=.*/ {print $1}' ${emails[$count]}` # Get attachment name ### First scanning pass---- echo "First pass scans for obvious bad stuff like script attachments..." echo "" if infected=`grep -slf $matchesbad ${emails[$count]}`; then results=`grep -nsf $matchesbad $infected` mv -v $infected $quarantine echo "Found a virus in file $infected and moved it to $quarantine." echo "" mail -s "VIRUS INFECTED E-MAIL ALERT" $mailto <<endofinput At $tstamp, the e-mail "$infected" going to <$goingto> from <$respondto> was quarantined in "$quarantine" due to a suspicious attachment named $attachment. The trigger was $results. endofinput export virus_total=$((virus_total+1)) # Increment our daily virus counter break else echo "Okay." echo "There is nothing obviously wrong with $infected " echo "" fi ### Second scanning pass---- echo "Second pass scans for attachments with embedded viruses like macros..." echo "" if infected=`grep -slf $matchesdoc ${emails[$count]}`; then results=`grep -nsf $matchesdoc $infected` echo "Found an attached document. Decoding and scanning it now." mkdir $infected"_d" # Make a temp directory for the attachment mv $infected $infected"_d" # Move the email into it cd $infected"_d" /usr/bin/metamail -w -r -q $infected # Decode the attachment if scanresults=`/usr/local/bin/uvscan --noboot --secure --norename -v --summary .`; then echo "" mv $infected .. cd .. rm -rf $infected"_d" mv -v ${emails[$count]} $outgoing echo "Okay. No viruses found in $attachment." echo "" else echo "" cd .. mv $infected"_d" $quarantine echo "Found an infected file named $infected and moved it to $quarantine." echo "" mail -s "VIRUS INFECTED E-MAIL ALERT" $mailto <<endofinput2 At $tstamp, the e-mail "$infected" going to <$goingto> from <$respondto> was quarantined in "$quarantine" because the attached document named $attachment had a virus. The results were: $scanresults. An alert message was sent to <$respondto> letting them know about the virus. endofinput2 mail -s "VIRUS INFECTED E-MAIL ALERT" $respondto <<endofinput3 At $tstamp, an e-mail sent by $respondto to $goingto was found to contain a virus and was quarantined. You should check your system with antivirus software to make sure it is clean. The virus was found in $attachment. This e-mail was automatically generated. Please do not reply to it directly. Send all responses to ($mailto). Best Regards, System Administrator($mailto) endofinput3 export virus_total=$((virus_total+1)) fi else mv -v ${emails[$count]} $outgoing echo "No attached documents to scan." echo "" fi echo "+------------------------------------------------------------------+" echo "Finished scanning ${emails[$count]}." echo "+------------------------------------------------------------------+" echo "" count=$((count+1)) done /bin/chown uucp.uucp $outgoing/* # Make sure permissions and owner are correct /bin/chmod 750 $outgoing/* # so that smtpfwdd won't stall echo "Finished." echo "" popd > /dev/null # Go back to where we came from ### Give a brief summary for command line use---- echo "There have been $email_total e-mails processed today." echo "There have been $virus_total viruses found today." ### Check and make sure mail isn't stacking up in the outqueue---- outqcount=`ls -1 $outgoing/* | wc -l` echo "There are $outqcount e-mails in the outgoing queue." echo "" if [ $outqcount -gt $outqthresh ]; then mail -s "MAIL BACKING UP IN OUT-QUEUE" $mailto <<endofinput4 There are $outqcount e-mails waiting to be delivered in $outgoing. You may need to check and make sure there isn't a problem with the forwarding agent. endofinput4 fi ### Update the daily email and virus log files---- echo $email_total > $etc/email-log.$date echo $virus_total > $etc/virus-log.$date ### Flush out the local sendmail queue---- /usr/sbin/sendmail -q exit 0