blob: 71ddc4a566cecc7de5530f98fac89032ae2ca9aa [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
Georg Brandlfceab5a2008-01-19 20:08:23 +000042 def testSSLconnect(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000043 if not support.is_resource_enabled('network'):
Georg Brandlfceab5a2008-01-19 20:08:23 +000044 return
45 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
46 cert_reqs=ssl.CERT_NONE)
47 s.connect(("svn.python.org", 443))
48 c = s.getpeercert()
49 if c:
Benjamin Petersonee8712c2008-05-20 21:35:26 +000050 raise support.TestFailed("Peer cert %s shouldn't be here!")
Georg Brandlfceab5a2008-01-19 20:08:23 +000051 s.close()
52
53 # this should fail because we have no verification certs
54 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
55 cert_reqs=ssl.CERT_REQUIRED)
56 try:
57 s.connect(("svn.python.org", 443))
58 except ssl.SSLError:
59 pass
60 finally:
61 s.close()
62
Thomas Wouters1b7f8912007-09-19 03:06:30 +000063 def testCrucialConstants(self):
64 ssl.PROTOCOL_SSLv2
65 ssl.PROTOCOL_SSLv23
66 ssl.PROTOCOL_SSLv3
67 ssl.PROTOCOL_TLSv1
68 ssl.CERT_NONE
69 ssl.CERT_OPTIONAL
70 ssl.CERT_REQUIRED
Thomas Woutersed03b412007-08-28 21:37:11 +000071
Thomas Wouters1b7f8912007-09-19 03:06:30 +000072 def testRAND(self):
73 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +000074 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000075 sys.stdout.write("\n RAND_status is %d (%s)\n"
76 % (v, (v and "sufficient randomness") or
77 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +000078 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000079 ssl.RAND_egd(1)
80 except TypeError:
81 pass
Thomas Woutersed03b412007-08-28 21:37:11 +000082 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000083 print("didn't raise TypeError")
84 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +000085
Thomas Wouters1b7f8912007-09-19 03:06:30 +000086 def testParseCert(self):
87 # note that this uses an 'unofficial' function in _ssl.c,
88 # provided solely for this test, to exercise the certificate
89 # parsing code
90 p = ssl._ssl._test_decode_cert(CERTFILE, False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000091 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000092 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +000093
Thomas Wouters1b7f8912007-09-19 03:06:30 +000094 def testDERtoPEM(self):
95
96 pem = open(SVN_PYTHON_ORG_ROOT_CERT, 'r').read()
97 d1 = ssl.PEM_cert_to_DER_cert(pem)
98 p2 = ssl.DER_cert_to_PEM_cert(d1)
99 d2 = ssl.PEM_cert_to_DER_cert(p2)
100 if (d1 != d2):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000101 raise support.TestFailed("PEM-to-DER or DER-to-PEM translation failed")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000102
Antoine Pitrou78f4a9a2010-04-23 23:12:22 +0000103 @support.cpython_only
104 def test_refcycle(self):
105 # Issue #7943: an SSL object doesn't create reference cycles with
106 # itself.
107 s = socket.socket(socket.AF_INET)
108 ss = ssl.wrap_socket(s)
109 wr = weakref.ref(ss)
110 del ss
111 self.assertEqual(wr(), None)
112
Antoine Pitrouc2203f92010-04-24 22:07:51 +0000113 def test_timeout(self):
114 # Issue #8524: when creating an SSL socket, the timeout of the
115 # original socket should be retained.
116 for timeout in (None, 0.0, 5.0):
117 s = socket.socket(socket.AF_INET)
118 s.settimeout(timeout)
119 ss = ssl.wrap_socket(s)
120 self.assertEqual(timeout, ss.gettimeout())
121
Antoine Pitrou3b9b9ba2010-04-23 23:33:50 +0000122
Bill Janssen6e027db2007-11-15 22:23:56 +0000123class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000124
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000125 def testConnect(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000126 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
127 cert_reqs=ssl.CERT_NONE)
128 s.connect(("svn.python.org", 443))
129 c = s.getpeercert()
130 if c:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000131 raise support.TestFailed("Peer cert %s shouldn't be here!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000132 s.close()
133
134 # this should fail because we have no verification certs
135 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
136 cert_reqs=ssl.CERT_REQUIRED)
Thomas Woutersed03b412007-08-28 21:37:11 +0000137 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000138 s.connect(("svn.python.org", 443))
139 except ssl.SSLError:
140 pass
141 finally:
142 s.close()
143
144 # this should succeed because we specify the root cert
145 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
146 cert_reqs=ssl.CERT_REQUIRED,
147 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
148 try:
149 s.connect(("svn.python.org", 443))
150 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000151 raise support.TestFailed("Unexpected exception %s" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000152 finally:
153 s.close()
154
Antoine Pitroufe0f1172010-04-24 11:17:37 +0000155 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
156 def test_makefile_close(self):
157 # Issue #5238: creating a file-like object with makefile() shouldn't
158 # delay closing the underlying "real socket" (here tested with its
159 # file descriptor, hence skipping the test under Windows).
160 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
161 ss.connect(("svn.python.org", 443))
162 fd = ss.fileno()
163 f = ss.makefile()
164 f.close()
165 # The fd is still open
166 os.read(fd, 0)
167 # Closing the SSL socket should close the fd too
168 ss.close()
169 gc.collect()
170 try:
171 os.read(fd, 0)
172 except OSError as e:
173 self.assertEqual(e.errno, errno.EBADF)
174 else:
175 self.fail("OSError wasn't raised")
176
Bill Janssen6e027db2007-11-15 22:23:56 +0000177 def testNonBlockingHandshake(self):
178 s = socket.socket(socket.AF_INET)
179 s.connect(("svn.python.org", 443))
180 s.setblocking(False)
181 s = ssl.wrap_socket(s,
182 cert_reqs=ssl.CERT_NONE,
183 do_handshake_on_connect=False)
184 count = 0
185 while True:
186 try:
187 count += 1
188 s.do_handshake()
189 break
190 except ssl.SSLError as err:
191 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
192 select.select([s], [], [])
193 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
194 select.select([], [s], [])
195 else:
196 raise
197 s.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000198 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000199 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000200
Bill Janssen54cc54c2007-12-14 22:08:56 +0000201 def testFetchServerCert(self):
202
203 pem = ssl.get_server_certificate(("svn.python.org", 443))
204 if not pem:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000205 raise support.TestFailed("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000206
207 return
208
209 try:
210 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
211 except ssl.SSLError as x:
212 #should fail
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000213 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000214 sys.stdout.write("%s\n" % x)
215 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000216 raise support.TestFailed("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000217
218 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
219 if not pem:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000220 raise support.TestFailed("No server certificate on svn.python.org:443!")
221 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000222 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
223
Antoine Pitrou754b98c2010-04-22 18:47:06 +0000224 # Test disabled: OPENSSL_VERSION* not available in Python 3.1
Antoine Pitrouda6902c2010-04-21 19:52:52 +0000225 def test_algorithms(self):
Antoine Pitrouae92a722010-04-22 18:46:16 +0000226 if support.verbose:
227 sys.stdout.write("test_algorithms disabled, "
228 "as it fails on some old OpenSSL versions")
229 return
Antoine Pitrouda6902c2010-04-21 19:52:52 +0000230 # Issue #8484: all algorithms should be available when verifying a
231 # certificate.
Antoine Pitrouae92a722010-04-22 18:46:16 +0000232 # SHA256 was added in OpenSSL 0.9.8
233 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
234 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrouda6902c2010-04-21 19:52:52 +0000235 # NOTE: https://sha256.tbs-internet.com is another possible test host
236 remote = ("sha2.hboeck.de", 443)
237 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
238 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
239 cert_reqs=ssl.CERT_REQUIRED,
240 ca_certs=sha256_cert,)
241 with support.transient_internet():
242 try:
243 s.connect(remote)
244 if support.verbose:
245 sys.stdout.write("\nCipher with %r is %r\n" %
246 (remote, s.cipher()))
247 sys.stdout.write("Certificate is:\n%s\n" %
248 pprint.pformat(s.getpeercert()))
249 finally:
250 s.close()
251
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000252
253try:
254 import threading
255except ImportError:
256 _have_threads = False
257else:
258
259 _have_threads = True
260
261 class ThreadedEchoServer(threading.Thread):
262
263 class ConnectionHandler(threading.Thread):
264
265 """A mildly complicated class, because we want it to work both
266 with and without the SSL wrapper around the socket connection, so
267 that we can test the STARTTLS functionality."""
268
Bill Janssen6e027db2007-11-15 22:23:56 +0000269 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000270 self.server = server
271 self.running = False
272 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000273 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000274 self.sock.setblocking(1)
275 self.sslconn = None
276 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000277 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000278
279 def wrap_conn (self):
280 try:
281 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
282 certfile=self.server.certificate,
283 ssl_version=self.server.protocol,
284 ca_certs=self.server.cacerts,
285 cert_reqs=self.server.certreqs)
286 except:
287 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000288 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000289 if not self.server.expect_bad_connects:
290 # here, we want to stop the server, because this shouldn't
291 # happen in the context of our test case
292 self.running = False
293 # normally, we'd just stop here, but for the test
294 # harness, we want to stop the server
295 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000296 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000297 return False
298
299 else:
300 if self.server.certreqs == ssl.CERT_REQUIRED:
301 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000302 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000303 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
304 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000305 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000306 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
307 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000308 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000309 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
310 return True
311
312 def read(self):
313 if self.sslconn:
314 return self.sslconn.read()
315 else:
316 return self.sock.recv(1024)
317
318 def write(self, bytes):
319 if self.sslconn:
320 return self.sslconn.write(bytes)
321 else:
322 return self.sock.send(bytes)
323
324 def close(self):
325 if self.sslconn:
326 self.sslconn.close()
327 else:
328 self.sock.close()
329
330 def run (self):
331 self.running = True
332 if not self.server.starttls_server:
333 if not self.wrap_conn():
334 return
335 while self.running:
336 try:
337 msg = self.read()
Bill Janssen6e027db2007-11-15 22:23:56 +0000338 amsg = (msg and str(msg, 'ASCII', 'strict')) or ''
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000339 if not msg:
340 # eof, so quit this handler
341 self.running = False
342 self.close()
Bill Janssen6e027db2007-11-15 22:23:56 +0000343 elif amsg.strip() == 'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000344 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000345 sys.stdout.write(" server: client closed connection\n")
346 self.close()
347 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000348 elif (self.server.starttls_server and
349 amsg.strip() == 'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000350 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000351 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000352 self.write("OK\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000353 if not self.wrap_conn():
354 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000355 elif (self.server.starttls_server and self.sslconn
356 and amsg.strip() == 'ENDTLS'):
357 if support.verbose and self.server.connectionchatty:
358 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
359 self.write("OK\n".encode("ASCII", "strict"))
360 self.sock = self.sslconn.unwrap()
361 self.sslconn = None
362 if support.verbose and self.server.connectionchatty:
363 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000364 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000365 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000366 self.server.connectionchatty):
367 ctype = (self.sslconn and "encrypted") or "unencrypted"
368 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
369 % (repr(msg), ctype, repr(msg.lower()), ctype))
Bill Janssen6e027db2007-11-15 22:23:56 +0000370 self.write(amsg.lower().encode('ASCII', 'strict'))
371 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000372 if self.server.chatty:
373 handle_error("Test server failure:\n")
374 self.close()
375 self.running = False
376 # normally, we'd just stop here, but for the test
377 # harness, we want to stop the server
378 self.server.stop()
379 except:
380 handle_error('')
381
Trent Nelson78520002008-04-10 20:54:35 +0000382 def __init__(self, certificate, ssl_version=None,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000383 certreqs=None, cacerts=None, expect_bad_connects=False,
384 chatty=True, connectionchatty=False, starttls_server=False):
385 if ssl_version is None:
386 ssl_version = ssl.PROTOCOL_TLSv1
387 if certreqs is None:
388 certreqs = ssl.CERT_NONE
389 self.certificate = certificate
390 self.protocol = ssl_version
391 self.certreqs = certreqs
392 self.cacerts = cacerts
393 self.expect_bad_connects = expect_bad_connects
394 self.chatty = chatty
395 self.connectionchatty = connectionchatty
396 self.starttls_server = starttls_server
397 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000398 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000399 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000400 self.active = False
401 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000402 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000403
404 def start (self, flag=None):
405 self.flag = flag
406 threading.Thread.start(self)
407
408 def run (self):
409 self.sock.settimeout(0.5)
410 self.sock.listen(5)
411 self.active = True
412 if self.flag:
413 # signal an event
414 self.flag.set()
415 while self.active:
416 try:
417 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000418 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000419 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000420 + repr(connaddr) + '\n')
421 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000422 handler.start()
423 except socket.timeout:
424 pass
425 except KeyboardInterrupt:
426 self.stop()
427 except:
428 if self.chatty:
429 handle_error("Test server failure:\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000430 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000431
432 def stop (self):
433 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000434
Bill Janssen54cc54c2007-12-14 22:08:56 +0000435 class OurHTTPSServer(threading.Thread):
436
437 # This one's based on HTTPServer, which is based on SocketServer
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000438
439 class HTTPSServer(HTTPServer):
440
441 def __init__(self, server_address, RequestHandlerClass, certfile):
442
443 HTTPServer.__init__(self, server_address, RequestHandlerClass)
444 # we assume the certfile contains both private key and certificate
445 self.certfile = certfile
446 self.active = False
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000447 self.active_lock = threading.Lock()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000448 self.allow_reuse_address = True
449
Bill Janssen6e027db2007-11-15 22:23:56 +0000450 def __str__(self):
451 return ('<%s %s:%s>' %
452 (self.__class__.__name__,
453 self.server_name,
454 self.server_port))
455
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000456 def get_request (self):
457 # override this to wrap socket with SSL
458 sock, addr = self.socket.accept()
459 sslconn = ssl.wrap_socket(sock, server_side=True,
460 certfile=self.certfile)
461 return sslconn, addr
462
463 # The methods overridden below this are mainly so that we
464 # can run it in a thread and be able to stop it from another
465 # You probably wouldn't need them in other uses.
466
467 def server_activate(self):
468 # We want to run this in a thread for testing purposes,
469 # so we override this to set timeout, so that we get
470 # a chance to stop the server
471 self.socket.settimeout(0.5)
472 HTTPServer.server_activate(self)
473
474 def serve_forever(self):
475 # We want this to run in a thread, so we use a slightly
476 # modified version of "forever".
477 self.active = True
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000478 while 1:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000479 try:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000480 # We need to lock while handling the request.
481 # Another thread can close the socket after self.active
482 # has been checked and before the request is handled.
483 # This causes an exception when using the closed socket.
484 with self.active_lock:
485 if not self.active:
486 break
487 self.handle_request()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000488 except socket.timeout:
489 pass
490 except KeyboardInterrupt:
491 self.server_close()
492 return
493 except:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000494 sys.stdout.write(''.join(traceback.format_exception(*sys.exc_info())))
495 break
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000496 time.sleep(0.1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000497
498 def server_close(self):
499 # Again, we want this to run in a thread, so we need to override
500 # close to clear the "active" flag, so that serve_forever() will
501 # terminate.
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000502 with self.active_lock:
503 HTTPServer.server_close(self)
504 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000505
506 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
507
508 # need to override translate_path to get a known root,
509 # instead of using os.curdir, since the test could be
510 # run from anywhere
511
512 server_version = "TestHTTPS/1.0"
513
514 root = None
515
516 def translate_path(self, path):
517 """Translate a /-separated PATH to the local filename syntax.
518
519 Components that mean special things to the local file system
520 (e.g. drive or directory names) are ignored. (XXX They should
521 probably be diagnosed.)
522
523 """
524 # abandon query parameters
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000525 path = urllib.parse.urlparse(path)[2]
526 path = os.path.normpath(urllib.parse.unquote(path))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000527 words = path.split('/')
528 words = filter(None, words)
529 path = self.root
530 for word in words:
531 drive, word = os.path.splitdrive(word)
532 head, word = os.path.split(word)
533 if word in self.root: continue
534 path = os.path.join(path, word)
535 return path
536
537 def log_message(self, format, *args):
538
539 # we override this to suppress logging unless "verbose"
540
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000541 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000542 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
543 (self.server.server_address,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000544 self.server.server_port,
545 self.request.cipher(),
546 self.log_date_time_string(),
547 format%args))
Thomas Woutersed03b412007-08-28 21:37:11 +0000548
549
Trent Nelson78520002008-04-10 20:54:35 +0000550 def __init__(self, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000551 self.flag = None
552 self.active = False
553 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
554 self.server = self.HTTPSServer(
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000555 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
556 self.port = self.server.server_port
Thomas Woutersed03b412007-08-28 21:37:11 +0000557 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000558 self.daemon = True
Thomas Woutersed03b412007-08-28 21:37:11 +0000559
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000560 def __str__(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000561 return "<%s %s>" % (self.__class__.__name__, self.server)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000562
563 def start (self, flag=None):
564 self.flag = flag
565 threading.Thread.start(self)
566
Thomas Woutersed03b412007-08-28 21:37:11 +0000567 def run (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000568 self.active = True
569 if self.flag:
570 self.flag.set()
571 self.server.serve_forever()
572 self.active = False
573
574 def stop (self):
575 self.active = False
576 self.server.server_close()
577
578
Bill Janssen54cc54c2007-12-14 22:08:56 +0000579 class AsyncoreEchoServer(threading.Thread):
580
581 # this one's based on asyncore.dispatcher
582
583 class EchoServer (asyncore.dispatcher):
584
585 class ConnectionHandler (asyncore.dispatcher_with_send):
586
587 def __init__(self, conn, certfile):
588 self.socket = ssl.wrap_socket(conn, server_side=True,
589 certfile=certfile,
590 do_handshake_on_connect=False)
591 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitrouec146182010-04-24 21:30:20 +0000592 self._ssl_accepting = True
593 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000594
595 def readable(self):
596 if isinstance(self.socket, ssl.SSLSocket):
597 while self.socket.pending() > 0:
598 self.handle_read_event()
599 return True
600
Antoine Pitrouec146182010-04-24 21:30:20 +0000601 def _do_ssl_handshake(self):
602 try:
603 self.socket.do_handshake()
604 except ssl.SSLError as err:
605 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
606 ssl.SSL_ERROR_WANT_WRITE):
607 return
608 elif err.args[0] == ssl.SSL_ERROR_EOF:
609 return self.handle_close()
610 raise
611 except socket.error as err:
612 if err.args[0] == errno.ECONNABORTED:
613 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000614 else:
Antoine Pitrouec146182010-04-24 21:30:20 +0000615 self._ssl_accepting = False
616
617 def handle_read(self):
618 if self._ssl_accepting:
619 self._do_ssl_handshake()
620 else:
621 data = self.recv(1024)
622 if support.verbose:
623 sys.stdout.write(" server: read %s from client\n" % repr(data))
624 if not data:
625 self.close()
626 else:
627 self.send(str(data, 'ASCII', 'strict').lower().encode('ASCII', 'strict'))
Bill Janssen54cc54c2007-12-14 22:08:56 +0000628
629 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000630 self.close()
Antoine Pitrouec146182010-04-24 21:30:20 +0000631 if test_support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000632 sys.stdout.write(" server: closed connection %s\n" % self.socket)
633
634 def handle_error(self):
635 raise
636
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000637 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000638 self.certfile = certfile
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000639 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
640 self.port = support.bind_port(sock, '')
641 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000642 self.listen(5)
643
644 def handle_accept(self):
645 sock_obj, addr = self.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000646 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000647 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
648 self.ConnectionHandler(sock_obj, self.certfile)
649
650 def handle_error(self):
651 raise
652
Trent Nelson78520002008-04-10 20:54:35 +0000653 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000654 self.flag = None
655 self.active = False
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000656 self.server = self.EchoServer(certfile)
657 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000658 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000659 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000660
661 def __str__(self):
662 return "<%s %s>" % (self.__class__.__name__, self.server)
663
664 def start (self, flag=None):
665 self.flag = flag
666 threading.Thread.start(self)
667
668 def run (self):
669 self.active = True
670 if self.flag:
671 self.flag.set()
672 while self.active:
673 try:
674 asyncore.loop(1)
675 except:
676 pass
677
678 def stop (self):
679 self.active = False
680 self.server.close()
681
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000682 def badCertTest (certfile):
Trent Nelson78520002008-04-10 20:54:35 +0000683 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000684 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000685 cacerts=CERTFILE, chatty=False,
686 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000687 flag = threading.Event()
688 server.start(flag)
689 # wait for it to start
690 flag.wait()
691 # try to connect
692 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000693 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000694 s = ssl.wrap_socket(socket.socket(),
695 certfile=certfile,
696 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelson78520002008-04-10 20:54:35 +0000697 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000698 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000699 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000700 sys.stdout.write("\nSSLError is %s\n" % x)
Bill Janssenddc56692008-07-17 18:17:20 +0000701 except socket.error as x:
702 if support.verbose:
703 sys.stdout.write("\nsocket.error is %s\n" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000704 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000705 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000706 "Use of invalid cert should have failed!")
707 finally:
708 server.stop()
709 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000710
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000711 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
Bill Janssen6e027db2007-11-15 22:23:56 +0000712 client_certfile, client_protocol=None,
713 indata="FOO\n",
714 chatty=False, connectionchatty=False):
Thomas Woutersed03b412007-08-28 21:37:11 +0000715
Trent Nelson78520002008-04-10 20:54:35 +0000716 server = ThreadedEchoServer(certfile,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000717 certreqs=certreqs,
718 ssl_version=protocol,
719 cacerts=cacertsfile,
720 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000721 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000722 flag = threading.Event()
723 server.start(flag)
724 # wait for it to start
725 flag.wait()
726 # try to connect
727 if client_protocol is None:
728 client_protocol = protocol
729 try:
Bill Janssen6e027db2007-11-15 22:23:56 +0000730 s = ssl.wrap_socket(socket.socket(),
Trent Nelson6b240cd2008-04-10 20:12:06 +0000731 server_side=False,
Bill Janssen6e027db2007-11-15 22:23:56 +0000732 certfile=client_certfile,
733 ca_certs=cacertsfile,
734 cert_reqs=certreqs,
735 ssl_version=client_protocol)
Trent Nelson78520002008-04-10 20:54:35 +0000736 s.connect((HOST, server.port))
Bill Janssen6e027db2007-11-15 22:23:56 +0000737 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000738 raise support.TestFailed("Unexpected SSL error: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000739 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000740 raise support.TestFailed("Unexpected exception: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000741 else:
742 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000743 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000744 sys.stdout.write(
745 " client: sending %s...\n" % (repr(indata)))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000746 s.write(indata.encode('ASCII', 'strict'))
Bill Janssen6e027db2007-11-15 22:23:56 +0000747 outdata = s.read()
748 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000749 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000750 sys.stdout.write(" client: read %s\n" % repr(outdata))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000751 outdata = str(outdata, 'ASCII', 'strict')
Bill Janssen6e027db2007-11-15 22:23:56 +0000752 if outdata != indata.lower():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000753 raise support.TestFailed(
Bill Janssen6e027db2007-11-15 22:23:56 +0000754 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +0000755 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
756 repr(indata[:min(len(indata),20)].lower()), len(indata)))
757 s.write("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +0000758 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000759 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000760 sys.stdout.write(" client: closing connection.\n")
761 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000762 finally:
763 server.stop()
764 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000765
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000766 def tryProtocolCombo (server_protocol,
767 client_protocol,
768 expectedToWork,
769 certsreqs=None):
Thomas Woutersed03b412007-08-28 21:37:11 +0000770
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000771 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000772 certsreqs = ssl.CERT_NONE
Thomas Woutersed03b412007-08-28 21:37:11 +0000773
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000774 if certsreqs == ssl.CERT_NONE:
775 certtype = "CERT_NONE"
776 elif certsreqs == ssl.CERT_OPTIONAL:
777 certtype = "CERT_OPTIONAL"
778 elif certsreqs == ssl.CERT_REQUIRED:
779 certtype = "CERT_REQUIRED"
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000780 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000781 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
782 sys.stdout.write(formatstr %
783 (ssl.get_protocol_name(client_protocol),
784 ssl.get_protocol_name(server_protocol),
785 certtype))
786 try:
787 serverParamsTest(CERTFILE, server_protocol, certsreqs,
Bill Janssen6e027db2007-11-15 22:23:56 +0000788 CERTFILE, CERTFILE, client_protocol,
789 chatty=False, connectionchatty=False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000790 except support.TestFailed:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000791 if expectedToWork:
792 raise
793 else:
794 if not expectedToWork:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000795 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000796 "Client protocol %s succeeded with server protocol %s!"
797 % (ssl.get_protocol_name(client_protocol),
798 ssl.get_protocol_name(server_protocol)))
799
800
Bill Janssen6e027db2007-11-15 22:23:56 +0000801 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000802
Trent Nelson6b240cd2008-04-10 20:12:06 +0000803 def testEcho (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000804
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000805 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000806 sys.stdout.write("\n")
807 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
808 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
809 chatty=True, connectionchatty=True)
810
811 def testReadCert(self):
812
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000813 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000814 sys.stdout.write("\n")
815 s2 = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000816 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000817 certreqs=ssl.CERT_NONE,
818 ssl_version=ssl.PROTOCOL_SSLv23,
819 cacerts=CERTFILE,
820 chatty=False)
821 flag = threading.Event()
822 server.start(flag)
823 # wait for it to start
824 flag.wait()
825 # try to connect
826 try:
827 try:
828 s = ssl.wrap_socket(socket.socket(),
829 certfile=CERTFILE,
830 ca_certs=CERTFILE,
831 cert_reqs=ssl.CERT_REQUIRED,
832 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelson78520002008-04-10 20:54:35 +0000833 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000834 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000835 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000836 "Unexpected SSL error: " + str(x))
837 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000838 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000839 "Unexpected exception: " + str(x))
840 else:
841 if not s:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000842 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000843 "Can't SSL-handshake with test server")
844 cert = s.getpeercert()
845 if not cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000846 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000847 "Can't get peer certificate.")
848 cipher = s.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000849 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000850 sys.stdout.write(pprint.pformat(cert) + '\n')
851 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
Bill Janssen6e027db2007-11-15 22:23:56 +0000852 if 'subject' not in cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000853 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000854 "No subject field in certificate: %s." %
855 pprint.pformat(cert))
856 if ((('organizationName', 'Python Software Foundation'),)
857 not in cert['subject']):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000858 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000859 "Missing or invalid 'organizationName' field in certificate subject; "
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000860 "should be 'Python Software Foundation'.")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000861 s.close()
862 finally:
863 server.stop()
864 server.join()
865
866 def testNULLcert(self):
867 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
868 "nullcert.pem"))
869 def testMalformedCert(self):
870 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
871 "badcert.pem"))
Bill Janssen58afe4c2008-09-08 16:45:19 +0000872 def testWrongCert(self):
873 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
874 "wrongcert.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000875 def testMalformedKey(self):
876 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
877 "badkey.pem"))
878
Trent Nelson6b240cd2008-04-10 20:12:06 +0000879 def testRudeShutdown(self):
880
881 listener_ready = threading.Event()
882 listener_gone = threading.Event()
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000883 s = socket.socket()
884 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000885
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000886 # `listener` runs in a thread. It sits in an accept() until
887 # the main thread connects. Then it rudely closes the socket,
888 # and sets Event `listener_gone` to let the main thread know
889 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +0000890 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +0000891 s.listen(5)
892 listener_ready.set()
893 s.accept()
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000894 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000895 listener_gone.set()
896
897 def connector():
898 listener_ready.wait()
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000899 c = socket.socket()
900 c.connect((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000901 listener_gone.wait()
902 try:
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000903 ssl_sock = ssl.wrap_socket(c)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000904 except IOError:
905 pass
906 else:
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000907 raise test_support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +0000908 'connecting to closed SSL socket should have failed')
909
910 t = threading.Thread(target=listener)
911 t.start()
Antoine Pitrou0fb2e542010-04-27 08:58:38 +0000912 try:
913 connector()
914 finally:
915 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000916
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000917 def testProtocolSSL2(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000918 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000919 sys.stdout.write("\n")
920 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
921 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
922 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
923 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
924 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
925 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
926
927 def testProtocolSSL23(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000928 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000929 sys.stdout.write("\n")
930 try:
931 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000932 except support.TestFailed as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000933 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000934 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000935 sys.stdout.write(
936 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
937 % str(x))
938 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
939 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
940 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
941
942 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
943 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
944 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
945
946 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
947 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
948 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
949
950 def testProtocolSSL3(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000951 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000952 sys.stdout.write("\n")
953 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
954 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
955 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
956 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
957 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
958 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
959
960 def testProtocolTLS1(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000961 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000962 sys.stdout.write("\n")
963 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
964 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
965 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
966 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
967 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
968 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
969
970 def testSTARTTLS (self):
971
Bill Janssen40a0f662008-08-12 16:56:25 +0000972 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000973
Trent Nelson78520002008-04-10 20:54:35 +0000974 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000975 ssl_version=ssl.PROTOCOL_TLSv1,
976 starttls_server=True,
977 chatty=True,
978 connectionchatty=True)
979 flag = threading.Event()
980 server.start(flag)
981 # wait for it to start
982 flag.wait()
983 # try to connect
984 wrapped = False
985 try:
986 try:
987 s = socket.socket()
988 s.setblocking(1)
Trent Nelson78520002008-04-10 20:54:35 +0000989 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000990 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000991 raise support.TestFailed("Unexpected exception: " + str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000992 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000993 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000994 sys.stdout.write("\n")
995 for indata in msgs:
Bill Janssen6e027db2007-11-15 22:23:56 +0000996 msg = indata.encode('ASCII', 'replace')
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000997 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000998 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +0000999 " client: sending %s...\n" % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001000 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +00001001 conn.write(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001002 outdata = conn.read()
1003 else:
Bill Janssen6e027db2007-11-15 22:23:56 +00001004 s.send(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001005 outdata = s.recv(1024)
1006 if (indata == "STARTTLS" and
Bill Janssen6e027db2007-11-15 22:23:56 +00001007 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001008 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001009 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001010 sys.stdout.write(
1011 " client: read %s from server, starting TLS...\n"
Bill Janssen6e027db2007-11-15 22:23:56 +00001012 % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001013 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001014 wrapped = True
Bill Janssen40a0f662008-08-12 16:56:25 +00001015 elif (indata == "ENDTLS" and
1016 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
1017 if support.verbose:
1018 msg = str(outdata, 'ASCII', 'replace')
1019 sys.stdout.write(
1020 " client: read %s from server, ending TLS...\n"
1021 % repr(msg))
1022 s = conn.unwrap()
1023 wrapped = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001024 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001025 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001026 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001027 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +00001028 " client: read %s from server\n" % repr(msg))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001029 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001030 sys.stdout.write(" client: closing connection.\n")
1031 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +00001032 conn.write("over\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001033 else:
Bill Janssen40a0f662008-08-12 16:56:25 +00001034 s.send("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +00001035 if wrapped:
1036 conn.close()
1037 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001038 s.close()
1039 finally:
1040 server.stop()
1041 server.join()
1042
Bill Janssen54cc54c2007-12-14 22:08:56 +00001043 def testSocketServer(self):
Bill Janssen6e027db2007-11-15 22:23:56 +00001044
Trent Nelson78520002008-04-10 20:54:35 +00001045 server = OurHTTPSServer(CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001046 flag = threading.Event()
1047 server.start(flag)
1048 # wait for it to start
1049 flag.wait()
1050 # try to connect
1051 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001052 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001053 sys.stdout.write('\n')
1054 d1 = open(CERTFILE, 'rb').read()
1055 d2 = ''
1056 # now fetch the same data from the HTTPS server
Trent Nelson78520002008-04-10 20:54:35 +00001057 url = 'https://%s:%d/%s' % (
1058 HOST, server.port, os.path.split(CERTFILE)[1])
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001059 f = urllib.request.urlopen(url)
Barry Warsaw820c1202008-06-12 04:06:45 +00001060 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001061 if dlen and (int(dlen) > 0):
1062 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001063 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001064 sys.stdout.write(
1065 " client: read %d bytes from remote server '%s'\n"
1066 % (len(d2), server))
1067 f.close()
1068 except:
1069 msg = ''.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001070 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001071 sys.stdout.write('\n' + msg)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001072 raise support.TestFailed(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001073 else:
1074 if not (d1 == d2):
Bill Janssen6e027db2007-11-15 22:23:56 +00001075 print("d1 is", len(d1), repr(d1))
1076 print("d2 is", len(d2), repr(d2))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001077 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001078 "Couldn't fetch data from HTTPS server")
1079 finally:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001080 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001081 sys.stdout.write('stopping server\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001082 server.stop()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001083 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001084 sys.stdout.write('joining thread\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001085 server.join()
1086
Trent Nelson6b240cd2008-04-10 20:12:06 +00001087 def testAsyncoreServer(self):
1088
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001089 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001090 sys.stdout.write("\n")
1091
1092 indata="FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001093 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001094 flag = threading.Event()
1095 server.start(flag)
1096 # wait for it to start
1097 flag.wait()
1098 # try to connect
1099 try:
1100 s = ssl.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001101 s.connect((HOST, server.port))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001102 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001103 raise support.TestFailed("Unexpected SSL error: " + str(x))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001104 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001105 raise support.TestFailed("Unexpected exception: " + str(x))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001106 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001107 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001108 sys.stdout.write(
1109 " client: sending %s...\n" % (repr(indata)))
1110 s.sendall(indata.encode('ASCII', 'strict'))
1111 outdata = s.recv()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001112 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001113 sys.stdout.write(" client: read %s\n" % repr(outdata))
1114 outdata = str(outdata, 'ASCII', 'strict')
1115 if outdata != indata.lower():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001116 raise support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +00001117 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1118 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
1119 repr(indata[:min(len(indata),20)].lower()), len(indata)))
1120 s.write("over\n".encode("ASCII", "strict"))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001121 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001122 sys.stdout.write(" client: closing connection.\n")
1123 s.close()
1124 finally:
1125 server.stop()
1126 server.join()
1127
Bill Janssen58afe4c2008-09-08 16:45:19 +00001128 def testAllRecvAndSendMethods(self):
1129
1130 if support.verbose:
1131 sys.stdout.write("\n")
1132
1133 server = ThreadedEchoServer(CERTFILE,
1134 certreqs=ssl.CERT_NONE,
1135 ssl_version=ssl.PROTOCOL_TLSv1,
1136 cacerts=CERTFILE,
1137 chatty=True,
1138 connectionchatty=False)
1139 flag = threading.Event()
1140 server.start(flag)
1141 # wait for it to start
1142 flag.wait()
1143 # try to connect
1144 try:
1145 s = ssl.wrap_socket(socket.socket(),
1146 server_side=False,
1147 certfile=CERTFILE,
1148 ca_certs=CERTFILE,
1149 cert_reqs=ssl.CERT_NONE,
1150 ssl_version=ssl.PROTOCOL_TLSv1)
1151 s.connect((HOST, server.port))
1152 except ssl.SSLError as x:
1153 raise support.TestFailed("Unexpected SSL error: " + str(x))
1154 except Exception as x:
1155 raise support.TestFailed("Unexpected exception: " + str(x))
1156 else:
1157 # helper methods for standardising recv* method signatures
1158 def _recv_into():
1159 b = bytearray(b"\0"*100)
1160 count = s.recv_into(b)
1161 return b[:count]
1162
1163 def _recvfrom_into():
1164 b = bytearray(b"\0"*100)
1165 count, addr = s.recvfrom_into(b)
1166 return b[:count]
1167
1168 # (name, method, whether to expect success, *args)
1169 send_methods = [
1170 ('send', s.send, True, []),
1171 ('sendto', s.sendto, False, ["some.address"]),
1172 ('sendall', s.sendall, True, []),
1173 ]
1174 recv_methods = [
1175 ('recv', s.recv, True, []),
1176 ('recvfrom', s.recvfrom, False, ["some.address"]),
1177 ('recv_into', _recv_into, True, []),
1178 ('recvfrom_into', _recvfrom_into, False, []),
1179 ]
1180 data_prefix = "PREFIX_"
1181
1182 for meth_name, send_meth, expect_success, args in send_methods:
1183 indata = data_prefix + meth_name
1184 try:
1185 send_meth(indata.encode('ASCII', 'strict'), *args)
1186 outdata = s.read()
1187 outdata = str(outdata, 'ASCII', 'strict')
1188 if outdata != indata.lower():
1189 raise support.TestFailed(
1190 "While sending with <<{name:s}>> bad data "
1191 "<<{outdata:s}>> ({nout:d}) received; "
1192 "expected <<{indata:s}>> ({nin:d})\n".format(
1193 name=meth_name, outdata=repr(outdata[:20]),
1194 nout=len(outdata),
1195 indata=repr(indata[:20]), nin=len(indata)
1196 )
1197 )
1198 except ValueError as e:
1199 if expect_success:
1200 raise support.TestFailed(
1201 "Failed to send with method <<{name:s}>>; "
1202 "expected to succeed.\n".format(name=meth_name)
1203 )
1204 if not str(e).startswith(meth_name):
1205 raise support.TestFailed(
1206 "Method <<{name:s}>> failed with unexpected "
1207 "exception message: {exp:s}\n".format(
1208 name=meth_name, exp=e
1209 )
1210 )
1211
1212 for meth_name, recv_meth, expect_success, args in recv_methods:
1213 indata = data_prefix + meth_name
1214 try:
1215 s.send(indata.encode('ASCII', 'strict'))
1216 outdata = recv_meth(*args)
1217 outdata = str(outdata, 'ASCII', 'strict')
1218 if outdata != indata.lower():
1219 raise support.TestFailed(
1220 "While receiving with <<{name:s}>> bad data "
1221 "<<{outdata:s}>> ({nout:d}) received; "
1222 "expected <<{indata:s}>> ({nin:d})\n".format(
1223 name=meth_name, outdata=repr(outdata[:20]),
1224 nout=len(outdata),
1225 indata=repr(indata[:20]), nin=len(indata)
1226 )
1227 )
1228 except ValueError as e:
1229 if expect_success:
1230 raise support.TestFailed(
1231 "Failed to receive with method <<{name:s}>>; "
1232 "expected to succeed.\n".format(name=meth_name)
1233 )
1234 if not str(e).startswith(meth_name):
1235 raise support.TestFailed(
1236 "Method <<{name:s}>> failed with unexpected "
1237 "exception message: {exp:s}\n".format(
1238 name=meth_name, exp=e
1239 )
1240 )
1241 # consume data
1242 s.read()
1243
1244 s.write("over\n".encode("ASCII", "strict"))
1245 s.close()
1246 finally:
1247 server.stop()
1248 server.join()
1249
Antoine Pitrouec146182010-04-24 21:30:20 +00001250 def test_handshake_timeout(self):
1251 # Issue #5103: SSL handshake must respect the socket timeout
1252 server = socket.socket(socket.AF_INET)
1253 host = "127.0.0.1"
1254 port = support.bind_port(server)
1255 started = threading.Event()
1256 finish = False
1257
1258 def serve():
1259 server.listen(5)
1260 started.set()
1261 conns = []
1262 while not finish:
1263 r, w, e = select.select([server], [], [], 0.1)
1264 if server in r:
1265 # Let the socket hang around rather than having
1266 # it closed by garbage collection.
1267 conns.append(server.accept()[0])
1268
1269 t = threading.Thread(target=serve)
1270 t.start()
1271 started.wait()
1272
1273 try:
Antoine Pitrouc2203f92010-04-24 22:07:51 +00001274 try:
1275 c = socket.socket(socket.AF_INET)
1276 c.settimeout(0.2)
1277 c.connect((host, port))
1278 # Will attempt handshake and time out
1279 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1280 ssl.wrap_socket, c)
1281 finally:
1282 c.close()
Antoine Pitrouec146182010-04-24 21:30:20 +00001283 try:
1284 c = socket.socket(socket.AF_INET)
1285 c = ssl.wrap_socket(c)
1286 c.settimeout(0.2)
1287 # Will attempt handshake and time out
1288 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1289 c.connect, (host, port))
1290 finally:
1291 c.close()
1292 finally:
1293 finish = True
1294 t.join()
1295 server.close()
1296
Bill Janssen58afe4c2008-09-08 16:45:19 +00001297
Thomas Woutersed03b412007-08-28 21:37:11 +00001298def test_main(verbose=False):
1299 if skip_expected:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001300 raise unittest.SkipTest("No SSL support")
Thomas Woutersed03b412007-08-28 21:37:11 +00001301
Trent Nelson78520002008-04-10 20:54:35 +00001302 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Thomas Woutersed03b412007-08-28 21:37:11 +00001303 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
1304 "keycert.pem")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001305 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1306 os.path.dirname(__file__) or os.curdir,
1307 "https_svn_python_org_root.pem")
1308
1309 if (not os.path.exists(CERTFILE) or
1310 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001311 raise support.TestFailed("Can't read certificate files!")
Bill Janssen6e027db2007-11-15 22:23:56 +00001312
Thomas Woutersed03b412007-08-28 21:37:11 +00001313 tests = [BasicTests]
1314
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001315 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001316 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001317
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001318 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001319 thread_info = support.threading_setup()
1320 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001321 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001322
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001323 support.run_unittest(*tests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001324
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001325 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001326 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001327
1328if __name__ == "__main__":
1329 test_main()