]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
TCPServer: Do some validation of ssl_options 547/head
authorEvan Jones <ej@evanjones.ca>
Tue, 26 Jun 2012 16:17:13 +0000 (12:17 -0400)
committerEvan Jones <ej@evanjones.ca>
Thu, 28 Jun 2012 12:05:13 +0000 (08:05 -0400)
Previously, errors aren't detected until a client connects.

tornado/netutil.py
tornado/test/httpserver_test.py

index d06a176b41c44de31232566054c7b3a415d310e2..574cf72e20206de29a5028e40c25cd0a734fa1c3 100644 (file)
@@ -92,6 +92,23 @@ class TCPServer(object):
         self._pending_sockets = []
         self._started = False
 
+        # Verify the SSL options. Otherwise we don't get errors until clients
+        # connect. This doesn't verify that the keys are legitimate, but
+        # the SSL module doesn't do that until there is a connected socket
+        # which seems like too much work
+        if self.ssl_options is not None:
+            # Only certfile is required: it can contain both keys
+            if 'certfile' not in self.ssl_options:
+                raise KeyError('missing key "certfile" in ssl_options')
+
+            if not os.path.exists(self.ssl_options['certfile']):
+                raise ValueError('certfile "%s" does not exist' %
+                    self.ssl_options['certfile'])
+            if ('keyfile' in self.ssl_options and
+                    not os.path.exists(self.ssl_options['keyfile'])):
+                raise ValueError('keyfile "%s" does not exist' %
+                    self.ssl_options['keyfile'])
+
     def listen(self, port, address=""):
         """Starts accepting connections on the given port.
 
index 5237e75e46e816d62120830b05d4f5a73c69cc20..e9078da2801d7492f7b2f51e8ce15543d6bc8184 100644 (file)
@@ -6,6 +6,7 @@ from tornado import httpclient, simple_httpclient, netutil
 from tornado.escape import json_decode, utf8, _unicode, recursive_unicode, native_str
 from tornado.httpserver import HTTPServer
 from tornado.httputil import HTTPHeaders
+from tornado.ioloop import IOLoop
 from tornado.iostream import IOStream
 from tornado.simple_httpclient import SimpleAsyncHTTPClient
 from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, LogTrapTestCase
@@ -16,6 +17,7 @@ import shutil
 import socket
 import sys
 import tempfile
+import unittest
 
 try:
     import ssl
@@ -101,6 +103,35 @@ class TLSv1Test(BaseSSLTest, SSLTestMixin):
         return ssl.PROTOCOL_TLSv1
 
 
+class BadSSLOptionsTest(unittest.TestCase):
+    def test_missing_arguments(self):
+        application = Application()
+        self.assertRaises(KeyError, HTTPServer, application, ssl_options={
+            "keyfile": "/__missing__.crt",
+        })
+
+    def test_missing_key(self):
+        '''A missing SSL key should cause an immediate exception.'''
+
+        application = Application()
+        module_dir = os.path.dirname(__file__)
+        existing_certificate = os.path.join(module_dir, 'test.crt')
+
+        self.assertRaises(ValueError, HTTPServer, application, ssl_options={
+           "certfile": "/__mising__.crt",
+        })
+        self.assertRaises(ValueError, HTTPServer, application, ssl_options={
+           "certfile": existing_certificate,
+           "keyfile": "/__missing__.key"
+        })
+
+        # This actually works because both files exist
+        server = HTTPServer(application, ssl_options={
+           "certfile": existing_certificate,
+           "keyfile": existing_certificate
+        })
+
+
 if ssl is None:
     del BaseSSLTest
     del SSLv23Test