#!/bin/sh
###################################################################
# Inflex - Bidirectional Email scanner
#
#
# Inflex is copyright to Mr Paul L Daniels.
#
# you are free to use and distribute Inflex as per the GPL licence
# agreement.
#
# All alterations and addtions should be sent to Paul L Daniels
# at jdaniels@stocks.co.za
#
# This program was created with the assistance of looking at
# AmaVis.  It's purpose is to provide a one-stop scanning
# point for all emails, both inbound and outbound, irrespective
# of the method required for the final delivery
#
# Written by Paul/Jack L Daniels
# 07/01/2000 [heheh, y2k compliant ;)]
#
#
# CHANGES -
#
#
#	0.1.5b - 22/06/2000 [Emergency Release]
#		. Added SHS extention blocking
#		. Added -i flag to sendmail calling
#		
#	0.1.5 - 04/04/2000
#		.Removed '7' out of the Minflex flags
#		.Provided both relaying and non-relaying version of .cf
#		.Updated FAQ with some useful hints re McAfee
#		.Inserted filename block specifically for the I LOVE YOU virus
#		.
#	0.1.4 - 17/01/2000
#		.Fixed up reported blocked directory
#		.Replaced hard-coded sendmail cmd line with a more
#		  generic one.
#		.Added Ability to turn on/off various sections of scanner
#		  ie, file type, file name, antivirus
#		.Ability to turn on/off sending of various proponents of 
#		  the messages to various people when a block is performed
#		.Minor typos in sender,receiver messages
#		.X-header addition
#
#	0.1.3 - 13/01/2000
#		.Made blocked emails get moved to a blocked$$ directory
#		.Added Exim mailout support
#
#	0.1.2 - 10/01/2000
#		.Changed version format, to match that of typical
#		  LINUX based systems.
#		.Added support for McAfee and Sophos AntiVirus packages
#		.Cleaned up logging 
#		.changed directory naming to inflex$$ rather than av$$
#               .Made common apps such as find, file, grep become vars
#                 in the script so as to make things easier for
#                 alteration later on.
#		.Altered AntiVirus sections to report either a success
#		  or failure rather than requiring later in the script
#		  to decipher the dozens of possible exit codes from
#                 all of the various AV apps.
#
#########################################################################

#
# Our systemwide INFLEX Log file
#
logfile=/var/log/inflexlog

#
#
# Options to turn on/off various bits of Inflex scanning
#
# Use either y [for yes] or n [for no]
#
scanforvirus=y
scanforfiletype=y
scanforfilename=y
scanfortext=y
outlookbuffertest=y

#
# Options for delivery of email to various people whom
# might want to hear that their email has been blocked
#
deliverSenderAVmsg=y
deliverReceiverAVmsg=y
deliverSenderBLmsg=y
deliverReceiverBLmsg=y
deliverRootmsg=y

#
# Options for composition of actual outgoing email
#
appendXheader=y
Xheader="X-scanner: scanned by Inflex 0.1.5c - (http://www.inflex.co.za/)"


#
# Get our temporary directory name... from the process ID
# which is about as good as any random number
#
pid="inflex$$"
tmpdir=/var/tmp/${pid}
blockdir=/var/tmp/Blocked$$

#
# Our sendmail.cf file
#
cf=/etc/sendmail.cf


#
# Our mail-specific logfiles
#
locallog=${tmpdir}/logfile
badfileslog=${tmpdir}/badfileslog
fsavlog=${tmpdir}/fsavlog

# 
# Our message files
#
sendermsg=${tmpdir}/sendermsg
recvmsg=${tmpdir}/recvmsg
blockmsg=${tmpdir}/blockmsg

#
# setup our commonly used files
#
test=/bin/test
mail=/usr/bin/mail
grep=/usr/bin/grep
file=/usr/bin/file
find=/usr/bin/find
touch=/usr/bin/touch
metamail=/usr/local/bin/metamail
formail=/usr/local/bin/formail


#
# Our MAIL PROGRAMS
#
sendmail=/usr/sbin/sendmail
exim=/usr/local/sbin/exim

# 
# Our Virus Scanners
#
#sophos=/usr/local/bin/sweep
sophos=
mcafee=
fsav=


# 
# Setup who sent and who was supposed to receive all this
#
sender=$3
receiver=$2
hostname=$1

#
# Who's going to receive all the bounced reports
#
administrator=root@localhost

#
# Make the directory
#
mkdir -p ${tmpdir}
mkdir ${tmpdir}/unpacked

