From 21e3c6f489e2f1ab86870a95229643fb8d67cf3f Mon Sep 17 00:00:00 2001 From: Stuart Gathman <stuart@gathman.org> Date: Thu, 25 Jan 2007 22:47:26 +0000 Subject: [PATCH] Persist blacklisting from delayed DSNs. --- Milter/cache.py | 15 +++++++++------ NEWS | 1 + bms.py | 15 ++++++++++----- doc/links.h | 1 + milter.spec | 1 + testutils.py | 14 ++++++++++++-- 6 files changed, 34 insertions(+), 13 deletions(-) diff --git a/Milter/cache.py b/Milter/cache.py index 9377531..e8ab0b5 100644 --- a/Milter/cache.py +++ b/Milter/cache.py @@ -10,6 +10,11 @@ # CBV results. # # $Log$ +# Revision 1.6 2007/01/19 23:31:38 customdesigned +# Move parse_header to Milter.utils. +# Test case for delayed DSN parsing. +# Fix plock when source missing or cannot set owner/group. +# # Revision 1.5 2007/01/11 19:59:40 customdesigned # Purge old entries in auto_whitelist and send_dsn logs. # @@ -129,12 +134,10 @@ class AddrCache(object): def __setitem__(self,sender,res): lsender = sender.lower() now = time.time() - cached = self.has_key(sender) - if not cached: - self.cache[lsender] = (now,res) - if not res and self.fname: - s = time.strftime(AddrCache.time_format,time.localtime(now)) - print >>open(self.fname,'a'),sender,s # log refreshed senders + self.cache[lsender] = (now,res) + if not res and self.fname: + s = time.strftime(AddrCache.time_format,time.localtime(now)) + print >>open(self.fname,'a'),sender,s # log refreshed senders def __len__(self): return len(self.cache) diff --git a/NEWS b/NEWS index a48e1b0..c169e39 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ Here is a history of user visible changes to Python milter. 0.8.8 move AddrCache, parse_addr, iniplist, parse_header to Milter package fix plock for missing source and can't change owner/group add sample spfmilter.py milter + private_relay config option 0.8.7 Move spf module to pyspf Prevent PTR cache poisoning More lame bounce heuristics diff --git a/bms.py b/bms.py index 038624f..65364c6 100644 --- a/bms.py +++ b/bms.py @@ -1,6 +1,9 @@ #!/usr/bin/env python # A simple milter that has grown quite a bit. # $Log$ +# Revision 1.90 2007/01/23 19:46:20 customdesigned +# Add private relay. +# # Revision 1.89 2007/01/22 02:46:01 customdesigned # Convert tabs to spaces. # @@ -359,7 +362,7 @@ def findsrs(fp): lnl = ln.lower() if lnl.startswith('action:'): if lnl.split()[-1] != 'failed': break - for k in ('message-id:','x-mailer:','sender:'): + for k in ('message-id:','x-mailer:','sender:','references:'): if lnl.startswith(k): lastln = ln break @@ -907,6 +910,7 @@ class bmsMilter(Milter.Milter): self.log('REJECT: RELAY:',to) self.setreply('550','5.7.1','Unauthorized relay for %s' % domain) return Milter.REJECT + # non DSN mail to SRS address will bounce due to invalid local part canon_to = '@'.join(t) self.recipients.append(canon_to) @@ -941,8 +945,8 @@ class bmsMilter(Milter.Milter): self.reject_spam = False self.smart_alias(to) # get recipient after virtusertable aliasing - #rcpt = self.getsymval("{rcpt_addr}") - #self.log("rcpt-addr",rcpt); + rcpt = self.getsymval("{rcpt_addr}") + self.log("rcpt-addr",rcpt); return Milter.CONTINUE # Heuristic checks for spam headers @@ -1379,7 +1383,9 @@ class bmsMilter(Milter.Milter): self.fp.seek(0) sender = findsrs(self.fp) if sender: - cbv_cache[sender] = 500,self.delayed_failure,time.time() + cbv_cache[sender] = 550,self.delayed_failure + # make blacklisting persistent, since delayed DSNs are expensive + blacklist[sender] = None try: # save message for debugging fname = tempfile.mktemp(".dsn") @@ -1596,7 +1602,6 @@ class bmsMilter(Milter.Milter): self.log('TEMPFAIL:',desc) self.setreply('450','4.2.0',*desc.splitlines()) return Milter.TEMPFAIL - if len(res) < 3: res += time.time(), cbv_cache[sender] = res self.log('REJECT:',desc) self.setreply('550','5.7.1',*desc.splitlines()) diff --git a/doc/links.h b/doc/links.h index 92336fa..a72ce76 100644 --- a/doc/links.h +++ b/doc/links.h @@ -9,6 +9,7 @@ <li><a href="logmsgs.html">Log Messages</a> <li><a href="http://bmsi.com/mailman/listinfo/pymilter">Mailing List</a> <li><a href="credits.html">CREDITS</a> +<li><a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=139894&type=1" width="88" height="31" border="0" alt="SourceForge.net Logo" /></a> <h3>Links</h3> <li><a href="http://www.milter.org/milter_api/api.html">C API</a> <li><a href="http://www.milter.org/">Milter.Org</a> diff --git a/milter.spec b/milter.spec index d27eaea..a10c2d3 100644 --- a/milter.spec +++ b/milter.spec @@ -181,6 +181,7 @@ rm -rf $RPM_BUILD_ROOT - move parse_header to Milter.utils - fix plock for missing source and can't change owner/group - add sample spfmilter.py milter +- private_relay config option * Sat Nov 04 2006 Stuart Gathman <stuart@bmsi.com> 0.8.7-1 - More lame bounce heuristics - SPF moved to pyspf RPM diff --git a/testutils.py b/testutils.py index 24ff11f..2d78feb 100644 --- a/testutils.py +++ b/testutils.py @@ -8,13 +8,12 @@ class AddrCacheTestCase(unittest.TestCase): def setUp(self): self.fname = 'test.dat' - self.cache = AddrCache(fname=self.fname) def tearDown(self): os.remove(self.fname) def testAdd(self): - cache = self.cache + cache = AddrCache(fname=self.fname) cache['foo@bar.com'] = None cache.addperm('baz@bar.com') cache['temp@bar.com'] = 'testing' @@ -26,6 +25,17 @@ class AddrCacheTestCase(unittest.TestCase): self.failUnless(len(s) == 2) self.failUnless(s[0].startswith('foo@bar.com ')) self.assertEquals(s[1].strip(),'baz@bar.com') + # check that new result overrides old + cache['temp@bar.com'] = None + self.failUnless(not cache['temp@bar.com']) + + def testDomain(self): + fp = open(self.fname,'w') + print >>fp,'spammer.com' + fp.close() + cache = AddrCache(fname=self.fname) + cache.load(self.fname,30) + self.failUnless('spammer.com' in cache) def suite(): s = unittest.makeSuite(AddrCacheTestCase,'test') -- GitLab