flask-mail icon indicating copy to clipboard operation
flask-mail copied to clipboard

SSL used even when explicitly set to False

Open thmsklngr opened this issue 6 years ago • 4 comments

Hi, I just encountered a problem which took me some time to figure out what happens. I developed a small application using Flask-Mail to send emails. Hosting ist done on Heroku. I use environment variables to configure my mailhost and so here's my configuration (read via heroku config):

MAIL_USERNAME: my_username
MAIL_PASSWORD: my_secret
MAIL_HOST: smtp.example.com
MAIL_USE_SSL: False
MAIL_PORT: 25

As you can see, SSL is explicitly set to false, the standard port 25 is used. But for some reason smtplib still goes for using an SSL connection:

2019-08-07T08:51:16.582041+00:00 app[web.1]: Exception in thread Thread-1:
2019-08-07T08:51:16.582044+00:00 app[web.1]: Traceback (most recent call last):
2019-08-07T08:51:16.582046+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/threading.py", line 916, in _bootstrap_inner
2019-08-07T08:51:16.582047+00:00 app[web.1]:     self.run()
2019-08-07T08:51:16.582049+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/threading.py", line 864, in run
2019-08-07T08:51:16.582050+00:00 app[web.1]:     self._target(*self._args, **self._kwargs)
2019-08-07T08:51:16.582052+00:00 app[web.1]:   File "/app/stocksportevents/helper.py", line 125, in send_async_mail
2019-08-07T08:51:16.582053+00:00 app[web.1]:     mail.send(msg)
2019-08-07T08:51:16.582055+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask_mail.py", line 491, in send
2019-08-07T08:51:16.582056+00:00 app[web.1]:     with self.connect() as connection:
2019-08-07T08:51:16.582057+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask_mail.py", line 144, in __enter__
2019-08-07T08:51:16.582059+00:00 app[web.1]:     self.host = self.configure_host()
2019-08-07T08:51:16.582060+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask_mail.py", line 156, in configure_host
2019-08-07T08:51:16.582062+00:00 app[web.1]:     host = smtplib.SMTP_SSL(self.mail.server, self.mail.port)
2019-08-07T08:51:16.582063+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/smtplib.py", line 1031, in __init__
2019-08-07T08:51:16.582065+00:00 app[web.1]:     source_address)
2019-08-07T08:51:16.582066+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/smtplib.py", line 251, in __init__
2019-08-07T08:51:16.582067+00:00 app[web.1]:     (code, msg) = self.connect(host, port)
2019-08-07T08:51:16.582069+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/smtplib.py", line 336, in connect
2019-08-07T08:51:16.582070+00:00 app[web.1]:     self.sock = self._get_socket(host, port, self.timeout)
2019-08-07T08:51:16.582071+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/smtplib.py", line 1039, in _get_socket
2019-08-07T08:51:16.582073+00:00 app[web.1]:     server_hostname=self._host)
2019-08-07T08:51:16.582074+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/ssl.py", line 407, in wrap_socket
2019-08-07T08:51:16.582075+00:00 app[web.1]:     _context=self, _session=session)
2019-08-07T08:51:16.582077+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/ssl.py", line 817, in __init__
2019-08-07T08:51:16.582078+00:00 app[web.1]:     self.do_handshake()
2019-08-07T08:51:16.582080+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/ssl.py", line 1077, in do_handshake
2019-08-07T08:51:16.582081+00:00 app[web.1]:     self._sslobj.do_handshake()
2019-08-07T08:51:16.582082+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/ssl.py", line 689, in do_handshake
2019-08-07T08:51:16.582084+00:00 app[web.1]:     self._sslobj.do_handshake()
2019-08-07T08:51:16.582085+00:00 app[web.1]: ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:852)

After several tries and reloads I came across the idea to simply unset MAIL_USE_SSL on Heroku - and it was working! I tried to retrace the variable in your code, but I would say there's nothing which would point to this problem. You're just reading MAIL_USE_SSL from app.config and set self.use_ssl accordingly, that's it.

Any ideas why this happens?

Regads, Thomas

thmsklngr avatar Aug 07 '19 09:08 thmsklngr

I can confirm this. I set MAIL_USE_SSL to False and tracked that value into flask_mail.py. It seems like it's lost at this point in _MailMixin.connect()

app = getattr(self, "app", None) or current_app
try:
  return Connection(app.extensions['mail'])
except KeyError:
  ...

openbrian avatar Sep 12 '19 13:09 openbrian

It seems that "class Mail" is not being registered as an app.extension as it should in Mail.init_app(self, app). Which is to say when calling

mail = Mail(app)

that the app is None, because Mail.init will call self.init_app(app).

openbrian avatar Sep 12 '19 13:09 openbrian

Also in your app config (like settings.py if you use that), be sure not to have a comma like this:

MAIL_USE_SSL = False,

That will make this setting a tuple, not a boolean.

openbrian avatar Sep 12 '19 14:09 openbrian

Also in your app config (like settings.py if you use that), be sure not to have a comma like this:

MAIL_USE_SSL = False,

That will make this setting a tuple, not a boolean.

great,I made this mistake.Thank you.

LittleTheFu avatar Nov 10 '19 02:11 LittleTheFu