#
# Take standard input and create a file called RECEIVEDMAIL
#
cat > ${tmpdir}/receivedmail

# 
# Start a log file, with the basic information of who/etc 
#
echo "" >> ${locallog}
echo "${pid}  from:${sender}  to:${hostname}" >> ${locallog}

#
# Setup the Metamil unpacking directory, else it'll unpack to /tmp
#
METAMAIL_TMPDIR=${tmpdir}/unpacked
export METAMAIL_TMPDIR

#
# Unpack the newly arrived email
#
${metamail} -r -q -x -w ${tmpdir}/receivedmail


#
# SCAN for files we don't really want people sending/receiving
#
#
# First up, get a list of all the files we have in this metamail package
#
${touch} ${badfileslog}
${find} ${tmpdir} -name '*' > ${tmpdir}/filelist1

#
# Now we run a magic-number file test on each of the files
# this way we can get around people who have tried renaming
# the files.
#
# The output from this is a full list of the files, and their
# TYPE as per the /etc/magic file
#
${file} -f ${tmpdir}/filelist1 > ${tmpdir}/fileresults



if [ "a${scanforfiletype}" != "an" ]; 
then
	#
	# Now we can search through the resultant file/type list as
	# generated from above, and we output the results to the
	# BADFILES list.
	#
	${grep} "MS-DOS executable" ${tmpdir}/fileresults >> ${badfileslog}
	${grep} "PC bitmap data" ${tmpdir}/fileresults >> ${badfileslog}
	${grep} "AVI" ${tmpdir}/fileresults >> ${badfileslog}
	${grep} "MPEG" ${tmpdir}/fileresults >> ${badfileslog}
	${grep} "WAVE" ${tmpdir}/fileresults >> ${badfileslog}
else
	echo "Type scanning off." >> ${locallog}
	fi
	
	

if [ "a${scanforfilename}" != "an" ];
then
	#
	# Next we also scan for actual file names
	# This is VERY useful for if there is a know file that contains
	# a virus, but alas, our virus scanner can't pick it up 
	#
#${find} ${tmpdir} -iname 'links.vbs' >> ${badfileslog}
${find} ${tmpdir} -iname '*.mp3' >> ${badfileslog}
${find} ${tmpdir} -iname '*.vbs' >> ${badfileslog}
${find} ${tmpdir} -iname 'LOVE-LETTER-FOR-YOU*' >> ${badfileslog}
${find} ${tmpdir} -iname '*.shs' >> ${badfileslog}

else
	echo "Name scanning off." >> ${locallog}
	fi
	
	
#
# If any files tested positive in the above magic/name tests
# then the badfileslist will be bigger than 0-bytes
# Hence if so, set the scan status to say so!
#
if [ -s ${badfileslog} ];
then
	badfilescan=1
else
	badfilescan=0
fi




