[tor-commits] [bridgedb/develop] Add rudimentary (email_addr, gpg_key_fingerprint) whitelist feature.

isis at torproject.org isis at torproject.org
Tue Jul 8 13:05:02 UTC 2014


commit 5595c9a5384d2ce1ec2e6420192254221ce7b774
Author: Isis Lovecruft <isis at torproject.org>
Date:   Sat Jun 7 02:41:15 2014 +0000

    Add rudimentary (email_addr,gpg_key_fingerprint) whitelist feature.
    
    This serves two purposes. It allows arbitrary whitelisting of certain email
    addresses for testing purposes, and once #9332 is fully implemented, will
    allow encrypted emails to be sent to these whitelisted addresses.
    
     * FIXES part of #9332.
---
 bridgedb.conf                       |    8 +++++++-
 lib/bridgedb/email/autoresponder.py |   28 +++++++++++++++++++++++-----
 lib/bridgedb/email/server.py        |    9 +++++++++
 lib/bridgedb/test/email_helpers.py  |    3 +++
 4 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/bridgedb.conf b/bridgedb.conf
index eac6a34..85c86f1 100644
--- a/bridgedb.conf
+++ b/bridgedb.conf
@@ -15,11 +15,14 @@
 #           for details.
 # :copyright: (c) 2007-2013 The Tor Project, Inc.
 #             (c) 2007-2013, all sentient entities within the AUTHORS file
-# :version: 0.0.8
+# :version: 0.0.9
 #===============================================================================
 #
 # CHANGELOG:
 # ~~~~~~~~~~
+# Changes in version 0.0.9 - 2014-06-06
+#   * ADD EMAIL_WHITELIST setting.
+#
 # Changes in version 0.0.8 - 2014-05-14
 #   * CHANGE RECAPTCHA_PRIV_KEY to RECAPTCHA_SEC_KEY.
 #
