Skip to content

Commit

Permalink
Merge pull request #547 from evanj/master
Browse files Browse the repository at this point in the history
Detect SSL option errors at start up
  • Loading branch information
bdarnell committed Jun 29, 2012
2 parents ff12f29 + 73d26a4 commit a240c76
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
17 changes: 17 additions & 0 deletions tornado/netutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,23 @@ def __init__(self, io_loop=None, ssl_options=None):
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.
Expand Down
31 changes: 31 additions & 0 deletions tornado/test/httpserver_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
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
Expand All @@ -16,6 +17,7 @@
import socket
import sys
import tempfile
import unittest

try:
import ssl
Expand Down Expand Up @@ -101,6 +103,35 @@ def get_ssl_version(self):
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
Expand Down

0 comments on commit a240c76

Please sign in to comment.