From 994bcce7dc0f2d33471b1fa676205c8947a9781c Mon Sep 17 00:00:00 2001 From: Stuart Gathman <stuart@gathman.org> Date: Fri, 24 Feb 2006 02:12:54 +0000 Subject: [PATCH] Properly report hard PermError (lax mode fails also) by always setting perm_error attribute with PermError exception. Improve reporting of invalid domain PermError. --- TODO | 3 +++ bms.py | 13 ++++++++++--- spf.py | 7 ++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index dc909e9..cf3e57c 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,6 @@ +Added Message-ID header to DSN with SRS signed sender. When seen on incoming +rfc ignorant failure message, blacklist sender. + Allow verified hostnames for trusted_relay. E.g. HELO name that passes SPF. diff --git a/bms.py b/bms.py index ae62d40..11d50f7 100644 --- a/bms.py +++ b/bms.py @@ -1,6 +1,11 @@ #!/usr/bin/env python # A simple milter that has grown quite a bit. # $Log$ +# Revision 1.55 2006/02/17 05:04:29 customdesigned +# Use SRS sign domain list. +# Accept but do not use for training whitelisted senders without SPF pass. +# Immediate rejection of unsigned bounces. +# # Revision 1.54 2006/02/16 02:16:36 customdesigned # User specific SPF receiver policy. # @@ -753,6 +758,8 @@ class bmsMilter(Milter.Milter): if hostname == 'GC': n = gc.collect() self.log("gc:",n,' unreachable objects') + self.log("auto-whitelist:",len(auto_whitelist),' entries') + self.log("cbv_cache:",len(cbv_cache),' entries') self.setreply('550','5.7.1','%d unreachable objects'%n) return Milter.REJECT return Milter.CONTINUE @@ -935,9 +942,6 @@ class bmsMilter(Milter.Milter): res,code,txt = q.best_guess('v=spf1 a/24 mx/24') else: res,code,txt = q.best_guess() - if q.perm_error: # FIXME: should never happen? - res,code,txt = q.perm_error.ext # extended result - txt = 'EXT: ' + txt if self.missing_ptr and ores == 'none' and res != 'pass' \ and hres != 'pass': policy = p.getNonePolicy() @@ -1638,6 +1642,9 @@ class bmsMilter(Milter.Milter): template = file(template_name).read() except IOError: template = None m = dsn.create_msg(q,self.recipients,msg,template) + if srs: + msgid = srs.forward(sender,self.receiver) + m.add_header('Message-Id','<%s>'%msgid) m = m.as_string() print >>open('last_dsn','w'),m res = dsn.send_dsn(sender,self.receiver,m) diff --git a/spf.py b/spf.py index 82cb128..428673a 100755 --- a/spf.py +++ b/spf.py @@ -47,6 +47,9 @@ For news, bugfixes, etc. visit the home page for this implementation at # Terrence is not responding to email. # # $Log$ +# Revision 1.18 2005/12/29 19:15:35 customdesigned +# Handle NULL MX +# # Revision 1.17 2005/12/23 21:44:15 customdesigned # Always include keyword data in Received-SPF header. # @@ -507,6 +510,8 @@ class query(object): except TempError,x: return ('error', 450, 'SPF Temporary Error: ' + str(x)) except PermError,x: + if not self.perm_error: + self.perm_error = x self.prob = x.msg if x.mech: self.mech.append(x.mech) @@ -577,7 +582,7 @@ class query(object): arg = self.expand(arg) if not (0 < arg.find('.') < len(arg) - 1): raise PermError('Invalid domain found (use FQDN)', - arg) + m+':'+arg) if m == 'include': if arg == self.d: if mech != 'include': -- GitLab