URL: https://github.com/freeipa/freeipa/pull/396 Author: stlaz Title: #396: Explicitly remove support of SSLv2 Action: synchronized
To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/396/head:pr396 git checkout pr396
From be99b8327a488440a9991b5d76d2046aae3d74a3 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka <slazn...@redhat.com> Date: Fri, 13 Jan 2017 12:31:29 +0100 Subject: [PATCH] Explicitly remove support of SSLv2 It was possible to set tls_version_min/max to 'ssl2', even though newer versions of NSS will fail to set this as a valid TLS version. This patch explicitly checks for deprecated TLS versions prior to creating a TLS connection. https://fedorahosted.org/freeipa/ticket/6607 --- ipalib/config.py | 18 ++++++++++++++++-- ipalib/constants.py | 10 ++++++++++ ipapython/nsslib.py | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/ipalib/config.py b/ipalib/config.py index 20591db..22446ca 100644 --- a/ipalib/config.py +++ b/ipalib/config.py @@ -41,8 +41,11 @@ from ipapython.dn import DN from ipalib.base import check_name -from ipalib.constants import CONFIG_SECTION -from ipalib.constants import OVERRIDE_ERROR, SET_ERROR, DEL_ERROR +from ipalib.constants import ( + CONFIG_SECTION, + OVERRIDE_ERROR, SET_ERROR, DEL_ERROR, + TLS_VERSIONS +) from ipalib import errors if six.PY3: @@ -497,6 +500,17 @@ def _bootstrap(self, **overrides): if 'plugins_on_demand' not in self: self.plugins_on_demand = (self.context == 'cli') + if self.tls_version_min not in TLS_VERSIONS: + raise errors.EnvironmentError( + "Unknown TLS version '{ver}' set in tls_version_min." + .format(self.tls_version_min)) + + if self.tls_version_min not in TLS_VERSIONS: + raise errors.EnvironmentError( + "Unknown TLS version '{ver}' set in tls_version_min." + .format(self.tls_version_min)) + + def _finalize_core(self, **defaults): """ Complete initialization of standard IPA environment. diff --git a/ipalib/constants.py b/ipalib/constants.py index 81643da..1e8f51a 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -276,3 +276,13 @@ # regexp definitions PATTERN_GROUPUSER_NAME = '^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*[a-zA-Z0-9_.$-]?$' + +# TLS related constants +TLS_VERSIONS = [ + "ssl2", + "ssl3", + "tls1.0", + "tls1.1", + "tls1.2" +] +TLS_VERSION_MINIMAL = "tls1.0" diff --git a/ipapython/nsslib.py b/ipapython/nsslib.py index 08d05fc..5e8bde0 100644 --- a/ipapython/nsslib.py +++ b/ipapython/nsslib.py @@ -23,6 +23,8 @@ import getpass import socket from ipapython.ipa_log_manager import root_logger +from ipalib.errors import InvocationError +from ipalib.constants import TLS_VERSIONS, TLS_VERSION_MINIMAL from nss.error import NSPRError import nss.io as io @@ -129,6 +131,45 @@ def client_auth_data_callback(ca_names, chosen_nickname, password, certdb): socket.AF_UNSPEC: io.PR_AF_UNSPEC } + +def get_proper_tls_version_span(tls_version_min, tls_version_max): + # every tls version from `tls_versions` prior to min_allowed_idx + # is deprecated in IPA + min_allowed_idx = TLS_VERSIONS.index(TLS_VERSION_MINIMAL) + + try: + min_version_idx = TLS_VERSIONS.index(tls_version_min) + except ValueError: + raise InvocationError("tls_version_min ('{val}') is not a known " + "TLS version.".format(val=tls_version_min)) + + try: + max_version_idx = TLS_VERSIONS.index(tls_version_max) + except ValueError: + raise InvocationError("tls_version_max ('{val}') is not a known " + "TLS version.".format(val=tls_version_max)) + + if min_version_idx > max_version_idx: + raise InvocationError("tls_version_min is higher than " + "tls_version_max.") + + if min_version_idx < min_allowed_idx: + min_version_idx = min_allowed_idx + root_logger.warning("tls_version_min set too low ('{old}')," + "using '{new}' instead" + .format(old=tls_version_min, + new=TLS_VERSIONS[min_version_idx])) + + if max_version_idx < min_allowed_idx: + max_version_idx = min_version_idx + root_logger.warning("tls_version_max set too low ('{old}')," + "using '{new}' instead" + .format(old=tls_version_max, + new=TLS_VERSIONS[max_version_idx])) + + return TLS_VERSIONS[min_version_idx:max_version_idx+1] + + class NSSAddressFamilyFallback(object): def __init__(self, family): self.sock_family = family @@ -217,8 +258,10 @@ def __init__(self, host, port=None, strict=None, ssl.set_domestic_policy() nss.set_password_callback(self.password_callback) - self.tls_version_min = str(tls_version_min) - self.tls_version_max = str(tls_version_max) + tls_versions = get_proper_tls_version_span( + tls_version_min, tls_version_max) + self.tls_version_min = tls_versions[0] + self.tls_version_max = tls_versions[-1] def _create_socket(self): ssl_enable_renegotiation = getattr(
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code