blob: b622da5cb99b346fb51de7fb2c898a97a5b43062 [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Thomas Woutersed03b412007-08-28 21:37:11 +00006import socket
Bill Janssen6e027db2007-11-15 22:23:56 +00007import select
Thomas Woutersed03b412007-08-28 21:37:11 +00008import errno
Thomas Woutersed03b412007-08-28 21:37:11 +00009import subprocess
10import time
Antoine Pitrou3b9b9ba2010-04-23 23:33:50 +000011import gc
Thomas Woutersed03b412007-08-28 21:37:11 +000012import os
Antoine Pitrou3b9b9ba2010-04-23 23:33:50 +000013import errno
Thomas Woutersed03b412007-08-28 21:37:11 +000014import pprint
Jeremy Hylton1afc1692008-06-18 20:49:58 +000015import urllib.parse, urllib.request
Thomas Woutersed03b412007-08-28 21:37:11 +000016import shutil
17import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000018import asyncore
Antoine Pitrou78f4a9a2010-04-23 23:12:22 +000019import weakref
Thomas Woutersed03b412007-08-28 21:37:11 +000020
Georg Brandl24420152008-05-26 16:32:26 +000021from http.server import HTTPServer, SimpleHTTPRequestHandler
Thomas Wouters1b7f8912007-09-19 03:06:30 +000022
Thomas Woutersed03b412007-08-28 21:37:11 +000023# Optionally test SSL support, if we have it in the tested platform
24skip_expected = False
25try:
26 import ssl
27except ImportError:
28 skip_expected = True
29
Benjamin Petersonee8712c2008-05-20 21:35:26 +000030HOST = support.HOST
Thomas Woutersed03b412007-08-28 21:37:11 +000031CERTFILE = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +000032SVN_PYTHON_ORG_ROOT_CERT = None
Thomas Woutersed03b412007-08-28 21:37:11 +000033
Thomas Woutersed03b412007-08-28 21:37:11 +000034def handle_error(prefix):
35 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000036 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000037 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000038
39
40class BasicTests(unittest.TestCase):
41
Antoine Pitrou91382d82010-04-28 21:39:56 +000042 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000043 ssl.PROTOCOL_SSLv2
44 ssl.PROTOCOL_SSLv23
45 ssl.PROTOCOL_SSLv3
46 ssl.PROTOCOL_TLSv1
47 ssl.CERT_NONE
48 ssl.CERT_OPTIONAL
49 ssl.CERT_REQUIRED
Thomas Woutersed03b412007-08-28 21:37:11 +000050
Antoine Pitrou91382d82010-04-28 21:39:56 +000051 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000052 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +000053 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000054 sys.stdout.write("\n RAND_status is %d (%s)\n"
55 % (v, (v and "sufficient randomness") or
56 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +000057 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000058 ssl.RAND_egd(1)
59 except TypeError:
60 pass
Thomas Woutersed03b412007-08-28 21:37:11 +000061 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000062 print("didn't raise TypeError")
63 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +000064
Antoine Pitrou91382d82010-04-28 21:39:56 +000065 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000066 # note that this uses an 'unofficial' function in _ssl.c,
67 # provided solely for this test, to exercise the certificate
68 # parsing code
69 p = ssl._ssl._test_decode_cert(CERTFILE, False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000070 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000071 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +000072
Antoine Pitrou91382d82010-04-28 21:39:56 +000073 def test_DER_to_PEM(self):
74 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
75 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +000076 d1 = ssl.PEM_cert_to_DER_cert(pem)
77 p2 = ssl.DER_cert_to_PEM_cert(d1)
78 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou66ffb262010-04-27 11:05:15 +000079 self.assertEqual(d1, d2)
Antoine Pitrou00f905e2010-04-27 22:09:05 +000080 if not p2.startswith(ssl.PEM_HEADER + '\n'):
81 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
82 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
83 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +000084
Antoine Pitrou78f4a9a2010-04-23 23:12:22 +000085 @support.cpython_only
86 def test_refcycle(self):
87 # Issue #7943: an SSL object doesn't create reference cycles with
88 # itself.
89 s = socket.socket(socket.AF_INET)
90 ss = ssl.wrap_socket(s)
91 wr = weakref.ref(ss)
92 del ss
93 self.assertEqual(wr(), None)
94
Antoine Pitrouc2203f92010-04-24 22:07:51 +000095 def test_timeout(self):
96 # Issue #8524: when creating an SSL socket, the timeout of the
97 # original socket should be retained.
98 for timeout in (None, 0.0, 5.0):
99 s = socket.socket(socket.AF_INET)
100 s.settimeout(timeout)
101 ss = ssl.wrap_socket(s)
102 self.assertEqual(timeout, ss.gettimeout())
103
Antoine Pitrou3b9b9ba2010-04-23 23:33:50 +0000104
Bill Janssen6e027db2007-11-15 22:23:56 +0000105class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000106
Antoine Pitrou91382d82010-04-28 21:39:56 +0000107 def test_connect(self):
Antoine Pitrou78d89462010-09-09 13:33:33 +0000108 with support.transient_internet("svn.python.org"):
109 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
110 cert_reqs=ssl.CERT_NONE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000111 s.connect(("svn.python.org", 443))
Antoine Pitrou78d89462010-09-09 13:33:33 +0000112 c = s.getpeercert()
113 if c:
114 self.fail("Peer cert %s shouldn't be here!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000115 s.close()
116
Antoine Pitrou78d89462010-09-09 13:33:33 +0000117 # this should fail because we have no verification certs
118 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
119 cert_reqs=ssl.CERT_REQUIRED)
120 try:
121 s.connect(("svn.python.org", 443))
122 except ssl.SSLError:
123 pass
124 finally:
125 s.close()
126
127 # this should succeed because we specify the root cert
128 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
129 cert_reqs=ssl.CERT_REQUIRED,
130 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
131 try:
132 s.connect(("svn.python.org", 443))
133 finally:
134 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000135
Antoine Pitroufe0f1172010-04-24 11:17:37 +0000136 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
137 def test_makefile_close(self):
138 # Issue #5238: creating a file-like object with makefile() shouldn't
139 # delay closing the underlying "real socket" (here tested with its
140 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou78d89462010-09-09 13:33:33 +0000141 with support.transient_internet("svn.python.org"):
142 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
143 ss.connect(("svn.python.org", 443))
144 fd = ss.fileno()
145 f = ss.makefile()
146 f.close()
147 # The fd is still open
Antoine Pitroufe0f1172010-04-24 11:17:37 +0000148 os.read(fd, 0)
Antoine Pitrou78d89462010-09-09 13:33:33 +0000149 # Closing the SSL socket should close the fd too
150 ss.close()
151 gc.collect()
152 try:
153 os.read(fd, 0)
154 except OSError as e:
155 self.assertEqual(e.errno, errno.EBADF)
156 else:
157 self.fail("OSError wasn't raised")
Antoine Pitroufe0f1172010-04-24 11:17:37 +0000158
Antoine Pitrou91382d82010-04-28 21:39:56 +0000159 def test_non_blocking_handshake(self):
Antoine Pitrou78d89462010-09-09 13:33:33 +0000160 with support.transient_internet("svn.python.org"):
161 s = socket.socket(socket.AF_INET)
162 s.connect(("svn.python.org", 443))
163 s.setblocking(False)
164 s = ssl.wrap_socket(s,
165 cert_reqs=ssl.CERT_NONE,
166 do_handshake_on_connect=False)
167 count = 0
168 while True:
169 try:
170 count += 1
171 s.do_handshake()
172 break
173 except ssl.SSLError as err:
174 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
175 select.select([s], [], [])
176 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
177 select.select([], [s], [])
178 else:
179 raise
180 s.close()
181 if support.verbose:
182 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000183
Antoine Pitrou91382d82010-04-28 21:39:56 +0000184 def test_get_server_certificate(self):
Antoine Pitrou78d89462010-09-09 13:33:33 +0000185 with support.transient_internet("svn.python.org"):
186 pem = ssl.get_server_certificate(("svn.python.org", 443))
187 if not pem:
188 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000189
Antoine Pitrou78d89462010-09-09 13:33:33 +0000190 try:
191 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
192 except ssl.SSLError as x:
193 #should fail
194 if support.verbose:
195 sys.stdout.write("%s\n" % x)
196 else:
197 self.fail("Got server certificate %s for svn.python.org!" % pem)
198
199 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
200 if not pem:
201 self.fail("No server certificate on svn.python.org:443!")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000202 if support.verbose:
Antoine Pitrou78d89462010-09-09 13:33:33 +0000203 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000204
Antoine Pitrou754b98c2010-04-22 18:47:06 +0000205 # Test disabled: OPENSSL_VERSION* not available in Python 3.1
Antoine Pitrouda6902c2010-04-21 19:52:52 +0000206 def test_algorithms(self):
Antoine Pitrouae92a722010-04-22 18:46:16 +0000207 if support.verbose:
208 sys.stdout.write("test_algorithms disabled, "
209 "as it fails on some old OpenSSL versions")
210 return
Antoine Pitrouda6902c2010-04-21 19:52:52 +0000211 # Issue #8484: all algorithms should be available when verifying a
212 # certificate.
Antoine Pitrouae92a722010-04-22 18:46:16 +0000213 # SHA256 was added in OpenSSL 0.9.8
214 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
215 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrouda6902c2010-04-21 19:52:52 +0000216 # NOTE: https://sha256.tbs-internet.com is another possible test host
217 remote = ("sha2.hboeck.de", 443)
218 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou4d7979b2010-09-07 21:22:56 +0000219 with support.transient_internet("sha2.hboeck.de"):
220 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
221 cert_reqs=ssl.CERT_REQUIRED,
222 ca_certs=sha256_cert,)
Antoine Pitrouda6902c2010-04-21 19:52:52 +0000223 try:
224 s.connect(remote)
225 if support.verbose:
226 sys.stdout.write("\nCipher with %r is %r\n" %
227 (remote, s.cipher()))
228 sys.stdout.write("Certificate is:\n%s\n" %
229 pprint.pformat(s.getpeercert()))
230 finally:
231 s.close()
232
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000233
234try:
235 import threading
236except ImportError:
237 _have_threads = False
238else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000239 _have_threads = True
240
241 class ThreadedEchoServer(threading.Thread):
242
243 class ConnectionHandler(threading.Thread):
244
245 """A mildly complicated class, because we want it to work both
246 with and without the SSL wrapper around the socket connection, so
247 that we can test the STARTTLS functionality."""
248
Bill Janssen6e027db2007-11-15 22:23:56 +0000249 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000250 self.server = server
251 self.running = False
252 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000253 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000254 self.sock.setblocking(1)
255 self.sslconn = None
256 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000257 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000258
Antoine Pitrou91382d82010-04-28 21:39:56 +0000259 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000260 try:
261 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
262 certfile=self.server.certificate,
263 ssl_version=self.server.protocol,
264 ca_certs=self.server.cacerts,
265 cert_reqs=self.server.certreqs)
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000266 except ssl.SSLError:
267 # XXX Various errors can have happened here, for example
268 # a mismatching protocol version, an invalid certificate,
269 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000270 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000271 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000272 self.running = False
273 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000274 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000275 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000276 else:
277 if self.server.certreqs == ssl.CERT_REQUIRED:
278 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000279 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000280 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
281 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000282 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000283 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
284 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000285 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000286 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
287 return True
288
289 def read(self):
290 if self.sslconn:
291 return self.sslconn.read()
292 else:
293 return self.sock.recv(1024)
294
295 def write(self, bytes):
296 if self.sslconn:
297 return self.sslconn.write(bytes)
298 else:
299 return self.sock.send(bytes)
300
301 def close(self):
302 if self.sslconn:
303 self.sslconn.close()
304 else:
305 self.sock.close()
306
Antoine Pitrou91382d82010-04-28 21:39:56 +0000307 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000308 self.running = True
309 if not self.server.starttls_server:
310 if not self.wrap_conn():
311 return
312 while self.running:
313 try:
314 msg = self.read()
Antoine Pitrou91382d82010-04-28 21:39:56 +0000315 stripped = msg.strip()
316 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000317 # eof, so quit this handler
318 self.running = False
319 self.close()
Antoine Pitrou91382d82010-04-28 21:39:56 +0000320 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000321 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000322 sys.stdout.write(" server: client closed connection\n")
323 self.close()
324 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000325 elif (self.server.starttls_server and
Antoine Pitroub1997962010-04-28 22:58:16 +0000326 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000327 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000328 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou91382d82010-04-28 21:39:56 +0000329 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000330 if not self.wrap_conn():
331 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000332 elif (self.server.starttls_server and self.sslconn
Antoine Pitroub1997962010-04-28 22:58:16 +0000333 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000334 if support.verbose and self.server.connectionchatty:
335 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou91382d82010-04-28 21:39:56 +0000336 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000337 self.sock = self.sslconn.unwrap()
338 self.sslconn = None
339 if support.verbose and self.server.connectionchatty:
340 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000341 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000342 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000343 self.server.connectionchatty):
344 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou91382d82010-04-28 21:39:56 +0000345 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
346 % (msg, ctype, msg.lower(), ctype))
347 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000348 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000349 if self.server.chatty:
350 handle_error("Test server failure:\n")
351 self.close()
352 self.running = False
353 # normally, we'd just stop here, but for the test
354 # harness, we want to stop the server
355 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000356
Trent Nelson78520002008-04-10 20:54:35 +0000357 def __init__(self, certificate, ssl_version=None,
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000358 certreqs=None, cacerts=None,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000359 chatty=True, connectionchatty=False, starttls_server=False):
360 if ssl_version is None:
361 ssl_version = ssl.PROTOCOL_TLSv1
362 if certreqs is None:
363 certreqs = ssl.CERT_NONE
364 self.certificate = certificate
365 self.protocol = ssl_version
366 self.certreqs = certreqs
367 self.cacerts = cacerts
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000368 self.chatty = chatty
369 self.connectionchatty = connectionchatty
370 self.starttls_server = starttls_server
371 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000372 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000373 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000374 self.active = False
375 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000376 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000377
Antoine Pitrou91382d82010-04-28 21:39:56 +0000378 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000379 self.flag = flag
380 threading.Thread.start(self)
381
Antoine Pitrou91382d82010-04-28 21:39:56 +0000382 def run(self):
Antoine Pitroube168132010-04-27 10:41:37 +0000383 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000384 self.sock.listen(5)
385 self.active = True
386 if self.flag:
387 # signal an event
388 self.flag.set()
389 while self.active:
390 try:
391 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000392 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000393 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000394 + repr(connaddr) + '\n')
395 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000396 handler.start()
397 except socket.timeout:
398 pass
399 except KeyboardInterrupt:
400 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000401 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000402
Antoine Pitrou91382d82010-04-28 21:39:56 +0000403 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000404 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000405
Bill Janssen54cc54c2007-12-14 22:08:56 +0000406 class OurHTTPSServer(threading.Thread):
407
408 # This one's based on HTTPServer, which is based on SocketServer
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000409
410 class HTTPSServer(HTTPServer):
411
412 def __init__(self, server_address, RequestHandlerClass, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000413 HTTPServer.__init__(self, server_address, RequestHandlerClass)
414 # we assume the certfile contains both private key and certificate
415 self.certfile = certfile
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000416 self.allow_reuse_address = True
417
Bill Janssen6e027db2007-11-15 22:23:56 +0000418 def __str__(self):
419 return ('<%s %s:%s>' %
420 (self.__class__.__name__,
421 self.server_name,
422 self.server_port))
423
Antoine Pitrou91382d82010-04-28 21:39:56 +0000424 def get_request(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000425 # override this to wrap socket with SSL
426 sock, addr = self.socket.accept()
427 sslconn = ssl.wrap_socket(sock, server_side=True,
428 certfile=self.certfile)
429 return sslconn, addr
430
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000431 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000432 # need to override translate_path to get a known root,
433 # instead of using os.curdir, since the test could be
434 # run from anywhere
435
436 server_version = "TestHTTPS/1.0"
437
438 root = None
439
440 def translate_path(self, path):
441 """Translate a /-separated PATH to the local filename syntax.
442
443 Components that mean special things to the local file system
444 (e.g. drive or directory names) are ignored. (XXX They should
445 probably be diagnosed.)
446
447 """
448 # abandon query parameters
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000449 path = urllib.parse.urlparse(path)[2]
450 path = os.path.normpath(urllib.parse.unquote(path))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000451 words = path.split('/')
452 words = filter(None, words)
453 path = self.root
454 for word in words:
455 drive, word = os.path.splitdrive(word)
456 head, word = os.path.split(word)
457 if word in self.root: continue
458 path = os.path.join(path, word)
459 return path
460
461 def log_message(self, format, *args):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000462 # we override this to suppress logging unless "verbose"
463
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000464 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000465 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
466 (self.server.server_address,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000467 self.server.server_port,
468 self.request.cipher(),
469 self.log_date_time_string(),
470 format%args))
Thomas Woutersed03b412007-08-28 21:37:11 +0000471
472
Trent Nelson78520002008-04-10 20:54:35 +0000473 def __init__(self, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000474 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000475 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
476 self.server = self.HTTPSServer(
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000477 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
478 self.port = self.server.server_port
Thomas Woutersed03b412007-08-28 21:37:11 +0000479 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000480 self.daemon = True
Thomas Woutersed03b412007-08-28 21:37:11 +0000481
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000482 def __str__(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000483 return "<%s %s>" % (self.__class__.__name__, self.server)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000484
Antoine Pitrou91382d82010-04-28 21:39:56 +0000485 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000486 self.flag = flag
487 threading.Thread.start(self)
488
Antoine Pitrou91382d82010-04-28 21:39:56 +0000489 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000490 if self.flag:
491 self.flag.set()
Antoine Pitroube168132010-04-27 10:41:37 +0000492 self.server.serve_forever(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000493
Antoine Pitrou91382d82010-04-28 21:39:56 +0000494 def stop(self):
Antoine Pitroube168132010-04-27 10:41:37 +0000495 self.server.shutdown()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000496
497
Bill Janssen54cc54c2007-12-14 22:08:56 +0000498 class AsyncoreEchoServer(threading.Thread):
499
500 # this one's based on asyncore.dispatcher
501
502 class EchoServer (asyncore.dispatcher):
503
504 class ConnectionHandler (asyncore.dispatcher_with_send):
505
506 def __init__(self, conn, certfile):
507 self.socket = ssl.wrap_socket(conn, server_side=True,
508 certfile=certfile,
509 do_handshake_on_connect=False)
510 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitrouec146182010-04-24 21:30:20 +0000511 self._ssl_accepting = True
512 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000513
514 def readable(self):
515 if isinstance(self.socket, ssl.SSLSocket):
516 while self.socket.pending() > 0:
517 self.handle_read_event()
518 return True
519
Antoine Pitrouec146182010-04-24 21:30:20 +0000520 def _do_ssl_handshake(self):
521 try:
522 self.socket.do_handshake()
523 except ssl.SSLError as err:
524 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
525 ssl.SSL_ERROR_WANT_WRITE):
526 return
527 elif err.args[0] == ssl.SSL_ERROR_EOF:
528 return self.handle_close()
529 raise
530 except socket.error as err:
531 if err.args[0] == errno.ECONNABORTED:
532 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000533 else:
Antoine Pitrouec146182010-04-24 21:30:20 +0000534 self._ssl_accepting = False
535
536 def handle_read(self):
537 if self._ssl_accepting:
538 self._do_ssl_handshake()
539 else:
540 data = self.recv(1024)
541 if support.verbose:
542 sys.stdout.write(" server: read %s from client\n" % repr(data))
543 if not data:
544 self.close()
545 else:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000546 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000547
548 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000549 self.close()
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000550 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000551 sys.stdout.write(" server: closed connection %s\n" % self.socket)
552
553 def handle_error(self):
554 raise
555
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000556 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000557 self.certfile = certfile
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000558 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
559 self.port = support.bind_port(sock, '')
560 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000561 self.listen(5)
562
563 def handle_accept(self):
564 sock_obj, addr = self.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000565 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000566 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
567 self.ConnectionHandler(sock_obj, self.certfile)
568
569 def handle_error(self):
570 raise
571
Trent Nelson78520002008-04-10 20:54:35 +0000572 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000573 self.flag = None
574 self.active = False
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000575 self.server = self.EchoServer(certfile)
576 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000577 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000578 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000579
580 def __str__(self):
581 return "<%s %s>" % (self.__class__.__name__, self.server)
582
583 def start (self, flag=None):
584 self.flag = flag
585 threading.Thread.start(self)
586
Antoine Pitrou91382d82010-04-28 21:39:56 +0000587 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000588 self.active = True
589 if self.flag:
590 self.flag.set()
591 while self.active:
592 try:
593 asyncore.loop(1)
594 except:
595 pass
596
Antoine Pitrou91382d82010-04-28 21:39:56 +0000597 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000598 self.active = False
599 self.server.close()
600
Antoine Pitrou91382d82010-04-28 21:39:56 +0000601 def bad_cert_test(certfile):
602 """
603 Launch a server with CERT_REQUIRED, and check that trying to
604 connect to it with the given client certificate fails.
605 """
Trent Nelson78520002008-04-10 20:54:35 +0000606 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000607 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000608 cacerts=CERTFILE, chatty=False,
609 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000610 flag = threading.Event()
611 server.start(flag)
612 # wait for it to start
613 flag.wait()
614 # try to connect
615 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000616 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000617 s = ssl.wrap_socket(socket.socket(),
618 certfile=certfile,
619 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelson78520002008-04-10 20:54:35 +0000620 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000621 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000622 if support.verbose:
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000623 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou537bed62010-04-27 13:16:06 +0000624 except socket.error as x:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000625 if support.verbose:
Antoine Pitrou537bed62010-04-27 13:16:06 +0000626 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000627 else:
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000628 self.fail("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000629 finally:
630 server.stop()
631 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000632
Antoine Pitrou91382d82010-04-28 21:39:56 +0000633 def server_params_test(certfile, protocol, certreqs, cacertsfile,
634 client_certfile, client_protocol=None, indata=b"FOO\n",
635 chatty=True, connectionchatty=False):
636 """
637 Launch a server, connect a client to it and try various reads
638 and writes.
639 """
Trent Nelson78520002008-04-10 20:54:35 +0000640 server = ThreadedEchoServer(certfile,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000641 certreqs=certreqs,
642 ssl_version=protocol,
643 cacerts=cacertsfile,
644 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000645 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000646 flag = threading.Event()
647 server.start(flag)
648 # wait for it to start
649 flag.wait()
650 # try to connect
651 if client_protocol is None:
652 client_protocol = protocol
653 try:
Bill Janssen6e027db2007-11-15 22:23:56 +0000654 s = ssl.wrap_socket(socket.socket(),
655 certfile=client_certfile,
656 ca_certs=cacertsfile,
657 cert_reqs=certreqs,
658 ssl_version=client_protocol)
Trent Nelson78520002008-04-10 20:54:35 +0000659 s.connect((HOST, server.port))
Antoine Pitrou91382d82010-04-28 21:39:56 +0000660 arg = indata
Bill Janssen6e027db2007-11-15 22:23:56 +0000661 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000662 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000663 sys.stdout.write(
Antoine Pitrou91382d82010-04-28 21:39:56 +0000664 " client: sending %r...\n" % indata)
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000665 s.write(arg)
Bill Janssen6e027db2007-11-15 22:23:56 +0000666 outdata = s.read()
667 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000668 if support.verbose:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000669 sys.stdout.write(" client: read %r\n" % outdata)
Bill Janssen6e027db2007-11-15 22:23:56 +0000670 if outdata != indata.lower():
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000671 self.fail(
Antoine Pitrou91382d82010-04-28 21:39:56 +0000672 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
673 % (outdata[:20], len(outdata),
674 indata[:20].lower(), len(indata)))
675 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000676 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000677 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000678 sys.stdout.write(" client: closing connection.\n")
679 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000680 finally:
681 server.stop()
682 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000683
Antoine Pitrou91382d82010-04-28 21:39:56 +0000684 def try_protocol_combo(server_protocol,
685 client_protocol,
686 expect_success,
687 certsreqs=None):
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000688 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000689 certsreqs = ssl.CERT_NONE
Antoine Pitrou91382d82010-04-28 21:39:56 +0000690 certtype = {
691 ssl.CERT_NONE: "CERT_NONE",
692 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
693 ssl.CERT_REQUIRED: "CERT_REQUIRED",
694 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000695 if support.verbose:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000696 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000697 sys.stdout.write(formatstr %
698 (ssl.get_protocol_name(client_protocol),
699 ssl.get_protocol_name(server_protocol),
700 certtype))
701 try:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000702 server_params_test(CERTFILE, server_protocol, certsreqs,
703 CERTFILE, CERTFILE, client_protocol,
704 chatty=False,
705 connectionchatty=False)
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000706 # Protocol mismatch can result in either an SSLError, or a
707 # "Connection reset by peer" error.
708 except ssl.SSLError:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000709 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000710 raise
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000711 except socket.error as e:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000712 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000713 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000714 else:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000715 if not expect_success:
Antoine Pitrou452a5802010-05-06 13:54:43 +0000716 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000717 "Client protocol %s succeeded with server protocol %s!"
718 % (ssl.get_protocol_name(client_protocol),
719 ssl.get_protocol_name(server_protocol)))
720
721
Bill Janssen6e027db2007-11-15 22:23:56 +0000722 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000723
Antoine Pitrou91382d82010-04-28 21:39:56 +0000724 def test_echo(self):
725 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000726 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000727 sys.stdout.write("\n")
Antoine Pitrou91382d82010-04-28 21:39:56 +0000728 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
729 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
730 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000731
Antoine Pitrou91382d82010-04-28 21:39:56 +0000732 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000733 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000734 sys.stdout.write("\n")
735 s2 = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000736 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000737 certreqs=ssl.CERT_NONE,
738 ssl_version=ssl.PROTOCOL_SSLv23,
739 cacerts=CERTFILE,
740 chatty=False)
741 flag = threading.Event()
742 server.start(flag)
743 # wait for it to start
744 flag.wait()
745 # try to connect
746 try:
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000747 s = ssl.wrap_socket(socket.socket(),
748 certfile=CERTFILE,
749 ca_certs=CERTFILE,
750 cert_reqs=ssl.CERT_REQUIRED,
751 ssl_version=ssl.PROTOCOL_SSLv23)
752 s.connect((HOST, server.port))
753 cert = s.getpeercert()
754 self.assertTrue(cert, "Can't get peer certificate.")
755 cipher = s.cipher()
756 if support.verbose:
757 sys.stdout.write(pprint.pformat(cert) + '\n')
758 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
759 if 'subject' not in cert:
760 self.fail("No subject field in certificate: %s." %
761 pprint.pformat(cert))
762 if ((('organizationName', 'Python Software Foundation'),)
763 not in cert['subject']):
764 self.fail(
765 "Missing or invalid 'organizationName' field in certificate subject; "
766 "should be 'Python Software Foundation'.")
767 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000768 finally:
769 server.stop()
770 server.join()
771
Antoine Pitrou91382d82010-04-28 21:39:56 +0000772 def test_empty_cert(self):
773 """Connecting with an empty cert file"""
774 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
775 "nullcert.pem"))
776 def test_malformed_cert(self):
777 """Connecting with a badly formatted certificate (syntax error)"""
778 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
779 "badcert.pem"))
780 def test_nonexisting_cert(self):
781 """Connecting with a non-existing cert file"""
782 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
783 "wrongcert.pem"))
784 def test_malformed_key(self):
785 """Connecting with a badly formatted key (syntax error)"""
786 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
787 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000788
Antoine Pitrou91382d82010-04-28 21:39:56 +0000789 def test_rude_shutdown(self):
790 """A brutal shutdown of an SSL server should raise an IOError
791 in the client when attempting handshake.
792 """
Trent Nelson6b240cd2008-04-10 20:12:06 +0000793 listener_ready = threading.Event()
794 listener_gone = threading.Event()
Antoine Pitrou91382d82010-04-28 21:39:56 +0000795
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000796 s = socket.socket()
797 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000798
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000799 # `listener` runs in a thread. It sits in an accept() until
800 # the main thread connects. Then it rudely closes the socket,
801 # and sets Event `listener_gone` to let the main thread know
802 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +0000803 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +0000804 s.listen(5)
805 listener_ready.set()
806 s.accept()
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000807 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000808 listener_gone.set()
809
810 def connector():
811 listener_ready.wait()
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000812 c = socket.socket()
813 c.connect((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000814 listener_gone.wait()
815 try:
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000816 ssl_sock = ssl.wrap_socket(c)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000817 except IOError:
818 pass
819 else:
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000820 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +0000821
822 t = threading.Thread(target=listener)
823 t.start()
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000824 try:
825 connector()
826 finally:
827 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000828
Antoine Pitrou91382d82010-04-28 21:39:56 +0000829 def test_protocol_sslv2(self):
830 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000831 if support.verbose:
Antoine Pitrou452a5802010-05-06 13:54:43 +0000832 sys.stdout.write("\ntest_protocol_sslv2 disabled, "
833 "as it fails on OpenSSL 1.0.0+")
834 return
Antoine Pitrou91382d82010-04-28 21:39:56 +0000835 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
836 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
837 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
838 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
839 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
840 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000841
Antoine Pitrou91382d82010-04-28 21:39:56 +0000842 def test_protocol_sslv23(self):
843 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000844 if support.verbose:
Antoine Pitrou452a5802010-05-06 13:54:43 +0000845 sys.stdout.write("\ntest_protocol_sslv23 disabled, "
846 "as it fails on OpenSSL 1.0.0+")
847 return
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000848 try:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000849 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000850 except (ssl.SSLError, socket.error) as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000851 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000852 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000853 sys.stdout.write(
854 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
855 % str(x))
Antoine Pitrou91382d82010-04-28 21:39:56 +0000856 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
857 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
858 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000859
Antoine Pitrou91382d82010-04-28 21:39:56 +0000860 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
861 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
862 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000863
Antoine Pitrou91382d82010-04-28 21:39:56 +0000864 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
865 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
866 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000867
Antoine Pitrou91382d82010-04-28 21:39:56 +0000868 def test_protocol_sslv3(self):
869 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000870 if support.verbose:
Antoine Pitrou452a5802010-05-06 13:54:43 +0000871 sys.stdout.write("\ntest_protocol_sslv3 disabled, "
872 "as it fails on OpenSSL 1.0.0+")
873 return
Antoine Pitrou91382d82010-04-28 21:39:56 +0000874 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
875 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
876 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
877 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
878 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
879 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000880
Antoine Pitrou91382d82010-04-28 21:39:56 +0000881 def test_protocol_tlsv1(self):
882 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000883 if support.verbose:
Antoine Pitrou452a5802010-05-06 13:54:43 +0000884 sys.stdout.write("\ntest_protocol_tlsv1 disabled, "
885 "as it fails on OpenSSL 1.0.0+")
886 return
Antoine Pitrou91382d82010-04-28 21:39:56 +0000887 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
888 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
889 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
890 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
891 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
892 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000893
Antoine Pitrou91382d82010-04-28 21:39:56 +0000894 def test_starttls(self):
895 """Switching from clear text to encrypted and back again."""
896 msgs = (b"msg 1", b"MSG 2", b"STARTTLS", b"MSG 3", b"msg 4", b"ENDTLS", b"msg 5", b"msg 6")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000897
Trent Nelson78520002008-04-10 20:54:35 +0000898 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000899 ssl_version=ssl.PROTOCOL_TLSv1,
900 starttls_server=True,
901 chatty=True,
902 connectionchatty=True)
903 flag = threading.Event()
904 server.start(flag)
905 # wait for it to start
906 flag.wait()
907 # try to connect
908 wrapped = False
909 try:
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000910 s = socket.socket()
911 s.setblocking(1)
912 s.connect((HOST, server.port))
913 if support.verbose:
914 sys.stdout.write("\n")
915 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000916 if support.verbose:
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000917 sys.stdout.write(
Antoine Pitrou91382d82010-04-28 21:39:56 +0000918 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000919 if wrapped:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000920 conn.write(indata)
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000921 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000922 else:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000923 s.send(indata)
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000924 outdata = s.recv(1024)
Antoine Pitrou91382d82010-04-28 21:39:56 +0000925 msg = outdata.strip().lower()
926 if indata == b"STARTTLS" and msg.startswith(b"ok"):
927 # STARTTLS ok, switch to secure mode
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000928 if support.verbose:
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000929 sys.stdout.write(
Antoine Pitrou91382d82010-04-28 21:39:56 +0000930 " client: read %r from server, starting TLS...\n"
931 % msg)
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000932 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
933 wrapped = True
Antoine Pitrou91382d82010-04-28 21:39:56 +0000934 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
935 # ENDTLS ok, switch back to clear text
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000936 if support.verbose:
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000937 sys.stdout.write(
Antoine Pitrou91382d82010-04-28 21:39:56 +0000938 " client: read %r from server, ending TLS...\n"
939 % msg)
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000940 s = conn.unwrap()
941 wrapped = False
942 else:
943 if support.verbose:
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000944 sys.stdout.write(
Antoine Pitrou91382d82010-04-28 21:39:56 +0000945 " client: read %r from server\n" % msg)
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000946 if support.verbose:
947 sys.stdout.write(" client: closing connection.\n")
948 if wrapped:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000949 conn.write(b"over\n")
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000950 else:
Antoine Pitrou91382d82010-04-28 21:39:56 +0000951 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000952 if wrapped:
953 conn.close()
954 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000955 s.close()
956 finally:
957 server.stop()
958 server.join()
959
Antoine Pitrou91382d82010-04-28 21:39:56 +0000960 def test_socketserver(self):
961 """Using a SocketServer to create and manage SSL connections."""
Trent Nelson78520002008-04-10 20:54:35 +0000962 server = OurHTTPSServer(CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000963 flag = threading.Event()
964 server.start(flag)
965 # wait for it to start
966 flag.wait()
967 # try to connect
968 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000969 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000970 sys.stdout.write('\n')
Antoine Pitrou91382d82010-04-28 21:39:56 +0000971 with open(CERTFILE, 'rb') as f:
972 d1 = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000973 d2 = ''
974 # now fetch the same data from the HTTPS server
Trent Nelson78520002008-04-10 20:54:35 +0000975 url = 'https://%s:%d/%s' % (
976 HOST, server.port, os.path.split(CERTFILE)[1])
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000977 f = urllib.request.urlopen(url)
Barry Warsaw820c1202008-06-12 04:06:45 +0000978 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000979 if dlen and (int(dlen) > 0):
980 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000981 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000982 sys.stdout.write(
983 " client: read %d bytes from remote server '%s'\n"
984 % (len(d2), server))
985 f.close()
Antoine Pitrou66ffb262010-04-27 11:05:15 +0000986 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000987 finally:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000988 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000989 sys.stdout.write('stopping server\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000990 server.stop()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000991 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000992 sys.stdout.write('joining thread\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000993 server.join()
994
Antoine Pitrou91382d82010-04-28 21:39:56 +0000995 def test_asyncore_server(self):
996 """Check the example asyncore integration."""
997 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +0000998
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000999 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001000 sys.stdout.write("\n")
1001
Antoine Pitrou91382d82010-04-28 21:39:56 +00001002 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001003 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001004 flag = threading.Event()
1005 server.start(flag)
1006 # wait for it to start
1007 flag.wait()
1008 # try to connect
1009 try:
1010 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou66ffb262010-04-27 11:05:15 +00001011 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001012 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001013 sys.stdout.write(
Antoine Pitrou91382d82010-04-28 21:39:56 +00001014 " client: sending %r...\n" % indata)
1015 s.write(indata)
Antoine Pitrou66ffb262010-04-27 11:05:15 +00001016 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001017 if support.verbose:
Antoine Pitrou91382d82010-04-28 21:39:56 +00001018 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001019 if outdata != indata.lower():
Antoine Pitrou66ffb262010-04-27 11:05:15 +00001020 self.fail(
Antoine Pitrou91382d82010-04-28 21:39:56 +00001021 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1022 % (outdata[:20], len(outdata),
1023 indata[:20].lower(), len(indata)))
1024 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001025 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001026 sys.stdout.write(" client: closing connection.\n")
1027 s.close()
1028 finally:
1029 server.stop()
1030 server.join()
1031
Antoine Pitrou91382d82010-04-28 21:39:56 +00001032 def test_recv_send(self):
1033 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001034 if support.verbose:
1035 sys.stdout.write("\n")
1036
1037 server = ThreadedEchoServer(CERTFILE,
1038 certreqs=ssl.CERT_NONE,
1039 ssl_version=ssl.PROTOCOL_TLSv1,
1040 cacerts=CERTFILE,
1041 chatty=True,
1042 connectionchatty=False)
1043 flag = threading.Event()
1044 server.start(flag)
1045 # wait for it to start
1046 flag.wait()
1047 # try to connect
Antoine Pitrou66ffb262010-04-27 11:05:15 +00001048 s = ssl.wrap_socket(socket.socket(),
1049 server_side=False,
1050 certfile=CERTFILE,
1051 ca_certs=CERTFILE,
1052 cert_reqs=ssl.CERT_NONE,
1053 ssl_version=ssl.PROTOCOL_TLSv1)
1054 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001055 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001056 # helper methods for standardising recv* method signatures
1057 def _recv_into():
1058 b = bytearray(b"\0"*100)
1059 count = s.recv_into(b)
1060 return b[:count]
1061
1062 def _recvfrom_into():
1063 b = bytearray(b"\0"*100)
1064 count, addr = s.recvfrom_into(b)
1065 return b[:count]
1066
1067 # (name, method, whether to expect success, *args)
1068 send_methods = [
1069 ('send', s.send, True, []),
1070 ('sendto', s.sendto, False, ["some.address"]),
1071 ('sendall', s.sendall, True, []),
1072 ]
1073 recv_methods = [
1074 ('recv', s.recv, True, []),
1075 ('recvfrom', s.recvfrom, False, ["some.address"]),
1076 ('recv_into', _recv_into, True, []),
1077 ('recvfrom_into', _recvfrom_into, False, []),
1078 ]
1079 data_prefix = "PREFIX_"
1080
1081 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou91382d82010-04-28 21:39:56 +00001082 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001083 try:
Antoine Pitrou91382d82010-04-28 21:39:56 +00001084 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001085 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001086 if outdata != indata.lower():
1087 raise support.TestFailed(
1088 "While sending with <<{name:s}>> bad data "
Antoine Pitrou91382d82010-04-28 21:39:56 +00001089 "<<{outdata:r}>> ({nout:d}) received; "
1090 "expected <<{indata:r}>> ({nin:d})\n".format(
1091 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001092 nout=len(outdata),
Antoine Pitrou91382d82010-04-28 21:39:56 +00001093 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001094 )
1095 )
1096 except ValueError as e:
1097 if expect_success:
1098 raise support.TestFailed(
1099 "Failed to send with method <<{name:s}>>; "
1100 "expected to succeed.\n".format(name=meth_name)
1101 )
1102 if not str(e).startswith(meth_name):
1103 raise support.TestFailed(
1104 "Method <<{name:s}>> failed with unexpected "
1105 "exception message: {exp:s}\n".format(
1106 name=meth_name, exp=e
1107 )
1108 )
1109
1110 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou91382d82010-04-28 21:39:56 +00001111 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001112 try:
Antoine Pitrou91382d82010-04-28 21:39:56 +00001113 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001114 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001115 if outdata != indata.lower():
1116 raise support.TestFailed(
1117 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou91382d82010-04-28 21:39:56 +00001118 "<<{outdata:r}>> ({nout:d}) received; "
1119 "expected <<{indata:r}>> ({nin:d})\n".format(
1120 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001121 nout=len(outdata),
Antoine Pitrou91382d82010-04-28 21:39:56 +00001122 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001123 )
1124 )
1125 except ValueError as e:
1126 if expect_success:
1127 raise support.TestFailed(
1128 "Failed to receive with method <<{name:s}>>; "
1129 "expected to succeed.\n".format(name=meth_name)
1130 )
1131 if not str(e).startswith(meth_name):
1132 raise support.TestFailed(
1133 "Method <<{name:s}>> failed with unexpected "
1134 "exception message: {exp:s}\n".format(
1135 name=meth_name, exp=e
1136 )
1137 )
1138 # consume data
1139 s.read()
1140
Antoine Pitrou91382d82010-04-28 21:39:56 +00001141 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001142 s.close()
1143 finally:
1144 server.stop()
1145 server.join()
1146
Antoine Pitrouec146182010-04-24 21:30:20 +00001147 def test_handshake_timeout(self):
1148 # Issue #5103: SSL handshake must respect the socket timeout
1149 server = socket.socket(socket.AF_INET)
1150 host = "127.0.0.1"
1151 port = support.bind_port(server)
1152 started = threading.Event()
1153 finish = False
1154
1155 def serve():
1156 server.listen(5)
1157 started.set()
1158 conns = []
1159 while not finish:
1160 r, w, e = select.select([server], [], [], 0.1)
1161 if server in r:
1162 # Let the socket hang around rather than having
1163 # it closed by garbage collection.
1164 conns.append(server.accept()[0])
1165
1166 t = threading.Thread(target=serve)
1167 t.start()
1168 started.wait()
1169
1170 try:
Antoine Pitrouc2203f92010-04-24 22:07:51 +00001171 try:
1172 c = socket.socket(socket.AF_INET)
1173 c.settimeout(0.2)
1174 c.connect((host, port))
1175 # Will attempt handshake and time out
1176 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1177 ssl.wrap_socket, c)
1178 finally:
1179 c.close()
Antoine Pitrouec146182010-04-24 21:30:20 +00001180 try:
1181 c = socket.socket(socket.AF_INET)
1182 c = ssl.wrap_socket(c)
1183 c.settimeout(0.2)
1184 # Will attempt handshake and time out
1185 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1186 c.connect, (host, port))
1187 finally:
1188 c.close()
1189 finally:
1190 finish = True
1191 t.join()
1192 server.close()
1193
Bill Janssen58afe4c2008-09-08 16:45:19 +00001194
Thomas Woutersed03b412007-08-28 21:37:11 +00001195def test_main(verbose=False):
1196 if skip_expected:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001197 raise unittest.SkipTest("No SSL support")
Thomas Woutersed03b412007-08-28 21:37:11 +00001198
Trent Nelson78520002008-04-10 20:54:35 +00001199 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Thomas Woutersed03b412007-08-28 21:37:11 +00001200 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
1201 "keycert.pem")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001202 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1203 os.path.dirname(__file__) or os.curdir,
1204 "https_svn_python_org_root.pem")
1205
1206 if (not os.path.exists(CERTFILE) or
1207 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001208 raise support.TestFailed("Can't read certificate files!")
Bill Janssen6e027db2007-11-15 22:23:56 +00001209
Thomas Woutersed03b412007-08-28 21:37:11 +00001210 tests = [BasicTests]
1211
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001212 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001213 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001214
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001215 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001216 thread_info = support.threading_setup()
1217 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001218 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001219
Antoine Pitrou91382d82010-04-28 21:39:56 +00001220 try:
1221 support.run_unittest(*tests)
1222 finally:
1223 if _have_threads:
1224 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001225
1226if __name__ == "__main__":
1227 test_main()