diff --git a/bms.py b/bms.py index 60f04f3d37cde6693911db477cbd7af3c1bd8f4a..ba14a82aa29e542b2456ce98b1ad6f6a4bc21dc2 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.123 2008/07/29 21:59:29 customdesigned +# Parse ESMTP params +# # Revision 1.122 2008/05/08 21:35:56 customdesigned # Allow explicitly whitelisted email from banned_users. # @@ -1580,7 +1583,7 @@ class bmsMilter(Milter.Milter): ds.check_spam(screener,txt,self.recipients, force_result=dspam.DSR_ISINNOCENT) return False - if self.reject_spam: + if self.reject_spam and self.spf.result != 'pass': self.log("DSPAM:",screener, 'REJECT: X-DSpam-Score: %f' % ds.probability) self.setreply('550','5.7.1','Your Message looks spammy') @@ -1590,12 +1593,18 @@ class bmsMilter(Milter.Milter): if self.spf and self.mailfrom != '<>': # check that sender accepts quarantine DSN self.fp.seek(0) - msg = mime.message_from_file(self.fp) - rc = self.send_dsn(self.spf,msg,'quarantine') + if self.spf.result == 'pass' or self.cbv_needed: + msg = mime.message_from_file(self.fp) + if self.spf.result == 'pass': + rc = self.send_dsn(self.spf,msg,'quarantine') + else: + rc = self.do_needed_cbv(msg) + del msg + else: + rc = self.send_dsn(self.spf) if rc != Milter.CONTINUE: self.fp = None return rc - del msg if not ds.check_spam(screener,txt,self.recipients,classify=True): self.fp = None return Milter.DISCARD @@ -1638,6 +1647,25 @@ class bmsMilter(Milter.Milter): quarantine=False) self.log("TRAINSPAM:",screener,'X-Dspam-Score: %f' % ds.probability) + def do_needed_cbv(self,msg): + q,res = self.cbv_needed + if res == 'softfail': + template_name = 'softfail' + elif res in ('fail','deny'): + template_name = 'fail' + elif res in ('unknown','permerror'): + template_name = 'permerror' + elif res == 'neutral': + #template_name = 'neutral' + template_name = None + elif res in ('error','temperror'): + template_name = 'temperror' + else: + template_name = 'strike3' + rc = self.send_dsn(q,msg,template_name) + self.cbv_needed = None + return rc + def eom(self): if not self.fp: return Milter.ACCEPT # no message collected - so no eom processing @@ -1763,21 +1791,7 @@ class bmsMilter(Milter.Milter): # need CBV. However, whitelisted domains might (to discover # bogus localparts). Need a way to tell the difference. if self.cbv_needed and not self.internal_domain: - q,res = self.cbv_needed - if res == 'softfail': - template_name = 'softfail' - elif res in ('fail','deny'): - template_name = 'fail' - elif res in ('unknown','permerror'): - template_name = 'permerror' - elif res == 'neutral': - template_name = 'neutral' - elif res in ('error','temperror'): - template_name = 'temperror' - else: - template_name = 'strike3' - rc = self.send_dsn(q,msg,template_name) - self.cbv_needed = None + rc = self.do_needed_cbv(msg) if rc == Milter.REJECT: # Do not feedback here, because feedback should only occur # for messages that have gone to DATA. Reputation lets us @@ -1886,7 +1900,10 @@ class bmsMilter(Milter.Milter): return Milter.TEMPFAIL cbv_cache[sender] = res self.log('REJECT:',desc) - self.setreply('550','5.7.1',*desc.splitlines()) + try: + self.setreply('550','5.7.1',*desc.splitlines()) + except TypeError: + self.setreply('550','5.7.1',"Callback failure") return Milter.REJECT cbv_cache[sender] = res return Milter.CONTINUE diff --git a/milter.cfg b/milter.cfg index 6ae81a3785a6930b659ea7178f5ad06bced692a1..1e479794c66a86472aab79121c472dbffe1d2c13 100644 --- a/milter.cfg +++ b/milter.cfg @@ -61,7 +61,7 @@ porn_words = penis, breast, pussy, horse cock, porn, xenical, diet pill, d1ck, p-e-n-i-s, hydrocodone, vicodin, xanax, vicod1n, x@nax, diazepam, v1@gra, xan@x, cialis, ci@lis, fr�e, x�nax, val�um, v�lium, via-gra, x@n3x, vicod3n, pen�s, c0d1n, phentermine, en1arge, dip1oma, v1codin, - valium, rolex, sexual, fuck, adv1t, vgaira, medz + valium, rolex, sexual, fuck, adv1t, vgaira, medz, acai berry # reject mail with these case sensitive strings in the subject spam_words = $$$, !!!, XXX, FREE, HGH # attachments with these extensions will be replaced with a warning