Juan Hernandez has uploaded a new change for review. Change subject: sdk: Check SSL server certificate ......................................................................
sdk: Check SSL server certificate Currently we don't check that the host name provided in the URL matches the host name contained in the server certificate. This is a common feature of most SSL clients, but it isn't well supported by the SSL implementation in Python 2.6. To improve security this patch explicitly checks the host name given in the URL against the subject common name attribute and the subject alternative names extension. This check will be enabled by default and disabled when using "insecure=True" in the constructor of the entry point object. Change-Id: I6a08179288fd564fbb79f5731c3e32251e560d81 Signed-off-by: Juan Hernandez <juan.hernan...@redhat.com> --- M src/ovirtsdk/web/connection.py M src/ovirtsdk/web/httpsconnection.py 2 files changed, 59 insertions(+), 2 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine-sdk refs/changes/71/26271/1 diff --git a/src/ovirtsdk/web/connection.py b/src/ovirtsdk/web/connection.py index 5bd84d7..646f36b 100644 --- a/src/ovirtsdk/web/connection.py +++ b/src/ovirtsdk/web/connection.py @@ -233,7 +233,8 @@ cert_file=cert_file, ca_file=ca_file, strict=strict, - timeout=timeout + timeout=timeout, + insecure=insecure ) return HTTPConnection( host=u.hostname, diff --git a/src/ovirtsdk/web/httpsconnection.py b/src/ovirtsdk/web/httpsconnection.py index 4d60b34..8ec8d4a 100644 --- a/src/ovirtsdk/web/httpsconnection.py +++ b/src/ovirtsdk/web/httpsconnection.py @@ -15,6 +15,7 @@ # import httplib +import re import socket import ssl @@ -26,10 +27,12 @@ ''' def __init__(self, host, port=None, key_file=None, cert_file=None, ca_file=None, - strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + insecure=False): httplib.HTTPSConnection.__init__(self, host=host, port=port, key_file=key_file, cert_file=cert_file, strict=strict, timeout=timeout) self.ca_file = ca_file + self.insecure = insecure def connect(self): ''' @@ -58,3 +61,56 @@ self.cert_file, cert_reqs=ssl.CERT_NONE ) + + # Check that the host name contained in the URL matches at least one of + # the host names contained in the server certificate: + if not self.insecure: + self.__check_hostname() + + def __check_hostname(self): + # Get the names contained in the common name and in the subject + # alternative names of the certificate: + hostnames = self.__get_certificate_hosts() + + # Transform each name into a pattern taking into account + # that they can be wildcard names: + patterns = [] + for hostname in hostnames: + pattern = None + if hostname.startswith("*."): + pattern = "[^.]+" + re.escape(hostname[1:]) + else: + pattern = re.escape(hostname) + pattern = "^" + pattern + "$" + patterns.append(pattern) + + # Check if the host name matches any of the patterns: + for pattern in patterns: + if re.match(pattern, self.host, flags=re.IGNORECASE): + return + raise httplib.HTTPException("The host name \"%s\" contained in the " + "URL doesn't match any of the DNS names in the server " + "certificate." % self.host) + + def __get_certificate_hosts(self): + hosts = [] + + # Get the server certificate: + certificate = self.sock.getpeercert() + + # Get the common name: + names = certificate.get("subject") + if names is not None: + for rdn in names: + for key, value in rdn: + if key == "commonName": + hosts.append(value) + + # Get the DNS subject alternative names: + names = certificate.get("subjectAltName") + if names is not None: + for key, value in names: + if key == "DNS": + hosts.append(value) + + return hosts -- To view, visit http://gerrit.ovirt.org/26271 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6a08179288fd564fbb79f5731c3e32251e560d81 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine-sdk Gerrit-Branch: master Gerrit-Owner: Juan Hernandez <juan.hernan...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches