Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 851358 Details for
Bug 1044246
CVE-2013-6444 pywbem: failure to check certificate hostname
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Final fix
pywbem-20131121-ssl_verify_host.patch (text/plain), 12.11 KB, created by
Murray McAllister
on 2014-01-16 23:55:53 UTC
(
hide
)
Description:
Final fix
Filename:
MIME Type:
Creator:
Murray McAllister
Created:
2014-01-16 23:55:53 UTC
Size:
12.11 KB
patch
obsolete
>Index: pywbem-20131121/cim_http.py >=================================================================== >--- pywbem-20131121.orig/cim_http.py >+++ pywbem-20131121/cim_http.py >@@ -28,6 +28,7 @@ being transferred is XML. It is up to t > data and interpret the result. > ''' > >+from M2Crypto import SSL, Err > import sys, string, re, os, socket, getpass > from stat import S_ISSOCK > import cim_obj >@@ -74,8 +75,26 @@ def parse_url(url): > > return host, port, ssl > >+def get_default_ca_certs(): >+ """ >+ Try to find out system path with ca certificates. This path is cached and >+ returned. If no path is found out, None is returned. >+ """ >+ if not hasattr(get_default_ca_certs, '_path'): >+ for path in ( >+ '/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt', >+ '/etc/ssl/certs', >+ '/etc/ssl/certificates'): >+ if os.path.exists(path): >+ get_default_ca_certs._path = path >+ break >+ else: >+ get_default_ca_certs._path = None >+ return get_default_ca_certs._path >+ > def wbem_request(url, data, creds, headers = [], debug = 0, x509 = None, >- verify_callback = None): >+ verify_callback = None, ca_certs = None, >+ no_verification = False): > """Send XML data over HTTP to the specified url. Return the > response in XML. Uses Python's build-in httplib. x509 may be a > dictionary containing the location of the SSL certificate and key >@@ -105,10 +124,49 @@ def wbem_request(url, data, creds, heade > > class HTTPSConnection(HTTPBaseConnection, httplib.HTTPSConnection): > def __init__(self, host, port=None, key_file=None, cert_file=None, >- strict=None): >+ strict=None, ca_certs=None, verify_callback=None): > httplib.HTTPSConnection.__init__(self, host, port, key_file, > cert_file, strict) >- >+ self.ca_certs = ca_certs >+ self.verify_callback = verify_callback >+ >+ def connect(self): >+ "Connect to a host on a given (SSL) port." >+ self.sock = socket.create_connection((self.host, self.port), >+ self.timeout, self.source_address) >+ if self._tunnel_host: >+ self.sock = sock >+ self._tunnel() >+ ctx = SSL.Context('sslv23') >+ if self.cert_file: >+ ctx.load_cert(self.cert_file, keyfile=self.key_file) >+ if self.ca_certs: >+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, >+ depth=9, callback=verify_callback) >+ if os.path.isdir(self.ca_certs): >+ ctx.load_verify_locations(capath=self.ca_certs) >+ else: >+ ctx.load_verify_locations(cafile=self.ca_certs) >+ try: >+ self.sock = SSL.Connection(ctx, self.sock) >+ # Below is a body of SSL.Connection.connect() method >+ # except for the first line (socket connection). We want to preserve >+ # tunneling ability. >+ self.sock.addr = (self.host, self.port) >+ self.sock.setup_ssl() >+ self.sock.set_connect_state() >+ ret = self.sock.connect_ssl() >+ if self.ca_certs: >+ check = getattr(self.sock, 'postConnectionCheck', >+ self.sock.clientPostConnectionCheck) >+ if check is not None: >+ if not check(self.sock.get_peer_cert(), self.host): >+ raise Error('SSL error: post connection check failed') >+ return ret >+ except ( Err.SSLError, SSL.SSLError, SSL.SSLTimeoutError >+ , SSL.Checker.WrongHost), arg: >+ raise Error("SSL error: %s" % arg) >+ > class FileHTTPConnection(HTTPBaseConnection, httplib.HTTPConnection): > def __init__(self, uds_path): > httplib.HTTPConnection.__init__(self, 'localhost') >@@ -117,64 +175,36 @@ def wbem_request(url, data, creds, heade > self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) > self.sock.connect(self.uds_path) > >- host, port, ssl = parse_url(url) >+ host, port, use_ssl = parse_url(url) > > key_file = None > cert_file = None > >- if ssl: >- >- if x509 is not None: >- cert_file = x509.get('cert_file') >- key_file = x509.get('key_file') >- >- if verify_callback is not None: >- addr_ind = 0 >- # Temporary exception store >- addr_exc = None >- # Get a list of arguments for socket(). >- addr_list = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM) >- for addr_ind in xrange(len(addr_list)): >- family, socktype, proto, canonname, sockaddr = addr_list[addr_ind] >- try: >- from OpenSSL import SSL >- ctx = SSL.Context(SSL.SSLv3_METHOD) >- ctx.set_verify(SSL.VERIFY_PEER, verify_callback) >- ctx.set_default_verify_paths() >- # Add the key and certificate to the session >- if cert_file is not None and key_file is not None: >- ctx.use_certificate_file(cert_file) >- ctx.use_privatekey_file(key_file) >- s = SSL.Connection(ctx, socket.socket(family, socktype, proto)) >- s.connect((host, port)) >- s.do_handshake() >- s.shutdown() >- s.close() >- addr_exc = None >- break >- except (socket.gaierror, socket.error), arg: >- # Could not perform connect() call, store the exception object for >- # later use. >- addr_exc = arg >- continue >- except socket.sslerror, arg: >- raise Error("SSL error: %s" % (arg,)) >- >- # Did we try all the addresses from getaddrinfo() and no successful >- # connection performed? >- if addr_exc: >- raise Error("Socket error: %s" % (addr_exc),) >+ if use_ssl and x509 is not None: >+ cert_file = x509.get('cert_file') >+ key_file = x509.get('key_file') > > numTries = 0 > localAuthHeader = None > tryLimit = 5 > >+ if isinstance(data, unicode): >+ data = data.encode('utf-8') > data = '<?xml version="1.0" encoding="utf-8" ?>\n' + data > >+ if not no_verification and ca_certs is None: >+ ca_certs = get_default_ca_certs() >+ elif no_verification: >+ ca_certs = None >+ > local = False >- if ssl: >- h = HTTPSConnection(host, port = port, key_file = key_file, >- cert_file = cert_file) >+ if use_ssl: >+ h = HTTPSConnection(host, >+ port = port, >+ key_file = key_file, >+ cert_file = cert_file, >+ ca_certs = ca_certs, >+ verify_callback = verify_callback) > else: > if url.startswith('http'): > h = HTTPConnection(host, port = port) >@@ -216,6 +246,8 @@ def wbem_request(url, data, creds, heade > h.putheader('PegasusAuthorization', 'Local "%s"' % locallogin) > > for hdr in headers: >+ if isinstance(hdr, unicode): >+ hdr = hdr.encode('utf-8') > s = map(lambda x: string.strip(x), string.split(hdr, ":", 1)) > h.putheader(urllib.quote(s[0]), urllib.quote(s[1])) > >Index: pywbem-20131121/cim_operations.py >=================================================================== >--- pywbem-20131121.orig/cim_operations.py >+++ pywbem-20131121/cim_operations.py >@@ -78,12 +78,12 @@ class WBEMConnection(object): > the request before it is sent, and the reply before it is > unpacked. > >- verify_callback is used to verify the server certificate. >- It is passed to OpenSSL.SSL.set_verify, and is called during the SSL >- handshake. verify_callback should take five arguments: A Connection >- object, an X509 object, and three integer variables, which are in turn >- potential error number, error depth and return code. verify_callback >- should return True if verification passes and False otherwise. >+ verify_callback is used to verify the server certificate. It is passed to >+ M2Crypto.SSL.Context.set_verify, and is called during the SSL handshake. >+ verify_callback should take five arguments: An SSL Context object, an X509 >+ object, and three integer variables, which are in turn potential error >+ number, error depth and return code. verify_callback should return True if >+ verification passes and False otherwise. > > The value of the x509 argument is used only when the url contains > 'https'. x509 must be a dictionary containing the keys 'cert_file' >@@ -91,14 +91,27 @@ class WBEMConnection(object): > filename of an certificate and the value of 'key_file' must consist > of a filename containing the private key belonging to the public key > that is part of the certificate in cert_file. >+ >+ ca_certs specifies where CA certificates for verification purposes are >+ located. These are trusted certificates. Note that the certificates have to >+ be in PEM format. Either it is a directory prepared using the c_rehash tool >+ included with OpenSSL or an pemfile. If None, default system path will be >+ used. >+ >+ no_verification allows to disable peer's verification. This is insecure and >+ should be avoided. If True, peer's certificate is not verified and ca_certs >+ argument is ignored. > """ > > def __init__(self, url, creds = None, default_namespace = DEFAULT_NAMESPACE, >- x509 = None, verify_callback = None): >+ x509 = None, verify_callback = None, ca_certs = None, >+ no_verification = False): > self.url = url > self.creds = creds > self.x509 = x509 > self.verify_callback = verify_callback >+ self.ca_certs = ca_certs >+ self.no_verification = no_verification > self.last_request = self.last_reply = '' > self.default_namespace = default_namespace > self.debug = False >@@ -164,7 +177,9 @@ class WBEMConnection(object): > resp_xml = cim_http.wbem_request(self.url, req_xml.toxml(), > self.creds, headers, > x509 = self.x509, >- verify_callback = self.verify_callback) >+ verify_callback = self.verify_callback, >+ ca_certs = self.ca_certs, >+ no_verification = self.no_verification) > except cim_http.AuthError: > raise > except cim_http.Error, arg: >@@ -321,7 +336,9 @@ class WBEMConnection(object): > resp_xml = cim_http.wbem_request(self.url, req_xml.toxml(), > self.creds, headers, > x509 = self.x509, >- verify_callback = self.verify_callback) >+ verify_callback = self.verify_callback, >+ ca_certs = self.ca_certs, >+ no_verification = self.no_verification) > except cim_http.Error, arg: > # Convert cim_http exceptions to CIMError exceptions > raise CIMError(0, str(arg)) >Index: pywbem-20131121/setup.py >=================================================================== >--- pywbem-20131121.orig/setup.py >+++ pywbem-20131121/setup.py >@@ -37,6 +37,7 @@ args = {'name': 'pywbem', > 'version': '0.7.0', > 'license': 'LGPLv2', > 'packages': ['pywbem'], >+ 'install_requires': ['M2Crypto'], > # Make packages in root dir appear in pywbem module > 'package_dir': {'pywbem': ''}, > # Make extensions in root dir appear in pywbem module
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1044246
: 851358