Attach SSL context to SMTP notify and IMAP sensor (#72568)

This commit is contained in:
Paulus Schoutsen 2022-05-26 22:15:20 -07:00 committed by GitHub
parent a526b2b819
commit cbd0c8976b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 18 deletions

View File

@ -17,12 +17,14 @@ from homeassistant.const import (
CONF_PORT, CONF_PORT,
CONF_USERNAME, CONF_USERNAME,
CONF_VALUE_TEMPLATE, CONF_VALUE_TEMPLATE,
CONF_VERIFY_SSL,
CONTENT_TYPE_TEXT_PLAIN, CONTENT_TYPE_TEXT_PLAIN,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util.ssl import client_context
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -46,6 +48,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_FOLDER, default="INBOX"): cv.string, vol.Optional(CONF_FOLDER, default="INBOX"): cv.string,
vol.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
} }
) )
@ -58,11 +61,12 @@ def setup_platform(
) -> None: ) -> None:
"""Set up the Email sensor platform.""" """Set up the Email sensor platform."""
reader = EmailReader( reader = EmailReader(
config.get(CONF_USERNAME), config[CONF_USERNAME],
config.get(CONF_PASSWORD), config[CONF_PASSWORD],
config.get(CONF_SERVER), config[CONF_SERVER],
config.get(CONF_PORT), config[CONF_PORT],
config.get(CONF_FOLDER), config[CONF_FOLDER],
config[CONF_VERIFY_SSL],
) )
if (value_template := config.get(CONF_VALUE_TEMPLATE)) is not None: if (value_template := config.get(CONF_VALUE_TEMPLATE)) is not None:
@ -70,8 +74,8 @@ def setup_platform(
sensor = EmailContentSensor( sensor = EmailContentSensor(
hass, hass,
reader, reader,
config.get(CONF_NAME) or config.get(CONF_USERNAME), config.get(CONF_NAME) or config[CONF_USERNAME],
config.get(CONF_SENDERS), config[CONF_SENDERS],
value_template, value_template,
) )
@ -82,21 +86,25 @@ def setup_platform(
class EmailReader: class EmailReader:
"""A class to read emails from an IMAP server.""" """A class to read emails from an IMAP server."""
def __init__(self, user, password, server, port, folder): def __init__(self, user, password, server, port, folder, verify_ssl):
"""Initialize the Email Reader.""" """Initialize the Email Reader."""
self._user = user self._user = user
self._password = password self._password = password
self._server = server self._server = server
self._port = port self._port = port
self._folder = folder self._folder = folder
self._verify_ssl = verify_ssl
self._last_id = None self._last_id = None
self._unread_ids = deque([]) self._unread_ids = deque([])
self.connection = None self.connection = None
def connect(self): def connect(self):
"""Login and setup the connection.""" """Login and setup the connection."""
ssl_context = client_context() if self._verify_ssl else None
try: try:
self.connection = imaplib.IMAP4_SSL(self._server, self._port) self.connection = imaplib.IMAP4_SSL(
self._server, self._port, ssl_context=ssl_context
)
self.connection.login(self._user, self._password) self.connection.login(self._user, self._password)
return True return True
except imaplib.IMAP4.error: except imaplib.IMAP4.error:

View File

@ -25,10 +25,12 @@ from homeassistant.const import (
CONF_SENDER, CONF_SENDER,
CONF_TIMEOUT, CONF_TIMEOUT,
CONF_USERNAME, CONF_USERNAME,
CONF_VERIFY_SSL,
) )
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.reload import setup_reload_service from homeassistant.helpers.reload import setup_reload_service
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from homeassistant.util.ssl import client_context
from . import DOMAIN, PLATFORMS from . import DOMAIN, PLATFORMS
@ -65,6 +67,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
vol.Optional(CONF_PASSWORD): cv.string, vol.Optional(CONF_PASSWORD): cv.string,
vol.Optional(CONF_SENDER_NAME): cv.string, vol.Optional(CONF_SENDER_NAME): cv.string,
vol.Optional(CONF_DEBUG, default=DEFAULT_DEBUG): cv.boolean, vol.Optional(CONF_DEBUG, default=DEFAULT_DEBUG): cv.boolean,
vol.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
} }
) )
@ -73,16 +76,17 @@ def get_service(hass, config, discovery_info=None):
"""Get the mail notification service.""" """Get the mail notification service."""
setup_reload_service(hass, DOMAIN, PLATFORMS) setup_reload_service(hass, DOMAIN, PLATFORMS)
mail_service = MailNotificationService( mail_service = MailNotificationService(
config.get(CONF_SERVER), config[CONF_SERVER],
config.get(CONF_PORT), config[CONF_PORT],
config.get(CONF_TIMEOUT), config[CONF_TIMEOUT],
config.get(CONF_SENDER), config[CONF_SENDER],
config.get(CONF_ENCRYPTION), config[CONF_ENCRYPTION],
config.get(CONF_USERNAME), config.get(CONF_USERNAME),
config.get(CONF_PASSWORD), config.get(CONF_PASSWORD),
config.get(CONF_RECIPIENT), config[CONF_RECIPIENT],
config.get(CONF_SENDER_NAME), config.get(CONF_SENDER_NAME),
config.get(CONF_DEBUG), config[CONF_DEBUG],
config[CONF_VERIFY_SSL],
) )
if mail_service.connection_is_valid(): if mail_service.connection_is_valid():
@ -106,6 +110,7 @@ class MailNotificationService(BaseNotificationService):
recipients, recipients,
sender_name, sender_name,
debug, debug,
verify_ssl,
): ):
"""Initialize the SMTP service.""" """Initialize the SMTP service."""
self._server = server self._server = server
@ -118,18 +123,25 @@ class MailNotificationService(BaseNotificationService):
self.recipients = recipients self.recipients = recipients
self._sender_name = sender_name self._sender_name = sender_name
self.debug = debug self.debug = debug
self._verify_ssl = verify_ssl
self.tries = 2 self.tries = 2
def connect(self): def connect(self):
"""Connect/authenticate to SMTP Server.""" """Connect/authenticate to SMTP Server."""
ssl_context = client_context() if self._verify_ssl else None
if self.encryption == "tls": if self.encryption == "tls":
mail = smtplib.SMTP_SSL(self._server, self._port, timeout=self._timeout) mail = smtplib.SMTP_SSL(
self._server,
self._port,
timeout=self._timeout,
context=ssl_context,
)
else: else:
mail = smtplib.SMTP(self._server, self._port, timeout=self._timeout) mail = smtplib.SMTP(self._server, self._port, timeout=self._timeout)
mail.set_debuglevel(self.debug) mail.set_debuglevel(self.debug)
mail.ehlo_or_helo_if_needed() mail.ehlo_or_helo_if_needed()
if self.encryption == "starttls": if self.encryption == "starttls":
mail.starttls() mail.starttls(context=ssl_context)
mail.ehlo() mail.ehlo()
if self.username and self.password: if self.username and self.password:
mail.login(self.username, self.password) mail.login(self.username, self.password)

View File

@ -76,6 +76,7 @@ def message():
["recip1@example.com", "testrecip@test.com"], ["recip1@example.com", "testrecip@test.com"],
"Home Assistant", "Home Assistant",
0, 0,
True,
) )
yield mailer yield mailer