diff --git a/bms.py b/bms.py index 3e043b2e74debe7879b7c1473fd70359f852ffac..bee0e42f21fec888a99adf6a71804f9cb3a0f67e 100644 --- a/bms.py +++ b/bms.py @@ -1,6 +1,10 @@ #!/usr/bin/env python # A simple milter that has grown quite a bit. # $Log$ +# Revision 1.115 2007/10/10 18:23:54 customdesigned +# Send quarantine DSN to SPF pass (official or guessed) only. +# Reject blacklisted email too big for dspam. +# # Revision 1.114 2007/10/10 18:07:50 customdesigned # Check porn keywords in From header field. # @@ -256,6 +260,7 @@ hello_blacklist = () smart_alias = {} dspam_dict = None dspam_users = {} +dspam_train = {} dspam_userdir = None dspam_exempt = {} dspam_whitelist = {} @@ -387,6 +392,7 @@ def read_config(list): dspam_users = cp.getaddrdict('dspam','dspam_users') dspam_userdir = cp.getdefault('dspam','dspam_userdir') dspam_screener = cp.getlist('dspam','dspam_screener') + dspam_train = set(cp.getlist('dspam','dspam_train')) dspam_reject = cp.getlist('dspam','dspam_reject') dspam_internal = cp.getboolean('dspam','dspam_internal') if cp.has_option('dspam','dspam_sizelimit'): @@ -539,6 +545,12 @@ class SPFPolicy(object): policy = 'REJECT' return policy + def getTempErrorPolicy(self): + policy = self.getPolicy('spf-temperror:') + if not policy: + policy = 'REJECT' + return policy + def getPassPolicy(self): policy = self.getPolicy('spf-pass:') if not policy: @@ -895,8 +907,21 @@ class bmsMilter(Milter.Milter): txt = 'EXT: ' + txt p = SPFPolicy(q.s) # FIXME: try:finally to close policy db, or reuse with lock + if res in ('error','temperror'): + policy = p.getTempErrorPolicy() + if policy == 'CBV': + if self.mailfrom != '<>': + self.cbv_needed = (q,res) + elif policy != 'OK': + self.log('TEMPFAIL: SPF %s %i %s' % (res,code,txt)) + self.setreply(str(code),'4.3.0',txt, + 'We cannot accept your email until the DNS server for %s' % q.o, + 'is operational for TXT record queries.' + ) + return Milter.TEMPFAIL + res,code,txt = 'none',250,'EXT: ignoring DNS error' hres = None - if res not in ('pass','error','temperror'): + if res != 'pass': if self.mailfrom != '<>': # check hello name via spf unless spf pass h = spf.query(self.connectip,'',self.hello_name,receiver=receiver) @@ -1012,10 +1037,6 @@ class bmsMilter(Milter.Milter): 'We cannot accept mail from %s until this is corrected.' % q.o ) return Milter.REJECT - if res in ('error','temperror'): - self.log('TEMPFAIL: SPF %s %i %s' % (res,code,txt)) - self.setreply(str(code),'4.3.0',txt) - return Milter.TEMPFAIL kv = {} if hres and q.h != q.o: kv['helo_spf'] = hres @@ -1473,8 +1494,13 @@ class bmsMilter(Milter.Milter): elif self.blacklist: txt = ds.check_spam(user,txt,self.recipients, force_result=dspam.DSR_ISSPAM) - else: + elif user in dspam_train: txt = ds.check_spam(user,txt,self.recipients) + else: + txt = ds.check_spam(user,txt,self.recipients,classify=True) + if txt: + self.add_header("X-DSpam-Score",'%f' % ds.probability) + return False if not txt: # DISCARD if quarrantined for any recipient. It # will be resent to all recipients if they submit @@ -1697,6 +1723,8 @@ class bmsMilter(Milter.Milter): 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) diff --git a/temperror.txt b/temperror.txt new file mode 100644 index 0000000000000000000000000000000000000000..1d1c9fa2542a758e158bb5b342b037a79a6514df --- /dev/null +++ b/temperror.txt @@ -0,0 +1,33 @@ +To: %(sender)s +From: postmaster@%(receiver)s +Subject: Critical DNS configuration error +Auto-Submitted: auto-generated (configuration error) + +This is an automatically generated Delivery Status Notification. + +THIS IS A WARNING MESSAGE ONLY. + +YOU DO *NOT* NEED TO RESEND YOUR MESSAGE. + +Delivery to the following recipients has been delayed. + + %(rcpt)s + +Subject: %(subject)s +Received-SPF: %(spf_result)s + +Your DNS server is not responding to TXT queries. In other words, +it is BROKEN. You need to get somebody to fix it ASAP. We +are attempting to do TXT queries to see if you have an SPF record. + +See http://openspf.org + +We are sending you this message to alert you to the fact that +you have problems with your DNS. + +If you need further assistance, please do not hesitate to +contact me again. + +Kind regards, + +postmaster@%(receiver)s