Commit 012ef1a4 authored by Cecylia Bocovich's avatar Cecylia Bocovich 💬
Browse files

Check to see if email is from an autoresponder

This checks to see if an incoming request is from a known autoresponder.
GetTor can get into infinite loops with itself or postmaster addresses
(Bug #34286)
parent b78bc3ff
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -86,8 +86,8 @@ class EmailParser(object):
            )

            # Add a check for auto-generated mail-daemon emails
            if "mailer-daemon@" in norm_addr.lower():
                raise AddressError("Received mail from Mail Delivery System {}"
            if validate_email.autoresponder(norm_addr):
                raise AddressError("Received mail from a known autoresponder {}"
                        .format(msg['From']))
            return True

+21 −0
Original line number Diff line number Diff line
@@ -96,6 +96,13 @@ MX_DNS_CACHE = {}
MX_CHECK_CACHE = {}


# List of known autoresponder email patterns
autoresponders = [
        r'mailer-daemon@.*',
        r'postmaster@.*',
        r'gettor.*@torproject.org'
]

def get_mx_ip(hostname):
    if hostname not in MX_DNS_CACHE:
        try:
@@ -176,6 +183,20 @@ def validate_email(email, check_mx=False, verify=False, debug=False, smtp_timeou
        return None
    return True

def autoresponder(from_addr):
    """
    We sometimes receive messages from autoresponders like Mail Deliver System
    or postmaster due to bounced messages. This can send GetTor into an infinite
    loop with the autoresponder (or itself).

    Returns true if the email address matches a known autoresponder pattern.
    """
    for pattern in autoresponders:
        if re.match(pattern, from_addr.lower()) is not None:
            return True

    return False

if __name__ == "__main__":
    import time
    while True:
+16 −1
Original line number Diff line number Diff line
@@ -289,13 +289,28 @@ class EmailServiceTests(unittest.TestCase):
                ">\n")
        self.assertEqual(request["command"], "help")

    def test_bounce(self):
    def test_from_autoresponder(self):
        ep = conftests.EmailParser(self.settings, "gettor@torproject.org")
        request = ep.parse("From: MAILER-DAEMON@mx1.riseup.net\n"
                "Subject: Undelivered Mail Returned to Sender\r\n"
                "To: gettor@torproject.org\n osx en\n")

        self.assertEqual(request, {})
        request = ep.parse("From: postmaster@example.sk\n"
                "Subject: Undelivered Mail Returned to Sender\r\n"
                "To: gettor@torproject.org\n\n osx en\n")

        self.assertEqual(request, {})
        request = ep.parse("From: gettor@torproject.org\n"
                "Subject: links\r\n"
                "To: gettor@torproject.org\n\n osx en\n")

        self.assertEqual(request, {})
        request = ep.parse("From: gettor+en@torproject.org\n"
                "Subject: links\r\n"
                "To: gettor@torproject.org\n\n osx en\n")

        self.assertEqual(request, {})

if __name__ == "__main__":
    unittest.main()