@@ -305,6 +308,9 @@ EMAIL_DOMAIN_MAP = {"mail.google.com": "gmail.com",
 EMAIL_DOMAIN_RULES = {'gmail.com': ["ignore_dots", "dkim"],
                       'yahoo.com': ["dkim"]}
 
+# A mapping of whitelisted email addresses to GnuPG key fingerprints:
+EMAIL_WHITELIST = {}
+
 # If there are any IPs in this list, only allow incoming connections from
 # those IPs.
 EMAIL_RESTRICT_IPS = []
diff --git a/lib/bridgedb/email/autoresponder.py b/lib/bridgedb/email/autoresponder.py
index 9be7e7d..2556da9 100644
--- a/lib/bridgedb/email/autoresponder.py
+++ b/lib/bridgedb/email/autoresponder.py
@@ -433,15 +433,27 @@ class SMTPAutoresponder(smtp.SMTPClient):
         if not addrHeader:
             logging.warn("No Sender header on incoming mail.")
         else:
+            client = None
             try:
-                client = smtp.Address(addr.normalizeEmail(
+                normalized = addr.normalizeEmail(
                     addrHeader,
                     self.incoming.context.domainMap,
-                    self.incoming.context.domainRules))
-            except (addr.UnsupportedDomain, addr.BadEmail,
-                    smtp.AddressError) as error:
+                    self.incoming.context.domainRules)
+                client = smtp.Address(normalized)
+            except (addr.UnsupportedDomain, addr.BadEmail) as error:
                 logging.warn(error)
-            else:
+                # Check if it was one of the whitelisted addresses, because
+                # then it would make sense that it couldn't be canonicalized:
+                try: client = smtp.Address(addrHeader)
+                except smtp.AddressError as error: pass
+                else:
+                    if str(client) in self.incoming.context.whitelist.keys():
+                        logging.debug("Email address was whitelisted: %s."
+                                      % str(client))
+            except smtp.AddressError as error:
+                logging.warn(error)
+
+            if client:
                 clients.append(client)
         return clients
 
@@ -594,6 +606,9 @@ class SMTPAutoresponder(smtp.SMTPClient):
             return False
 
         logging.debug("Canonicalizing client email domain...")
+        # Allow whitelisted addresses through the canonicalization check:
+        if str(client) in self.incoming.context.whitelist.keys():
+            canonicalFromEmail = client.domain
         # The client's address was already checked to see if it came from a
         # supported domain and is a valid email address in :meth:`getMailTo`,
         # so we should just be able to re-extract the canonical domain safely
@@ -606,6 +621,9 @@ class SMTPAutoresponder(smtp.SMTPClient):
         # ``From:`` header should match:
         if self.incoming.canonicalFromSMTP != canonicalFromEmail:
             logging.error("SMTP/Email canonical domain mismatch!")
+            logging.debug("Canonical domain mismatch: %s != %s"
+                          % (self.incoming.canonicalFromSMTP,
+                             canonicalFromEmail))
             return False
 
         domainRules = self.incoming.context.domainRules.get(
diff --git a/lib/bridgedb/email/server.py b/lib/bridgedb/email/server.py
index 7c86395..62d3bff 100644
--- a/lib/bridgedb/email/server.py
+++ b/lib/bridgedb/email/server.py
@@ -91,6 +91,7 @@ class MailServerContext(object):
         self.domainRules = config.EMAIL_DOMAIN_RULES or {}
         self.domainMap = config.EMAIL_DOMAIN_MAP or {}
         self.canon = self.buildCanonicalDomainMap()
+        self.whitelist = config.EMAIL_WHITELIST or {}
 
         self.gpgContext = getGPGContext(config)
 
@@ -276,6 +277,14 @@ class SMTPIncomingDelivery(smtp.SMTP):
             error.
         """
         try:
+            if str(origin) in self.context.whitelist.keys():
+                logging.warn("Got SMTP 'MAIL FROM:' whitelisted address: %s."
+                             % str(origin))
+                # We need to be certain later that when the fromCanonicalSMTP
+                # domain is checked again the email 'From:' canonical domain,
+                # that we allow whitelisted addresses through the check.
+                self.fromCanonicalSMTP = origin.domain
+                return origin
             if ((origin.domain == self.context.hostname) or
                 (origin.domain == smtp.DNSNAME)):
                 self.fromCanonicalSMTP = origin.domain
diff --git a/lib/bridgedb/test/email_helpers.py b/lib/bridgedb/test/email_helpers.py
index 59b3aa8..f171419 100644
--- a/lib/bridgedb/test/email_helpers.py
+++ b/lib/bridgedb/test/email_helpers.py
@@ -37,6 +37,7 @@ EMAIL_DOMAIN_RULES = {
    'localhost': [],
 }
 EMAIL_DOMAINS = ["gmail.com", "example.com", "localhost"]
+EMAIL_WHITELIST = {'white at list.ed': 'ABCD1234ABCD1234ABCD1234ABCD1234ABCD1234'}
 EMAIL_USERNAME = "bridges"
 EMAIL_SMTP_HOST = "127.0.0.1"
 EMAIL_SMTP_PORT = 25
@@ -54,6 +55,7 @@ EMAIL_GPG_SIGNING_KEY = %s
 EMAIL_DOMAIN_MAP = %s
 EMAIL_DOMAIN_RULES = %s
 EMAIL_DOMAINS = %s
+EMAIL_WHITELIST = %s
 EMAIL_USERNAME = %s
 EMAIL_SMTP_HOST = %s
 EMAIL_SMTP_PORT = %s
@@ -69,6 +71,7 @@ EMAIL_PORT = %s
        repr(EMAIL_DOMAIN_MAP),
        repr(EMAIL_DOMAIN_RULES),
        repr(EMAIL_DOMAINS),
+       repr(EMAIL_WHITELIST),
        repr(EMAIL_USERNAME),
        repr(EMAIL_SMTP_HOST),
        repr(EMAIL_SMTP_PORT),





More information about the tor-commits mailing list