File python-bugzilla-0.6.2-CVE-2013-2191-ssl-validate.patch of Package python-bugzilla

Index: python-bugzilla-0.6.2/bugzilla/base.py
===================================================================
--- python-bugzilla-0.6.2.orig/bugzilla/base.py	2013-06-28 12:36:49.861947869 +0200
+++ python-bugzilla-0.6.2/bugzilla/base.py	2013-06-28 13:18:08.508875654 +0200
@@ -10,6 +10,7 @@
 # the full text of the license.
 
 import xmlrpclib, urllib2
+import httplib, socket, ssl
 try:
        import cookielib
 except ImportError:
@@ -102,7 +103,8 @@
         cookies persistently.
     '''
     def __init__(self, url=None, user=None, password=None,
-            cookiefile=os.path.expanduser('~/.bugzillacookies')):
+            cookiefile=os.path.expanduser('~/.bugzillacookies'),
+            sslverify=True):
         # Settings the user might want to tweak
         self.user       = user or ''
         self.password   = password or ''
@@ -115,6 +117,7 @@
         else:
             self._cookiefile = True
         self.cookiefile = cookiefile
+        self._sslverify = bool(sslverify)
 
         self.user_agent = user_agent
         self.logged_in  = False
@@ -253,6 +256,11 @@
         If 'user' and 'password' are both set, we'll run login(). Otherwise
         you'll have to login() yourself before some methods will work.
         '''
+
+        # init ssl verification
+        if self._sslverify:
+            httplib.HTTPSConnection = VerifiedHTTPSConnection
+
         # Set up the transport
         if url.startswith('https'):
             self._transport = SafeCookieTransport()
@@ -1050,6 +1058,44 @@
     else:
         request = request_with_cookies # python 2.6 and earlier
 
+
+class SSLVerifyError(Exception):
+    pass
+
+class VerifiedHTTPSConnection(httplib.HTTPSConnection):
+
+    def _get_valid_hosts(self, cert):
+        if 'subjectAltName' in cert:
+            return [x[1] for x in cert['subjectAltName']
+                         if x[0].lower() == 'dns']
+        else:
+            return [x[0][1] for x in cert['subject']
+                            if x[0][0].lower() == 'commonname']
+
+    def validate_hosts(self):
+        cert = self.sock.getpeercert()
+        hosts = self._get_valid_hosts(cert)
+        import re
+        for host in hosts:
+            host_re = host.replace('.', '\.').replace('*', '[^.]*')
+            if re.search('^%s$' % (host_re,), self.host, re.I):
+                return
+        raise SSLVerifyError("hostnames in certificate don't match request")
+
+    def connect(self):
+        # overrides the version in httplib so that we do
+        #    certificate verification
+        sock = socket.create_connection((self.host, self.port),
+                                        self.timeout)
+        if self._tunnel_host:
+            self.sock = sock
+            self._tunnel()
+        # wrap the socket using verification with the root
+        #    certs in trusted_root_certs
+        self.sock = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs='/etc/ssl/certs')
+        self.validate_hosts()
+
+
 class BasicAuthTransport(xmlrpclib.SafeTransport):
     """A subclass of xmlrpclib.SafeTransport that allows setting HTTP Basic Auth
     without exposing it as part of URL in backtraces."""
Index: python-bugzilla-0.6.2/bin/bugzilla
===================================================================
--- python-bugzilla-0.6.2.orig/bin/bugzilla	2013-06-28 12:36:49.839947240 +0200
+++ python-bugzilla-0.6.2/bin/bugzilla	2013-06-28 13:16:52.103689280 +0200
@@ -55,6 +55,8 @@
     p.add_option('--bztype',default='auto',
             help="Bugzilla type. Autodetected if not set. "
                  "Available types: %s" % " ".join(bugzilla.classlist))
+    p.add_option('--nosslverify', dest='sslverify', action='store_false', default=True,
+            help="don't error on invalid bugzilla SSL certificate")
     p.add_option('--user',
             help="username")
     p.add_option('--password',
@@ -363,7 +365,7 @@
         bzclass = getattr(bugzilla,global_opt.bztype)
     else:
         parser.error("bztype must be one of: %s" % str(bugzilla.classlist))
-    bz=bzclass(url=global_opt.bugzilla)
+    bz=bzclass(url=global_opt.bugzilla, sslverify=global_opt.sslverify)
 
     # Handle 'login' action
     if action == 'login':
openSUSE Build Service is sponsored by