From 9711cd33c4d0d4a69279c8a79d8a8460accf1f12 Mon Sep 17 00:00:00 2001 From: Brad Schoening <5796692+bschoening@users.noreply.github.com> Date: Tue, 5 Apr 2022 15:09:14 -0400 Subject: [PATCH] remove support for deprecated version specific TLS in Python 3.6 patch by Brad Schoening; reviewed by Stefan Miklosovic and Brandon Williams for CASSANDRA-17365 --- CHANGES.txt | 1 + conf/cqlshrc.sample | 4 +- pylib/cqlshlib/sslhandling.py | 12 +-- pylib/cqlshlib/test/config/sslhandling.config | 2 - .../test/config/sslhandling_invalid.config | 2 - pylib/cqlshlib/test/test_sslhandling.py | 75 ------------------- 6 files changed, 5 insertions(+), 91 deletions(-) delete mode 100644 pylib/cqlshlib/test/config/sslhandling.config delete mode 100644 pylib/cqlshlib/test/config/sslhandling_invalid.config delete mode 100644 pylib/cqlshlib/test/test_sslhandling.py diff --git a/CHANGES.txt b/CHANGES.txt index cbbad3d1c9..28181195c5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.1 + * remove support for deprecated version specific TLS in Python 3.6 (CASSANDRA-17365) * Add support for IF EXISTS and IF NOT EXISTS in ALTER statements (CASSANDRA-16916) * resolve several pylint issues in cqlsh.py and pylib (CASSANDRA-17480) * Streaming sessions longer than 3 minutes fail with timeout (CASSANDRA-17510) diff --git a/conf/cqlshrc.sample b/conf/cqlshrc.sample index e79d970375..0da2b6dba5 100644 --- a/conf/cqlshrc.sample +++ b/conf/cqlshrc.sample @@ -112,7 +112,9 @@ port = 9042 ;; To be provided when require_client_auth=true ;usercert = ~/cert.pem - +; this is effectively ignored from 4.1 included as TLS protocol is auto-negotiated and will +; be removed in the next major version of Cassandra, possible values were TLSv1, TLSv1_1 or TLSv1_2 +;version = ;; Optional section, overrides default certfile in [ssl] section, if present ; [certfiles] diff --git a/pylib/cqlshlib/sslhandling.py b/pylib/cqlshlib/sslhandling.py index 3ac73bee25..4fc6eae711 100644 --- a/pylib/cqlshlib/sslhandling.py +++ b/pylib/cqlshlib/sslhandling.py @@ -49,15 +49,8 @@ def ssl_settings(host, config_file, env=os.environ): return None def get_best_tls_protocol(ssl_ver_str): - # newer python versions suggest to use PROTOCOL_TLS to negotiate the highest TLS version. - # older protocol versions have been deprecated: - # https://docs.python.org/2/library/ssl.html#ssl.PROTOCOL_TLS - # https://docs.python.org/3/library/ssl.html#ssl.PROTOCOL_TLS if ssl_ver_str: - return getattr(ssl, "PROTOCOL_%s" % ssl_ver_str, None) - for protocol in ['PROTOCOL_TLS', 'PROTOCOL_TLSv1_2', 'PROTOCOL_TLSv1_1', 'PROTOCOL_TLSv1']: - if hasattr(ssl, protocol): - return getattr(ssl, protocol) + print("Warning: Explicit SSL and TLS versions in the cqlshrc file or in SSL_VERSION environment property are ignored as the protocol is auto-negotiated.\n") return ssl.PROTOCOL_TLS ssl_validate = env.get('SSL_VALIDATE') @@ -70,9 +63,6 @@ def ssl_settings(host, config_file, env=os.environ): ssl_version_str = get_option('ssl', 'version') ssl_version = get_best_tls_protocol(ssl_version_str) - if ssl_version is None: - sys.exit("%s is not a valid SSL protocol, please use one of " - "TLS, TLSv1_2, TLSv1_1, or TLSv1" % (ssl_version_str,)) ssl_certfile = env.get('SSL_CERTFILE') if ssl_certfile is None: diff --git a/pylib/cqlshlib/test/config/sslhandling.config b/pylib/cqlshlib/test/config/sslhandling.config deleted file mode 100644 index 63f41c7a51..0000000000 --- a/pylib/cqlshlib/test/config/sslhandling.config +++ /dev/null @@ -1,2 +0,0 @@ -[ssl] -version = TLSv1 \ No newline at end of file diff --git a/pylib/cqlshlib/test/config/sslhandling_invalid.config b/pylib/cqlshlib/test/config/sslhandling_invalid.config deleted file mode 100644 index 90e061fe82..0000000000 --- a/pylib/cqlshlib/test/config/sslhandling_invalid.config +++ /dev/null @@ -1,2 +0,0 @@ -[ssl] -version = invalid_ssl \ No newline at end of file diff --git a/pylib/cqlshlib/test/test_sslhandling.py b/pylib/cqlshlib/test/test_sslhandling.py deleted file mode 100644 index dffe43abf5..0000000000 --- a/pylib/cqlshlib/test/test_sslhandling.py +++ /dev/null @@ -1,75 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from cassandra.policies import SimpleConvictionPolicy -from cassandra.pool import Host -from cqlshlib.sslhandling import ssl_settings -import pytest - -import unittest -import os -import ssl - - -class SslSettingsTest(unittest.TestCase): - - def setUp(self): - os.environ['SSL_VALIDATE'] = 'False' - self.config_file = 'test_config' - self.host = Host('10.0.0.1', SimpleConvictionPolicy, 9000) - - def tearDown(self): - del os.environ['SSL_VALIDATE'] - try: - del os.environ['SSL_VERSION'] - except KeyError: - pass - - def _test_ssl_version_from_env(self, version): - """ - Getting SSL version string from env variable SSL_VERSION. - """ - os.environ['SSL_VERSION'] = version - ssl_ret_val = ssl_settings(self.host, self.config_file) - assert ssl_ret_val is not None - assert ssl_ret_val.get('ssl_version') == getattr(ssl, 'PROTOCOL_%s' % version) - - def test_ssl_versions_from_env(self): - versions = ['TLS', 'TLSv1_1', 'TLSv1_2', 'TLSv1'] - for version in versions: - self._test_ssl_version_from_env(version) - - def test_invalid_ssl_versions_from_env(self): - msg = "invalid_ssl is not a valid SSL protocol, please use one of TLSv1, TLSv1_1, or TLSv1_2" - with pytest.raises(SystemExit) as error: - self._test_ssl_version_from_env('invalid_ssl') - assert msg == error.args[0] - - def test_default_ssl_version(self): - ssl_ret_val = ssl_settings(self.host, self.config_file) - assert ssl_ret_val is not None - assert ssl_ret_val.get('ssl_version') == getattr(ssl, 'PROTOCOL_TLS') - - def test_ssl_version_config(self): - ssl_ret_val = ssl_settings(self.host, os.path.join('test', 'config', 'sslhandling.config')) - assert ssl_ret_val is not None - assert ssl_ret_val.get('ssl_version') == getattr(ssl, 'PROTOCOL_TLSv1') - - def test_invalid_ssl_version_config(self): - msg = "invalid_ssl is not a valid SSL protocol, please use one of TLSv1, TLSv1_1, or TLSv1_2" - with pytest.raises(SystemExit) as error: - ssl_settings(self.host, os.path.join('test', 'config', 'sslhandling_invalid.config')) - assert msg in error.exception.message