diff --git a/Milter/cache.py b/Milter/cache.py index 937753124622774cd828f85ccc249171c722d2f1..e8ab0b5e59e956471c9eb13ba0e4506e9799c33c 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 a48e1b0f8b4ede007e10ab8a6b389c996b2d627f..c169e3951a7b6e1409700fdf41ef1a5041ada4d0 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 038624fd40948625527b1c58e12e72b4d9027252..65364c6df7e942a225a100c955ec113633596cc2 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 92336fa0562997221a1cfe4816b669e7e711e61f..a72ce765e50c1d8f596f5ace9c3e0849d4228d0c 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 d27eaeaee4f068c3fb6b059ba88d74fa2a8096e7..a10c2d3e459aad70a79809483996497afdb82586 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 24ff11f125fd84cbc969f74df25d16f417559685..2d78febf20004ff9a1e437485684f0d2c14bc0f1 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')