#!/usr/bin/python

import sys
import zipfile
import email
import StringIO
import cStringIO
import re

reject_patterns = map (re.compile,
		       ['\\.scr$', '\\.exe$', '\\.pif$', '\\.com$'])

def do_reject (name):
	for x in reject_patterns:
		if x.search (name):
			return "Found forbidden filename pattern %s\n" % x.pattern 
	return None

def inspect_zip_attachment (msg):
	zip_str = email.base64MIME.decode (msg.get_payload ())
	zip_file = cStringIO.StringIO (zip_str)

	try:
		zip = zipfile.ZipFile (zip_file)
	except zipfile.BadZipfile:
		return 'is not a zip file?' 

	names =zip.namelist ()
	if len (names) > 100:
		return 'Zip file with > 100 entries.'

	fn = zip.testzip ()
	if fn:
		return 'File %s in zip file is corrupt.' % fn
	
	for n in names:
		r= do_reject (n)
		if r:
			return r
	

recurse_patterns = {
	'.zip$' : inspect_zip_attachment,
	}
	


def scan_message (msg):
	if msg.is_multipart ():
		for p in msg.get_payload ():
			r= scan_message (p)
			if r:
				return r
			
	else:
		fn = msg.get_filename ()
		if not fn:
			return None
		
		r = do_reject (fn)
		if r:			
			return r
		
		for (p,f) in recurse_patterns.items ():
			if re.search (p, fn):
				r = f (msg)
				if r:	
					return r

				

str = sys.stdin.read ()
msg = email.message_from_string (str)

r= scan_message (msg)

if r:
	msg.add_header ('X-Filter-Zip-Scanned', 'suspect; reason: %s' % r)
else:
	msg.add_header ('X-Filter-Zip-Scanned', 'clean')
	
sys.stdout.write (msg.as_string (unixfrom=1))
	
