From: Ben Darnell Date: Mon, 9 Jan 2012 19:59:24 +0000 (-0800) Subject: Disable SSLv2 in simple_httpclient. X-Git-Tag: v2.2.0~42 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dbe1c9bc84e48da50cee13124efb8b8a86870e7b;p=thirdparty%2Ftornado.git Disable SSLv2 in simple_httpclient. Contrary to the python documentation, SSLv2 is enabled by default unless openssl version 1.0 or newer is used; older versions appear to still be in use (e.g. in Ubuntu 10.04 LTS and Mac OS X Lion) --- diff --git a/tornado/simple_httpclient.py b/tornado/simple_httpclient.py index ce2762f1d..1f90bef93 100644 --- a/tornado/simple_httpclient.py +++ b/tornado/simple_httpclient.py @@ -17,6 +17,7 @@ import logging import os.path import re import socket +import sys import time import urlparse import zlib @@ -185,6 +186,26 @@ class _HTTPConnection(object): ssl_options["keyfile"] = request.client_key if request.client_cert is not None: ssl_options["certfile"] = request.client_cert + + # SSL interoperability is tricky. We want to disable + # SSLv2 for security reasons; it wasn't disabled by default + # until openssl 1.0. The best way to do this is to use + # the SSL_OP_NO_SSLv2, but that wasn't exposed to python + # until 3.2. Python 2.7 adds the ciphers argument, which + # can also be used to disable SSLv2. As a last resort + # on python 2.6, we set ssl_version to SSLv3. This is + # more narrow than we'd like since it also breaks + # compatibility with servers configured for TLSv1 only, + # but nearly all servers support SSLv3: + # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html + if sys.version_info >= (2,7): + ssl_options["ciphers"] = "DEFAULT:!SSLv2" + else: + # This is really only necessary for pre-1.0 versions + # of openssl, but python 2.6 doesn't expose version + # information. + ssl_options["ssl_version"] = ssl.PROTOCOL_SSLv3 + self.stream = SSLIOStream(socket.socket(af, socktype, proto), io_loop=self.io_loop, ssl_options=ssl_options, diff --git a/tornado/test/httpserver_test.py b/tornado/test/httpserver_test.py index 1f0fb23c2..a55ca92fc 100644 --- a/tornado/test/httpserver_test.py +++ b/tornado/test/httpserver_test.py @@ -104,11 +104,22 @@ class SSLv3Test(BaseSSLTest, SSLTestMixin): class TLSv1Test(BaseSSLTest, SSLTestMixin): def get_ssl_version(self): return ssl.PROTOCOL_TLSv1 +class SSLv2Test(BaseSSLTest): + def get_ssl_version(self): return ssl.PROTOCOL_SSLv2 + + def test_sslv2_fail(self): + # This is really more of a client test, but run it here since + # we've got all the other ssl version tests here. + # Clients should have SSLv2 disabled by default. + response = self.fetch('/') + self.assertEqual(response.code, 599) + if ssl is None: del BaseSSLTest del SSLv23Test del SSLv3Test del TLSv1Test + del SSLv2Test elif getattr(ssl, 'OPENSSL_VERSION_INFO', (0,0)) < (1,0): # In pre-1.0 versions of openssl, SSLv23 clients always send SSLv2 # ClientHello messages, which are rejected by SSLv3 and TLSv1