From 66a1a108bf87e015e4508bfb52748b326c31daf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C4=93teris=20Caune?= Date: Tue, 8 Sep 2020 12:06:32 +0300 Subject: [PATCH] When decoding inbound emails, decode encoded headers. Fixes #420 --- CHANGELOG.md | 1 + hc/api/management/commands/smtpd.py | 5 ++++- hc/api/tests/test_smtpd.py | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a007d7d9..f0ed9c02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. - Don't allow duplicate team memberships - When copying a check, copy all fields from the "Filtering Rules" dialog (#417) - Fix missing Resume button (#421) +- When decoding inbound emails, decode encoded headers (#420) ## v1.16.0 - 2020-08-04 diff --git a/hc/api/management/commands/smtpd.py b/hc/api/management/commands/smtpd.py index 173c582d..001906ec 100644 --- a/hc/api/management/commands/smtpd.py +++ b/hc/api/management/commands/smtpd.py @@ -1,5 +1,6 @@ import asyncore import email +import email.policy import re from smtpd import SMTPServer @@ -41,7 +42,9 @@ def _process_message(remote_addr, mailfrom, mailto, data): action = "success" if check.subject or check.subject_fail: action = "ign" - subject = email.message_from_string(data).get("subject", "") + # Specify policy, the default policy does not decode encoded headers: + parsed = email.message_from_string(data, policy=email.policy.SMTP) + subject = parsed.get("subject", "") if check.subject and _match(subject, check.subject): action = "success" elif check.subject_fail and _match(subject, check.subject_fail): diff --git a/hc/api/tests/test_smtpd.py b/hc/api/tests/test_smtpd.py index 5d583ab3..db8a0a8f 100644 --- a/hc/api/tests/test_smtpd.py +++ b/hc/api/tests/test_smtpd.py @@ -98,3 +98,15 @@ class SmtpdTestCase(BaseTestCase): self.assertEqual(ping.scheme, "email") self.assertEqual(ping.ua, "Email from foo@example.org") self.assertEqual(ping.kind, "fail") + + def test_it_handles_encoded_subject(self): + self.check.subject = "SUCCESS" + self.check.save() + + body = PAYLOAD_TMPL % "=?US-ASCII?B?W1NVQ0NFU1NdIEJhY2t1cCBjb21wbGV0ZWQ=?=" + _process_message("1.2.3.4", "foo@example.org", self.email, body.encode("utf8")) + + ping = Ping.objects.latest("id") + self.assertEqual(ping.scheme, "email") + self.assertEqual(ping.ua, "Email from foo@example.org") + self.assertEqual(ping.kind, None)