diff options
Diffstat (limited to 'Mailman/Utils.py')
-rw-r--r-- | Mailman/Utils.py | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/Mailman/Utils.py b/Mailman/Utils.py index 37ae940b..89b7975e 100644 --- a/Mailman/Utils.py +++ b/Mailman/Utils.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2011 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -231,7 +231,7 @@ def ValidateEmail(s): # Pretty minimal, cheesy check. We could do better... if not s or s.count(' ') > 0: raise Errors.MMBadEmailError - if _badchars.search(s) or s[0] == '-': + if _badchars.search(s): raise Errors.MMHostileAddress, s user, domain_parts = ParseEmail(s) # This means local, unqualified addresses, are not allowed @@ -240,8 +240,9 @@ def ValidateEmail(s): if len(domain_parts) < 2: raise Errors.MMBadEmailError, s # domain parts may only contain ascii letters, digits and hyphen + # and must not begin with hyphen. for p in domain_parts: - if len(_valid_domain.sub('', p)) > 0: + if len(p) == 0 or p[0] == '-' or len(_valid_domain.sub('', p)) > 0: raise Errors.MMHostileAddress, s @@ -1067,7 +1068,8 @@ def suspiciousHTML(html): # This takes an email address, and returns True if DMARC policy is p=reject -def IsDmarcProhibited(email): +# or possibly quarantine. +def IsDMARCProhibited(email): if not dns_resolver: return False @@ -1085,7 +1087,8 @@ def IsDmarcProhibited(email): except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): return False except DNSException, e: - syslog('error', 'DNSException: Unable to query DMARC policy for %s (%s). %s', + syslog('error', + 'DNSException: Unable to query DMARC policy for %s (%s). %s', email, dmarc_domain, e.__class__) return False else: @@ -1098,10 +1101,12 @@ def IsDmarcProhibited(email): want_names = set([dmarc_domain + '.']) for txt_rec in txt_recs.response.answer: if txt_rec.rdtype == dns.rdatatype.CNAME: - cnames[txt_rec.name.to_text()] = txt_rec.items[0].target.to_text() + cnames[txt_rec.name.to_text()] = ( + txt_rec.items[0].target.to_text()) if txt_rec.rdtype != dns.rdatatype.TXT: continue - results_by_name[txt_rec.name.to_text()].append("".join(txt_rec.items[0].strings)) + results_by_name[txt_rec.name.to_text()].append( + "".join(txt_rec.items[0].strings)) expands = list(want_names) seen = set(expands) while expands: @@ -1115,26 +1120,34 @@ def IsDmarcProhibited(email): want_names.discard(item) if len(want_names) != 1: - syslog('error', 'multiple DMARC entries in results for %s, processing each to be strict', - dmarc_domain) + syslog('error', + """multiple DMARC entries in results for %s, + processing each to be strict""", + dmarc_domain) for name in want_names: if name not in results_by_name: continue - dmarcs = filter(lambda n: n.startswith('v=DMARC1;'), results_by_name[name]) + dmarcs = filter(lambda n: n.startswith('v=DMARC1;'), + results_by_name[name]) if len(dmarcs) == 0: return False if len(dmarcs) > 1: - syslog('error', 'RRset of TXT records for %s has %d v=DMARC1 entries; testing them all', + syslog('error', + """RRset of TXT records for %s has %d v=DMARC1 entries; + testing them all""", dmarc_domain, len(dmarc)) for entry in dmarcs: if re.search(r'\bp=reject\b', entry, re.IGNORECASE): - syslog('info', 'DMARC lookup for %s (%s) found p=reject in %s = %s', - email, dmarc_domain, name, entry) +# syslog('info', +# 'DMARC lookup for %s (%s) found p=reject in %s = %s', +# email, dmarc_domain, name, entry) return True - if re.search(r'\bp=quarantine\b', entry, re.IGNORECASE): - syslog('info', 'DMARC lookup for %s (%s) found p=quarantine in %s = %s', - email, dmarc_domain, name, entry) + if (mm_cfg.DMARC_QUARANTINE_MODERATION_ACTION and + re.search(r'\bp=quarantine\b', entry, re.IGNORECASE)): +# syslog('info', +# 'DMARC lookup for %s (%s) found p=quarantine in %s = %s', +# email, dmarc_domain, name, entry) return True return False |