diff options
author | Andy McCurdy <andy@andymccurdy.com> | 2019-12-29 15:40:09 -0800 |
---|---|---|
committer | Andy McCurdy <andy@andymccurdy.com> | 2019-12-29 15:40:09 -0800 |
commit | ff69f0d77284643909462ee6d1e37233c6677672 (patch) | |
tree | 972d887954e0f46e418e19d62eebb9e15a1a1596 | |
parent | a9ef0fe200507480ad721e6cc1520fef74f4d396 (diff) | |
download | redis-py-ff69f0d77284643909462ee6d1e37233c6677672.tar.gz |
Added the 'ssl_check_hostname' option.
'ssl_check_hostname' tells SSL Connections to whether to require the TCP
hostname to match the hostname specified in the SSL Cert. By default
'ssl_check_hostname' is False to maintain backwards compatibility.
Fixed #1196
-rw-r--r-- | CHANGES | 4 | ||||
-rwxr-xr-x | redis/client.py | 2 | ||||
-rwxr-xr-x | redis/connection.py | 7 | ||||
-rw-r--r-- | tests/test_connection_pool.py | 8 |
4 files changed, 19 insertions, 2 deletions
@@ -14,6 +14,10 @@ argument. If supplied, all connections created will call CLIENT SETNAME as soon as the connection is opened. Thanks to @Habbie for supplying the basis of this chanfge. #802 + * Added the 'ssl_check_hostname' argument to specify whether SSL + connections should require the server hostname to match the hostname + specified in the SSL cert. By default 'ssl_check_hostname' is False + for backwards compatibility. #1196 * 3.3.11 * Further fix for the SSLError -> TimeoutError mapping to work on obscure releases of Python 2.7. diff --git a/redis/client.py b/redis/client.py index eb1ccf1..fba80c9 100755 --- a/redis/client.py +++ b/redis/client.py @@ -683,6 +683,7 @@ class Redis(object): decode_responses=False, retry_on_timeout=False, ssl=False, ssl_keyfile=None, ssl_certfile=None, ssl_cert_reqs='required', ssl_ca_certs=None, + ssl_check_hostname=False, max_connections=None, single_connection_client=False, health_check_interval=0, client_name=None): if not connection_pool: @@ -731,6 +732,7 @@ class Redis(object): 'ssl_certfile': ssl_certfile, 'ssl_cert_reqs': ssl_cert_reqs, 'ssl_ca_certs': ssl_ca_certs, + 'ssl_check_hostname': ssl_check_hostname, }) connection_pool = ConnectionPool(**kwargs) self.connection_pool = connection_pool diff --git a/redis/connection.py b/redis/connection.py index 85d5c30..926f2c7 100755 --- a/redis/connection.py +++ b/redis/connection.py @@ -799,7 +799,8 @@ class Connection(object): class SSLConnection(Connection): def __init__(self, ssl_keyfile=None, ssl_certfile=None, - ssl_cert_reqs='required', ssl_ca_certs=None, **kwargs): + ssl_cert_reqs='required', ssl_ca_certs=None, + ssl_check_hostname=False, **kwargs): if not ssl_available: raise RedisError("Python wasn't built with SSL support") @@ -822,13 +823,14 @@ class SSLConnection(Connection): ssl_cert_reqs = CERT_REQS[ssl_cert_reqs] self.cert_reqs = ssl_cert_reqs self.ca_certs = ssl_ca_certs + self.check_hostname = ssl_check_hostname def _connect(self): "Wrap the socket with SSL support" sock = super(SSLConnection, self)._connect() if hasattr(ssl, "create_default_context"): context = ssl.create_default_context() - context.check_hostname = False + context.check_hostname = self.check_hostname context.verify_mode = self.cert_reqs if self.certfile and self.keyfile: context.load_cert_chain(certfile=self.certfile, @@ -917,6 +919,7 @@ URL_QUERY_ARGUMENT_PARSERS = { 'retry_on_timeout': to_bool, 'max_connections': int, 'health_check_interval': int, + 'ssl_check_hostname': to_bool, } diff --git a/tests/test_connection_pool.py b/tests/test_connection_pool.py index 7ebd5ff..a862e4e 100644 --- a/tests/test_connection_pool.py +++ b/tests/test_connection_pool.py @@ -579,6 +579,14 @@ class TestSSLConnectionURLParsing(object): 'rediss://?ssl_cert_reqs=required') assert pool.get_connection('_').cert_reqs == ssl.CERT_REQUIRED + pool = DummyConnectionPool.from_url( + 'rediss://?ssl_check_hostname=False') + assert pool.get_connection('_').check_hostname is False + + pool = DummyConnectionPool.from_url( + 'rediss://?ssl_check_hostname=True') + assert pool.get_connection('_').check_hostname is True + class TestConnection(object): def test_on_connect_error(self): |