Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
Changelog
=========

0.25
------
* **Breaking changes**
- SSL certificate verification is now on by default. `connect(use_ssl=True)`
now verifies the server's certificate against the system's CA certificates
(or against `ca_cert` if provided). Previously `verify_cert` defaulted to
False and the server was not verified unless `verify_cert=True` or `ca_cert`
was set. Pass `verify_cert=False` to restore the old, insecure behavior.

0.24
------
* **Breaking changes**
Expand Down
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,18 @@ df = as_pandas(cur)
# carry df through scikit-learn, for example
```

For secure connection set use_ssl=True in connect(). Warning: this doesn't verify the server
by default! To verify server set verify_cert or ca_cart perameter:
For a secure connection set use_ssl=True in connect(). Since 0.25.0 this verifies the
server's certificate against the system's CA certificates by default:

```python
# Verify server using system CA certificates:
conn = connect(host='my.host.com', use_ssl=True, verify_cert=True)
# Verify server using system CA certificates (the default):
conn = connect(host='my.host.com', use_ssl=True)

# Verify server using custom CA certificate:
conn = connect(host='my.host.com', use_ssl=True, ca_cart="/tmp/my_cert.pem")
# Verify server using a custom CA certificate:
conn = connect(host='my.host.com', use_ssl=True, ca_cert="/tmp/my_cert.pem")

# Disable verification (insecure). Before 0.25.0 this was the default behavior.
conn = connect(host='my.host.com', use_ssl=True, verify_cert=False)
```

[pep249]: http://legacy.python.org/dev/peps/pep-0249/
Expand Down
2 changes: 1 addition & 1 deletion impala/_thrift_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ def get_http_transport(host, port, http_path, timeout=None, use_ssl=False,
ca_cert=None, auth_mechanism='NOSASL', user=None,
password=None, kerberos_host=None, kerberos_service_name=None,
http_cookie_names=None, jwt=None, user_agent=None,
get_user_custom_headers_func=None, verify_cert=False):
get_user_custom_headers_func=None, verify_cert=True):
host_url = "[%s]" % host if ":" in host else host # add brackets for ipv6 address
# TODO: support timeout
if timeout is not None:
Expand Down
20 changes: 12 additions & 8 deletions impala/dbapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def connect(host='localhost', port=21050, database=None, timeout=None,
protocol=None, krb_host=None, use_http_transport=False,
http_path='', auth_cookie_names=None, http_cookie_names=None,
retries=3, jwt=None, user_agent=None,
get_user_custom_headers_func=None, verify_cert=False):
get_user_custom_headers_func=None, verify_cert=True):
"""Get a connection to HiveServer2 (HS2).

These options are largely compatible with the impala-shell command line
Expand All @@ -64,8 +64,9 @@ def connect(host='localhost', port=21050, database=None, timeout=None,
Enable SSL.
ca_cert : str, optional
Local path to the the third-party CA certificate. If set, the server certificate
will be verified using the provided CA cert. If SSL is enabled but
the certificate is not specified, see 'verify_cert' for behavior.
will be verified using the provided CA cert instead of the system's CA
certificates. If SSL is enabled but the certificate is not specified, see
'verify_cert' for behavior.
auth_mechanism : {'NOSASL', 'PLAIN', 'GSSAPI', 'LDAP', 'JWT'}
Specify the authentication mechanism. `'NOSASL'` for unsecured Impala.
`'PLAIN'` for unsecured Hive (because Hive requires the SASL
Expand Down Expand Up @@ -108,11 +109,14 @@ def connect(host='localhost', port=21050, database=None, timeout=None,
This is a function returning a list of tuples, each tuple contains a key-value
pair. This allows duplicate headers to be set.
verify_cert : bool, optional
Whether to verify the server's TLS certificate when using SSL using the systems's
CA certificates. Ignored if 'ca_cert' is provided, in which case the certificate
will be verified using the provided CA cert.

.. deprecated:: 0.18.0
Whether to verify the server's TLS certificate against the system's CA
certificates when using SSL. Defaults to True. Set to False to disable
verification. Ignored if 'ca_cert' is provided, in which case the certificate
is always verified using the provided CA cert.

.. versionchanged:: 0.25.0
The default changed from False to True, so SSL connections verify the
server certificate unless 'verify_cert=False' is passed.
auth_cookie_names : list of str or str, optional
Use `http_cookie_names` parameter instead.

Expand Down
2 changes: 1 addition & 1 deletion impala/hiveserver2.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ def connect(host, port, timeout=None, use_ssl=False, ca_cert=None,
user=None, password=None, kerberos_service_name='impala',
auth_mechanism=None, krb_host=None, use_http_transport=False,
http_path='', http_cookie_names=None, retries=3, jwt=None,
user_agent=None, get_user_custom_headers_func=None, verify_cert=False):
user_agent=None, get_user_custom_headers_func=None, verify_cert=True):
log.debug('Connecting to HiveServer2 %s:%s with %s authentication '
'mechanism', host, port, auth_mechanism)

Expand Down
18 changes: 10 additions & 8 deletions impala/tests/test_dbapi_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ def test_jwt_auth_with_ldap_password(self):
@pytest.mark.skipif(SSL_DISABLED, reason=SSL_DISABLED_ERROR)
@pytest.mark.ssl
def test_ssl_connection_no_cert(self):
self.connection = connect(ENV.host, ENV.port, timeout=TIMEOUT_S, use_ssl=True)
self.connection = connect(
ENV.host, ENV.port, timeout=TIMEOUT_S, use_ssl=True, verify_cert=False)
self._execute_queries(self.connection)


Expand All @@ -267,9 +268,9 @@ def test_ssl_connection_wrong_cert(self):
@pytest.mark.ssl
def test_ssl_connection_default_certs(self):
try:
# With verify_cert=True, the system's CA certificates will be used to verify
# the server certificate. Since the server certificate is self-signed and not
# in the system CA store, verification should fail.
# verify_cert=True (also the default) uses the system's CA certificates to
# verify the server certificate. Since the server certificate is self-signed
# and not in the system CA store, verification should fail.
# TODO: writing positive test would be nice but is more difficult
connect(
ENV.host, ENV.port, use_ssl=True, timeout=TIMEOUT_S, verify_cert=True)
Expand All @@ -282,7 +283,8 @@ def test_ssl_connection_default_certs(self):
@pytest.mark.ssl
def test_https_connection_nocert(self):
self.connection = connect(ENV.host, ENV.http_port, use_http_transport=True,
http_path="cliservice", use_ssl=True, timeout=TIMEOUT_S)
http_path="cliservice", use_ssl=True, timeout=TIMEOUT_S,
verify_cert=False)
self._execute_queries(self.connection)

@pytest.mark.skipif(SSL_DISABLED, reason=SSL_DISABLED_ERROR)
Expand Down Expand Up @@ -310,9 +312,9 @@ def test_https_connection_wrong_cert(self):
@pytest.mark.ssl
def test_https_connection_default_certs(self):
try:
# With verify_cert=True, the system's CA certificates will be used to verify
# the server certificate. Since the server certificate is self-signed and not
# in the system CA store, verification should fail.
# verify_cert=True (also the default) uses the system's CA certificates to
# verify the server certificate. Since the server certificate is self-signed
# and not in the system CA store, verification should fail.
# TODO: writing positive test would be nice but is more difficult
connection = connect(ENV.host, ENV.http_port, use_http_transport=True,
http_path="cliservice", use_ssl=True, timeout=TIMEOUT_S,
Expand Down