diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman/handlers/tests/test_dmarc.py | 128 | ||||
| -rw-r--r-- | src/mailman/rules/dmarc.py | 19 | ||||
| -rw-r--r-- | src/mailman/rules/tests/test_dmarc.py | 33 |
3 files changed, 167 insertions, 13 deletions
diff --git a/src/mailman/handlers/tests/test_dmarc.py b/src/mailman/handlers/tests/test_dmarc.py index a90fb3618..3d60b6d02 100644 --- a/src/mailman/handlers/tests/test_dmarc.py +++ b/src/mailman/handlers/tests/test_dmarc.py @@ -20,8 +20,10 @@ import unittest from mailman.app.lifecycle import create_list +from mailman.app.membership import add_member from mailman.handlers import dmarc from mailman.interfaces.mailinglist import DMARCMitigateAction, ReplyToMunging +from mailman.interfaces.subscriptions import RequestRecord from mailman.testing.helpers import specialized_message_from_string as mfs from mailman.testing.layers import ConfigLayer @@ -77,6 +79,32 @@ Content-Transfer-Encoding: 7bit dmarc.process(self._mlist, msg, msgdata) self.assertMultiLineEqual(msg.as_string(), self._text) + def test_no_mitigation_no_change_1(self): + msg = mfs(self._text) + self._mlist.dmarc_mitigate_unconditionally = True + dmarc.process(self._mlist, msg, {}) + self.assertMultiLineEqual(msg.as_string(), self._text) + + def test_no_mitigation_no_change_2(self): + msg = mfs(self._text) + msgdata = {'dmarc': True} + dmarc.process(self._mlist, msg, msgdata) + self.assertMultiLineEqual(msg.as_string(), self._text) + + def test_action_reject_mitigate_unconditionally(self): + msg = mfs(self._text) + self._mlist.dmarc_mitigate_unconditionally = True + self._mlist.dmarc_mitigate_action = DMARCMitigateAction.reject + dmarc.process(self._mlist, msg, {}) + self.assertMultiLineEqual(msg.as_string(), self._text) + + def test_action_discard_mitigate_unconditionally(self): + msg = mfs(self._text) + self._mlist.dmarc_mitigate_unconditionally = True + self._mlist.dmarc_mitigate_action = DMARCMitigateAction.discard + dmarc.process(self._mlist, msg, {}) + self.assertMultiLineEqual(msg.as_string(), self._text) + def test_action_munge_from(self): self._mlist.dmarc_mitigate_action = DMARCMitigateAction.munge_from msgdata = {'dmarc': True} @@ -107,6 +135,106 @@ Content-Transfer-Encoding: 7bit --=====abc==-- """) + def test_action_munge_from_no_from(self): + self._mlist.dmarc_mitigate_action = DMARCMitigateAction.munge_from + msgdata = dict( + dmarc=True, + original_sender='anne@example.com', + ) + msg = mfs(self._text) + del msg['from'] + dmarc.process(self._mlist, msg, msgdata) + self.assertMultiLineEqual(msg.as_string(), """\ +To: ant@example.com +Subject: A subject +X-Mailman-Version: X.Y +Message-ID: <some-id@example.com> +Date: Fri, 1 Jan 2016 00:00:01 +0000 +Another-Header: To test removal in wrapper +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="=====abc==" +From: anne--- via Ant <ant@example.com> +Reply-To: anne@example.com + +--=====abc== +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: 7bit + +Some things to say. +--=====abc== +Content-Type: text/html; charset="us-ascii" +Content-Transfer-Encoding: 7bit + +<html><head></head><body>Some things to say.</body></html> +--=====abc==-- +""") + + def test_action_munge_from_display_name_in_from(self): + self._mlist.dmarc_mitigate_action = DMARCMitigateAction.munge_from + msgdata = {'dmarc': True} + msg = mfs(self._text) + del msg['from'] + msg['From'] = 'Anne Person <anne@example.com>' + dmarc.process(self._mlist, msg, msgdata) + self.assertMultiLineEqual(msg.as_string(), """\ +To: ant@example.com +Subject: A subject +X-Mailman-Version: X.Y +Message-ID: <some-id@example.com> +Date: Fri, 1 Jan 2016 00:00:01 +0000 +Another-Header: To test removal in wrapper +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="=====abc==" +From: Anne Person via Ant <ant@example.com> +Reply-To: Anne Person <anne@example.com> + +--=====abc== +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: 7bit + +Some things to say. +--=====abc== +Content-Type: text/html; charset="us-ascii" +Content-Transfer-Encoding: 7bit + +<html><head></head><body>Some things to say.</body></html> +--=====abc==-- +""") + + def test_action_munge_from_display_name_in_list(self): + self._mlist.dmarc_mitigate_action = DMARCMitigateAction.munge_from + add_member( + self._mlist, + RequestRecord('anne@example.com', 'Anna Banana') + ) + msgdata = {'dmarc': True} + msg = mfs(self._text) + dmarc.process(self._mlist, msg, msgdata) + self.assertMultiLineEqual(msg.as_string(), """\ +To: ant@example.com +Subject: A subject +X-Mailman-Version: X.Y +Message-ID: <some-id@example.com> +Date: Fri, 1 Jan 2016 00:00:01 +0000 +Another-Header: To test removal in wrapper +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="=====abc==" +From: Anna Banana via Ant <ant@example.com> +Reply-To: anne@example.com + +--=====abc== +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: 7bit + +Some things to say. +--=====abc== +Content-Type: text/html; charset="us-ascii" +Content-Transfer-Encoding: 7bit + +<html><head></head><body>Some things to say.</body></html> +--=====abc==-- +""") + def test_no_action_without_msgdata(self): self._mlist.dmarc_mitigate_action = DMARCMitigateAction.munge_from msg = mfs(self._text) diff --git a/src/mailman/rules/dmarc.py b/src/mailman/rules/dmarc.py index dac1cd88c..90b874e32 100644 --- a/src/mailman/rules/dmarc.py +++ b/src/mailman/rules/dmarc.py @@ -43,8 +43,6 @@ def _get_suffixes(url): # This loads and parses the data from the url argument into s_dict for # use by _get_org_dom. global s_dict - if s_dict: - return if not url: return try: @@ -199,17 +197,16 @@ def _DMARCProhibited(mlist, email, dmarc_domain, org=False): policy = mo.group(1).lower() else: continue - if policy == 'reject': - vlog.info( - """%s: DMARC lookup for %s (%s) - found p=reject in %s = %s""", - mlist.list_name, email, dmarc_domain, name, entry) - return True - if policy == 'quarantine': + if policy in ('reject', 'quarantine'): vlog.info( """%s: DMARC lookup for %s (%s) - found p=quarantine in %s = %s""", - mlist.list_name, email, dmarc_domain, name, entry) + found p=%s in %s = %s""", + mlist.list_name, + email, + dmarc_domain, + policy, + name, + entry) return True return False diff --git a/src/mailman/rules/tests/test_dmarc.py b/src/mailman/rules/tests/test_dmarc.py index 930741997..666375699 100644 --- a/src/mailman/rules/tests/test_dmarc.py +++ b/src/mailman/rules/tests/test_dmarc.py @@ -15,12 +15,15 @@ # You should have received a copy of the GNU General Public License along with # GNU Mailman. If not, see <http://www.gnu.org/licenses/>. -"""Support for mocking dnspython calls from dmarc rules.""" +"""Provides support for mocking dnspython calls from dmarc rules and some +organizational domain tests.""" from dns.rdatatype import TXT from dns.resolver import NXDOMAIN, NoAnswer +from mailman.rules import dmarc +from mailman.testing.layers import ConfigLayer from public import public -from unittest import mock +from unittest import TestCase, mock @public @@ -79,3 +82,29 @@ def get_dns_resolver(): return self patcher = mock.patch('dns.resolver.Resolver', Resolver) return patcher + + +class TestDMARCRules(TestCase): + """Test organizational domain determination.""" + + layer = ConfigLayer + + def setUp(self): + pass + + def test_no_url(self): + dmarc.s_dict = {} + dmarc._get_suffixes(None) + self.assertEqual(dmarc.s_dict, dict()) + + def test_no_data_for_domain(self): + self.assertEqual( + dmarc._get_org_dom('sub.dom.example.nxtld'), 'example.nxtld') + + def test_domain_with_wild_card(self): + self.assertEqual( + dmarc._get_org_dom('ssub.sub.foo.kobe.jp'), 'sub.foo.kobe.jp') + + def test_exception_to_wild_card(self): + self.assertEqual( + dmarc._get_org_dom('ssub.sub.city.kobe.jp'), 'city.kobe.jp') |
