[Freeipa-devel] [freeipa PR#396][synchronized] Explicitly remove support of SSLv2
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 661ed55292dda18f1f09f89af883086f9b5a7ab0 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka Date: Fri, 13 Jan 2017 12:31:29 +0100 Subject: [PATCH] Explicitly remove support of SSLv2/3 It was possible to set tls_version_min/max to 'ssl2' or 'ssl3', 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. Also, we don't allow tls_version_min/max to be set to a random string anymore. https://fedorahosted.org/freeipa/ticket/6607 --- ipalib/config.py| 27 ++-- ipalib/constants.py | 10 + ipapython/nsslib.py | 61 +++-- 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/ipalib/config.py b/ipalib/config.py index 20591db..1a59879 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: @@ -578,6 +581,26 @@ def _finalize_core(self, **defaults): self._merge(**defaults) +# set the best known TLS version if min/max versions are not set +if 'tls_version_min' not in self: +self.tls_version_min = TLS_VERSIONS[-1] +elif self.tls_version_min not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_min." +.format(ver=self.tls_version_min)) + +if 'tls_version_max' not in self: +self.tls_version_max = TLS_VERSIONS[-1] +elif self.tls_version_max not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_max." +.format(ver=self.tls_version_max)) + +if self.tls_version_max < self.tls_version_min: +raise errors.EnvironmentError( +"tls_version_min is set to a higher TLS version than " +"tls_version_max.") + def _finalize(self, **lastchance): """ Finalize and lock environment. diff --git a/ipalib/constants.py b/ipalib/constants.py index fa20624..e64324f 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -283,3 +283,13 @@ # IPA API Framework user IPAAPI_USER = 'ipaapi' IPAAPI_GROUP = 'ipaapi' + +# 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..97bbf64 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 ipapython.ipa_log_manager import log_mgr +from ipalib.constants import TLS_VERSIONS, TLS_VERSION_MINIMAL from nss.error import NSPRError import nss.io as io @@ -38,6 +40,9 @@ # pylint: disable=import-error import http.client as httplib +# get a logger for this module +logger = log_mgr.get_logger(__name__) + # NSS database currently open current_dbdir = None @@ -129,6 +134,56 @@ 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): +""" +This function checks whether the given TLS versions are known in FreeIPA +and that these versions fulfill the requirements for minimal TLS version +(see `ipalib.constants: TLS_VERSIONS, TLS_VERSION_MINIMAL`). + +:param tls_version_min: +the lower value in the TLS min-max span, raised to the lowest allowed +value if too low +:param tls_version_max: +the higher value in the TLS min-max span, raised to tls_version_min +if lower than TLS_VERSION_MINIMAL +:raises: ValueError +""" +min_allowed_idx = TLS_VERSIONS.index(TLS_VERSION_MINIMAL) + +try: +min_version_idx = TLS_VERSIONS.index(tls_version_min) +except ValueError: +raise ValueError("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 ValueError("tls_version_max ('{val}') is not a known " + "TLS version.".format(val=tls_version_max)) + +if min_version_idx > ma
[Freeipa-devel] [freeipa PR#396][synchronized] Explicitly remove support of SSLv2
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 b5bea925775bd07e867ac79db9287d06faa0189b Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka 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. Also, we don't allow tls_version_min/max to be set to a random string anymore. https://fedorahosted.org/freeipa/ticket/6607 --- ipalib/config.py| 27 ++-- ipalib/constants.py | 10 + ipapython/nsslib.py | 60 +++-- 3 files changed, 93 insertions(+), 4 deletions(-) diff --git a/ipalib/config.py b/ipalib/config.py index 20591db..1a59879 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: @@ -578,6 +581,26 @@ def _finalize_core(self, **defaults): self._merge(**defaults) +# set the best known TLS version if min/max versions are not set +if 'tls_version_min' not in self: +self.tls_version_min = TLS_VERSIONS[-1] +elif self.tls_version_min not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_min." +.format(ver=self.tls_version_min)) + +if 'tls_version_max' not in self: +self.tls_version_max = TLS_VERSIONS[-1] +elif self.tls_version_max not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_max." +.format(ver=self.tls_version_max)) + +if self.tls_version_max < self.tls_version_min: +raise errors.EnvironmentError( +"tls_version_min is set to a higher TLS version than " +"tls_version_max.") + def _finalize(self, **lastchance): """ Finalize and lock environment. diff --git a/ipalib/constants.py b/ipalib/constants.py index fa20624..e64324f 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -283,3 +283,13 @@ # IPA API Framework user IPAAPI_USER = 'ipaapi' IPAAPI_GROUP = 'ipaapi' + +# 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..8b02f4b 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 ipapython.ipa_log_manager import log_mgr +from ipalib.constants import TLS_VERSIONS, TLS_VERSION_MINIMAL from nss.error import NSPRError import nss.io as io @@ -38,6 +40,9 @@ # pylint: disable=import-error import http.client as httplib +# get a logger for this module +logger = log_mgr.get_logger(__name__) + # NSS database currently open current_dbdir = None @@ -129,6 +134,55 @@ 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): +""" +This function checks whether the given TLS versions are known in FreeIPA +and that these versions fulfill the requirements for minimal TLS version +(see `ipalib.constants: TLS_VERSIONS, TLS_VERSION_MINIMAL`). + +:param tls_version_min: +the lower value in the TLS min-max span, raised to the lowest allowed +value if too low +:param tls_version_max: +the higher value in the TLS min-max span, raised to tls_version_min +if lower than TLS_VERSION_MINIMAL +""" +min_allowed_idx = TLS_VERSIONS.index(TLS_VERSION_MINIMAL) + +try: +min_version_idx = TLS_VERSIONS.index(tls_version_min) +except ValueError: +raise ValueError("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 ValueError("tls_version_max ('{val}') is not a known " + "TLS version.".format(val=tls_version_max)) + +if min_version_idx > max_version_idx: +raise ValueEr
[Freeipa-devel] [freeipa PR#396][synchronized] Explicitly remove support of SSLv2
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 53aebe8ea2663dc6c57730e797f1e0b06a0b3b69 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka 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. Also, we don't allow tls_version_min/max to be set to a random string anymore. https://fedorahosted.org/freeipa/ticket/6607 --- ipalib/config.py| 27 ++-- ipalib/constants.py | 10 + ipapython/nsslib.py | 60 +++-- 3 files changed, 93 insertions(+), 4 deletions(-) diff --git a/ipalib/config.py b/ipalib/config.py index 20591db..1a59879 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: @@ -578,6 +581,26 @@ def _finalize_core(self, **defaults): self._merge(**defaults) +# set the best known TLS version if min/max versions are not set +if 'tls_version_min' not in self: +self.tls_version_min = TLS_VERSIONS[-1] +elif self.tls_version_min not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_min." +.format(ver=self.tls_version_min)) + +if 'tls_version_max' not in self: +self.tls_version_max = TLS_VERSIONS[-1] +elif self.tls_version_max not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_max." +.format(ver=self.tls_version_max)) + +if self.tls_version_max < self.tls_version_min: +raise errors.EnvironmentError( +"tls_version_min is set to a higher TLS version than " +"tls_version_max.") + def _finalize(self, **lastchance): """ Finalize and lock 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..8b02f4b 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 ipapython.ipa_log_manager import log_mgr +from ipalib.constants import TLS_VERSIONS, TLS_VERSION_MINIMAL from nss.error import NSPRError import nss.io as io @@ -38,6 +40,9 @@ # pylint: disable=import-error import http.client as httplib +# get a logger for this module +logger = log_mgr.get_logger(__name__) + # NSS database currently open current_dbdir = None @@ -129,6 +134,55 @@ 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): +""" +This function checks whether the given TLS versions are known in FreeIPA +and that these versions fulfill the requirements for minimal TLS version +(see `ipalib.constants: TLS_VERSIONS, TLS_VERSION_MINIMAL`). + +:param tls_version_min: +the lower value in the TLS min-max span, raised to the lowest allowed +value if too low +:param tls_version_max: +the higher value in the TLS min-max span, raised to tls_version_min +if lower than TLS_VERSION_MINIMAL +""" +min_allowed_idx = TLS_VERSIONS.index(TLS_VERSION_MINIMAL) + +try: +min_version_idx = TLS_VERSIONS.index(tls_version_min) +except ValueError: +raise ValueError("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 ValueError("tls_version_max ('{val}') is not a known " + "TLS version.".format(val=tls_version_max)) + +if min_version_idx > max_version_idx
[Freeipa-devel] [freeipa PR#396][synchronized] Explicitly remove support of SSLv2
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 2761cbf779c97fd590913c21e753e673236d3378 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka 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. Also, we don't allow tls_version_min/max to be set to a random string anymore. https://fedorahosted.org/freeipa/ticket/6607 --- ipalib/config.py| 22 ++-- ipalib/constants.py | 10 + ipapython/nsslib.py | 59 +++-- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/ipalib/config.py b/ipalib/config.py index 20591db..f717732 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: @@ -578,6 +581,21 @@ def _finalize_core(self, **defaults): self._merge(**defaults) +# set the best known TLS version if min/max versions are not set +if 'tls_version_min' not in self: +self.tls_version_min = TLS_VERSIONS[-1] +elif self.tls_version_min not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_min." +.format(ver=self.tls_version_min)) + +if 'tls_version_max' not in self: +self.tls_version_max = TLS_VERSIONS[-1] +elif self.tls_version_max not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_max." +.format(ver=self.tls_version_max)) + def _finalize(self, **lastchance): """ Finalize and lock 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..ce3e5f6 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 ipapython.ipa_log_manager import log_mgr +from ipalib.constants import TLS_VERSIONS, TLS_VERSION_MINIMAL from nss.error import NSPRError import nss.io as io @@ -129,6 +131,57 @@ 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): +""" +This function checks whether the given TLS versions are known in FreeIPA +and that these versions fulfill the requirements for minimal TLS version +(see `ipalib.constants: TLS_VERSIONS, TLS_VERSION_MINIMAL`). + +:param tls_version_min: +the lower value in the TLS min-max span, raised to the lowest allowed +value if too low +:param tls_version_max: +the higher value in the TLS min-max span, raised to tls_version_min +if lower than TLS_VERSION_MINIMAL +""" +logger = log_mgr.get_logger(__name__) + +min_allowed_idx = TLS_VERSIONS.index(TLS_VERSION_MINIMAL) + +try: +min_version_idx = TLS_VERSIONS.index(tls_version_min) +except ValueError: +raise RuntimeError("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 RuntimeError("tls_version_max ('{val}') is not a known " + "TLS version.".format(val=tls_version_max)) + +if min_version_idx > max_version_idx: +raise RuntimeError("tls_version_min is higher than " + "tls_version_max.") + +if min_version_idx < min_allowed_idx: +min_version_idx = min_allowed_idx +logger.warning("tls_version_min set too low ('{old}')," + "using '{new}' instead" + .format(old=tls_version_min, +
[Freeipa-devel] [freeipa PR#396][synchronized] Explicitly remove support of SSLv2
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 c59b2aef542d4a394283703d24718399af0d5d30 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka 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. Also, we don't allow tls_version_min/max to be set to a random string anymore. https://fedorahosted.org/freeipa/ticket/6607 --- ipalib/config.py| 22 -- ipalib/constants.py | 10 ++ ipapython/nsslib.py | 46 -- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/ipalib/config.py b/ipalib/config.py index 20591db..f717732 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: @@ -578,6 +581,21 @@ def _finalize_core(self, **defaults): self._merge(**defaults) +# set the best known TLS version if min/max versions are not set +if 'tls_version_min' not in self: +self.tls_version_min = TLS_VERSIONS[-1] +elif self.tls_version_min not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_min." +.format(ver=self.tls_version_min)) + +if 'tls_version_max' not in self: +self.tls_version_max = TLS_VERSIONS[-1] +elif self.tls_version_max not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_max." +.format(ver=self.tls_version_max)) + def _finalize(self, **lastchance): """ Finalize and lock 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..9f8fd3c 100644 --- a/ipapython/nsslib.py +++ b/ipapython/nsslib.py @@ -23,6 +23,7 @@ import getpass import socket from ipapython.ipa_log_manager import root_logger +from ipalib.constants import TLS_VERSIONS, TLS_VERSION_MINIMAL from nss.error import NSPRError import nss.io as io @@ -129,6 +130,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 RuntimeError("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 RuntimeError("tls_version_max ('{val}') is not a known " + "TLS version.".format(val=tls_version_max)) + +if min_version_idx > max_version_idx: +raise RuntimeError("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):
[Freeipa-devel] [freeipa PR#396][synchronized] Explicitly remove support of SSLv2
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 db2b762293815c1263b3ce9390f564fe9e611735 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka 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. Also, we don't allow tls_version_min/max to be set to a random string anymore. https://fedorahosted.org/freeipa/ticket/6607 --- ipalib/config.py| 19 +-- ipalib/constants.py | 10 ++ ipapython/nsslib.py | 46 -- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/ipalib/config.py b/ipalib/config.py index 20591db..79f7a82 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,7 @@ def _bootstrap(self, **overrides): if 'plugins_on_demand' not in self: self.plugins_on_demand = (self.context == 'cli') + def _finalize_core(self, **defaults): """ Complete initialization of standard IPA environment. @@ -578,6 +582,17 @@ def _finalize_core(self, **defaults): self._merge(**defaults) +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_max not in TLS_VERSIONS: +raise errors.EnvironmentError( +"Unknown TLS version '{ver}' set in tls_version_max." +.format(self.tls_version_max)) + + def _finalize(self, **lastchance): """ Finalize and lock 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..9f8fd3c 100644 --- a/ipapython/nsslib.py +++ b/ipapython/nsslib.py @@ -23,6 +23,7 @@ import getpass import socket from ipapython.ipa_log_manager import root_logger +from ipalib.constants import TLS_VERSIONS, TLS_VERSION_MINIMAL from nss.error import NSPRError import nss.io as io @@ -129,6 +130,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 RuntimeError("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 RuntimeError("tls_version_max ('{val}') is not a known " + "TLS version.".format(val=tls_version_max)) + +if min_version_idx > max_version_idx: +raise RuntimeError("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
[Freeipa-devel] [freeipa PR#396][synchronized] Explicitly remove support of SSLv2
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 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_callb