class AttachmentMemoryTest(unittest.TestCase): """ Test memory removal for attachment manager in realistic case using the attachment plugin """ def setUp(self): self.tempdir = tempfile.mkdtemp('attachtest', 'fuglu') self.template = '%s/blockedfile.tmpl' % self.tempdir shutil.copy( CONFDIR + '/templates/blockedfile.tmpl.dist', self.template) shutil.copy(CONFDIR + '/rules/default-filenames.conf.dist', '%s/default-filenames.conf' % self.tempdir) shutil.copy(CONFDIR + '/rules/default-filetypes.conf.dist', '%s/default-filetypes.conf' % self.tempdir) config = RawConfigParser() config.add_section('FiletypePlugin') config.set('FiletypePlugin', 'template_blockedfile', self.template) config.set('FiletypePlugin', 'rulesdir', self.tempdir) config.set('FiletypePlugin', 'blockaction', 'DELETE') config.set('FiletypePlugin', 'sendbounce', 'True') config.set('FiletypePlugin', 'checkarchivenames', 'True') config.set('FiletypePlugin', 'checkarchivecontent', 'True') config.set('FiletypePlugin', 'archivecontentmaxsize', '7000000') config.set('FiletypePlugin', 'archiveextractlevel', -1) config.set('FiletypePlugin', 'enabledarchivetypes', '') config.add_section('main') config.set('main', 'disablebounces', '1') self.candidate = FiletypePlugin(config) self.rulescache = RulesCache(self.tempdir) self.candidate.rulescache = self.rulescache def tearDown(self): os.remove('%s/default-filenames.conf' % self.tempdir) os.remove('%s/default-filetypes.conf' % self.tempdir) os.remove(self.template) shutil.rmtree(self.tempdir) def test_archiveextractsize(self): """Test reference counts based on the archive test 'test archive extract max filesize'""" for testfile in ['6mbzipattachment.eml', '6mbrarattachment.eml']: try: tmpfile = tempfile.NamedTemporaryFile( suffix='virus', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-archivefiletypes.conf" % user # the largefile in the test message is just a bunch of zeroes open(conffile, 'w').write( "deny application\/octet\-stream no data allowed") self.rulescache._loadrules() suspect = Suspect( '*****@*****.**', user, tmpfile.name) print("Refcounts to suspect/manager after creating it: %u/%u" % (sys.getrefcount(suspect), 0 if suspect._att_mgr is None else sys.getrefcount(suspect._att_mgr))) # backup old limits from config file oldlimit = self.candidate.config.getint('FiletypePlugin', 'archivecontentmaxsize') oldlimit_aelevel = self.candidate.config.getint('FiletypePlugin', 'archiveextractlevel') # now set the limit to 4 mb, the file should be skipped now # # check log # reason of skipping should be the size is to large, file largefile/6mbfile is not extracted self.candidate.config.set( 'FiletypePlugin', 'archivecontentmaxsize', 4000000) print("Refcounts to suspect/manager before first examine: %u/%u" % (sys.getrefcount(suspect), 0 if suspect._att_mgr is None else sys.getrefcount(suspect._att_mgr))) result = self.candidate.examine(suspect) print("Refcounts to suspect/manager after first examine: %u/%u" % (sys.getrefcount(suspect),sys.getrefcount(suspect._att_mgr))) if type(result) is tuple: result, message = result self.assertEqual(result, DUNNO, 'large file should be skipped (not extracted)') self.candidate.config.set( 'FiletypePlugin', 'archivecontentmaxsize', 7000000) print("Refcounts to suspect/manager before second examine: %u/%u" % (sys.getrefcount(suspect),sys.getrefcount(suspect._att_mgr))) result = self.candidate.examine(suspect) print("Refcounts to suspect/manager after second examine: %u/%u" % (sys.getrefcount(suspect),sys.getrefcount(suspect._att_mgr))) if type(result) is tuple: result, message = result self.assertEqual( result, DELETE, 'extracted large file should be blocked') # now set the limit to 5 mb, the file should be skipped now # check log # reason of skipping should be the size is to large for check, # file largefile/6mbfile is already extracted self.candidate.config.set( 'FiletypePlugin', 'archivecontentmaxsize', 5000000) print("Refcounts to suspect/manager before third examine: %u/%u" % (sys.getrefcount(suspect),sys.getrefcount(suspect._att_mgr))) result = self.candidate.examine(suspect) print("Refcounts to suspect/manager after third examine: %u/%u" % (sys.getrefcount(suspect),sys.getrefcount(suspect._att_mgr))) if type(result) is tuple: result, message = result self.assertEqual(result, DUNNO, 'large file should be skipped') # now set the limit to 7 mb, the file should be skipped now self.candidate.config.set('FiletypePlugin', 'archivecontentmaxsize', 7000000) self.candidate.config.set('FiletypePlugin', 'archiveextractlevel', 0) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual(result, DUNNO, 'large file should be skipped') # reset config self.candidate.config.set('FiletypePlugin', 'archivecontentmaxsize', oldlimit) self.candidate.config.set('FiletypePlugin', 'archiveextractlevel', oldlimit_aelevel) print("Refcounts to suspect/manager before deleting it: %u/%u" % (sys.getrefcount(suspect),sys.getrefcount(suspect._att_mgr))) self.assertEqual(2, sys.getrefcount(suspect), "only two references should remain, suspect and the one" "from the 'getrefcount' call itself") self.assertEqual(2, sys.getrefcount(suspect._att_mgr), "only two references should remain, the one in " "suspect and the one from the 'getrefcount' " "call itself") del suspect if OBJGRAPH_EXTENSION_ENABLED: print("\n----------------------") print("After deleting suspect") print("----------------------") sus_objects = objgraph.by_type('Suspect') ma_objects = objgraph.by_type('Mailattachment') mam_objects = objgraph.by_type('Mailattachment_mgr') print("Suspects in memory: %u" % len(sus_objects)) print("MailAttachments in memory: %u" % len(ma_objects)) print("MailAttachmentMgr in memory: %u" % len(mam_objects)) print("Refcounts:") for sus in sus_objects: print(" Suspect: %u" % sys.getrefcount(sus)) for mgr in mam_objects: print(" Mgr: %u" % sys.getrefcount(mgr)) for ma in ma_objects: print(" MailAttachment: %u" % sys.getrefcount(ma)) # if enabled print graphs if print_graphs: if len(sus_objects) > 0: objgraph.show_backrefs(sus_objects, max_depth=5, refcounts=True) elif len(ma_objects) > 0: objgraph.show_backrefs(ma_objects, max_depth=5, refcounts=True) elif len(mam_objects) > 0: objgraph.show_backrefs(mam_objects, max_depth=5, refcounts=True) self.assertEqual(0, len(sus_objects), "Deleting suspect should have removed Suspect objects") self.assertEqual(0, len(mam_objects), "Deleting suspect should have removed Mailattachment_mgr objects") self.assertEqual(0, len(ma_objects), "Deleting suspect should have removed Mailattachment objects") finally: tmpfile.close() os.remove(conffile)
class AttachmentPluginTestCaseMockBounce(unittest.TestCase): """ Test setup with bouncing enabled. Don't forget to patch SMTP to prevent actual sending mail. Patch SMTP is done putting the mocking decorator: @patch("smtplib.SMTP") # when working with smtplib directly @patch("fuglu.bounce.FugluSMTPClient" # when using fuglu's smtp client from fuglu.bounce module in front of the test. """ def setUp(self): self.tempdir = tempfile.mkdtemp('attachtest', 'fuglu') self.template = '%s/blockedfile.tmpl' % self.tempdir shutil.copy(CONFDIR + '/templates/blockedfile.tmpl.dist', self.template) shutil.copy(CONFDIR + '/rules/default-filenames.conf.dist', '%s/default-filenames.conf' % self.tempdir) shutil.copy(CONFDIR + '/rules/default-filetypes.conf.dist', '%s/default-filetypes.conf' % self.tempdir) config = RawConfigParser() config.add_section('FiletypePlugin') config.set('FiletypePlugin', 'template_blockedfile', self.template) config.set('FiletypePlugin', 'rulesdir', self.tempdir) config.set('FiletypePlugin', 'blockaction', 'DELETE') config.set('FiletypePlugin', 'sendbounce', 'True') config.set('FiletypePlugin', 'checkarchivenames', 'True') config.set('FiletypePlugin', 'checkarchivecontent', 'True') config.set('FiletypePlugin', 'archivecontentmaxsize', '7000000') config.set('FiletypePlugin', 'archiveextractlevel', -1) config.set('FiletypePlugin', 'enabledarchivetypes', '') config.add_section('main') config.set('main', 'disablebounces', '0') config.set('main', 'nobouncefile', '') config.set('main', 'outgoingport', '10038') config.set('main', 'outgoinghelo', 'test.fuglu.org') config.set('main', 'bindaddress', '127.0.0.1') self.candidate = FiletypePlugin(config) self.rulescache = RulesCache(self.tempdir) self.candidate.rulescache = self.rulescache def tearDown(self): os.remove('%s/default-filenames.conf' % self.tempdir) os.remove('%s/default-filetypes.conf' % self.tempdir) os.remove(self.template) shutil.rmtree(self.tempdir) @patch("fuglu.bounce.FugluSMTPClient") def test_bounce_withenvsender(self, smtpmock): """Reference test bounce is called for setup, next test 'test_bounce_noenvsender' should behave differently.""" testfile = '6mbzipattachment.eml' # copy file rules tmpfile = tempfile.NamedTemporaryFile(suffix='virus', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-archivenames.conf" % user open(conffile, 'w').write( "deny largefile user does not like the largefile within a zip\ndeny 6mbfile user does not like the largefile within a zip" ) self.rulescache._loadrules() suspect = Suspect('*****@*****.**', user, tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual( result, DELETE, 'archive containing blocked filename was not blocked') tmpfile.close() os.remove(conffile) smtpmock_membercalls = [call[0] for call in smtpmock.mock_calls] self.assertTrue(smtpmock.called) self.assertTrue("().helo" in smtpmock_membercalls) self.assertTrue("().sendmail" in smtpmock_membercalls) self.assertTrue("().quit" in smtpmock_membercalls) @patch("fuglu.bounce.FugluSMTPClient") def test_bounce_noenvsender(self, smtpmock): """Don't try to send a bounce if original env sender is empty""" testfile = '6mbzipattachment.eml' # copy file rules tmpfile = tempfile.NamedTemporaryFile(suffix='virus', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-archivenames.conf" % user open(conffile, 'w').write( "deny largefile user does not like the largefile within a zip\ndeny 6mbfile user does not like the largefile within a zip" ) self.rulescache._loadrules() suspect = Suspect('', user, tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual( result, DELETE, 'archive containing blocked filename was not blocked') tmpfile.close() os.remove(conffile) self.assertFalse( smtpmock.called, "No SMTP client should have been created because there's no mail to send." )
class AttachmentPluginTestCase(unittest.TestCase): """Testcases for the Attachment Checker Plugin""" def setUp(self): self.tempdir = tempfile.mkdtemp('attachtest', 'fuglu') self.template = '%s/blockedfile.tmpl' % self.tempdir shutil.copy( CONFDIR + '/templates/blockedfile.tmpl.dist', self.template) shutil.copy(CONFDIR + '/rules/default-filenames.conf.dist', '%s/default-filenames.conf' % self.tempdir) shutil.copy(CONFDIR + '/rules/default-filetypes.conf.dist', '%s/default-filetypes.conf' % self.tempdir) config = RawConfigParser() config.add_section('FiletypePlugin') config.set('FiletypePlugin', 'template_blockedfile', self.template) config.set('FiletypePlugin', 'rulesdir', self.tempdir) config.set('FiletypePlugin', 'blockaction', 'DELETE') config.set('FiletypePlugin', 'sendbounce', 'True') config.set('FiletypePlugin', 'checkarchivenames', 'True') config.set('FiletypePlugin', 'checkarchivecontent', 'True') config.set('FiletypePlugin', 'archivecontentmaxsize', '5000000') config.set('FiletypePlugin', 'enabledarchivetypes', '') config.add_section('main') config.set('main', 'disablebounces', '1') self.candidate = FiletypePlugin(config) self.rulescache = RulesCache(self.tempdir) self.candidate.rulescache = self.rulescache def tearDown(self): os.remove('%s/default-filenames.conf' % self.tempdir) os.remove('%s/default-filetypes.conf' % self.tempdir) os.remove(self.template) shutil.rmtree(self.tempdir) def test_hiddenbinary(self): """Test if hidden binaries get detected correctly""" # copy file rules tmpfile = tempfile.NamedTemporaryFile( suffix='virus', prefix='fuglu-unittest', dir='/tmp') shutil.copy(TESTDATADIR + '/binaryattachment.eml', tmpfile.name) suspect = Suspect( '*****@*****.**', '*****@*****.**', tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result tmpfile.close() self.assertEqual(result, DELETE) def test_umlaut_in_zip(self): """Issue 69: Test if zip with files that contain umlauts are extracted ok""" tmpfile = tempfile.NamedTemporaryFile( suffix='badattach', prefix='fuglu-unittest', dir='/tmp') shutil.copy(TESTDATADIR + '/umlaut-in-attachment.eml', tmpfile.name) suspect = Suspect( '*****@*****.**', '*****@*****.**', tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result tmpfile.close() self.assertEqual(result, DUNNO) def test_archiveextractsize(self): """Test archive extract max filesize""" # copy file rules for testfile in ['6mbzipattachment.eml', '6mbrarattachment.eml']: try: tmpfile = tempfile.NamedTemporaryFile( suffix='virus', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-archivefiletypes.conf" % user # the largefile in the test message is just a bunch of zeroes open(conffile, 'w').write( "deny application\/octet\-stream no data allowed") self.rulescache._loadrules() suspect = Suspect( '*****@*****.**', user, tmpfile.name) # test with high limit first oldlimit = self.candidate.config.get( 'FiletypePlugin', 'archivecontentmaxsize') self.candidate.config.set( 'FiletypePlugin', 'archivecontentmaxsize', '7000000') result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual( result, DELETE, 'extracted large file should be blocked') # now set the limit to 5 mb, the file should be skipped now self.candidate.config.set( 'FiletypePlugin', 'archivecontentmaxsize', '5000000') result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual(result, DUNNO, 'large file should be skipped') # reset config self.candidate.config.set( 'FiletypePlugin', 'archivecontentmaxsize', oldlimit) finally: tmpfile.close() os.remove(conffile) def test_archivename(self): """Test check archive names""" for testfile in ['6mbzipattachment.eml', '6mbrarattachment.eml']: try: # copy file rules tmpfile = tempfile.NamedTemporaryFile( suffix='virus', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-archivenames.conf" % user open(conffile, 'w').write( "deny largefile user does not like the largefile within a zip\ndeny 6mbfile user does not like the largefile within a zip") self.rulescache._loadrules() suspect = Suspect( '*****@*****.**', user, tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual( result, DELETE, 'archive containing blocked filename was not blocked') finally: tmpfile.close() os.remove(conffile) def test_hiddenpart(self): """Test for hidden part in message epilogue""" testfile='hiddenpart.eml' try: tmpfile = tempfile.NamedTemporaryFile( suffix='hidden', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-filetypes.conf" % user # the largefile in the test message is just a bunch of zeroes open(conffile, 'w').write( "deny application\/zip no zips allowed") self.rulescache._loadrules() suspect = Suspect( '*****@*****.**', user, tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual( result, DELETE, 'hidden message part was not detected') finally: tmpfile.close() os.remove(conffile) def test_archive_wrong_extension(self): """Test if archives don't fool us with forged file extensions""" testfile = 'wrongextension.eml' try: tmpfile = tempfile.NamedTemporaryFile( suffix='wrongext', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-archivenames.conf" % user # the largefile in the test message is just a bunch of zeroes open(conffile, 'w').write( "deny \.exe$ exe detected in zip with wrong extension") self.rulescache._loadrules() suspect = Suspect( '*****@*****.**', user, tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual( result, DELETE, 'exe in zip with .gz extension was not detected') finally: tmpfile.close() os.remove(conffile)
class AttachmentPluginTestCase(unittest.TestCase): """Testcases for the Attachment Checker Plugin""" def setUp(self): self.tempdir = tempfile.mkdtemp('attachtest', 'fuglu') self.template = '%s/blockedfile.tmpl' % self.tempdir shutil.copy(CONFDIR + '/templates/blockedfile.tmpl.dist', self.template) shutil.copy(CONFDIR + '/rules/default-filenames.conf.dist', '%s/default-filenames.conf' % self.tempdir) shutil.copy(CONFDIR + '/rules/default-filetypes.conf.dist', '%s/default-filetypes.conf' % self.tempdir) config = RawConfigParser() config.add_section('FiletypePlugin') config.set('FiletypePlugin', 'template_blockedfile', self.template) config.set('FiletypePlugin', 'rulesdir', self.tempdir) config.set('FiletypePlugin', 'blockaction', 'DELETE') config.set('FiletypePlugin', 'sendbounce', 'True') config.set('FiletypePlugin', 'checkarchivenames', 'True') config.set('FiletypePlugin', 'checkarchivecontent', 'True') config.set('FiletypePlugin', 'archivecontentmaxsize', '7000000') config.set('FiletypePlugin', 'archiveextractlevel', -1) config.set('FiletypePlugin', 'enabledarchivetypes', '') config.add_section('main') config.set('main', 'disablebounces', '1') config.set('main', 'nobouncefile', '') self.candidate = FiletypePlugin(config) self.rulescache = RulesCache(self.tempdir) self.candidate.rulescache = self.rulescache def tearDown(self): os.remove('%s/default-filenames.conf' % self.tempdir) os.remove('%s/default-filetypes.conf' % self.tempdir) os.remove(self.template) shutil.rmtree(self.tempdir) def test_hiddenbinary(self): """Test if hidden binaries get detected correctly""" # copy file rules tmpfile = tempfile.NamedTemporaryFile(suffix='virus', prefix='fuglu-unittest', dir='/tmp') shutil.copy(TESTDATADIR + '/binaryattachment.eml', tmpfile.name) suspect = Suspect('*****@*****.**', '*****@*****.**', tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result tmpfile.close() self.assertEqual(result, DELETE) def test_umlaut_in_zip(self): """Issue 69: Test if zip with files that contain umlauts are extracted ok""" tmpfile = tempfile.NamedTemporaryFile(suffix='badattach', prefix='fuglu-unittest', dir='/tmp') shutil.copy(TESTDATADIR + '/umlaut-in-attachment.eml', tmpfile.name) suspect = Suspect('*****@*****.**', '*****@*****.**', tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result tmpfile.close() self.assertEqual(result, DUNNO) def test_special_archive_name(self): """Check if gz file with exclamantion marks and points in archive name is extracted ok""" import logging import sys root = logging.getLogger() root.setLevel(logging.DEBUG) ch = logging.StreamHandler(sys.stdout) ch.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) root.addHandler(ch) tmpfile = tempfile.NamedTemporaryFile(suffix='badattach', prefix='fuglu-unittest', dir='/tmp') shutil.copy(TESTDATADIR + '/attachment_exclamation_marks_points.eml', tmpfile.name) suspect = Suspect('*****@*****.**', '*****@*****.**', tmpfile.name) self.assertTrue('aaa.aa!aaaaaaaaa.aa!2345678910!1234567891.xml' in suspect.att_mgr.get_fileslist(None)) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result tmpfile.close() self.assertEqual(result, DUNNO) def test_archiveextractsize(self): """Test archive extract max filesize""" # copy file rules for testfile in ['6mbzipattachment.eml', '6mbrarattachment.eml']: try: tmpfile = tempfile.NamedTemporaryFile(suffix='virus', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-archivefiletypes.conf" % user # the largefile in the test message is just a bunch of zeroes open(conffile, 'w').write( "deny application\/octet\-stream no data allowed") self.rulescache._loadrules() suspect = Suspect('*****@*****.**', user, tmpfile.name) # backup old limits from config file oldlimit = self.candidate.config.getint( 'FiletypePlugin', 'archivecontentmaxsize') oldlimit_aelevel = self.candidate.config.getint( 'FiletypePlugin', 'archiveextractlevel') # now set the limit to 4 mb, the file should be skipped now # # check log # reason of skipping should be the size is to large, file largefile/6mbfile is not extracted self.candidate.config.set('FiletypePlugin', 'archivecontentmaxsize', 4000000) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual( result, DUNNO, 'large file should be skipped (not extracted)') self.candidate.config.set('FiletypePlugin', 'archivecontentmaxsize', 7000000) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual(result, DELETE, 'extracted large file should be blocked') # now set the limit to 5 mb, the file should be skipped now # check log # reason of skipping should be the size is to large for check, file largefile/6mbfile is already extracted self.candidate.config.set('FiletypePlugin', 'archivecontentmaxsize', 5000000) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual(result, DUNNO, 'large file should be skipped') # now set the limit to 7 mb, the file should be skipped now self.candidate.config.set('FiletypePlugin', 'archivecontentmaxsize', 7000000) self.candidate.config.set('FiletypePlugin', 'archiveextractlevel', 0) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual(result, DUNNO, 'large file should be skipped') # reset config self.candidate.config.set('FiletypePlugin', 'archivecontentmaxsize', oldlimit) self.candidate.config.set('FiletypePlugin', 'archiveextractlevel', oldlimit_aelevel) finally: tmpfile.close() os.remove(conffile) def test_archivename(self): """Test check archive names""" for testfile in ['6mbzipattachment.eml', '6mbrarattachment.eml']: try: # copy file rules tmpfile = tempfile.NamedTemporaryFile(suffix='virus', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-archivenames.conf" % user open(conffile, 'w').write( "deny largefile user does not like the largefile within a zip\ndeny 6mbfile user does not like the largefile within a zip" ) self.rulescache._loadrules() suspect = Suspect('*****@*****.**', user, tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual( result, DELETE, 'archive containing blocked filename was not blocked') finally: tmpfile.close() os.remove(conffile) def test_archivename_nestedarchive(self): """Test check archive names in nested archive""" #--- # Note: #--- # mail testedarchive.eml contains the attachment "nestedarchive.tar.gz" # which has the following nested structure: #--- # Level : (extracted from archive ) -> Files #--- # 0 : nestedarchive.tar.gz # 1 : (extracting level1.tar.gz) -> level0.txt level1.tar.gz # 2 : (extracting level1.tar.gz) -> level1.txt level2.tar.gz # 3 : (extracting level2.tar.gz) -> level2.txt level3.tar.gz # 4 : (extracting level3.tar.gz) -> level3.txt level4.tar.gz # 5 : (extracting level4.tar.gz) -> level4.txt level5.tar.gz # 6 : (extracting level5.tar.gz) -> level5.txt level6.tar.gz # 7 : (extracting level6.tar.gz) -> level6.txt testfile = os.path.join(TESTDATADIR, "nestedarchive.eml") try: # copy file rules user = '******' conffile = self.tempdir + "/%s-archivenames.conf" % user open(conffile, 'w').write( "deny level6.txt user does not like the files in nested archives \ndeny 6mbfile user does not like the largefile within a zip" ) self.rulescache._loadrules() suspect = Suspect('*****@*****.**', user, testfile) oldlimit_aelevel = self.candidate.config.getint( 'FiletypePlugin', 'archiveextractlevel') #---- self.candidate.config.set('FiletypePlugin', 'archiveextractlevel', 6) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual( result, DUNNO, 'archive containing blocked filename should not be extracted') #---- self.candidate.config.set('FiletypePlugin', 'archiveextractlevel', 7) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual( result, DELETE, 'archive containing blocked filename was not blocked') self.candidate.config.set('FiletypePlugin', 'archiveextractlevel', oldlimit_aelevel) finally: os.remove(conffile) def test_hiddenpart(self): """Test for hidden part in message epilogue""" testfile = 'hiddenpart.eml' try: tmpfile = tempfile.NamedTemporaryFile(suffix='hidden', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-filetypes.conf" % user # the largefile in the test message is just a bunch of zeroes open(conffile, 'w').write("deny application\/zip no zips allowed") self.rulescache._loadrules() suspect = Suspect('*****@*****.**', user, tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual(result, DELETE, 'hidden message part was not detected') finally: tmpfile.close() os.remove(conffile) def test_archive_wrong_extension(self): """Test if archives don't fool us with forged file extensions""" testfile = 'wrongextension.eml' try: tmpfile = tempfile.NamedTemporaryFile(suffix='wrongext', prefix='fuglu-unittest', dir='/tmp') shutil.copy("%s/%s" % (TESTDATADIR, testfile), tmpfile.name) user = '******' conffile = self.tempdir + "/%s-archivenames.conf" % user # the largefile in the test message is just a bunch of zeroes open(conffile, 'w').write( "deny \.exe$ exe detected in zip with wrong extension") self.rulescache._loadrules() suspect = Suspect('*****@*****.**', user, tmpfile.name) result = self.candidate.examine(suspect) if type(result) is tuple: result, message = result self.assertEqual(result, DELETE, 'exe in zip with .gz extension was not detected') finally: tmpfile.close() os.remove(conffile)