]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Make certificate validation optional with an HTTPRequest parameter
authorBen Darnell <ben@bendarnell.com>
Tue, 15 Feb 2011 04:05:47 +0000 (20:05 -0800)
committerBen Darnell <ben@bendarnell.com>
Tue, 15 Feb 2011 04:05:47 +0000 (20:05 -0800)
for consistency between curl and simple HTTPClients.

tornado/httpclient.py
tornado/simple_httpclient.py
tornado/test/httpserver_test.py

index 25d07ae5c95f4cc685690793fe374370a803e5b4..c6f05b7fbf8b1525d2fe293da6549e953a46d8c3 100644 (file)
@@ -378,7 +378,8 @@ class HTTPRequest(object):
                  network_interface=None, streaming_callback=None,
                  header_callback=None, prepare_curl_callback=None,
                  proxy_host=None, proxy_port=None, proxy_username=None,
-                 proxy_password='', allow_nonstandard_methods=False):
+                 proxy_password='', allow_nonstandard_methods=False,
+                 validate_cert=True, ca_certs=None):
         if headers is None:
             headers = httputil.HTTPHeaders()
         if if_modified_since:
@@ -420,6 +421,12 @@ class HTTPRequest(object):
         self.header_callback = header_callback
         self.prepare_curl_callback = prepare_curl_callback
         self.allow_nonstandard_methods = allow_nonstandard_methods
+        # SSL certificate validation:
+        # validate_cert: boolean, set to False to disable validation
+        # ca_certs: filename of CA certificates in PEM format, or
+        #     None to use defaults
+        self.validate_cert = validate_cert
+        self.ca_certs = ca_certs
         self.start_time = time.time()
 
 
@@ -556,6 +563,11 @@ def _curl_setup_request(curl, request, buffer, headers):
             curl.setopt(pycurl.PROXYUSERPWD, credentials)
     else:
         curl.setopt(pycurl.PROXY, '')
+    curl.setopt(pycurl.SSL_VERIFYPEER, request.validate_cert)
+    if request.ca_certs is not None:
+        curl.setopt(pycurl.CAINFO, request.ca_certs)
+    else:
+        curl.unsetopt(pycurl.CAINFO)
 
     # Set the request method through curl's retarded interface which makes
     # up names for almost every single method
index c23def6cf502f205cb8e33ad6b402c0d77d8b619..a19805d8be33d5568b7a1339367ea627b47f8b08 100644 (file)
@@ -143,10 +143,14 @@ class _HTTPConnection(object):
                 host = self.client.hostname_mapping.get(host, host)
 
             if parsed.scheme == "https":
-                ssl_options = dict(
-                    cert_reqs=ssl.CERT_REQUIRED,
-                    ca_certs=os.path.dirname(__file__) + '/ca-certificates.crt',
-                    )
+                ssl_options = {}
+                if request.validate_cert:
+                    ssl_options["cert_reqs"] = ssl.CERT_REQUIRED
+                if request.ca_certs is not None:
+                    ssl_options["ca_certs"] = request.ca_certs
+                else:
+                    ssl_options["ca_certs"] = (os.path.dirname(__file__) + 
+                                               '/ca-certificates.crt')
                 self.stream = SSLIOStream(socket.socket(),
                                           io_loop=self.io_loop,
                                           ssl_options=ssl_options)
index b107578e75a2425f7fb8d68bafe6f1ac3747339e..e556e72910109e61cb885ba99f254e7a0b7dfbcd 100644 (file)
@@ -37,12 +37,9 @@ class SSLTest(AsyncHTTPTestCase, LogTrapTestCase):
                 keyfile=os.path.join(test_dir, 'test.key')))
 
     def fetch(self, path, **kwargs):
-        def disable_cert_check(curl):
-            # Our certificate was not signed by a CA, so don't check it
-            curl.setopt(pycurl.SSL_VERIFYPEER, 0)
         self.http_client.fetch(self.get_url(path).replace('http', 'https'),
                                self.stop,
-                               prepare_curl_callback=disable_cert_check,
+                               validate_cert=False,
                                **kwargs)
         return self.wait()