if [ "a${scanforvirus}" != "an" ];
then
#
# SCAN those files for viruses!
#
# Blocking out emails by method of file type is good for 
# controlling the abuse of resources on your network.  However
# we also should be wise enough to take this opportunity whilst
# we have a "foriegn" file in our network to SCAN it for a VIRUS!
#
# NOTE - We're using FPROT Antivirus here.... because I own
# a copy of it.  You could alter the following line to suit your
# own preferred AntiVirus scanner software, but I find FProt quite
# good, it also has a nice simple update utility which can be run
# via CRON.
#
# --archive, unpack archived files, eg zip, lha, exe-zip 
# --list,    display what we are scanning
# --dumb,    don't stop and ask questions, as the server cant answer
# --auto,    decide how to handle a virused file 
#
# FPROT Exit codes ---
#  0 - all clear
#  1 - fsav failed for some reason, perhaps a broken .def file
#  3 - virus was found.
#
if [ "a${fsav}" != "a" ]
then
	
	#
	# FPROT
	#
	${fsav} --archive --list --dumb --auto ${tmpdir}/unpacked/* > ${fsavlog} 2>&1
	fsavresult=$?
	if ${test} ${fsavresult} -eq 3
	then
		detectedvirus=1
	else
		detectedvirus=0
	fi
fi

	#
	# SOPHOS
	#

if [ "a${sophos}" != "a" ]
then
 	${sophos} -nb -f -all -rec -ss -sc ${tmpdir}/unpacked > ${fsavlog} 2>&1
	fsavresult=$?
	if ${test} ${fsavresult} -ne 0
	then
		detectedvirus=1
	else
		detectedvirus=0
	fi
fi


	#
	# McAfee / NAI - UVScan
	#
if [ "a${mcafee}" != "a" ]
then
 	${mcafee} --secure -rv --summary ${tmpdir}/unpacked > ${fsavlog} 2>&1
	fsavresult=$?
	if ${test} ${fsavresult} -eq 13
	then
		detectedvirus=1
	else
		detectedvirus=0
		fi
	fi

else
	echo "Virus scanning off." >> ${fsavlog}
	detectedvirus=0	
	fi

	#
	# check for long date field buffer overrun Via Outlook exploits
	# Thanks to Tom Currie for this 24/07/2000
	#
	
if [ "a${outlookbuffertest}" != "a" ]
then
	CC=`grep "^Date: " ${tmpdir}/receivedmail | head -1 | wc -c`
	if [ $CC -gt 76 ] ; then
	   # carrying the outlook buffer overrun hack:
	   grep -n ""  ${tmpdir}/receivedmail | head -20 | sed "s/:/:  /" | \
	   mail -s "Outlook buffer overrun hack" $administrator
	   sed "s/^Date: .*$/Date: Invalid Date Format/" ${tmpdir}/receivedmail  > ${tmpdir}/date$$
   	cat ${tmpdir}/date$$ > ${tmpdir}/receivedmail
	   rm ${tmpdir}/date$$
   	fi    
	fi


#
#
# Now process the results of our above scans and tests.
# Now process the results of our above scans and tests.
#
#
# return to our start path (good manners)
#
cd ${tmpdir}



if [ "a${deliverRootmsg}" != "an" ];
then
	#
	# Test to see if we came up with a bad email due
	# to a BAD FILE [as apposed to a virused file]
	#
	if ${test} ${badfilescan} -eq 1 -o ${detectedvirus} -eq 1
	then

		#
		# Create and send an email to INFLEX's operator
		#
		echo "Inflex Sent notification to ${sender} and ${receiver}" > ${blockmsg}
  		echo "The attached mail has been BLOCKED" >> ${blockmsg}
  		echo "The mail has been stored as ${blockdir}" >> ${blockmsg}
  		echo "" >> ${blockmsg}
  		echo "AntiVirus Results..." >> ${blockmsg}
  		cat ${tmpdir}/fsavlog >> ${blockmsg}
  		echo "" >> ${blockmsg}
  		echo "Badfiles Scan Results" >> ${blockmsg}
  		cat ${badfileslog} >> ${blockmsg}
  		echo "" >> ${blockmsg}
  		cat ${locallog} >> ${blockmsg}
  		echo "" >> ${blockmsg}
  		echo "END OF MESSAGE." >> ${blockmsg}
  		
		${mail} -s "BLOCKED DELIVERY" ${administrator} < ${blockmsg}
		fi

	fi



#
# Now, because we're blocking both viruses and bad files, we 
# should let the users know -which- one it was, else we'll
# have a flurry of users panicing that their email contains
# viruses, when in fact they probably just sent a BMP file
#

	#
	# Responses for VIRUSES
	#
if ${test} ${detectedvirus} -eq 1
then
echo "Mail blocked due to VIRUS" >> ${locallog}


	if [ "a${deliverSenderAVmsg}" != "an" ];
	then
	#
	# Message to the sender
	#
echo "                 BLOCKED DELIVERY OF YOUR EMAIL TO ${receiver}" > ${sendermsg}
echo "" >> ${sendermsg}
echo "Our email scanner has detected a VIRUS in your email" >> ${sendermsg}
echo "Your email has been stopped.  The intended recipient will receive a notification of this message." >> ${sendermsg}
echo "" >> ${sendermsg}
echo "The virus scanner revealed..." >> ${sendermsg}
cat ${fsavlog} >> ${sendermsg}
echo "" >> ${sendermsg}
echo "End." >> ${sendermsg}
${mail} -s "BLOCKED DELIVERY OF EMAIL TO ${receiver}" ${sender} < ${sendermsg}
	fi
	
	
	if [ "a${deliverReceiverAVmsg}" != "an" ];
	then
	#
	# Message to the intended receiver
	#
echo "                 BLOCKED DELIVERY OF EMAIL FROM ${sender}" > ${recvmsg}
echo "" >> ${recvmsg}
echo "Our email scanner has detected a VIRUS in an email destined for you." >> ${recvmsg}
echo "This email has been stopped.  The sender will receive a notification of this message." >> ${recvmsg}
echo "" >> ${recvmsg}
echo "The virus scanner revealed..." >> ${recvmsg}
cat ${fsavlog} >> ${recvmsg}
echo "" >> ${recvmsg}
echo "End." >> ${recvmsg}

${mail} -s "BLOCKED DELIVERY OF EMAIL FROM ${sender}" ${receiver} < ${recvmsg}
	fi
fi

	
	


if ${test} ${badfilescan} -eq 1
then
echo "Mail blocked due to BAD FILE" >> ${locallog}


	if [ "a${deliverSenderBLmsg}" != "an" ];
	then
	#
	# Message to the sender
	#
echo "                 BLOCKED DELIVERY OF YOUR EMAIL TO ${receiver}" > ${sendermsg}
echo "" >> ${sendermsg}
echo "Our email scanner has detected a file TYPE which we are not" >> ${sendermsg}
echo "permitting through our systems. These namely include movies, executables and large pictures." >> ${sendermsg}
echo "Your email has been stopped.  The intended recipient will receive a notification of this message." >> ${sendermsg}
echo "" >> ${sendermsg}
echo "The files that were blocked are..." >> ${sendermsg}
cat ${badfileslog} >> ${sendermsg}
echo "" >> ${sendermsg}
echo "End." >> ${sendermsg}

${mail} -s "BLOCKED DELIVERY OF EMAIL TO ${receiver}" ${sender} < ${sendermsg}
	fi
	
	
	if [ "a${deliverReceiverBLmsg}" != "an" ];
	then
	#
	# Message to the intended receiver
	#
echo "                 BLOCKED DELIVERY OF EMAIL FROM ${sender}" > ${recvmsg}
echo "" >> ${recvmsg}
echo "Our email scanner has detected a file TYPE which we are not" >> ${recvmsg}
echo "permitting through our systems. " >>${recvmsg}
echo "" >>${recvmsg}
echo "These namely include movies, executables and large pictures." >> ${recvmsg}
echo "Your email has been stopped.  The intended sender will receive a notification of this message." >> ${recvmsg}
echo "" >> ${recvmsg}
echo "The files that were blocked are..." >> ${recvmsg}
cat ${badfileslog} >> ${recvmsg}
echo "" >> ${recvmsg}
echo "End." >> ${recvmsg}
${mail} -s "BLOCKED DELIVERY OF EMAIL FROM ${sender}" ${receiver} < ${recvmsg}
	fi
	
fi




# 
# If nothing really happened and all went well through this whole scanning process
# We can then proceed to send off the email as per normal.
#

#
# Store our scanning results...
#
echo "Non-PassableFile status is: ${badfilescan}" >> ${locallog} 
echo "AntiVirus status is: ${detectedvirus}" >> ${locallog}
echo "Bad files details..." >> ${locallog}
cat ${badfileslog} >> ${locallog}
echo "" >> ${locallog}
echo "AntiVirus details..." >> ${locallog}
cat ${fsavlog} >> ${locallog}
echo "" >> ${locallog}
echo "completed scanning process for ${pid}" >> ${locallog}
echo "Non-PassableFile status is: ${badfilescan}" >> ${locallog} 
echo "AntiVirus status is: ${detectedvirus}" >> ${locallog}

#
# Now that our process is complete, we write the entire local log to the 
# main log file
#
cat ${locallog} >> ${logfile}

#
# Some basic house keeping... if the file was all okay, we remove it
# else we leave it there for the administrator to "check out"
#
if ${test} \
	${badfilescan} -eq 0 \
	-a ${detectedvirus} -eq 0
then
#
# Now that all is well and we're happy with the way things are
# we can send off the email to its required destination.
# NOTE - we use the servers NORMAL /etc/sendmail.cf file
#
#
# Select the mailer that you are going to use to send mail out
#
# By default sendmail is selected
#
# Exim is supposed to be command line compatible with sendmail, so
#  that is why it appears here initially.
#

	#
	# does the user want a custom X-header.
	#
	if [ "a${appendXheader}" != "an" ];
	then
		cat ${tmpdir}/receivedmail | ${formail} -f -A "${Xheader}" > ${tmpdir}/recm
		mv ${tmpdir}/recm ${tmpdir}/receivedmail
		fi
	
	
#	cat ${tmpdir}/receivedmail | ${exim} -f${sender} ${receiver} 
	cat ${tmpdir}/receivedmail | ${sendmail} -C${cf} -i -f${sender} ${receiver} 
	rm -rf ${tmpdir}
else
#
# ELSE move everything to a "blocked" directory for later perusal
#
	mv ${tmpdir} ${blockdir}
fi



# END.
