diff --git a/kombu/utils/url.py b/kombu/utils/url.py index f5f477019..e84cd18b1 100644 --- a/kombu/utils/url.py +++ b/kombu/utils/url.py @@ -39,7 +39,9 @@ def parse_url(url): if query: keys = [key for key in query.keys() if key.startswith('ssl_')] for key in keys: - if key == 'ssl_cert_reqs': + if key == "ssl_check_hostname": + query[key] = query[key].lower() != 'false' + elif key == 'ssl_cert_reqs': query[key] = parse_ssl_cert_reqs(query[key]) if query[key] is None: logger.warning('Defaulting to insecure SSL behaviour.') diff --git a/t/integration/test_redis.py b/t/integration/test_redis.py index 636848a93..d9950d0d0 100644 --- a/t/integration/test_redis.py +++ b/t/integration/test_redis.py @@ -222,3 +222,24 @@ def connect_timeout(self): # note the host/port here is irrelevant because # connect will raise a socket.timeout kombu.Connection('redis://localhost:12345').connect() + + +@pytest.mark.env('redis') +def test_RedisConnection_check_hostname(monkeypatch): + # simulate a connection timeout for a new connection + def connect_check_certificate(self): + if self.check_hostname: + raise OSError("check_hostname=True") + raise socket.timeout("check_hostname=False") + monkeypatch.setattr( + redis.connection.SSLConnection, "_connect", connect_check_certificate) + + # ensure the timeout raises a TimeoutError + with pytest.raises(redis.exceptions.TimeoutError): + # note the host/port here is irrelevant because + # connect will raise a socket.timeout, not a CertificateError + kombu.Connection('rediss://localhost:12345?ssl_check_hostname=false').connect() + with pytest.raises(redis.exceptions.ConnectionError): + # note the host/port here is irrelevant because + # connect will raise a CertificateError due to hostname mismatch + kombu.Connection('rediss://localhost:12345?ssl_check_hostname=true').connect() diff --git a/t/unit/utils/test_url.py b/t/unit/utils/test_url.py index f219002bf..0c219f0ec 100644 --- a/t/unit/utils/test_url.py +++ b/t/unit/utils/test_url.py @@ -50,11 +50,19 @@ def test_maybe_sanitize_url(url, expected): def test_ssl_parameters(): url = 'rediss://user:password@host:6379/0?' + querystring = urlencode({ + "ssl_check_hostname": "on", + }) + kwargs = parse_url(url + querystring) + assert kwargs['transport'] == 'rediss' + assert kwargs['ssl']['ssl_check_hostname'] is True + querystring = urlencode({ 'ssl_cert_reqs': 'required', 'ssl_ca_certs': '/var/ssl/myca.pem', 'ssl_certfile': '/var/ssl/server-cert.pem', 'ssl_keyfile': '/var/ssl/priv/worker-key.pem', + "ssl_check_hostname": "false", }) kwargs = parse_url(url + querystring) assert kwargs['transport'] == 'rediss' @@ -62,6 +70,7 @@ def test_ssl_parameters(): assert kwargs['ssl']['ssl_ca_certs'] == '/var/ssl/myca.pem' assert kwargs['ssl']['ssl_certfile'] == '/var/ssl/server-cert.pem' assert kwargs['ssl']['ssl_keyfile'] == '/var/ssl/priv/worker-key.pem' + assert kwargs['ssl']['ssl_check_hostname'] is False kombu.utils.url.ssl_available = False