diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 7c7b8f6eb11..69d84705088 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -8,7 +8,6 @@ import logging from operator import attrgetter import os import ssl -import sys from typing import Any, Callable, List, Optional, Union import attr @@ -161,39 +160,42 @@ def embedded_broker_deprecated(value): CONFIG_SCHEMA = vol.Schema( { - DOMAIN: vol.Schema( - { - vol.Optional(CONF_CLIENT_ID): cv.string, - vol.Optional(CONF_KEEPALIVE, default=DEFAULT_KEEPALIVE): vol.All( - vol.Coerce(int), vol.Range(min=15) - ), - vol.Required(CONF_BROKER): cv.string, - vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, - vol.Optional(CONF_USERNAME): cv.string, - vol.Optional(CONF_PASSWORD): cv.string, - vol.Optional(CONF_CERTIFICATE): vol.Any("auto", cv.isfile), - vol.Inclusive( - CONF_CLIENT_KEY, "client_key_auth", msg=CLIENT_KEY_AUTH_MSG - ): cv.isfile, - vol.Inclusive( - CONF_CLIENT_CERT, "client_key_auth", msg=CLIENT_KEY_AUTH_MSG - ): cv.isfile, - vol.Optional(CONF_TLS_INSECURE): cv.boolean, - vol.Optional(CONF_TLS_VERSION, default=DEFAULT_TLS_PROTOCOL): vol.Any( - "auto", "1.0", "1.1", "1.2" - ), - vol.Optional(CONF_PROTOCOL, default=DEFAULT_PROTOCOL): vol.All( - cv.string, vol.In([PROTOCOL_31, PROTOCOL_311]) - ), - vol.Optional(CONF_WILL_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, - vol.Optional(CONF_BIRTH_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, - vol.Optional(CONF_DISCOVERY, default=DEFAULT_DISCOVERY): cv.boolean, - # discovery_prefix must be a valid publish topic because if no - # state topic is specified, it will be created with the given prefix. - vol.Optional( - CONF_DISCOVERY_PREFIX, default=DEFAULT_DISCOVERY_PREFIX - ): valid_publish_topic, - } + DOMAIN: vol.All( + cv.deprecated(CONF_TLS_VERSION, invalidation_version="0.115"), + vol.Schema( + { + vol.Optional(CONF_CLIENT_ID): cv.string, + vol.Optional(CONF_KEEPALIVE, default=DEFAULT_KEEPALIVE): vol.All( + vol.Coerce(int), vol.Range(min=15) + ), + vol.Optional(CONF_BROKER): cv.string, + vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, + vol.Optional(CONF_USERNAME): cv.string, + vol.Optional(CONF_PASSWORD): cv.string, + vol.Optional(CONF_CERTIFICATE): vol.Any("auto", cv.isfile), + vol.Inclusive( + CONF_CLIENT_KEY, "client_key_auth", msg=CLIENT_KEY_AUTH_MSG + ): cv.isfile, + vol.Inclusive( + CONF_CLIENT_CERT, "client_key_auth", msg=CLIENT_KEY_AUTH_MSG + ): cv.isfile, + vol.Optional(CONF_TLS_INSECURE): cv.boolean, + vol.Optional( + CONF_TLS_VERSION, default=DEFAULT_TLS_PROTOCOL + ): vol.Any("auto", "1.0", "1.1", "1.2"), + vol.Optional(CONF_PROTOCOL, default=DEFAULT_PROTOCOL): vol.All( + cv.string, vol.In([PROTOCOL_31, PROTOCOL_311]) + ), + vol.Optional(CONF_WILL_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, + vol.Optional(CONF_BIRTH_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, + vol.Optional(CONF_DISCOVERY, default=DEFAULT_DISCOVERY): cv.boolean, + # discovery_prefix must be a valid publish topic because if no + # state topic is specified, it will be created with the given prefix. + vol.Optional( + CONF_DISCOVERY_PREFIX, default=DEFAULT_DISCOVERY_PREFIX + ): valid_publish_topic, + } + ), ) }, extra=vol.ALLOW_EXTRA, @@ -648,21 +650,6 @@ class MQTT: elif certificate == "auto": certificate = certifi.where() - # Be able to override versions other than TLSv1.0 under Python3.6 - conf_tls_version: str = self.conf.get(CONF_TLS_VERSION) - if conf_tls_version == "1.2": - tls_version = ssl.PROTOCOL_TLSv1_2 - elif conf_tls_version == "1.1": - tls_version = ssl.PROTOCOL_TLSv1_1 - elif conf_tls_version == "1.0": - tls_version = ssl.PROTOCOL_TLSv1 - else: - # Python3.6 supports automatic negotiation of highest TLS version - if sys.hexversion >= 0x03060000: - tls_version = ssl.PROTOCOL_TLS # pylint: disable=no-member - else: - tls_version = ssl.PROTOCOL_TLSv1 - client_key = self.conf.get(CONF_CLIENT_KEY) client_cert = self.conf.get(CONF_CLIENT_CERT) tls_insecure = self.conf.get(CONF_TLS_INSECURE) @@ -671,7 +658,7 @@ class MQTT: certificate, certfile=client_cert, keyfile=client_key, - tls_version=tls_version, + tls_version=ssl.PROTOCOL_TLS, ) if tls_insecure is not None: diff --git a/tests/components/mqtt/test_init.py b/tests/components/mqtt/test_init.py index 97031427142..58a982544f0 100644 --- a/tests/components/mqtt/test_init.py +++ b/tests/components/mqtt/test_init.py @@ -743,56 +743,6 @@ async def test_setup_without_tls_config_uses_tlsv1_under_python36(hass): assert calls[0][3] == expectedTlsVersion -async def test_setup_with_tls_config_uses_tls_version1_2(hass): - """Test setup uses specified TLS version.""" - calls = [] - - def mock_tls_set(certificate, certfile=None, keyfile=None, tls_version=None): - calls.append((certificate, certfile, keyfile, tls_version)) - - with patch("paho.mqtt.client.Client") as mock_client: - mock_client().tls_set = mock_tls_set - entry = MockConfigEntry( - domain=mqtt.DOMAIN, - data={ - "certificate": "auto", - mqtt.CONF_BROKER: "test-broker", - "tls_version": "1.2", - }, - ) - - assert await mqtt.async_setup_entry(hass, entry) - - assert calls - - assert calls[0][3] == ssl.PROTOCOL_TLSv1_2 - - -async def test_setup_with_tls_config_of_v1_under_python36_only_uses_v1(hass): - """Test setup uses TLSv1.0 if explicitly chosen.""" - calls = [] - - def mock_tls_set(certificate, certfile=None, keyfile=None, tls_version=None): - calls.append((certificate, certfile, keyfile, tls_version)) - - with patch("paho.mqtt.client.Client") as mock_client: - mock_client().tls_set = mock_tls_set - entry = MockConfigEntry( - domain=mqtt.DOMAIN, - data={ - "certificate": "auto", - mqtt.CONF_BROKER: "test-broker", - "tls_version": "1.0", - }, - ) - - assert await mqtt.async_setup_entry(hass, entry) - - assert calls - - assert calls[0][3] == ssl.PROTOCOL_TLSv1 - - @pytest.mark.parametrize( "mqtt_config", [