Skip to content

Added SMTP SSL/TLS support#7960

Merged
fabaff merged 5 commits into
home-assistant:devfrom
sn0oz:smtp-ssltls
Jun 19, 2017
Merged

Added SMTP SSL/TLS support#7960
fabaff merged 5 commits into
home-assistant:devfrom
sn0oz:smtp-ssltls

Conversation

@sn0oz
Copy link
Copy Markdown
Contributor

@sn0oz sn0oz commented Jun 8, 2017

Description:

  • Add SMTP SSL/TLS support from smtplib.py's class smtplib.SMTP_SSL
  • configurable option like 'starttls', default to False

I ran tox and had errors, not sure how to publish results, please help.

Related issue (if applicable): fixes #

Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#2843

Example entry for configuration.yaml (if applicable):

notify:
  - name: mail
    platform: smtp
    server: !secret smtp_server
    port: 465
    sender: !secret mail_alert
    username: !secret mail_username
    password: !secret mail_password
    recipient: !secret mail_admin
    starttls: false
    ssltls: true
    debug: true

automation:
  trigger:
    platform: homeassistant
    event: start
  action:
    - service: notify.mail
      data:
        title: "HASSdev started"

Checklist:

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • New dependencies have been added to the REQUIREMENTS variable (example).
  • New dependencies are only imported inside functions that use them (example).
  • New dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

If the code does not interact with devices:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • Tests have been added to verify that the new code works.

@homeassistant
Copy link
Copy Markdown
Contributor

Hi @sn0oz,

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

Comment thread homeassistant/components/notify/smtp.py Outdated
if self.ssltls:
mail = smtplib.SMTP_SSL(self._server, self._port, timeout=self._timeout)
else:
mail = smtplib.SMTP(self._server, self._port, timeout=self._timeout)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (80 > 79 characters)

Comment thread homeassistant/components/notify/smtp.py Outdated
"""Connect/authenticate to SMTP Server."""
mail = smtplib.SMTP(self._server, self._port, timeout=self._timeout)
if self.ssltls:
mail = smtplib.SMTP_SSL(self._server, self._port, timeout=self._timeout)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (84 > 79 characters)

Comment thread homeassistant/components/notify/smtp.py Outdated
"""Implement the notification service for E-mail messages."""

