#!/bin/bash

# Localize these. The -G option does nothing before Postfix 2.3.
SENDMAIL="/usr/sbin/sendmail -G -i"
EGREP="/bin/egrep"
AWK="/usr/bin/awk"

SPAMD_USER=amavis

SPOOL_DIR="/var/spool/mail-filter"
VIRUS_DIR="/var/spool/mail-filter/virus"
SPAM_DIR="/var/spool/mail-filter/spam"
MSG1="$SPOOL_DIR/message.$$.input"
MSG3="$SPOOL_DIR/message.$$.output"

# Number of *'s in X-Spam-level header needed to sideline message:
# (Eg. Score of 5.5 = "*****" )
SPAMLIMIT=7


# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69

#!/bin/bash

state=init
sender=''
recipients=()
for arg ; do
    case $state in
    init)
        case $arg in
        -f) state=sender ;;
        --) state=recipient ;;
        -*) true ;;
        *) state=recipient ; recipients[${#recipients}]="$arg" ;;
        esac
        ;;
    sender)
        sender="$arg"
        state=init
        ;;
    recipient)
        recipients[${#recipients}]="$arg"
        ;;
    esac
done

# Start processing.
cd "$SPOOL_DIR" || { echo "$SPOOL_DIR does not exist" ; exit $EX_TEMPFAIL ; }

# Clean up when done or when aborting.
trap "rm -f $MSG1 $MSG3" 0 1 2 3 15

( echo "X-Envelope-From: $sender"
  for recipient in ${recipients[@]} ; do
    echo "X-Envelope-To:   $recipient"
  done
  cat) >"$MSG1" || { echo "Cannot save mail to file" ; exit $EX_TEMPFAIL ; }

# $AWK 'BEGIN{IGNORECASE=1}/^$/{exit 0}/^Message-ID:/{print $0;exit 0}' <"$MSG1"
#mid="$(grep -i -e '^Message-ID *:' "$MSG1"|head -1)"
mid="message-id=$( $AWK 'BEGIN{IGNORECASE=1}/^$/{exit 0}/^Message-ID:/{print $2;exit 0}' <"$MSG1" )"

#------------#
# Anti Virus #
#------------#

if /usr/local/bin/clamdscan --config-file=/etc/mail/clamd.conf "$MSG1" ; then
    # no virus
    logger -p mail.info -t mail-filter -- "NO VIRUS in $mid, file=<$MSG1>"
else
    # mid="$(grep -i -e '^Message-ID *:' "$MSG1"|head -1)"
    logger -p mail.info -t mail-filter -- "VIRUS in $mid, file=<$MSG1>"
    mv "$MSG1" "$VIRUS_DIR/$(date +%Y%m%d-%H%M%S)-$$"
    echo VIRUS
    exit $EX_UNAVAILABLE
fi

#------------#
# Anti Spam  #
#------------#

# Pipe message to spamc
(echo 'X-ClamAV: No Virus detected' ; cat "$MSG1")\
| /usr/bin/spamc -p 2527 -u $SPAMD_USER >"$MSG3"

# Are there more than $SPAMLIMIT stars in X-Spam-Level header? :
REGEXP="^X-Spam-Level[	 ]*:[	 ]*$(for (( i = $SPAMLIMIT ; i-- ; i==0 )) ; do echo -n '\*' ; done )"
if $AWK "BEGIN{IGNORECASE=1;res=0;} \
        /$REGEXP/{res=1;exit(res);} \
        /^\$/{exit(res);} \
        END{exit(res);}" < "$MSG3" ; then
    # no spam
    logger -p mail.info -t mail-filter -- "NO SPAM in $mid, file=<$MSG1>"
    $SENDMAIL "$@" <"$MSG3" ; status=$?
    if [ $status = 0 ] ; then
        logger -p mail.info -t mail-filter -- "Message $mid forwarded successfully, file=<$MSG1>"
     else
        logger -p mail.info -t mail-filter -- "Failed to forward message $mid, status=$status, file=<$MSG1>"
    fi
else
    echo Detected SPAM.
    logger -p mail.info -t mail-filter -- "SPAM in $mid, file=<$MSG1>"
  # Option 1: Move high scoring messages to sideline dir so
  # a human can look at them later:
    mv "$MSG3" "$SPAM_DIR/$(date +%Y%m%d-%H%M%S)-$$"
    status=$?

  # Option 2: Divert to an alternate e-mail address:
  # $SENDMAIL xyz@xxxx.xx <"$MSG3"
  # status=$?

  # Option 3: Delete the message
  # rm -f "$MSG3"
fi

# Postfix returns the exit status of the Postfix sendmail command.
exit $status
ViewGit