From 2d4d24f51eb1a7a187dbfd9f077c864a309b3171 Mon Sep 17 00:00:00 2001 From: Matt Molyneaux Date: Mon, 24 Mar 2014 15:00:19 +0000 Subject: [PATCH] Use the STARTTLS command to upgrade SMTP connections where possible. Adds the option `email_smtp_force_tls` which will cause `send_email` to error if it is unable to use the `STARTTLS` command (e.g. where the user knows the SMTPd supports `STARTTLS` and wishes to protect themselves against a downgrade attack) Setting both `email_smtp_user_ssl` and `email_smtp_force_tls` may result in undefined behaviour if the SMTPd has not been correctly configured. TODO: Unit tests? TODO: Documentation? --- mediagoblin/config_spec.ini | 1 + mediagoblin/tools/mail.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index c35b709d..72993ed0 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -24,6 +24,7 @@ direct_remote_path = string(default="/mgoblin_static/") # set to false to enable sending notices email_debug_mode = boolean(default=True) email_smtp_use_ssl = boolean(default=False) +email_smtp_force_tls = boolean(default=False) email_sender_address = string(default="notice@mediagoblin.example.org") email_smtp_host = string(default='') email_smtp_port = integer(default=0) diff --git a/mediagoblin/tools/mail.py b/mediagoblin/tools/mail.py index 0fabc5a9..889a4420 100644 --- a/mediagoblin/tools/mail.py +++ b/mediagoblin/tools/mail.py @@ -14,7 +14,9 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import six import smtplib +import sys from email.MIMEText import MIMEText from mediagoblin import mg_globals, messages from mediagoblin.tools import common @@ -64,6 +66,8 @@ class FakeMhost(object): 'to': to_addrs, 'message': message}) + def starttls(self): + raise smtplib.SMTPException("No STARTTLS here") def _clear_test_inboxes(): global EMAIL_TEST_INBOX @@ -103,6 +107,13 @@ def send_email(from_addr, to_addrs, subject, message_body): if not mg_globals.app_config['email_smtp_host']: # e.g. host = '' mhost.connect() # We SMTP.connect explicitly + try: + mhost.starttls() + except smtplib.SMTPException: + # Only raise an exception if we're forced to + if mg_globals.app_config['email_smtp_force_tls']: + six.reraise(*sys.exc_info()) + if ((not common.TESTS_ENABLED) and (mg_globals.app_config['email_smtp_user'] or mg_globals.app_config['email_smtp_pass'])): -- 2.25.1