blob: bc2bfccf41181d956f526d7d9b4c700693ee9e43 [file] [log] [blame]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
5from test import test_support
Bill Janssen934b16d2008-06-28 22:19:33 +00006import asyncore
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00007import socket
Bill Janssen934b16d2008-06-28 22:19:33 +00008import select
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00009import time
Antoine Pitroub558f172010-04-23 23:25:45 +000010import gc
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000011import os
Antoine Pitroub558f172010-04-23 23:25:45 +000012import errno
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000013import pprint
Bill Janssen296a59d2007-09-16 22:06:00 +000014import urllib, urlparse
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000015import traceback
Antoine Pitroudfb299b2010-04-23 22:54:59 +000016import weakref
Antoine Pitroud75efd92010-08-04 17:38:33 +000017import functools
18import platform
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000019
Bill Janssen296a59d2007-09-16 22:06:00 +000020from BaseHTTPServer import HTTPServer
21from SimpleHTTPServer import SimpleHTTPRequestHandler
22
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +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
Trent Nelsone41b0062008-04-08 23:47:30 +000030HOST = test_support.HOST
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000031CERTFILE = None
Bill Janssen296a59d2007-09-16 22:06:00 +000032SVN_PYTHON_ORG_ROOT_CERT = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000033
Neal Norwitz3e533c22007-08-27 01:03:18 +000034def handle_error(prefix):
35 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Bill Janssen98d19da2007-09-10 21:51:02 +000036 if test_support.verbose:
37 sys.stdout.write(prefix + exc_format)
Neal Norwitz3e533c22007-08-27 01:03:18 +000038
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000039
40class BasicTests(unittest.TestCase):
41
Antoine Pitrou3945c862010-04-28 21:11:01 +000042 def test_sslwrap_simple(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000043 # A crude test for the legacy API
Bill Jansseneb257ac2008-09-29 18:56:38 +000044 try:
45 ssl.sslwrap_simple(socket.socket(socket.AF_INET))
46 except IOError, e:
47 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
48 pass
49 else:
50 raise
51 try:
52 ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
53 except IOError, e:
54 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
55 pass
56 else:
57 raise
Neal Norwitz3e533c22007-08-27 01:03:18 +000058
Antoine Pitroud75efd92010-08-04 17:38:33 +000059# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
60def skip_if_broken_ubuntu_ssl(func):
61 # We need to access the lower-level wrapper in order to create an
62 # implicit SSL context without trying to connect or listen.
Antoine Pitrou969fbe32010-08-05 01:30:23 +000063 try:
64 import _ssl
65 except ImportError:
66 # The returned function won't get executed, just ignore the error
67 pass
Antoine Pitroud75efd92010-08-04 17:38:33 +000068 @functools.wraps(func)
69 def f(*args, **kwargs):
70 try:
71 s = socket.socket(socket.AF_INET)
72 _ssl.sslwrap(s._sock, 0, None, None,
73 ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
74 except ssl.SSLError as e:
75 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
76 platform.linux_distribution() == ('debian', 'squeeze/sid', '')
77 and 'Invalid SSL protocol variant specified' in str(e)):
78 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
79 return func(*args, **kwargs)
80 return f
81
82
83class BasicSocketTests(unittest.TestCase):
84
Antoine Pitrou3945c862010-04-28 21:11:01 +000085 def test_constants(self):
Bill Janssen98d19da2007-09-10 21:51:02 +000086 ssl.PROTOCOL_SSLv2
87 ssl.PROTOCOL_SSLv23
88 ssl.PROTOCOL_SSLv3
89 ssl.PROTOCOL_TLSv1
90 ssl.CERT_NONE
91 ssl.CERT_OPTIONAL
92 ssl.CERT_REQUIRED
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000093
Antoine Pitrou3945c862010-04-28 21:11:01 +000094 def test_random(self):
Bill Janssen98d19da2007-09-10 21:51:02 +000095 v = ssl.RAND_status()
96 if test_support.verbose:
97 sys.stdout.write("\n RAND_status is %d (%s)\n"
98 % (v, (v and "sufficient randomness") or
99 "insufficient randomness"))
Guido van Rossume4729332007-08-26 19:35:09 +0000100 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000101 ssl.RAND_egd(1)
102 except TypeError:
103 pass
Guido van Rossume4729332007-08-26 19:35:09 +0000104 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000105 print "didn't raise TypeError"
106 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000107
Antoine Pitrou3945c862010-04-28 21:11:01 +0000108 def test_parse_cert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000109 # note that this uses an 'unofficial' function in _ssl.c,
110 # provided solely for this test, to exercise the certificate
111 # parsing code
112 p = ssl._ssl._test_decode_cert(CERTFILE, False)
113 if test_support.verbose:
114 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000115
Antoine Pitrou3945c862010-04-28 21:11:01 +0000116 def test_DER_to_PEM(self):
117 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
118 pem = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000119 d1 = ssl.PEM_cert_to_DER_cert(pem)
120 p2 = ssl.DER_cert_to_PEM_cert(d1)
121 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitroudb187842010-04-27 10:32:58 +0000122 self.assertEqual(d1, d2)
Antoine Pitrou4c7bcf12010-04-27 22:03:37 +0000123 if not p2.startswith(ssl.PEM_HEADER + '\n'):
124 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
125 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
126 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Bill Janssen296a59d2007-09-16 22:06:00 +0000127
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000128 def test_openssl_version(self):
129 n = ssl.OPENSSL_VERSION_NUMBER
130 t = ssl.OPENSSL_VERSION_INFO
131 s = ssl.OPENSSL_VERSION
132 self.assertIsInstance(n, (int, long))
133 self.assertIsInstance(t, tuple)
134 self.assertIsInstance(s, str)
135 # Some sanity checks follow
136 # >= 0.9
137 self.assertGreaterEqual(n, 0x900000)
138 # < 2.0
139 self.assertLess(n, 0x20000000)
140 major, minor, fix, patch, status = t
141 self.assertGreaterEqual(major, 0)
142 self.assertLess(major, 2)
143 self.assertGreaterEqual(minor, 0)
144 self.assertLess(minor, 256)
145 self.assertGreaterEqual(fix, 0)
146 self.assertLess(fix, 256)
147 self.assertGreaterEqual(patch, 0)
148 self.assertLessEqual(patch, 26)
149 self.assertGreaterEqual(status, 0)
150 self.assertLessEqual(status, 15)
151 # Version string as returned by OpenSSL, the format might change
152 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
153 (s, t))
154
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000155 def test_ciphers(self):
156 if not test_support.is_resource_enabled('network'):
157 return
158 remote = ("svn.python.org", 443)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000159 with test_support.transient_internet(remote[0]):
160 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
161 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000162 s.connect(remote)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000163 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
164 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
165 s.connect(remote)
166 # Error checking occurs when connecting, because the SSL context
167 # isn't created before.
168 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
169 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
170 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
171 s.connect(remote)
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000172
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000173 @test_support.cpython_only
174 def test_refcycle(self):
175 # Issue #7943: an SSL object doesn't create reference cycles with
176 # itself.
177 s = socket.socket(socket.AF_INET)
178 ss = ssl.wrap_socket(s)
179 wr = weakref.ref(ss)
180 del ss
181 self.assertEqual(wr(), None)
182
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000183 def test_wrapped_unconnected(self):
184 # The _delegate_methods in socket.py are correctly delegated to by an
185 # unconnected SSLSocket, so they will raise a socket.error rather than
186 # something unexpected like TypeError.
187 s = socket.socket(socket.AF_INET)
188 ss = ssl.wrap_socket(s)
189 self.assertRaises(socket.error, ss.recv, 1)
190 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
191 self.assertRaises(socket.error, ss.recvfrom, 1)
192 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
193 self.assertRaises(socket.error, ss.send, b'x')
194 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
195
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000196
Bill Janssen934b16d2008-06-28 22:19:33 +0000197class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +0000198
Antoine Pitrou3945c862010-04-28 21:11:01 +0000199 def test_connect(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000200 with test_support.transient_internet("svn.python.org"):
201 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
202 cert_reqs=ssl.CERT_NONE)
Bill Janssen296a59d2007-09-16 22:06:00 +0000203 s.connect(("svn.python.org", 443))
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000204 c = s.getpeercert()
205 if c:
206 self.fail("Peer cert %s shouldn't be here!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000207 s.close()
208
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000209 # this should fail because we have no verification certs
210 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
211 cert_reqs=ssl.CERT_REQUIRED)
212 try:
213 s.connect(("svn.python.org", 443))
214 except ssl.SSLError:
215 pass
216 finally:
217 s.close()
218
219 # this should succeed because we specify the root cert
220 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
221 cert_reqs=ssl.CERT_REQUIRED,
222 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
223 try:
224 s.connect(("svn.python.org", 443))
225 finally:
226 s.close()
Bill Janssen296a59d2007-09-16 22:06:00 +0000227
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000228 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
229 def test_makefile_close(self):
230 # Issue #5238: creating a file-like object with makefile() shouldn't
231 # delay closing the underlying "real socket" (here tested with its
232 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000233 with test_support.transient_internet("svn.python.org"):
234 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
235 ss.connect(("svn.python.org", 443))
236 fd = ss.fileno()
237 f = ss.makefile()
238 f.close()
239 # The fd is still open
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000240 os.read(fd, 0)
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000241 # Closing the SSL socket should close the fd too
242 ss.close()
243 gc.collect()
244 with self.assertRaises(OSError) as e:
245 os.read(fd, 0)
246 self.assertEqual(e.exception.errno, errno.EBADF)
Bill Janssen934b16d2008-06-28 22:19:33 +0000247
Antoine Pitrou3945c862010-04-28 21:11:01 +0000248 def test_non_blocking_handshake(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000249 with test_support.transient_internet("svn.python.org"):
250 s = socket.socket(socket.AF_INET)
251 s.connect(("svn.python.org", 443))
252 s.setblocking(False)
253 s = ssl.wrap_socket(s,
254 cert_reqs=ssl.CERT_NONE,
255 do_handshake_on_connect=False)
256 count = 0
257 while True:
258 try:
259 count += 1
260 s.do_handshake()
261 break
262 except ssl.SSLError, err:
263 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
264 select.select([s], [], [])
265 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
266 select.select([], [s], [])
267 else:
268 raise
269 s.close()
270 if test_support.verbose:
271 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Bill Janssen934b16d2008-06-28 22:19:33 +0000272
Antoine Pitrou3945c862010-04-28 21:11:01 +0000273 def test_get_server_certificate(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000274 with test_support.transient_internet("svn.python.org"):
275 pem = ssl.get_server_certificate(("svn.python.org", 443))
276 if not pem:
277 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000278
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000279 try:
280 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
281 except ssl.SSLError:
282 #should fail
283 pass
284 else:
285 self.fail("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000286
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000287 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
288 if not pem:
289 self.fail("No server certificate on svn.python.org:443!")
290 if test_support.verbose:
291 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000292
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000293 def test_algorithms(self):
294 # Issue #8484: all algorithms should be available when verifying a
295 # certificate.
Antoine Pitrou9aed6042010-04-22 18:00:41 +0000296 # SHA256 was added in OpenSSL 0.9.8
297 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
298 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000299 # NOTE: https://sha256.tbs-internet.com is another possible test host
Antoine Pitroud43245a2011-01-08 10:32:51 +0000300 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000301 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitroud43245a2011-01-08 10:32:51 +0000302 with test_support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrouc818ed42010-09-07 21:40:25 +0000303 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
304 cert_reqs=ssl.CERT_REQUIRED,
305 ca_certs=sha256_cert,)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000306 try:
307 s.connect(remote)
308 if test_support.verbose:
309 sys.stdout.write("\nCipher with %r is %r\n" %
310 (remote, s.cipher()))
311 sys.stdout.write("Certificate is:\n%s\n" %
312 pprint.pformat(s.getpeercert()))
313 finally:
314 s.close()
315
Bill Janssen296a59d2007-09-16 22:06:00 +0000316
Bill Janssen98d19da2007-09-10 21:51:02 +0000317try:
318 import threading
319except ImportError:
320 _have_threads = False
321else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000322 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000323
Bill Janssen98d19da2007-09-10 21:51:02 +0000324 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000325
Bill Janssen98d19da2007-09-10 21:51:02 +0000326 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000327
Bill Janssen98d19da2007-09-10 21:51:02 +0000328 """A mildly complicated class, because we want it to work both
329 with and without the SSL wrapper around the socket connection, so
330 that we can test the STARTTLS functionality."""
331
332 def __init__(self, server, connsock):
333 self.server = server
334 self.running = False
335 self.sock = connsock
336 self.sock.setblocking(1)
337 self.sslconn = None
338 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000339 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000340
Bill Janssen934b16d2008-06-28 22:19:33 +0000341 def show_conn_details(self):
342 if self.server.certreqs == ssl.CERT_REQUIRED:
343 cert = self.sslconn.getpeercert()
344 if test_support.verbose and self.server.chatty:
345 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
346 cert_binary = self.sslconn.getpeercert(True)
347 if test_support.verbose and self.server.chatty:
348 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
349 cipher = self.sslconn.cipher()
350 if test_support.verbose and self.server.chatty:
351 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
352
Antoine Pitrou3945c862010-04-28 21:11:01 +0000353 def wrap_conn(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000354 try:
355 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
356 certfile=self.server.certificate,
357 ssl_version=self.server.protocol,
358 ca_certs=self.server.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000359 cert_reqs=self.server.certreqs,
360 ciphers=self.server.ciphers)
Antoine Pitroudb187842010-04-27 10:32:58 +0000361 except ssl.SSLError:
362 # XXX Various errors can have happened here, for example
363 # a mismatching protocol version, an invalid certificate,
364 # or a low-level bug. This should be made more discriminating.
Bill Janssen98d19da2007-09-10 21:51:02 +0000365 if self.server.chatty:
366 handle_error("\n server: bad connection attempt from " +
367 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000368 self.close()
Antoine Pitroudb187842010-04-27 10:32:58 +0000369 self.running = False
370 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000371 return False
Bill Janssen98d19da2007-09-10 21:51:02 +0000372 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000373 return True
374
375 def read(self):
376 if self.sslconn:
377 return self.sslconn.read()
378 else:
379 return self.sock.recv(1024)
380
381 def write(self, bytes):
382 if self.sslconn:
383 return self.sslconn.write(bytes)
384 else:
385 return self.sock.send(bytes)
386
387 def close(self):
388 if self.sslconn:
389 self.sslconn.close()
390 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000391 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000392
Antoine Pitrou3945c862010-04-28 21:11:01 +0000393 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000394 self.running = True
395 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000396 if isinstance(self.sock, ssl.SSLSocket):
397 self.sslconn = self.sock
398 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000399 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000400 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000401 while self.running:
402 try:
403 msg = self.read()
404 if not msg:
405 # eof, so quit this handler
406 self.running = False
407 self.close()
408 elif msg.strip() == 'over':
409 if test_support.verbose and self.server.connectionchatty:
410 sys.stdout.write(" server: client closed connection\n")
411 self.close()
412 return
413 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
414 if test_support.verbose and self.server.connectionchatty:
415 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
416 self.write("OK\n")
417 if not self.wrap_conn():
418 return
Bill Janssen39295c22008-08-12 16:31:21 +0000419 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
420 if test_support.verbose and self.server.connectionchatty:
421 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
422 self.write("OK\n")
423 self.sslconn.unwrap()
424 self.sslconn = None
425 if test_support.verbose and self.server.connectionchatty:
426 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000427 else:
428 if (test_support.verbose and
429 self.server.connectionchatty):
430 ctype = (self.sslconn and "encrypted") or "unencrypted"
431 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
432 % (repr(msg), ctype, repr(msg.lower()), ctype))
433 self.write(msg.lower())
434 except ssl.SSLError:
435 if self.server.chatty:
436 handle_error("Test server failure:\n")
437 self.close()
438 self.running = False
439 # normally, we'd just stop here, but for the test
440 # harness, we want to stop the server
441 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000442
Trent Nelsone41b0062008-04-08 23:47:30 +0000443 def __init__(self, certificate, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +0000444 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000445 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000446 wrap_accepting_socket=False, ciphers=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000447
Bill Janssen98d19da2007-09-10 21:51:02 +0000448 if ssl_version is None:
449 ssl_version = ssl.PROTOCOL_TLSv1
450 if certreqs is None:
451 certreqs = ssl.CERT_NONE
452 self.certificate = certificate
453 self.protocol = ssl_version
454 self.certreqs = certreqs
455 self.cacerts = cacerts
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000456 self.ciphers = ciphers
Bill Janssen98d19da2007-09-10 21:51:02 +0000457 self.chatty = chatty
458 self.connectionchatty = connectionchatty
459 self.starttls_server = starttls_server
460 self.sock = socket.socket()
461 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000462 if wrap_accepting_socket:
463 self.sock = ssl.wrap_socket(self.sock, server_side=True,
464 certfile=self.certificate,
465 cert_reqs = self.certreqs,
466 ca_certs = self.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000467 ssl_version = self.protocol,
468 ciphers = self.ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000469 if test_support.verbose and self.chatty:
470 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
471 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000472 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000473 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000474 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000475
Antoine Pitrou3945c862010-04-28 21:11:01 +0000476 def start(self, flag=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000477 self.flag = flag
478 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000479
Antoine Pitrou3945c862010-04-28 21:11:01 +0000480 def run(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000481 self.sock.settimeout(0.05)
Bill Janssen98d19da2007-09-10 21:51:02 +0000482 self.sock.listen(5)
483 self.active = True
484 if self.flag:
485 # signal an event
486 self.flag.set()
487 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000488 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000489 newconn, connaddr = self.sock.accept()
490 if test_support.verbose and self.chatty:
491 sys.stdout.write(' server: new connection from '
492 + str(connaddr) + '\n')
493 handler = self.ConnectionHandler(self, newconn)
494 handler.start()
495 except socket.timeout:
496 pass
497 except KeyboardInterrupt:
498 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +0000499 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000500
Antoine Pitrou3945c862010-04-28 21:11:01 +0000501 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000502 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000503
Bill Janssen934b16d2008-06-28 22:19:33 +0000504 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000505
Antoine Pitrou3945c862010-04-28 21:11:01 +0000506 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +0000507
Antoine Pitrou3945c862010-04-28 21:11:01 +0000508 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +0000509
510 def __init__(self, conn, certfile):
511 asyncore.dispatcher_with_send.__init__(self, conn)
512 self.socket = ssl.wrap_socket(conn, server_side=True,
513 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +0000514 do_handshake_on_connect=False)
515 self._ssl_accepting = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000516
517 def readable(self):
518 if isinstance(self.socket, ssl.SSLSocket):
519 while self.socket.pending() > 0:
520 self.handle_read_event()
521 return True
522
Antoine Pitroufc69af12010-04-24 20:04:58 +0000523 def _do_ssl_handshake(self):
524 try:
525 self.socket.do_handshake()
526 except ssl.SSLError, err:
527 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
528 ssl.SSL_ERROR_WANT_WRITE):
529 return
530 elif err.args[0] == ssl.SSL_ERROR_EOF:
531 return self.handle_close()
532 raise
533 except socket.error, err:
534 if err.args[0] == errno.ECONNABORTED:
535 return self.handle_close()
536 else:
537 self._ssl_accepting = False
538
Bill Janssen934b16d2008-06-28 22:19:33 +0000539 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +0000540 if self._ssl_accepting:
541 self._do_ssl_handshake()
542 else:
543 data = self.recv(1024)
Antoine Pitroudb187842010-04-27 10:32:58 +0000544 if data and data.strip() != 'over':
545 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +0000546
547 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000548 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000549 if test_support.verbose:
550 sys.stdout.write(" server: closed connection %s\n" % self.socket)
551
552 def handle_error(self):
553 raise
554
555 def __init__(self, certfile):
556 self.certfile = certfile
557 asyncore.dispatcher.__init__(self)
558 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
559 self.port = test_support.bind_port(self.socket)
560 self.listen(5)
561
562 def handle_accept(self):
563 sock_obj, addr = self.accept()
564 if test_support.verbose:
565 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
566 self.ConnectionHandler(sock_obj, self.certfile)
567
568 def handle_error(self):
569 raise
570
571 def __init__(self, certfile):
572 self.flag = None
573 self.active = False
574 self.server = self.EchoServer(certfile)
575 self.port = self.server.port
576 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000577 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000578
579 def __str__(self):
580 return "<%s %s>" % (self.__class__.__name__, self.server)
581
Antoine Pitrou3945c862010-04-28 21:11:01 +0000582 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000583 self.flag = flag
584 threading.Thread.start(self)
585
Antoine Pitrou3945c862010-04-28 21:11:01 +0000586 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000587 self.active = True
588 if self.flag:
589 self.flag.set()
590 while self.active:
Antoine Pitroudb187842010-04-27 10:32:58 +0000591 asyncore.loop(0.05)
Bill Janssen934b16d2008-06-28 22:19:33 +0000592
Antoine Pitrou3945c862010-04-28 21:11:01 +0000593 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000594 self.active = False
595 self.server.close()
596
597 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000598
599 class HTTPSServer(HTTPServer):
600
601 def __init__(self, server_address, RequestHandlerClass, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000602 HTTPServer.__init__(self, server_address, RequestHandlerClass)
603 # we assume the certfile contains both private key and certificate
604 self.certfile = certfile
Bill Janssen296a59d2007-09-16 22:06:00 +0000605 self.allow_reuse_address = True
606
Bill Janssen934b16d2008-06-28 22:19:33 +0000607 def __str__(self):
608 return ('<%s %s:%s>' %
609 (self.__class__.__name__,
610 self.server_name,
611 self.server_port))
612
Antoine Pitrou3945c862010-04-28 21:11:01 +0000613 def get_request(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000614 # override this to wrap socket with SSL
615 sock, addr = self.socket.accept()
616 sslconn = ssl.wrap_socket(sock, server_side=True,
617 certfile=self.certfile)
618 return sslconn, addr
619
Bill Janssen296a59d2007-09-16 22:06:00 +0000620 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Bill Janssen296a59d2007-09-16 22:06:00 +0000621 # need to override translate_path to get a known root,
622 # instead of using os.curdir, since the test could be
623 # run from anywhere
624
625 server_version = "TestHTTPS/1.0"
626
627 root = None
628
629 def translate_path(self, path):
630 """Translate a /-separated PATH to the local filename syntax.
631
632 Components that mean special things to the local file system
633 (e.g. drive or directory names) are ignored. (XXX They should
634 probably be diagnosed.)
635
636 """
637 # abandon query parameters
638 path = urlparse.urlparse(path)[2]
639 path = os.path.normpath(urllib.unquote(path))
640 words = path.split('/')
641 words = filter(None, words)
642 path = self.root
643 for word in words:
644 drive, word = os.path.splitdrive(word)
645 head, word = os.path.split(word)
646 if word in self.root: continue
647 path = os.path.join(path, word)
648 return path
649
650 def log_message(self, format, *args):
651
652 # we override this to suppress logging unless "verbose"
653
654 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000655 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
656 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000657 self.server.server_port,
658 self.request.cipher(),
659 self.log_date_time_string(),
660 format%args))
661
662
Trent Nelsone41b0062008-04-08 23:47:30 +0000663 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000664 self.flag = None
Bill Janssen296a59d2007-09-16 22:06:00 +0000665 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
666 self.server = self.HTTPSServer(
Antoine Pitrou150acda2010-04-27 08:40:51 +0000667 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
668 self.port = self.server.server_port
Bill Janssen296a59d2007-09-16 22:06:00 +0000669 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000670 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000671
672 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000673 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000674
Antoine Pitrou3945c862010-04-28 21:11:01 +0000675 def start(self, flag=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000676 self.flag = flag
677 threading.Thread.start(self)
678
Antoine Pitrou3945c862010-04-28 21:11:01 +0000679 def run(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000680 if self.flag:
681 self.flag.set()
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000682 self.server.serve_forever(0.05)
Bill Janssen296a59d2007-09-16 22:06:00 +0000683
Antoine Pitrou3945c862010-04-28 21:11:01 +0000684 def stop(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000685 self.server.shutdown()
Bill Janssen296a59d2007-09-16 22:06:00 +0000686
687
Antoine Pitrou3945c862010-04-28 21:11:01 +0000688 def bad_cert_test(certfile):
689 """
690 Launch a server with CERT_REQUIRED, and check that trying to
691 connect to it with the given client certificate fails.
692 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000693 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000694 certreqs=ssl.CERT_REQUIRED,
695 cacerts=CERTFILE, chatty=False)
696 flag = threading.Event()
697 server.start(flag)
698 # wait for it to start
699 flag.wait()
700 # try to connect
701 try:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000702 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000703 s = ssl.wrap_socket(socket.socket(),
704 certfile=certfile,
705 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000706 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000707 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000708 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000709 sys.stdout.write("\nSSLError is %s\n" % x[1])
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000710 except socket.error, x:
711 if test_support.verbose:
712 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000713 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000714 raise AssertionError("Use of invalid cert should have failed!")
Bill Janssen98d19da2007-09-10 21:51:02 +0000715 finally:
716 server.stop()
717 server.join()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000718
Antoine Pitrou3945c862010-04-28 21:11:01 +0000719 def server_params_test(certfile, protocol, certreqs, cacertsfile,
720 client_certfile, client_protocol=None, indata="FOO\n",
721 ciphers=None, chatty=True, connectionchatty=False,
722 wrap_accepting_socket=False):
723 """
724 Launch a server, connect a client to it and try various reads
725 and writes.
726 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000727 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000728 certreqs=certreqs,
729 ssl_version=protocol,
730 cacerts=cacertsfile,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000731 ciphers=ciphers,
Bill Janssen98d19da2007-09-10 21:51:02 +0000732 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000733 connectionchatty=connectionchatty,
734 wrap_accepting_socket=wrap_accepting_socket)
Bill Janssen98d19da2007-09-10 21:51:02 +0000735 flag = threading.Event()
736 server.start(flag)
737 # wait for it to start
738 flag.wait()
739 # try to connect
740 if client_protocol is None:
741 client_protocol = protocol
742 try:
Antoine Pitroudb187842010-04-27 10:32:58 +0000743 s = ssl.wrap_socket(socket.socket(),
744 certfile=client_certfile,
745 ca_certs=cacertsfile,
746 ciphers=ciphers,
747 cert_reqs=certreqs,
748 ssl_version=client_protocol)
749 s.connect((HOST, server.port))
750 for arg in [indata, bytearray(indata), memoryview(indata)]:
Bill Janssen98d19da2007-09-10 21:51:02 +0000751 if connectionchatty:
752 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +0000753 sys.stdout.write(
754 " client: sending %s...\n" % (repr(arg)))
755 s.write(arg)
756 outdata = s.read()
757 if connectionchatty:
758 if test_support.verbose:
759 sys.stdout.write(" client: read %s\n" % repr(outdata))
760 if outdata != indata.lower():
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000761 raise AssertionError(
Antoine Pitroudb187842010-04-27 10:32:58 +0000762 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
763 % (outdata[:min(len(outdata),20)], len(outdata),
764 indata[:min(len(indata),20)].lower(), len(indata)))
765 s.write("over\n")
766 if connectionchatty:
767 if test_support.verbose:
768 sys.stdout.write(" client: closing connection.\n")
769 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000770 finally:
771 server.stop()
772 server.join()
773
Antoine Pitrou3945c862010-04-28 21:11:01 +0000774 def try_protocol_combo(server_protocol,
775 client_protocol,
776 expect_success,
777 certsreqs=None):
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000778 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000779 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +0000780 certtype = {
781 ssl.CERT_NONE: "CERT_NONE",
782 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
783 ssl.CERT_REQUIRED: "CERT_REQUIRED",
784 }[certsreqs]
Bill Janssen98d19da2007-09-10 21:51:02 +0000785 if test_support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000786 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +0000787 sys.stdout.write(formatstr %
788 (ssl.get_protocol_name(client_protocol),
789 ssl.get_protocol_name(server_protocol),
790 certtype))
791 try:
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000792 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
793 # will send an SSLv3 hello (rather than SSLv2) starting from
794 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou3945c862010-04-28 21:11:01 +0000795 server_params_test(CERTFILE, server_protocol, certsreqs,
796 CERTFILE, CERTFILE, client_protocol,
797 ciphers="ALL", chatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +0000798 # Protocol mismatch can result in either an SSLError, or a
799 # "Connection reset by peer" error.
800 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000801 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +0000802 raise
Antoine Pitroudb187842010-04-27 10:32:58 +0000803 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000804 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +0000805 raise
Bill Janssen98d19da2007-09-10 21:51:02 +0000806 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000807 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000808 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +0000809 "Client protocol %s succeeded with server protocol %s!"
810 % (ssl.get_protocol_name(client_protocol),
811 ssl.get_protocol_name(server_protocol)))
812
813
Bill Janssen934b16d2008-06-28 22:19:33 +0000814 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000815
Antoine Pitrou3945c862010-04-28 21:11:01 +0000816 def test_rude_shutdown(self):
817 """A brutal shutdown of an SSL server should raise an IOError
818 in the client when attempting handshake.
819 """
Bill Janssen98d19da2007-09-10 21:51:02 +0000820 listener_ready = threading.Event()
821 listener_gone = threading.Event()
822
Antoine Pitrou150acda2010-04-27 08:40:51 +0000823 s = socket.socket()
824 port = test_support.bind_port(s, HOST)
825
826 # `listener` runs in a thread. It sits in an accept() until
827 # the main thread connects. Then it rudely closes the socket,
828 # and sets Event `listener_gone` to let the main thread know
829 # the socket is gone.
Bill Janssen98d19da2007-09-10 21:51:02 +0000830 def listener():
Bill Janssen98d19da2007-09-10 21:51:02 +0000831 s.listen(5)
832 listener_ready.set()
833 s.accept()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000834 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000835 listener_gone.set()
836
837 def connector():
838 listener_ready.wait()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000839 c = socket.socket()
840 c.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000841 listener_gone.wait()
842 try:
Antoine Pitrou150acda2010-04-27 08:40:51 +0000843 ssl_sock = ssl.wrap_socket(c)
Bill Janssen934b16d2008-06-28 22:19:33 +0000844 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000845 pass
846 else:
Antoine Pitroudb187842010-04-27 10:32:58 +0000847 self.fail('connecting to closed SSL socket should have failed')
Bill Janssen98d19da2007-09-10 21:51:02 +0000848
849 t = threading.Thread(target=listener)
850 t.start()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000851 try:
852 connector()
853 finally:
854 t.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000855
Antoine Pitroud75efd92010-08-04 17:38:33 +0000856 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000857 def test_echo(self):
858 """Basic test of an SSL client connecting to a server"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000859 if test_support.verbose:
860 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000861 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
862 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
863 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000864
Antoine Pitrou3945c862010-04-28 21:11:01 +0000865 def test_getpeercert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000866 if test_support.verbose:
867 sys.stdout.write("\n")
868 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000869 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000870 certreqs=ssl.CERT_NONE,
871 ssl_version=ssl.PROTOCOL_SSLv23,
872 cacerts=CERTFILE,
873 chatty=False)
874 flag = threading.Event()
875 server.start(flag)
876 # wait for it to start
877 flag.wait()
878 # try to connect
879 try:
Antoine Pitroudb187842010-04-27 10:32:58 +0000880 s = ssl.wrap_socket(socket.socket(),
881 certfile=CERTFILE,
882 ca_certs=CERTFILE,
883 cert_reqs=ssl.CERT_REQUIRED,
884 ssl_version=ssl.PROTOCOL_SSLv23)
885 s.connect((HOST, server.port))
886 cert = s.getpeercert()
887 self.assertTrue(cert, "Can't get peer certificate.")
888 cipher = s.cipher()
889 if test_support.verbose:
890 sys.stdout.write(pprint.pformat(cert) + '\n')
891 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
892 if 'subject' not in cert:
893 self.fail("No subject field in certificate: %s." %
894 pprint.pformat(cert))
895 if ((('organizationName', 'Python Software Foundation'),)
896 not in cert['subject']):
897 self.fail(
898 "Missing or invalid 'organizationName' field in certificate subject; "
899 "should be 'Python Software Foundation'.")
900 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000901 finally:
902 server.stop()
903 server.join()
904
Antoine Pitrou3945c862010-04-28 21:11:01 +0000905 def test_empty_cert(self):
906 """Connecting with an empty cert file"""
907 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
908 "nullcert.pem"))
909 def test_malformed_cert(self):
910 """Connecting with a badly formatted certificate (syntax error)"""
911 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
912 "badcert.pem"))
913 def test_nonexisting_cert(self):
914 """Connecting with a non-existing cert file"""
915 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
916 "wrongcert.pem"))
917 def test_malformed_key(self):
918 """Connecting with a badly formatted key (syntax error)"""
919 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
920 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000921
Antoine Pitroud75efd92010-08-04 17:38:33 +0000922 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000923 def test_protocol_sslv2(self):
924 """Connecting to an SSLv2 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000925 if test_support.verbose:
926 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000927 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
928 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
929 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
930 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
931 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
932 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000933
Antoine Pitroud75efd92010-08-04 17:38:33 +0000934 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000935 def test_protocol_sslv23(self):
936 """Connecting to an SSLv23 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000937 if test_support.verbose:
938 sys.stdout.write("\n")
939 try:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000940 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000941 except (ssl.SSLError, socket.error), x:
Bill Janssen98d19da2007-09-10 21:51:02 +0000942 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
943 if test_support.verbose:
944 sys.stdout.write(
945 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
946 % str(x))
Antoine Pitrou3945c862010-04-28 21:11:01 +0000947 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
948 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
949 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000950
Antoine Pitrou3945c862010-04-28 21:11:01 +0000951 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
952 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
953 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +0000954
Antoine Pitrou3945c862010-04-28 21:11:01 +0000955 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
956 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
957 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +0000958
Antoine Pitroud75efd92010-08-04 17:38:33 +0000959 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000960 def test_protocol_sslv3(self):
961 """Connecting to an SSLv3 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000962 if test_support.verbose:
963 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000964 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
965 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
966 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
967 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
968 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
969 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000970
Antoine Pitroud75efd92010-08-04 17:38:33 +0000971 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000972 def test_protocol_tlsv1(self):
973 """Connecting to a TLSv1 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000974 if test_support.verbose:
975 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000976 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
977 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
978 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
979 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
980 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
981 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000982
Antoine Pitrou3945c862010-04-28 21:11:01 +0000983 def test_starttls(self):
984 """Switching from clear text to encrypted and back again."""
Bill Janssen39295c22008-08-12 16:31:21 +0000985 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +0000986
Trent Nelsone41b0062008-04-08 23:47:30 +0000987 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000988 ssl_version=ssl.PROTOCOL_TLSv1,
989 starttls_server=True,
990 chatty=True,
991 connectionchatty=True)
992 flag = threading.Event()
993 server.start(flag)
994 # wait for it to start
995 flag.wait()
996 # try to connect
997 wrapped = False
998 try:
Antoine Pitroudb187842010-04-27 10:32:58 +0000999 s = socket.socket()
1000 s.setblocking(1)
1001 s.connect((HOST, server.port))
1002 if test_support.verbose:
1003 sys.stdout.write("\n")
1004 for indata in msgs:
Bill Janssen98d19da2007-09-10 21:51:02 +00001005 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00001006 sys.stdout.write(
1007 " client: sending %s...\n" % repr(indata))
1008 if wrapped:
1009 conn.write(indata)
1010 outdata = conn.read()
1011 else:
1012 s.send(indata)
1013 outdata = s.recv(1024)
1014 if (indata == "STARTTLS" and
1015 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001016 # STARTTLS ok, switch to secure mode
Bill Janssen98d19da2007-09-10 21:51:02 +00001017 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00001018 sys.stdout.write(
Antoine Pitroudb187842010-04-27 10:32:58 +00001019 " client: read %s from server, starting TLS...\n"
1020 % repr(outdata))
1021 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1022 wrapped = True
1023 elif (indata == "ENDTLS" and
1024 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001025 # ENDTLS ok, switch back to clear text
Antoine Pitroudb187842010-04-27 10:32:58 +00001026 if test_support.verbose:
1027 sys.stdout.write(
1028 " client: read %s from server, ending TLS...\n"
1029 % repr(outdata))
1030 s = conn.unwrap()
1031 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00001032 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001033 if test_support.verbose:
1034 sys.stdout.write(
1035 " client: read %s from server\n" % repr(outdata))
1036 if test_support.verbose:
1037 sys.stdout.write(" client: closing connection.\n")
1038 if wrapped:
1039 conn.write("over\n")
1040 else:
1041 s.send("over\n")
1042 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001043 finally:
1044 server.stop()
1045 server.join()
1046
Antoine Pitrou3945c862010-04-28 21:11:01 +00001047 def test_socketserver(self):
1048 """Using a SocketServer to create and manage SSL connections."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001049 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +00001050 flag = threading.Event()
1051 server.start(flag)
1052 # wait for it to start
1053 flag.wait()
1054 # try to connect
1055 try:
1056 if test_support.verbose:
1057 sys.stdout.write('\n')
Antoine Pitrou3945c862010-04-28 21:11:01 +00001058 with open(CERTFILE, 'rb') as f:
1059 d1 = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +00001060 d2 = ''
1061 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +00001062 url = 'https://127.0.0.1:%d/%s' % (
1063 server.port, os.path.split(CERTFILE)[1])
Florent Xicluna07627882010-03-21 01:14:24 +00001064 with test_support.check_py3k_warnings():
1065 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +00001066 dlen = f.info().getheader("content-length")
1067 if dlen and (int(dlen) > 0):
1068 d2 = f.read(int(dlen))
1069 if test_support.verbose:
1070 sys.stdout.write(
1071 " client: read %d bytes from remote server '%s'\n"
1072 % (len(d2), server))
1073 f.close()
Antoine Pitroudb187842010-04-27 10:32:58 +00001074 self.assertEqual(d1, d2)
Bill Janssen296a59d2007-09-16 22:06:00 +00001075 finally:
1076 server.stop()
1077 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001078
Antoine Pitrou3945c862010-04-28 21:11:01 +00001079 def test_wrapped_accept(self):
1080 """Check the accept() method on SSL sockets."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001081 if test_support.verbose:
1082 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001083 server_params_test(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1084 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1085 chatty=True, connectionchatty=True,
1086 wrap_accepting_socket=True)
Bill Janssen934b16d2008-06-28 22:19:33 +00001087
Antoine Pitrou3945c862010-04-28 21:11:01 +00001088 def test_asyncore_server(self):
1089 """Check the example asyncore integration."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001090 indata = "TEST MESSAGE of mixed case\n"
1091
1092 if test_support.verbose:
1093 sys.stdout.write("\n")
1094 server = AsyncoreEchoServer(CERTFILE)
1095 flag = threading.Event()
1096 server.start(flag)
1097 # wait for it to start
1098 flag.wait()
1099 # try to connect
1100 try:
Antoine Pitroudb187842010-04-27 10:32:58 +00001101 s = ssl.wrap_socket(socket.socket())
1102 s.connect(('127.0.0.1', server.port))
1103 if test_support.verbose:
1104 sys.stdout.write(
1105 " client: sending %s...\n" % (repr(indata)))
1106 s.write(indata)
1107 outdata = s.read()
1108 if test_support.verbose:
1109 sys.stdout.write(" client: read %s\n" % repr(outdata))
1110 if outdata != indata.lower():
1111 self.fail(
1112 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1113 % (outdata[:min(len(outdata),20)], len(outdata),
1114 indata[:min(len(indata),20)].lower(), len(indata)))
1115 s.write("over\n")
1116 if test_support.verbose:
1117 sys.stdout.write(" client: closing connection.\n")
1118 s.close()
Bill Janssen934b16d2008-06-28 22:19:33 +00001119 finally:
1120 server.stop()
1121 # wait for server thread to end
1122 server.join()
1123
Antoine Pitrou3945c862010-04-28 21:11:01 +00001124 def test_recv_send(self):
1125 """Test recv(), send() and friends."""
Bill Janssen61c001a2008-09-08 16:37:24 +00001126 if test_support.verbose:
1127 sys.stdout.write("\n")
1128
1129 server = ThreadedEchoServer(CERTFILE,
1130 certreqs=ssl.CERT_NONE,
1131 ssl_version=ssl.PROTOCOL_TLSv1,
1132 cacerts=CERTFILE,
1133 chatty=True,
1134 connectionchatty=False)
1135 flag = threading.Event()
1136 server.start(flag)
1137 # wait for it to start
1138 flag.wait()
1139 # try to connect
Antoine Pitroudb187842010-04-27 10:32:58 +00001140 s = ssl.wrap_socket(socket.socket(),
1141 server_side=False,
1142 certfile=CERTFILE,
1143 ca_certs=CERTFILE,
1144 cert_reqs=ssl.CERT_NONE,
1145 ssl_version=ssl.PROTOCOL_TLSv1)
1146 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00001147 try:
Bill Janssen61c001a2008-09-08 16:37:24 +00001148 # helper methods for standardising recv* method signatures
1149 def _recv_into():
1150 b = bytearray("\0"*100)
1151 count = s.recv_into(b)
1152 return b[:count]
1153
1154 def _recvfrom_into():
1155 b = bytearray("\0"*100)
1156 count, addr = s.recvfrom_into(b)
1157 return b[:count]
1158
1159 # (name, method, whether to expect success, *args)
1160 send_methods = [
1161 ('send', s.send, True, []),
1162 ('sendto', s.sendto, False, ["some.address"]),
1163 ('sendall', s.sendall, True, []),
1164 ]
1165 recv_methods = [
1166 ('recv', s.recv, True, []),
1167 ('recvfrom', s.recvfrom, False, ["some.address"]),
1168 ('recv_into', _recv_into, True, []),
1169 ('recvfrom_into', _recvfrom_into, False, []),
1170 ]
1171 data_prefix = u"PREFIX_"
1172
1173 for meth_name, send_meth, expect_success, args in send_methods:
1174 indata = data_prefix + meth_name
1175 try:
1176 send_meth(indata.encode('ASCII', 'strict'), *args)
1177 outdata = s.read()
1178 outdata = outdata.decode('ASCII', 'strict')
1179 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001180 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001181 "While sending with <<%s>> bad data "
1182 "<<%r>> (%d) received; "
1183 "expected <<%r>> (%d)\n" % (
1184 meth_name, outdata[:20], len(outdata),
1185 indata[:20], len(indata)
1186 )
1187 )
1188 except ValueError as e:
1189 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001190 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001191 "Failed to send with method <<%s>>; "
1192 "expected to succeed.\n" % (meth_name,)
1193 )
1194 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001195 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001196 "Method <<%s>> failed with unexpected "
1197 "exception message: %s\n" % (
1198 meth_name, e
1199 )
1200 )
1201
1202 for meth_name, recv_meth, expect_success, args in recv_methods:
1203 indata = data_prefix + meth_name
1204 try:
1205 s.send(indata.encode('ASCII', 'strict'))
1206 outdata = recv_meth(*args)
1207 outdata = outdata.decode('ASCII', 'strict')
1208 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001209 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001210 "While receiving with <<%s>> bad data "
1211 "<<%r>> (%d) received; "
1212 "expected <<%r>> (%d)\n" % (
1213 meth_name, outdata[:20], len(outdata),
1214 indata[:20], len(indata)
1215 )
1216 )
1217 except ValueError as e:
1218 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001219 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001220 "Failed to receive with method <<%s>>; "
1221 "expected to succeed.\n" % (meth_name,)
1222 )
1223 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001224 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001225 "Method <<%s>> failed with unexpected "
1226 "exception message: %s\n" % (
1227 meth_name, e
1228 )
1229 )
1230 # consume data
1231 s.read()
1232
1233 s.write("over\n".encode("ASCII", "strict"))
1234 s.close()
1235 finally:
1236 server.stop()
1237 server.join()
1238
Antoine Pitroufc69af12010-04-24 20:04:58 +00001239 def test_handshake_timeout(self):
1240 # Issue #5103: SSL handshake must respect the socket timeout
1241 server = socket.socket(socket.AF_INET)
1242 host = "127.0.0.1"
1243 port = test_support.bind_port(server)
1244 started = threading.Event()
1245 finish = False
1246
1247 def serve():
1248 server.listen(5)
1249 started.set()
1250 conns = []
1251 while not finish:
1252 r, w, e = select.select([server], [], [], 0.1)
1253 if server in r:
1254 # Let the socket hang around rather than having
1255 # it closed by garbage collection.
1256 conns.append(server.accept()[0])
1257
1258 t = threading.Thread(target=serve)
1259 t.start()
1260 started.wait()
1261
1262 try:
1263 try:
1264 c = socket.socket(socket.AF_INET)
1265 c.settimeout(0.2)
1266 c.connect((host, port))
1267 # Will attempt handshake and time out
1268 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1269 ssl.wrap_socket, c)
1270 finally:
1271 c.close()
1272 try:
1273 c = socket.socket(socket.AF_INET)
1274 c.settimeout(0.2)
1275 c = ssl.wrap_socket(c)
1276 # Will attempt handshake and time out
1277 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1278 c.connect, (host, port))
1279 finally:
1280 c.close()
1281 finally:
1282 finish = True
1283 t.join()
1284 server.close()
1285
Bill Janssen61c001a2008-09-08 16:37:24 +00001286
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001287def test_main(verbose=False):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001288 if skip_expected:
Benjamin Peterson888a39b2009-03-26 20:48:25 +00001289 raise unittest.SkipTest("No SSL support")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001290
Trent Nelsone41b0062008-04-08 23:47:30 +00001291 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001292 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001293 "keycert.pem")
1294 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1295 os.path.dirname(__file__) or os.curdir,
1296 "https_svn_python_org_root.pem")
1297
1298 if (not os.path.exists(CERTFILE) or
1299 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001300 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001301
Antoine Pitroude30f702010-09-14 12:54:08 +00001302 tests = [BasicTests, BasicSocketTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001303
Bill Janssen296a59d2007-09-16 22:06:00 +00001304 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001305 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001306
Bill Janssen98d19da2007-09-10 21:51:02 +00001307 if _have_threads:
1308 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001309 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001310 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001311
Antoine Pitrou3945c862010-04-28 21:11:01 +00001312 try:
1313 test_support.run_unittest(*tests)
1314 finally:
1315 if _have_threads:
1316 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001317
1318if __name__ == "__main__":
1319 test_main()