diff options
author | Rob Crittenden <rcritten@redhat.com> | 2015-09-25 09:12:00 -0400 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2015-10-02 16:51:56 -0400 |
commit | 15af3be170f05b64a967f4f7755a90608033c374 (patch) | |
tree | d0448ee439e6229580459fc55d532e807856da9b /test/test_request.py | |
parent | 00fe09480dfd28674661830d8a045e0f560bbe51 (diff) | |
download | mod_nss-15af3be170f05b64a967f4f7755a90608033c374.tar.gz mod_nss-15af3be170f05b64a967f4f7755a90608033c374.tar.xz mod_nss-15af3be170f05b64a967f4f7755a90608033c374.zip |
Add test suite for SNI
python for OpenSSL is in quite a sad state with several competing
mid-level implementations which provide different feature sets.
The httplib client provides access to the negotiated cipher and
protocol but not SNI (and it has lousy hostname checking).
The urllib3 client provides SNI and is generally better but doesn't
give any details on the connection.
So I'm using both. The original one is used for basic server testing
and the urllib3 one is used just for SNI testing.
Also:
- Indent the test configuration to make it more readable
- Add separate config file for SNI testing
- Add a CGI configuration and script to test CGI variables
- Change client cipher test to use AES256-SHA instead of RC4
- Add a commented-out valgrind option in start for future
debuggers
- Change the VirtualServers to *:port and use ServerName
- Add per-VH document roots so SNI can be more easily tested
Diffstat (limited to 'test/test_request.py')
-rw-r--r-- | test/test_request.py | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/test/test_request.py b/test/test_request.py index bac2a2d..5d2a525 100644 --- a/test/test_request.py +++ b/test/test_request.py @@ -4,9 +4,12 @@ import socket import requests import urlparse -from urllib3.util import get_host -from urllib3.connectionpool import HTTPConnectionPool, HTTPSConnectionPool import logging +import socket +from requests.packages.urllib3.util import get_host +from requests.packages.urllib3.util.timeout import Timeout +from requests.packages.urllib3.contrib import pyopenssl +from requests.packages.urllib3.connectionpool import HTTPConnectionPool, HTTPSConnectionPool, VerifiedHTTPSConnection # Don't bend over backwards for ssl support, assume it is there. import ssl @@ -30,6 +33,8 @@ except ImportError: # Other older python we use the urllib3 bundled copy from urllib3.packages.ssl_match_hostname import match_hostname, CertificateError +SAVE_DEFAULT_SSL_CIPHER_LIST = pyopenssl.DEFAULT_SSL_CIPHER_LIST + log = logging.getLogger(__name__) @@ -61,7 +66,7 @@ def connection_from_url(url, **kw): class MyHTTPSConnectionPool(HTTPSConnectionPool): def __init__(self, host, port=None, - strict=False, timeout=None, maxsize=1, + strict=False, timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, block=False, headers=None, key_file=None, cert_file=None, cert_reqs='CERT_REQUIRED', ca_certs='/etc/ssl/certs/ca-certificates.crt', ssl_version=ssl.PROTOCOL_SSLv23, ciphers=None): @@ -75,6 +80,8 @@ class MyHTTPSConnectionPool(HTTPSConnectionPool): self.ca_certs = ca_certs self.ssl_version = ssl_version self.ciphers = ciphers + self.assert_hostname = None + self.assert_fingerprint = None def _new_conn(self): """ @@ -92,13 +99,14 @@ class MyHTTPSConnectionPool(HTTPSConnectionPool): # return HTTPSConnection(host=self.host, port=self.port) connection = MyVerifiedHTTPSConnection(host=self.host, port=self.port) + connection.sni = self.sni connection.set_cert(key_file=self.key_file, cert_file=self.cert_file, cert_reqs=self.cert_reqs, ca_certs=self.ca_certs) connection.set_ssl_version(self.ssl_version) connection.set_ciphers(self.ciphers) return connection -class MyVerifiedHTTPSConnection(HTTPSConnection): +class MyVerifiedHTTPSConnection(VerifiedHTTPSConnection): """ Based on httplib.HTTPSConnection but wraps the socket with SSL certification. @@ -106,6 +114,10 @@ class MyVerifiedHTTPSConnection(HTTPSConnection): cert_reqs = None ca_certs = None client_cipher = None + is_verified = True # squelch warning + sni = False + assert_hostname = None + assert_fingerprint = None def set_cert(self, key_file=None, cert_file=None, cert_reqs='CERT_NONE', ca_certs=None): @@ -127,6 +139,13 @@ class MyVerifiedHTTPSConnection(HTTPSConnection): self.ciphers = ciphers def connect(self): + if self.sni: + if self.ciphers: + pyopenssl.DEFAULT_SSL_CIPHER_LIST = self.ciphers + else: + pyopenssl.DEFAULT_SSL_CIPHER_LIST = SAVE_DEFAULT_SSL_CIPHER_LIST + return super(MyVerifiedHTTPSConnection, self).connect() + # Add certificate verification sock = socket.create_connection((self.host, self.port), self.timeout) @@ -141,9 +160,10 @@ class MyVerifiedHTTPSConnection(HTTPSConnection): match_hostname(self.sock.getpeercert(), self.host) def close(self): - if self.sock: - self.client_cipher = self.sock.cipher() - HTTPSConnection.close(self) + if not self.sni: + if self.sock: + self.client_cipher = self.sock.cipher() + super(MyVerifiedHTTPSConnection, self).close() class MyAdapter(requests.adapters.HTTPAdapter): @@ -171,6 +191,7 @@ class MyAdapter(requests.adapters.HTTPAdapter): conn.cert_file = verify['cert_file'] if 'key_file' in verify: conn.key_file = verify['key_file'] + conn.sni = verify.get('sni', False) else: # huh? Do nothing pass |