#!/bin/bash set -euo pipefail # Clean up when done or when aborting. trap "rm -f in.$$" 0 1 2 3 15 INSPECT_DIR=/var/spool/filter SENDMAIL=/usr/sbin/sendmail LOGFILE=/var/log/disclaimer.log OUTSTATFOLDER=/var/spool/filter/out.stats mkdir -p $OUTSTATFOLDER INSTATFOLDER=/var/spool/filter/in.stats mkdir -p $INSTATFOLDER DISCLAIMER_ADDRESSES=/etc/postfix/disclaimer_addressess TEXT_DISCLAIMER=/etc/postfix/text_disclaimer.txt HTML_DISCLAIMER_FILE=/etc/postfix/html_disclaimer.htm # Exit codes from EX_TEMPFAIL=75 EX_UNAVAILABLE=69 DATE=$(date +%s) APP=$(basename $0 .sh) function Message() { HIDE=$2 CDATE=$(date +%s) MSG="[$$] $CDATE $1" if [[ "$HIDE" != "true" ]]; then echo "$MSG" fi /usr/bin/env logger -t "$APP" "$MSG" echo "$MSG" >> $LOGFILE #logger -t disclaimer.sh "$MSG" } #GetRecordID $FROM mail_addresses mail_address mail function GetRecordID() { TEXT="$1" if [[ "$TEXT" == "" ]]; then echo NULL else TABLE="$2" FIELD="$3" DATABASE="$4" if [[ "$DATABASE" == "" ]]; then Message "No database indicated." true else ACTION="$5" QUERY="SELECT id FROM $TABLE WHERE $FIELD='$TEXT';" RESULT=$(echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf $DATABASE) RESULTID=$(echo "$RESULT" | grep -v id) error_code=$? if [[ "$error_code" != "0" ]]; then Message "Error getting $FIELD id for $TEXT from database with query '$QUERY'. Result: $RESULT" true else if [[ "$RESULTID" == "" ]]; then QUERY="INSERT INTO $TABLE (id, $FIELD) VALUES (NULL, '$TEXT');" RESULT=$(echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf $DATABASE) error_code=$? if [[ "$error_code" != "0" ]]; then Message "Error $error_code adding $FIELD to database with query '$QUERY'. Result: $RESULT" true else QUERY="SELECT id FROM $TABLE WHERE $FIELD='$FROM';" RESULT=$(echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf $DATABASE) RESULTID=$(echo "$RESULT" | grep -v id) error_code=$? if [[ "$error_code" != "0" ]]; then Message "Error $error_code obtaining $FIELD id with query '$QUERY'. Result: $RESULT" true fi fi fi fi echo $RESULTID fi fi } function FromID() { FROM=$1 SENDER_ID=$(GetRecordID $FROM senders sender mailview "Getting Id for From $1") echo $SENDER_ID } function RecipientID() { RECIPIENT=$1 RECIPIENT_ID=$(GetRecordID $FROM recipients recipient mailview "Getting Id for To $1") echo $RECIPIENT_ID } # Start processing. Message "Processing message 'in.$$'" cd $INSPECT_DIR error_code=$? if [[ "$error_code" != "0" ]]; then Message "Error $error_code changing to directory '$INSPECT_DIR'" exit $EX_TEMPFAIL; fi cat >in.$$ error_code=$? if [[ "$error_code" != "0" ]]; then Message "Cannot save mail to file" exit $EX_TEMPFAIL fi #Save last message cp in.$$ /var/spool/filter/last_message.eml -rfp #Save copy of the messages. DANGEROUS!! Will consumpt disk space mkdir -p /var/spool/filter/)date +%Y%m%d)/ cp in.$$ /var/spool/filter/)date +%Y%m%d)/)date +%Y%m%d%H%M%S%N).eml -rfp # obtain header FROMLONG=$(grep -m 1 "From:" in.$$ | sed "s/From://" -) FROM=$(echo $FROMLONG | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) SENDER_ID=$(FromID $FROM) Message "From: $FROMLONG (Id: $SENDER_ID)" MESSAGEID=$(grep -m 1 -i "^Message-id:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "Message ID: $MESSAGEID" SUBJECT=$(grep -m 1 "Subject:" in.$$ | sed "s/Subject://" - | sed "s/'/\'/g" - ) Message "Subject: $SUBJECT" RECIPIENT=$(grep -m 1 "^To:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) RECIPIENT_ID=$(RecipientID $RECIPIENT) Message "TO: $RECIPIENT" CCRECIPIENT=$(grep -m 1 "Cc:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "CC: $CCRECIPIENT" BCRECIPIENT=$(grep -m 1 "Bcc:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "CCO: $BCRECIPIENT" DELIVEREDTO=$(grep -m 1 "Delivered-To:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "Delivered to: $DELIVEREDTO" RETURNPATH=$(grep -m 1 "Return-Path:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "Return path: $RETURNPATH" REPLYTO=$(grep -m 1 "Reply-To:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "Reply to: $REPLYTO" XORIGINALSENDER=$(grep -m 1 "X-Original-Sender:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "Reply to: $XORIGINALSENDER" SENDER=$(grep -m 1 "Sender:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "Reply to: $SENDER" XFORWARDEDTO=$(grep -m 1 "X-Forwarded-To:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "Reply to: $XFORWARDEDTO" XFORWARDEDFOR=$(grep -m 1 "X-Forwarded-For:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "Reply to: $XFORWARDEDFOR" XBEENTHERE=$(grep -m 1 "X-BeenThere:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - ) Message "Reply to: $XBEENTHERE" if [[ $(grep -wi ^${FROM}$ ${DISCLAIMER_ADDRESSES}) ]]; then DIRECTION=0 CURHOUR=$(date +%Y%m%d%H) if [[ -e $INSTATFOLDER/$CURHOUR.stats ]]; then CURHOURSTAT=$(cat $INSTATFOLDER/$CURHOUR.stats) else CURHOURSTAT=0 fi CURHOURSTAT=$(expr $CURHOURSTAT + 1) echo $CURHOURSTAT > $INSTATFOLDER/$CURHOUR.stats Message "Sender '$FROMLONG' ($FROM) is in disclaimer addresses file" QUERY="INSERT INTO messages (id, sender_id, subject, date, messageid) VALUES (NULL, '$SENDER_ID', '$SUBJECT', '$DATE', '$MESSAGEID');" echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf mailview error_code=$? if [[ "$error_code" != "0" ]]; then Message "Error $error_code while adding message to database with query '$QUERY'" fi QUERY="SELECT id FROM messages WHERE sender_id='$SENDER_ID' AND subject='$SUBJECT' AND date='$DATE';" MSG_ID=$(echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf mailview | grep -v id) error_code=$? if [[ "$error_code" != "0" ]]; then Message "Error $error_code while obtaining message id with query '$QUERY'" fi TMP_HTML_DISCLAIMER_FILE=$(/bin/mktemp /tmp/disclaimer.XXXXX) if [[ -r /etc/postfix/$FROM.disclaimer.html ]]; then HTML_DISCLAIMER=/etc/postfix/$FROM.disclaimer.html fi sed "s/id=MSGID/id=$DB_MSG_ID/g" $HTML_DISCLAIMER_FILE > $TMP_HTML_DISCLAIMER_FILE TMP_HTML_DISCLAIMER_FILE_BIS=$(/bin/mktemp /tmp/disclaimer.XXXXX) sed "s/SENDERID/$SENDER_ID/g" $TMP_HTML_DISCLAIMER_FILE > $TMP_HTML_DISCLAIMER_FILE_BIS sed "s/RECIPIENTID/$RECIPIENT_ID/g" $TMP_HTML_DISCLAIMER_FILE_BIS > $TMP_HTML_DISCLAIMER_FILE Message "Disclaimer HTML at '$TMP_HTML_DISCLAIMER_FILE'" if [[ -r /etc/postfix/$FROM.disclaimer.txt ]]; then TEXT_DISCLAIMER=/etc/postfix/$FROM.disclaimer.txt fi ALTERMIMERESULT=$(/usr/bin/altermime --input=in.$$ --log-syslog --log-stdout --disclaimer=$TEXT_DISCLAIMER --disclaimer-html=$TMP_HTML_DISCLAIMER_FILE --xheader="X-MTA: mudito.susurrando.com") Message "altermime result: $ALTERMIMERESULT" error_code=$? if [[ "$error_code" != "0" ]]; then Message "Error $error_code Message content rejected." exit $EX_UNAVAILABLE; fi else DIRECTION=1 Message "Sender '$FROMLONG' ($FROM) is NOT in disclaimer addresses file" CURHOUR=$(date +%Y%m%d%H) if [[ -e $OUTSTATFOLDER/$CURHOUR.stats ]]; then CURHOURSTAT=$(cat $OUTSTATFOLDER/$CURHOUR.stats) else CURHOURSTAT=0 fi CURHOURSTAT=$(expr $CURHOURSTAT + 1) echo $CURHOURSTAT > $OUTSTATFOLDER/$CURHOUR.stats fi #Stats FROMID=$(GetRecordID $FROM mail_addresses mail_address mail "Get ID of From $FROM") Message "From $FROM with ID $FROMID" if [[ "$RECIPIENT" != "" ]]; then TOID=$(GetRecordID $RECIPIENT mail_addresses mail_address mail "Get ID of To $TO") else TOID="0" fi Message "To $RECIPIENT with ID $TOID" if [[ "$CCRECIPIENT" != "" ]]; then CCID=$(GetRecordID $CCRECIPIENT mail_addresses mail_address mail "Get ID of CC") else CCID="0" fi if [[ "$BCRECIPIENT" != "" ]]; then CCOID=$(GetRecordID $BCRECIPIENT mail_addresses mail_address mail "Get ID of BCC") else CCOID="0" fi if [[ "$DELIVEREDTO" != "" ]]; then DTID=$(GetRecordID $DELIVEREDTO mail_addresses mail_address mail "Get ID of DeliveredTo") else DTID="0" fi if [[ "$RETURNPATH" != "" ]]; then RPID=$(GetRecordID $RETURNPATH mail_addresses mail_address mail) else RPID="0" fi if [[ "$XORIGINALSENDER" != "" ]]; then XOSID=$(GetRecordID $XORIGINALSENDER mail_addresses mail_address mail) else XOSID="0" fi if [[ "$SENDER" != "" ]]; then SID=$(GetRecordID $SENDER mail_addresses mail_address mail) else SID="0" fi if [[ "$XFORWARDEDTO" != "" ]]; then XFTID=$(GetRecordID $XFORWARDEDTO mail_addresses mail_address mail) else XFTID="0" fi if [[ "$XFORWARDEDFOR" != "" ]]; then XFFID=$(GetRecordID $XFORWARDEDFOR mail_addresses mail_address mail) else XFFID="0" fi QUERY="INSERT INTO stats (msgid, from_id, to_id,cc_id, cco_id, subject, direction, delivered_to_id, return_path_id, s_original_sender_id, sender_id, x_forwarded_to, x_forwarded_for) VALUES ('$MESSAGEID',$FROMID, $TOID, $CCID, $CCOID, '$SUBJECT', $DIRECTION, $DTID, $RPID, $XOSID, $SID, $XFTID, $XFFID);" RESULT=$(echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf mail) error_code=$? if [[ "$error_code" != "0" ]]; then Message "Error $error_code saving stats with query '$QUERY'. Result: $RESULT" fi Message "Arguments: $*" $SENDMAIL "$@"