Barry Warsaw pushed to branch master at mailman / Mailman Core

Commits:
378be176 by Mark Sapiro at 2017-10-09T07:59:18-07:00
Updated the DMARC rule to treat certain DNS lookup failures as needing 
mitigation.

- - - - -
b794170a by Mark Sapiro at 2017-10-09T08:02:20-07:00
Rebased and fixed typo.

- - - - -
0ff35504 by Barry Warsaw at 2017-10-09T15:21:44+00:00
Merge branch 'dmarc' into 'master'

Updated the DMARC rule to treat certain DNS lookup failures as needing 
mitigation.

Closes #415

See merge request mailman/mailman!326
- - - - -


3 changed files:

- src/mailman/docs/NEWS.rst
- src/mailman/rules/dmarc.py
- src/mailman/rules/tests/test_dmarc.py


Changes:

=====================================
src/mailman/docs/NEWS.rst
=====================================
--- a/src/mailman/docs/NEWS.rst
+++ b/src/mailman/docs/NEWS.rst
@@ -30,6 +30,8 @@ Bugs
   additions to the ``-bounces`` and ``-confirm`` addresses.  (Closes #401)
 * Address confirmation notices are now properly encoded in the character set
   of the list's preferred_language.  (Closes #395 and #413)
+* Thanks to Jim Popovitch, certain failures in DNS lookups of DMARC policy
+  will now result in mitigations being applied.  (Closes #415)
 
 Command line
 ------------


=====================================
src/mailman/rules/dmarc.py
=====================================
--- a/src/mailman/rules/dmarc.py
+++ b/src/mailman/rules/dmarc.py
@@ -183,11 +183,23 @@ def is_reject_or_quarantine(mlist, email, dmarc_domain, 
org=False):
         txt_recs = resolver.query(dmarc_domain, dns.rdatatype.TXT)
     except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
         return KEEP_LOOKING
+    except (dns.resolver.NoNameservers):
+        elog.error(
+            'DNSException: No Nameservers available for %s (%s).',
+            email, dmarc_domain)
+        # Typically this means a dnssec validation error.  Clients that don't
+        # perform validation *may* successfully see a _dmarc RR whereas a
+        # validating mailman server won't see the _dmarc RR.  We should
+        # mitigate this email to be safe.
+        return True
     except DNSException as error:
         elog.error(
             'DNSException: Unable to query DMARC policy for %s (%s). %s',
             email, dmarc_domain, error.__doc__)
-        return KEEP_LOOKING
+        # While we can't be sure what caused the error, there is potentially
+        # a DMARC policy record that we missed and that a receiver of the mail
+        # might see.  Thus, we should err on the side of caution and mitigate.
+        return True
     # Be as robust as possible in parsing the result.
     results_by_name = {}
     cnames = {}


=====================================
src/mailman/rules/tests/test_dmarc.py
=====================================
--- a/src/mailman/rules/tests/test_dmarc.py
+++ b/src/mailman/rules/tests/test_dmarc.py
@@ -24,7 +24,7 @@ from contextlib import ExitStack
 from datetime import timedelta
 from dns.exception import DNSException
 from dns.rdatatype import CNAME, TXT
-from dns.resolver import NXDOMAIN, NoAnswer
+from dns.resolver import NXDOMAIN, NoAnswer, NoNameservers
 from http.server import BaseHTTPRequestHandler, HTTPServer
 from lazr.config import as_timedelta
 from mailman.app.lifecycle import create_list
@@ -156,6 +156,8 @@ def get_dns_resolver(
                 raise NoAnswer
             if dparts[2] == 'info':
                 raise DNSException('no internet')
+            if dparts[2] == 'home':
+                raise NoNameservers
             if dparts[1] != 'example' or dparts[2] != 'biz':
                 raise NXDOMAIN
             self.response = Answer()
@@ -227,7 +229,7 @@ To: a...@example.com
         mark = LogFileMark('mailman.error')
         rule = dmarc.DMARCMitigation()
         with get_dns_resolver():
-            self.assertFalse(rule.check(mlist, msg, {}))
+            self.assertTrue(rule.check(mlist, msg, {}))
         line = mark.readline()
         self.assertEqual(
             line[-144:],
@@ -235,6 +237,25 @@ To: a...@example.com
             'a...@example.info (_dmarc.example.info). '
             'Abstract base class shared by all dnspython exceptions.\n')
 
+    def test_dmarc_nonameservers_exception(self):
+        mlist = create_list('a...@example.com')
+        # Use action reject.  The rule only hits on reject and discard.
+        mlist.dmarc_mitigate_action = DMARCMitigateAction.reject
+        msg = mfs("""\
+From: a...@example.home
+To: a...@example.com
+
+""")
+        mark = LogFileMark('mailman.error')
+        rule = dmarc.DMARCMitigation()
+        with get_dns_resolver():
+            self.assertTrue(rule.check(mlist, msg, {}))
+        line = mark.readline()
+        self.assertEqual(
+            line[-84:],
+            'DNSException: No Nameservers available for '
+            'a...@example.home (_dmarc.example.home).\n')
+
     def test_cname_wrong_txt_name(self):
         mlist = create_list('a...@example.com')
         # Use action reject.  The rule only hits on reject and discard.



View it on GitLab: 
https://gitlab.com/mailman/mailman/compare/a3bfbe1dd2c1dd1c6286414c2b01595759044cc8...0ff35504ece1c2e06bd9aa0ff0e85f029d4d1dd3

---
View it on GitLab: 
https://gitlab.com/mailman/mailman/compare/a3bfbe1dd2c1dd1c6286414c2b01595759044cc8...0ff35504ece1c2e06bd9aa0ff0e85f029d4d1dd3
You're receiving this email because of your account on gitlab.com.
_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to