diff --git a/mime.py b/mime.py index 80a5a832fafacc1e77e9b6111c5121a3e493e2f2..6ceb6bdadf12cc7af80ad835242bbd508323919b 100644 --- a/mime.py +++ b/mime.py @@ -1,4 +1,7 @@ # $Log$ +# Revision 1.4 2005/06/17 01:49:39 customdesigned +# Handle zip within zip. +# # Revision 1.3 2005/06/02 15:00:17 customdesigned # Configure banned extensions. Scan zipfile option with test case. # @@ -193,7 +196,8 @@ class MimeMessage(Message): for key,name in tuple(names): # copy by converting to tuple if name and name.lower().endswith('.zip'): txt = self.get_payload(decode=True) - names += zipnames(txt) + if txt.strip(): + names += zipnames(txt) return names def ismodified(self): @@ -304,19 +308,25 @@ See your administrator. def check_name(msg,savname=None,ckname=check_ext,scan_zip=False): "Replace attachment with a warning if its name is suspicious." - for key,name in msg.getnames(scan_zip): - badname = ckname(name) - if badname: - hostname = socket.gethostname() - if key == 'zipname': - badname = msg.get_filename() - msg.set_payload(virus_msg % (badname,hostname,savname)) - del msg["content-type"] - del msg["content-disposition"] - del msg["content-transfer-encoding"] - name = "WARNING.TXT" - msg["Content-Type"] = "text/plain; name="+name - break + try: + for key,name in msg.getnames(scan_zip): + badname = ckname(name) + if badname: + if key == 'zipname': + badname = msg.get_filename() + break + else: + return Milter.CONTINUE + except zipfile.BadZipfile: + # a ZIP that is not a zip is very suspicious + badname = msg.get_filename() + hostname = socket.gethostname() + msg.set_payload(virus_msg % (badname,hostname,savname)) + del msg["content-type"] + del msg["content-disposition"] + del msg["content-transfer-encoding"] + name = "WARNING.TXT" + msg["Content-Type"] = "text/plain; name="+name return Milter.CONTINUE import email.Iterators diff --git a/test/zip2 b/test/zip2 new file mode 100644 index 0000000000000000000000000000000000000000..e25e77bc0abe9f03f7838b151c9bc8cb48d6733f --- /dev/null +++ b/test/zip2 @@ -0,0 +1,49 @@ +From paulp@go2net.com Wed Jun 1 22:35:12 2005 +Return-Path: <paulp@go2net.com> +Received: from mail.bmsi.com (spidey.bmsi.com [192.168.9.81]) + by bmsred.bmsi.com (8.13.1/8.12.10) with ESMTP id j522ZCQg014058 + for <stuart@bmsred.bmsi.com>; Wed, 1 Jun 2005 22:35:12 -0400 +Received: from 127.0.0.1 ([220.117.92.241]) + by mail.bmsi.com (8.13.1/8.13.1) with ESMTP id j522Ynjm028604 + for stuart@bmsi.com; Wed, 1 Jun 2005 22:34:51 -0400 +Message-Id: <200506020234.j522Ynjm028604@mail.bmsi.com> +SUBJECT: urgent +FROM: paulp@go2net.com +TO: stuart@bmsi.com +DATE: [[ ��, 02 6 2005 ���� 11:34:47 ]] +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="--------bound--" +X-DSpam-Score: 0.081200 +Received-SPF: neutral (mail.bmsi.com: guessing: 220.117.92.241 is neither permitted nor denied by domain of go2net.com) +Status: RO +X-Status: +X-Keywords: NonJunk + +----------bound-- +Content-Type: text/plain; charset=us-ascii +Content-Transfer-Encoding: 7bit + +Hi + +Sorry, I forgot to send an important +document to you in that last email. I had an important phone call. +Please checkout attached doc file when you have a moment. + +Best Regards + +<!DSPAM:1043AE6B6492860536935410> + + +----------bound-- +Content-Type: application/octet-stream; + name="Readme.zip" +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; + filename="Readme.zip" + + +----------bound-- + + +----------bound---- + diff --git a/test/zip3 b/test/zip3 new file mode 100644 index 0000000000000000000000000000000000000000..ebaa89be00260f87e2be83e59216c527aec4d67e --- /dev/null +++ b/test/zip3 @@ -0,0 +1,51 @@ +From paulp@go2net.com Wed Jun 1 22:35:12 2005 +Return-Path: <paulp@go2net.com> +Received: from mail.bmsi.com (spidey.bmsi.com [192.168.9.81]) + by bmsred.bmsi.com (8.13.1/8.12.10) with ESMTP id j522ZCQg014058 + for <stuart@bmsred.bmsi.com>; Wed, 1 Jun 2005 22:35:12 -0400 +Received: from 127.0.0.1 ([220.117.92.241]) + by mail.bmsi.com (8.13.1/8.13.1) with ESMTP id j522Ynjm028604 + for stuart@bmsi.com; Wed, 1 Jun 2005 22:34:51 -0400 +Message-Id: <200506020234.j522Ynjm028604@mail.bmsi.com> +SUBJECT: urgent +FROM: paulp@go2net.com +TO: stuart@bmsi.com +DATE: [[ ��, 02 6 2005 ���� 11:34:47 ]] +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="--------bound--" +X-DSpam-Score: 0.081200 +Received-SPF: neutral (mail.bmsi.com: guessing: 220.117.92.241 is neither permitted nor denied by domain of go2net.com) +Status: RO +X-Status: +X-Keywords: NonJunk + +----------bound-- +Content-Type: text/plain; charset=us-ascii +Content-Transfer-Encoding: 7bit + +Hi + +Sorry, I forgot to send an important +document to you in that last email. I had an important phone call. +Please checkout attached doc file when you have a moment. + +Best Regards + +<!DSPAM:1043AE6B6492860536935410> + + +----------bound-- +Content-Type: application/x-msdownload; name="zip.zip" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="zip.zip" + +USsDBAoBAAAAADVVwjLaV2nEGgAAABoAAAAzABUAemlwLmRvYyAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAuZXhlVVQJAAOmGp9CphqfQlV4BACGA2UAVGhpcyBw +cm9ncmFtIHdhcyBhIHZpcnVzLgpQSwECFwMKAAAAAAA1VcIy2ldpxBoAAAAaAAAAMwANAAAA +AAABAAAAtIEAAAAAemlwLmRvYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAuZXhlVVQFAAOmGp9CVXgAAFBLBQYAAAAAAQABAG4AAACAAAAAAAA= +----------bound-- + + +----------bound---- + diff --git a/testmime.py b/testmime.py index 3920d5b3c7c8b6e20fe06167d86faa6b608f0a95..7df94b32902547b9779dc4590be4c9e068f89487 100644 --- a/testmime.py +++ b/testmime.py @@ -1,4 +1,7 @@ # $Log$ +# Revision 1.3 2005/06/17 01:49:39 customdesigned +# Handle zip within zip. +# # Revision 1.2 2005/06/02 15:00:17 customdesigned # Configure banned extensions. Scan zipfile option with test case. # @@ -130,9 +133,16 @@ class MimeTestCase(unittest.TestCase): def testZip(self,vname="zip1",fname='zip.zip'): self.testDefang(vname,1,'zip.zip') + # test scan_zip flag msg = mime.message_from_file(open('test/'+vname,"r")) mime.defang(msg,scan_zip=False) self.failIf(msg.ismodified()) + # test ignoring empty zip (often found in DSNs) + msg = mime.message_from_file(open('test/zip2','r')) + mime.defang(msg,scan_zip=True) + self.failIf(msg.ismodified()) + # test corrupt zip (often an EXE named as a ZIP) + self.testDefang('zip3',1,'zip.zip') # test zip within zip self.testDefang('ziploop',1,'stuart@bmsi.com.zip')