def __init__(self, server, port, timeout, sender, starttls, username,
def __init__(self, server, port, timeout, sender, starttls, ssltls, username,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (81 > 79 characters)

@amelchio
Copy link
Copy Markdown
Contributor

amelchio commented Jun 8, 2017

I think this is confusing:

    starttls: false
    ssltls: true

I wonder if a single security config with these options could work instead:

  • auto (default)
  • starttls
  • ssl
  • none (not by default if a password is used)

(I know it's much more work to make it like that :-)

@sn0oz
Copy link
Copy Markdown
Contributor Author

sn0oz commented Jun 9, 2017

Totally agree, this is just a quick fix. It should not be possible to set the starttls and ssltls options to true simultaneously.
Could you specify how the "auto" option would work ?

@amelchio
Copy link
Copy Markdown
Contributor

amelchio commented Jun 9, 2017

I was thinking "auto" could work like this:

  1. if port is 465: pick "ssl"
  2. otherwise, if server supports SMTP STARTTLS: pick "starttls"
  3. otherwise, if password is specified: report failure
  4. otherwise, pick "none"

If that is too complicated, the first two should work for many users and the rest would have to specify "none" to confirm that they want unencrypted communication.

@sn0oz
Copy link
Copy Markdown
Contributor Author

sn0oz commented Jun 9, 2017

In my understanding, the encryption type is not related to password authentication.
You can authenticate by password on a non-encrypted SMTP session.
The encryption protocol may use any port depending on the server, SSL/TLS on port 587 is possible.

So the security option could be any of:

  • ssltls (default for enhanced security)
  • starttls
  • none

And port would be optional, default depending on the security option.

@amelchio
Copy link
Copy Markdown
Contributor

amelchio commented Jun 9, 2017

You can absolutely send your password in cleartext but it's a bad idea and I don't think we should encourage it (even if it is the current default).

@sn0oz
Copy link
Copy Markdown
Contributor Author

sn0oz commented Jun 12, 2017

We could set the default security to ssltls and add a warning on the documentation about sending password on a non encrypted session.
This would break existing configurations, is everybody ok with this ?

@amelchio
Copy link
Copy Markdown
Contributor

I don't think that's a good default, port 465 has been deprecated for 20 years. The standard these days is port 587 with STARTTLS.

@sn0oz
Copy link
Copy Markdown
Contributor Author

sn0oz commented Jun 13, 2017

It seems STARTTLS is less secure than SSL/TLS, as it is subject to man-in-the-middle attacks, and depending on the client if encryption negotiation fails it may fallback to non-encrypted session. https://en.wikipedia.org/wiki/Opportunistic_TLS
If I understand correctly port 465 as been deprecated for SMTP over SSL/TLS but is still in use on most mail servers (Gmail, etc...). More on this: https://www.fastmail.com/help/technical/ssltlsstarttls.html

@sn0oz
Copy link
Copy Markdown
Contributor Author

sn0oz commented Jun 16, 2017

Commited new proposal with "encryption" option, defaults to ssltls, and port defaults to 465.
Test configuration:

automation:
  trigger:
    platform: homeassistant
    event: start
  action:
    - service: notify.mail
      data:
        title: "HASSdev started"
        message: "yep"

notify:
  - name: mail
    platform: smtp
    server: !secret smtp_server
    sender: !secret mail_alert
    username: !secret mail_username
    password: !secret mail_password
    recipient: !secret mail_admin
    encryption: ssltls
    debug: true

Comment thread homeassistant/components/notify/smtp.py Outdated
if self.encryption == "ssltls":
mail = smtplib.SMTP_SSL(self._server, self._port, timeout=self._timeout)
elif self.encryption == "none" or self.encryption == "starttls":
mail = smtplib.SMTP(self._server, self._port, timeout=self._timeout)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (80 > 79 characters)

Comment thread homeassistant/components/notify/smtp.py Outdated
"""Connect/authenticate to SMTP Server."""
mail = smtplib.SMTP(self._server, self._port, timeout=self._timeout)
if self.encryption == "ssltls":
mail = smtplib.SMTP_SSL(self._server, self._port, timeout=self._timeout)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (84 > 79 characters)

Comment thread homeassistant/components/notify/smtp.py Outdated
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
vol.Optional(CONF_STARTTLS, default=DEFAULT_STARTTLS): cv.boolean,
vol.Optional(CONF_ENCRYPTION, default=DEFAULT_ENCRYPTION): cv.string,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should limit the options to valid entries. See our validation docs.

Comment thread homeassistant/components/notify/smtp.py Outdated
mail = smtplib.SMTP(self._server, self._port, timeout=self._timeout)
if self.encryption == "ssltls":
mail = smtplib.SMTP_SSL(self._server, self._port, timeout=self._timeout)
elif self.encryption == "none" or self.encryption == "starttls":
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be an else as you are covering the the two other options.

Comment thread homeassistant/components/notify/smtp.py Outdated
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
vol.Optional(CONF_STARTTLS, default=DEFAULT_STARTTLS): cv.boolean,
vol.Optional(CONF_ENCRYPTION, default=DEFAULT_ENCRYPTION): vol.In(['ssltls','starttls','none']),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (100 > 79 characters)
missing whitespace after ','

@sn0oz
Copy link
Copy Markdown
Contributor Author

sn0oz commented Jun 18, 2017

Thanks. Now the component fails to load with a nice error message:

2017-06-18 11:17:08 ERROR (MainThread) [homeassistant.config] Invalid config for [notify.smtp]: value is not allowed for dictionary value @ data['encryption']. Got 'wrong'. (See ?, line ?). Please check the docs at https://home-assistant.io/components/notify.smtp/

@fabaff fabaff merged commit 8e34c27 into home-assistant:dev Jun 19, 2017
@amelchio
Copy link
Copy Markdown
Contributor

STARTTLS is not less secure than the deprecated SSL wrapping. True, it can be "depending on the client" but in this case the client is HA, so we could choose not to be vulnerable.

@balloob balloob mentioned this pull request Jul 1, 2017
@sn0oz sn0oz deleted the smtp-ssltls branch July 8, 2017 08:40
dethpickle pushed a commit to dethpickle/home-assistant that referenced this pull request Aug 18, 2017
* Added SMTP SSL/TLS support

* added new encryption option

* validation of encryption option

* Fix lint issues

* Rename var
@home-assistant home-assistant locked and limited conversation to collaborators Oct 20, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants