blob: 2b1ba8a0ce22daa85e75cb46cf59059cef9319a7 [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 time
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +00009import gc
Thomas Woutersed03b412007-08-28 21:37:11 +000010import os
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000011import errno
Thomas Woutersed03b412007-08-28 21:37:11 +000012import pprint
Jeremy Hylton1afc1692008-06-18 20:49:58 +000013import urllib.parse, urllib.request
Thomas Woutersed03b412007-08-28 21:37:11 +000014import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000015import asyncore
Antoine Pitrou9d543662010-04-23 23:10:32 +000016import weakref
Thomas Woutersed03b412007-08-28 21:37:11 +000017
Georg Brandl24420152008-05-26 16:32:26 +000018from http.server import HTTPServer, SimpleHTTPRequestHandler
Thomas Wouters1b7f8912007-09-19 03:06:30 +000019
Thomas Woutersed03b412007-08-28 21:37:11 +000020# Optionally test SSL support, if we have it in the tested platform
21skip_expected = False
22try:
23 import ssl
24except ImportError:
25 skip_expected = True
26
Benjamin Petersonee8712c2008-05-20 21:35:26 +000027HOST = support.HOST
Thomas Woutersed03b412007-08-28 21:37:11 +000028CERTFILE = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +000029SVN_PYTHON_ORG_ROOT_CERT = None
Thomas Woutersed03b412007-08-28 21:37:11 +000030
Thomas Woutersed03b412007-08-28 21:37:11 +000031def handle_error(prefix):
32 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000033 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000034 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000035
36
37class BasicTests(unittest.TestCase):
38
Georg Brandlfceab5a2008-01-19 20:08:23 +000039 def testSSLconnect(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000040 if not support.is_resource_enabled('network'):
Georg Brandlfceab5a2008-01-19 20:08:23 +000041 return
42 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
43 cert_reqs=ssl.CERT_NONE)
44 s.connect(("svn.python.org", 443))
45 c = s.getpeercert()
46 if c:
Benjamin Petersonee8712c2008-05-20 21:35:26 +000047 raise support.TestFailed("Peer cert %s shouldn't be here!")
Georg Brandlfceab5a2008-01-19 20:08:23 +000048 s.close()
49
50 # this should fail because we have no verification certs
51 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
52 cert_reqs=ssl.CERT_REQUIRED)
53 try:
54 s.connect(("svn.python.org", 443))
55 except ssl.SSLError:
56 pass
57 finally:
58 s.close()
59
Thomas Wouters1b7f8912007-09-19 03:06:30 +000060 def testCrucialConstants(self):
61 ssl.PROTOCOL_SSLv2
62 ssl.PROTOCOL_SSLv23
63 ssl.PROTOCOL_SSLv3
64 ssl.PROTOCOL_TLSv1
65 ssl.CERT_NONE
66 ssl.CERT_OPTIONAL
67 ssl.CERT_REQUIRED
Thomas Woutersed03b412007-08-28 21:37:11 +000068
Thomas Wouters1b7f8912007-09-19 03:06:30 +000069 def testRAND(self):
70 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +000071 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000072 sys.stdout.write("\n RAND_status is %d (%s)\n"
73 % (v, (v and "sufficient randomness") or
74 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +000075 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000076 ssl.RAND_egd(1)
77 except TypeError:
78 pass
Thomas Woutersed03b412007-08-28 21:37:11 +000079 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000080 print("didn't raise TypeError")
81 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +000082
Thomas Wouters1b7f8912007-09-19 03:06:30 +000083 def testParseCert(self):
84 # note that this uses an 'unofficial' function in _ssl.c,
85 # provided solely for this test, to exercise the certificate
86 # parsing code
87 p = ssl._ssl._test_decode_cert(CERTFILE, False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000088 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000089 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +000090
Thomas Wouters1b7f8912007-09-19 03:06:30 +000091 def testDERtoPEM(self):
92
93 pem = open(SVN_PYTHON_ORG_ROOT_CERT, 'r').read()
94 d1 = ssl.PEM_cert_to_DER_cert(pem)
95 p2 = ssl.DER_cert_to_PEM_cert(d1)
96 d2 = ssl.PEM_cert_to_DER_cert(p2)
97 if (d1 != d2):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000098 raise support.TestFailed("PEM-to-DER or DER-to-PEM translation failed")
Thomas Wouters1b7f8912007-09-19 03:06:30 +000099
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000100 def test_openssl_version(self):
101 n = ssl.OPENSSL_VERSION_NUMBER
102 t = ssl.OPENSSL_VERSION_INFO
103 s = ssl.OPENSSL_VERSION
104 self.assertIsInstance(n, int)
105 self.assertIsInstance(t, tuple)
106 self.assertIsInstance(s, str)
107 # Some sanity checks follow
108 # >= 0.9
109 self.assertGreaterEqual(n, 0x900000)
110 # < 2.0
111 self.assertLess(n, 0x20000000)
112 major, minor, fix, patch, status = t
113 self.assertGreaterEqual(major, 0)
114 self.assertLess(major, 2)
115 self.assertGreaterEqual(minor, 0)
116 self.assertLess(minor, 256)
117 self.assertGreaterEqual(fix, 0)
118 self.assertLess(fix, 256)
119 self.assertGreaterEqual(patch, 0)
120 self.assertLessEqual(patch, 26)
121 self.assertGreaterEqual(status, 0)
122 self.assertLessEqual(status, 15)
123 # Version string as returned by OpenSSL, the format might change
124 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
125 (s, t))
126
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000127 def test_ciphers(self):
128 if not support.is_resource_enabled('network'):
129 return
130 remote = ("svn.python.org", 443)
131 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
132 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
133 s.connect(remote)
134 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
135 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
136 s.connect(remote)
137 # Error checking occurs when connecting, because the SSL context
138 # isn't created before.
139 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
140 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
141 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
142 s.connect(remote)
143
Antoine Pitrou9d543662010-04-23 23:10:32 +0000144 @support.cpython_only
145 def test_refcycle(self):
146 # Issue #7943: an SSL object doesn't create reference cycles with
147 # itself.
148 s = socket.socket(socket.AF_INET)
149 ss = ssl.wrap_socket(s)
150 wr = weakref.ref(ss)
151 del ss
152 self.assertEqual(wr(), None)
153
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000154
Bill Janssen6e027db2007-11-15 22:23:56 +0000155class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000156
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000157 def testConnect(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000158 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
159 cert_reqs=ssl.CERT_NONE)
160 s.connect(("svn.python.org", 443))
161 c = s.getpeercert()
162 if c:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000163 raise support.TestFailed("Peer cert %s shouldn't be here!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000164 s.close()
165
166 # this should fail because we have no verification certs
167 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
168 cert_reqs=ssl.CERT_REQUIRED)
Thomas Woutersed03b412007-08-28 21:37:11 +0000169 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000170 s.connect(("svn.python.org", 443))
171 except ssl.SSLError:
172 pass
173 finally:
174 s.close()
175
176 # this should succeed because we specify the root cert
177 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
178 cert_reqs=ssl.CERT_REQUIRED,
179 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
180 try:
181 s.connect(("svn.python.org", 443))
182 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000183 raise support.TestFailed("Unexpected exception %s" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000184 finally:
185 s.close()
186
Antoine Pitroue3220242010-04-24 11:13:53 +0000187 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
188 def test_makefile_close(self):
189 # Issue #5238: creating a file-like object with makefile() shouldn't
190 # delay closing the underlying "real socket" (here tested with its
191 # file descriptor, hence skipping the test under Windows).
192 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
193 ss.connect(("svn.python.org", 443))
194 fd = ss.fileno()
195 f = ss.makefile()
196 f.close()
197 # The fd is still open
198 os.read(fd, 0)
199 # Closing the SSL socket should close the fd too
200 ss.close()
201 gc.collect()
202 with self.assertRaises(OSError) as e:
203 os.read(fd, 0)
204 self.assertEqual(e.exception.errno, errno.EBADF)
205
Bill Janssen6e027db2007-11-15 22:23:56 +0000206 def testNonBlockingHandshake(self):
207 s = socket.socket(socket.AF_INET)
208 s.connect(("svn.python.org", 443))
209 s.setblocking(False)
210 s = ssl.wrap_socket(s,
211 cert_reqs=ssl.CERT_NONE,
212 do_handshake_on_connect=False)
213 count = 0
214 while True:
215 try:
216 count += 1
217 s.do_handshake()
218 break
219 except ssl.SSLError as err:
220 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
221 select.select([s], [], [])
222 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
223 select.select([], [s], [])
224 else:
225 raise
226 s.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000227 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000228 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000229
Bill Janssen54cc54c2007-12-14 22:08:56 +0000230 def testFetchServerCert(self):
231
232 pem = ssl.get_server_certificate(("svn.python.org", 443))
233 if not pem:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000234 raise support.TestFailed("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000235
236 return
237
238 try:
239 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
240 except ssl.SSLError as x:
241 #should fail
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000242 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000243 sys.stdout.write("%s\n" % x)
244 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000245 raise support.TestFailed("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000246
247 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
248 if not pem:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000249 raise support.TestFailed("No server certificate on svn.python.org:443!")
250 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000251 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
252
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000253 def test_algorithms(self):
254 # Issue #8484: all algorithms should be available when verifying a
255 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000256 # SHA256 was added in OpenSSL 0.9.8
257 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
258 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000259 # NOTE: https://sha256.tbs-internet.com is another possible test host
260 remote = ("sha2.hboeck.de", 443)
261 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
262 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
263 cert_reqs=ssl.CERT_REQUIRED,
264 ca_certs=sha256_cert,)
265 with support.transient_internet():
266 try:
267 s.connect(remote)
268 if support.verbose:
269 sys.stdout.write("\nCipher with %r is %r\n" %
270 (remote, s.cipher()))
271 sys.stdout.write("Certificate is:\n%s\n" %
272 pprint.pformat(s.getpeercert()))
273 finally:
274 s.close()
275
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000276
277try:
278 import threading
279except ImportError:
280 _have_threads = False
281else:
282
283 _have_threads = True
284
285 class ThreadedEchoServer(threading.Thread):
286
287 class ConnectionHandler(threading.Thread):
288
289 """A mildly complicated class, because we want it to work both
290 with and without the SSL wrapper around the socket connection, so
291 that we can test the STARTTLS functionality."""
292
Bill Janssen6e027db2007-11-15 22:23:56 +0000293 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000294 self.server = server
295 self.running = False
296 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000297 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000298 self.sock.setblocking(1)
299 self.sslconn = None
300 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000301 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000302
303 def wrap_conn (self):
304 try:
305 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
306 certfile=self.server.certificate,
307 ssl_version=self.server.protocol,
308 ca_certs=self.server.cacerts,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000309 cert_reqs=self.server.certreqs,
310 ciphers=self.server.ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000311 except:
312 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000313 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000314 if not self.server.expect_bad_connects:
315 # here, we want to stop the server, because this shouldn't
316 # happen in the context of our test case
317 self.running = False
318 # normally, we'd just stop here, but for the test
319 # harness, we want to stop the server
320 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000321 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000322 return False
323
324 else:
325 if self.server.certreqs == ssl.CERT_REQUIRED:
326 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000327 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000328 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
329 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000330 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000331 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
332 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000333 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000334 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
335 return True
336
337 def read(self):
338 if self.sslconn:
339 return self.sslconn.read()
340 else:
341 return self.sock.recv(1024)
342
343 def write(self, bytes):
344 if self.sslconn:
345 return self.sslconn.write(bytes)
346 else:
347 return self.sock.send(bytes)
348
349 def close(self):
350 if self.sslconn:
351 self.sslconn.close()
352 else:
353 self.sock.close()
354
355 def run (self):
356 self.running = True
357 if not self.server.starttls_server:
358 if not self.wrap_conn():
359 return
360 while self.running:
361 try:
362 msg = self.read()
Bill Janssen6e027db2007-11-15 22:23:56 +0000363 amsg = (msg and str(msg, 'ASCII', 'strict')) or ''
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000364 if not msg:
365 # eof, so quit this handler
366 self.running = False
367 self.close()
Bill Janssen6e027db2007-11-15 22:23:56 +0000368 elif amsg.strip() == 'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000369 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000370 sys.stdout.write(" server: client closed connection\n")
371 self.close()
372 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000373 elif (self.server.starttls_server and
374 amsg.strip() == 'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000375 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000376 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000377 self.write("OK\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000378 if not self.wrap_conn():
379 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000380 elif (self.server.starttls_server and self.sslconn
381 and amsg.strip() == 'ENDTLS'):
382 if support.verbose and self.server.connectionchatty:
383 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
384 self.write("OK\n".encode("ASCII", "strict"))
385 self.sock = self.sslconn.unwrap()
386 self.sslconn = None
387 if support.verbose and self.server.connectionchatty:
388 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000389 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000390 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000391 self.server.connectionchatty):
392 ctype = (self.sslconn and "encrypted") or "unencrypted"
393 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
394 % (repr(msg), ctype, repr(msg.lower()), ctype))
Bill Janssen6e027db2007-11-15 22:23:56 +0000395 self.write(amsg.lower().encode('ASCII', 'strict'))
396 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000397 if self.server.chatty:
398 handle_error("Test server failure:\n")
399 self.close()
400 self.running = False
401 # normally, we'd just stop here, but for the test
402 # harness, we want to stop the server
403 self.server.stop()
404 except:
405 handle_error('')
406
Trent Nelson78520002008-04-10 20:54:35 +0000407 def __init__(self, certificate, ssl_version=None,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000408 certreqs=None, cacerts=None, expect_bad_connects=False,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000409 chatty=True, connectionchatty=False, starttls_server=False,
410 ciphers=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000411 if ssl_version is None:
412 ssl_version = ssl.PROTOCOL_TLSv1
413 if certreqs is None:
414 certreqs = ssl.CERT_NONE
415 self.certificate = certificate
416 self.protocol = ssl_version
417 self.certreqs = certreqs
418 self.cacerts = cacerts
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000419 self.ciphers = ciphers
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000420 self.expect_bad_connects = expect_bad_connects
421 self.chatty = chatty
422 self.connectionchatty = connectionchatty
423 self.starttls_server = starttls_server
424 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000425 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000426 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000427 self.active = False
428 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000429 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000430
431 def start (self, flag=None):
432 self.flag = flag
433 threading.Thread.start(self)
434
435 def run (self):
436 self.sock.settimeout(0.5)
437 self.sock.listen(5)
438 self.active = True
439 if self.flag:
440 # signal an event
441 self.flag.set()
442 while self.active:
443 try:
444 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000445 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000446 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000447 + repr(connaddr) + '\n')
448 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000449 handler.start()
450 except socket.timeout:
451 pass
452 except KeyboardInterrupt:
453 self.stop()
454 except:
455 if self.chatty:
456 handle_error("Test server failure:\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000457 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000458
459 def stop (self):
460 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000461
Bill Janssen54cc54c2007-12-14 22:08:56 +0000462 class OurHTTPSServer(threading.Thread):
463
464 # This one's based on HTTPServer, which is based on SocketServer
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000465
466 class HTTPSServer(HTTPServer):
467
468 def __init__(self, server_address, RequestHandlerClass, certfile):
469
470 HTTPServer.__init__(self, server_address, RequestHandlerClass)
471 # we assume the certfile contains both private key and certificate
472 self.certfile = certfile
473 self.active = False
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000474 self.active_lock = threading.Lock()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000475 self.allow_reuse_address = True
476
Bill Janssen6e027db2007-11-15 22:23:56 +0000477 def __str__(self):
478 return ('<%s %s:%s>' %
479 (self.__class__.__name__,
480 self.server_name,
481 self.server_port))
482
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000483 def get_request (self):
484 # override this to wrap socket with SSL
485 sock, addr = self.socket.accept()
486 sslconn = ssl.wrap_socket(sock, server_side=True,
487 certfile=self.certfile)
488 return sslconn, addr
489
490 # The methods overridden below this are mainly so that we
491 # can run it in a thread and be able to stop it from another
492 # You probably wouldn't need them in other uses.
493
494 def server_activate(self):
495 # We want to run this in a thread for testing purposes,
496 # so we override this to set timeout, so that we get
497 # a chance to stop the server
498 self.socket.settimeout(0.5)
499 HTTPServer.server_activate(self)
500
501 def serve_forever(self):
502 # We want this to run in a thread, so we use a slightly
503 # modified version of "forever".
504 self.active = True
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000505 while 1:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000506 try:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000507 # We need to lock while handling the request.
508 # Another thread can close the socket after self.active
509 # has been checked and before the request is handled.
510 # This causes an exception when using the closed socket.
511 with self.active_lock:
512 if not self.active:
513 break
514 self.handle_request()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000515 except socket.timeout:
516 pass
517 except KeyboardInterrupt:
518 self.server_close()
519 return
520 except:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000521 sys.stdout.write(''.join(traceback.format_exception(*sys.exc_info())))
522 break
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000523 time.sleep(0.1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000524
525 def server_close(self):
526 # Again, we want this to run in a thread, so we need to override
527 # close to clear the "active" flag, so that serve_forever() will
528 # terminate.
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000529 with self.active_lock:
530 HTTPServer.server_close(self)
531 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000532
533 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
534
535 # need to override translate_path to get a known root,
536 # instead of using os.curdir, since the test could be
537 # run from anywhere
538
539 server_version = "TestHTTPS/1.0"
540
541 root = None
542
543 def translate_path(self, path):
544 """Translate a /-separated PATH to the local filename syntax.
545
546 Components that mean special things to the local file system
547 (e.g. drive or directory names) are ignored. (XXX They should
548 probably be diagnosed.)
549
550 """
551 # abandon query parameters
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000552 path = urllib.parse.urlparse(path)[2]
553 path = os.path.normpath(urllib.parse.unquote(path))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000554 words = path.split('/')
555 words = filter(None, words)
556 path = self.root
557 for word in words:
558 drive, word = os.path.splitdrive(word)
559 head, word = os.path.split(word)
560 if word in self.root: continue
561 path = os.path.join(path, word)
562 return path
563
564 def log_message(self, format, *args):
565
566 # we override this to suppress logging unless "verbose"
567
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000568 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000569 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
570 (self.server.server_address,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000571 self.server.server_port,
572 self.request.cipher(),
573 self.log_date_time_string(),
574 format%args))
Thomas Woutersed03b412007-08-28 21:37:11 +0000575
576
Trent Nelson78520002008-04-10 20:54:35 +0000577 def __init__(self, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000578 self.flag = None
579 self.active = False
580 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000581 self.port = support.find_unused_port()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000582 self.server = self.HTTPSServer(
Trent Nelson78520002008-04-10 20:54:35 +0000583 (HOST, self.port), self.RootedHTTPRequestHandler, certfile)
Thomas Woutersed03b412007-08-28 21:37:11 +0000584 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000585 self.daemon = True
Thomas Woutersed03b412007-08-28 21:37:11 +0000586
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000587 def __str__(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000588 return "<%s %s>" % (self.__class__.__name__, self.server)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000589
590 def start (self, flag=None):
591 self.flag = flag
592 threading.Thread.start(self)
593
Thomas Woutersed03b412007-08-28 21:37:11 +0000594 def run (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000595 self.active = True
596 if self.flag:
597 self.flag.set()
598 self.server.serve_forever()
599 self.active = False
600
601 def stop (self):
602 self.active = False
603 self.server.server_close()
604
605
Bill Janssen54cc54c2007-12-14 22:08:56 +0000606 class AsyncoreEchoServer(threading.Thread):
607
608 # this one's based on asyncore.dispatcher
609
610 class EchoServer (asyncore.dispatcher):
611
612 class ConnectionHandler (asyncore.dispatcher_with_send):
613
614 def __init__(self, conn, certfile):
615 self.socket = ssl.wrap_socket(conn, server_side=True,
616 certfile=certfile,
617 do_handshake_on_connect=False)
618 asyncore.dispatcher_with_send.__init__(self, self.socket)
619 # now we have to do the handshake
620 # we'll just do it the easy way, and block the connection
621 # till it's finished. If we were doing it right, we'd
622 # do this in multiple calls to handle_read...
623 self.do_handshake(block=True)
624
625 def readable(self):
626 if isinstance(self.socket, ssl.SSLSocket):
627 while self.socket.pending() > 0:
628 self.handle_read_event()
629 return True
630
631 def handle_read(self):
632 data = self.recv(1024)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000633 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000634 sys.stdout.write(" server: read %s from client\n" % repr(data))
635 if not data:
636 self.close()
637 else:
638 self.send(str(data, 'ASCII', 'strict').lower().encode('ASCII', 'strict'))
639
640 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000641 self.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000642 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000643 sys.stdout.write(" server: closed connection %s\n" % self.socket)
644
645 def handle_error(self):
646 raise
647
648 def __init__(self, port, certfile):
649 self.port = port
650 self.certfile = certfile
651 asyncore.dispatcher.__init__(self)
652 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
653 self.bind(('', port))
654 self.listen(5)
655
656 def handle_accept(self):
657 sock_obj, addr = self.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000658 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000659 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
660 self.ConnectionHandler(sock_obj, self.certfile)
661
662 def handle_error(self):
663 raise
664
Trent Nelson78520002008-04-10 20:54:35 +0000665 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000666 self.flag = None
667 self.active = False
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000668 self.port = support.find_unused_port()
Trent Nelson78520002008-04-10 20:54:35 +0000669 self.server = self.EchoServer(self.port, certfile)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000670 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000671 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000672
673 def __str__(self):
674 return "<%s %s>" % (self.__class__.__name__, self.server)
675
676 def start (self, flag=None):
677 self.flag = flag
678 threading.Thread.start(self)
679
680 def run (self):
681 self.active = True
682 if self.flag:
683 self.flag.set()
684 while self.active:
685 try:
686 asyncore.loop(1)
687 except:
688 pass
689
690 def stop (self):
691 self.active = False
692 self.server.close()
693
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000694 def badCertTest (certfile):
Trent Nelson78520002008-04-10 20:54:35 +0000695 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000696 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000697 cacerts=CERTFILE, chatty=False,
698 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000699 flag = threading.Event()
700 server.start(flag)
701 # wait for it to start
702 flag.wait()
703 # try to connect
704 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000705 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000706 s = ssl.wrap_socket(socket.socket(),
707 certfile=certfile,
708 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelson78520002008-04-10 20:54:35 +0000709 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000710 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000711 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000712 sys.stdout.write("\nSSLError is %s\n" % x)
Bill Janssenddc56692008-07-17 18:17:20 +0000713 except socket.error as x:
714 if support.verbose:
715 sys.stdout.write("\nsocket.error is %s\n" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000716 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000717 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000718 "Use of invalid cert should have failed!")
719 finally:
720 server.stop()
721 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000722
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000723 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
Bill Janssen6e027db2007-11-15 22:23:56 +0000724 client_certfile, client_protocol=None,
725 indata="FOO\n",
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000726 ciphers=None, chatty=False, connectionchatty=False):
Thomas Woutersed03b412007-08-28 21:37:11 +0000727
Trent Nelson78520002008-04-10 20:54:35 +0000728 server = ThreadedEchoServer(certfile,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000729 certreqs=certreqs,
730 ssl_version=protocol,
731 cacerts=cacertsfile,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000732 ciphers=ciphers,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000733 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000734 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +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:
Bill Janssen6e027db2007-11-15 22:23:56 +0000743 s = ssl.wrap_socket(socket.socket(),
Trent Nelson6b240cd2008-04-10 20:12:06 +0000744 server_side=False,
Bill Janssen6e027db2007-11-15 22:23:56 +0000745 certfile=client_certfile,
746 ca_certs=cacertsfile,
747 cert_reqs=certreqs,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000748 ciphers=ciphers,
Bill Janssen6e027db2007-11-15 22:23:56 +0000749 ssl_version=client_protocol)
Trent Nelson78520002008-04-10 20:54:35 +0000750 s.connect((HOST, server.port))
Bill Janssen6e027db2007-11-15 22:23:56 +0000751 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000752 raise support.TestFailed("Unexpected SSL error: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000753 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000754 raise support.TestFailed("Unexpected exception: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000755 else:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000756 bindata = indata.encode('ASCII', 'strict')
757 for arg in [bindata, bytearray(bindata), memoryview(bindata)]:
758 if connectionchatty:
759 if support.verbose:
760 sys.stdout.write(
761 " client: sending %s...\n" % (repr(indata)))
762 s.write(arg)
763 outdata = s.read()
764 if connectionchatty:
765 if support.verbose:
766 sys.stdout.write(" client: read %s\n" % repr(outdata))
767 outdata = str(outdata, 'ASCII', 'strict')
768 if outdata != indata.lower():
769 raise support.TestFailed(
770 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
771 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
772 repr(indata[:min(len(indata),20)].lower()), len(indata)))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000773 s.write("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +0000774 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000775 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000776 sys.stdout.write(" client: closing connection.\n")
777 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000778 finally:
779 server.stop()
780 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000781
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000782 def tryProtocolCombo (server_protocol,
783 client_protocol,
784 expectedToWork,
785 certsreqs=None):
Thomas Woutersed03b412007-08-28 21:37:11 +0000786
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000787 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000788 certsreqs = ssl.CERT_NONE
Thomas Woutersed03b412007-08-28 21:37:11 +0000789
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000790 if certsreqs == ssl.CERT_NONE:
791 certtype = "CERT_NONE"
792 elif certsreqs == ssl.CERT_OPTIONAL:
793 certtype = "CERT_OPTIONAL"
794 elif certsreqs == ssl.CERT_REQUIRED:
795 certtype = "CERT_REQUIRED"
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000796 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000797 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
798 sys.stdout.write(formatstr %
799 (ssl.get_protocol_name(client_protocol),
800 ssl.get_protocol_name(server_protocol),
801 certtype))
802 try:
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000803 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
804 # will send an SSLv3 hello (rather than SSLv2) starting from
805 # OpenSSL 1.0.0 (see issue #8322).
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000806 serverParamsTest(CERTFILE, server_protocol, certsreqs,
Bill Janssen6e027db2007-11-15 22:23:56 +0000807 CERTFILE, CERTFILE, client_protocol,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000808 ciphers="ALL",
Bill Janssen6e027db2007-11-15 22:23:56 +0000809 chatty=False, connectionchatty=False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000810 except support.TestFailed:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000811 if expectedToWork:
812 raise
813 else:
814 if not expectedToWork:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000815 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000816 "Client protocol %s succeeded with server protocol %s!"
817 % (ssl.get_protocol_name(client_protocol),
818 ssl.get_protocol_name(server_protocol)))
819
820
Bill Janssen6e027db2007-11-15 22:23:56 +0000821 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000822
Trent Nelson6b240cd2008-04-10 20:12:06 +0000823 def testEcho (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000824
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000825 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000826 sys.stdout.write("\n")
827 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
828 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
829 chatty=True, connectionchatty=True)
830
831 def testReadCert(self):
832
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000833 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000834 sys.stdout.write("\n")
835 s2 = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000836 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000837 certreqs=ssl.CERT_NONE,
838 ssl_version=ssl.PROTOCOL_SSLv23,
839 cacerts=CERTFILE,
840 chatty=False)
841 flag = threading.Event()
842 server.start(flag)
843 # wait for it to start
844 flag.wait()
845 # try to connect
846 try:
847 try:
848 s = ssl.wrap_socket(socket.socket(),
849 certfile=CERTFILE,
850 ca_certs=CERTFILE,
851 cert_reqs=ssl.CERT_REQUIRED,
852 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelson78520002008-04-10 20:54:35 +0000853 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000854 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000855 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000856 "Unexpected SSL error: " + str(x))
857 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000858 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000859 "Unexpected exception: " + str(x))
860 else:
861 if not s:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000862 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000863 "Can't SSL-handshake with test server")
864 cert = s.getpeercert()
865 if not cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000866 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000867 "Can't get peer certificate.")
868 cipher = s.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000869 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000870 sys.stdout.write(pprint.pformat(cert) + '\n')
871 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
Bill Janssen6e027db2007-11-15 22:23:56 +0000872 if 'subject' not in cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000873 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000874 "No subject field in certificate: %s." %
875 pprint.pformat(cert))
876 if ((('organizationName', 'Python Software Foundation'),)
877 not in cert['subject']):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000878 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000879 "Missing or invalid 'organizationName' field in certificate subject; "
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000880 "should be 'Python Software Foundation'.")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000881 s.close()
882 finally:
883 server.stop()
884 server.join()
885
886 def testNULLcert(self):
887 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
888 "nullcert.pem"))
889 def testMalformedCert(self):
890 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
891 "badcert.pem"))
Bill Janssen58afe4c2008-09-08 16:45:19 +0000892 def testWrongCert(self):
893 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
894 "wrongcert.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000895 def testMalformedKey(self):
896 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
897 "badkey.pem"))
898
Trent Nelson6b240cd2008-04-10 20:12:06 +0000899 def testRudeShutdown(self):
900
901 listener_ready = threading.Event()
902 listener_gone = threading.Event()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000903 port = support.find_unused_port()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000904
905 # `listener` runs in a thread. It opens a socket listening on
906 # PORT, and sits in an accept() until the main thread connects.
907 # Then it rudely closes the socket, and sets Event `listener_gone`
908 # to let the main thread know the socket is gone.
909 def listener():
910 s = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000911 s.bind((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000912 s.listen(5)
913 listener_ready.set()
914 s.accept()
915 s = None # reclaim the socket object, which also closes it
916 listener_gone.set()
917
918 def connector():
919 listener_ready.wait()
920 s = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000921 s.connect((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000922 listener_gone.wait()
923 try:
924 ssl_sock = ssl.wrap_socket(s)
925 except IOError:
926 pass
927 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000928 raise support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +0000929 'connecting to closed SSL socket should have failed')
930
931 t = threading.Thread(target=listener)
932 t.start()
933 connector()
934 t.join()
935
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000936 def testProtocolSSL2(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000937 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000938 sys.stdout.write("\n")
939 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
940 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
941 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
942 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
943 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
944 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
945
946 def testProtocolSSL23(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000947 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000948 sys.stdout.write("\n")
949 try:
950 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000951 except support.TestFailed as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000952 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000953 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000954 sys.stdout.write(
955 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
956 % str(x))
957 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
958 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
959 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
960
961 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
962 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
963 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
964
965 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
966 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
967 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
968
969 def testProtocolSSL3(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000970 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000971 sys.stdout.write("\n")
972 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
973 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
974 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
975 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
976 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
977 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
978
979 def testProtocolTLS1(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000980 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000981 sys.stdout.write("\n")
982 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
983 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
984 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
985 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
986 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
987 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
988
989 def testSTARTTLS (self):
990
Bill Janssen40a0f662008-08-12 16:56:25 +0000991 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000992
Trent Nelson78520002008-04-10 20:54:35 +0000993 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000994 ssl_version=ssl.PROTOCOL_TLSv1,
995 starttls_server=True,
996 chatty=True,
997 connectionchatty=True)
998 flag = threading.Event()
999 server.start(flag)
1000 # wait for it to start
1001 flag.wait()
1002 # try to connect
1003 wrapped = False
1004 try:
1005 try:
1006 s = socket.socket()
1007 s.setblocking(1)
Trent Nelson78520002008-04-10 20:54:35 +00001008 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001009 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001010 raise support.TestFailed("Unexpected exception: " + str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001011 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001012 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001013 sys.stdout.write("\n")
1014 for indata in msgs:
Bill Janssen6e027db2007-11-15 22:23:56 +00001015 msg = indata.encode('ASCII', 'replace')
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001016 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001017 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +00001018 " client: sending %s...\n" % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001019 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +00001020 conn.write(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001021 outdata = conn.read()
1022 else:
Bill Janssen6e027db2007-11-15 22:23:56 +00001023 s.send(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001024 outdata = s.recv(1024)
1025 if (indata == "STARTTLS" and
Bill Janssen6e027db2007-11-15 22:23:56 +00001026 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001027 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001028 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001029 sys.stdout.write(
1030 " client: read %s from server, starting TLS...\n"
Bill Janssen6e027db2007-11-15 22:23:56 +00001031 % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001032 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001033 wrapped = True
Bill Janssen40a0f662008-08-12 16:56:25 +00001034 elif (indata == "ENDTLS" and
1035 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
1036 if support.verbose:
1037 msg = str(outdata, 'ASCII', 'replace')
1038 sys.stdout.write(
1039 " client: read %s from server, ending TLS...\n"
1040 % repr(msg))
1041 s = conn.unwrap()
1042 wrapped = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001043 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001044 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001045 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001046 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +00001047 " client: read %s from server\n" % repr(msg))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001048 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001049 sys.stdout.write(" client: closing connection.\n")
1050 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +00001051 conn.write("over\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001052 else:
Bill Janssen40a0f662008-08-12 16:56:25 +00001053 s.send("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +00001054 if wrapped:
1055 conn.close()
1056 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001057 s.close()
1058 finally:
1059 server.stop()
1060 server.join()
1061
Bill Janssen54cc54c2007-12-14 22:08:56 +00001062 def testSocketServer(self):
Bill Janssen6e027db2007-11-15 22:23:56 +00001063
Trent Nelson78520002008-04-10 20:54:35 +00001064 server = OurHTTPSServer(CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001065 flag = threading.Event()
1066 server.start(flag)
1067 # wait for it to start
1068 flag.wait()
1069 # try to connect
1070 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001071 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001072 sys.stdout.write('\n')
1073 d1 = open(CERTFILE, 'rb').read()
1074 d2 = ''
1075 # now fetch the same data from the HTTPS server
Trent Nelson78520002008-04-10 20:54:35 +00001076 url = 'https://%s:%d/%s' % (
1077 HOST, server.port, os.path.split(CERTFILE)[1])
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001078 f = urllib.request.urlopen(url)
Barry Warsaw820c1202008-06-12 04:06:45 +00001079 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001080 if dlen and (int(dlen) > 0):
1081 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001082 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001083 sys.stdout.write(
1084 " client: read %d bytes from remote server '%s'\n"
1085 % (len(d2), server))
1086 f.close()
1087 except:
1088 msg = ''.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001089 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001090 sys.stdout.write('\n' + msg)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001091 raise support.TestFailed(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001092 else:
1093 if not (d1 == d2):
Bill Janssen6e027db2007-11-15 22:23:56 +00001094 print("d1 is", len(d1), repr(d1))
1095 print("d2 is", len(d2), repr(d2))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001096 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001097 "Couldn't fetch data from HTTPS server")
1098 finally:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001099 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001100 sys.stdout.write('stopping server\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001101 server.stop()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001102 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001103 sys.stdout.write('joining thread\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001104 server.join()
1105
Trent Nelson6b240cd2008-04-10 20:12:06 +00001106 def testAsyncoreServer(self):
1107
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001108 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001109 sys.stdout.write("\n")
1110
1111 indata="FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001112 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001113 flag = threading.Event()
1114 server.start(flag)
1115 # wait for it to start
1116 flag.wait()
1117 # try to connect
1118 try:
1119 s = ssl.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001120 s.connect((HOST, server.port))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001121 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001122 raise support.TestFailed("Unexpected SSL error: " + str(x))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001123 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001124 raise support.TestFailed("Unexpected exception: " + str(x))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001125 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001126 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001127 sys.stdout.write(
1128 " client: sending %s...\n" % (repr(indata)))
1129 s.sendall(indata.encode('ASCII', 'strict'))
1130 outdata = s.recv()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001131 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001132 sys.stdout.write(" client: read %s\n" % repr(outdata))
1133 outdata = str(outdata, 'ASCII', 'strict')
1134 if outdata != indata.lower():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001135 raise support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +00001136 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1137 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
1138 repr(indata[:min(len(indata),20)].lower()), len(indata)))
1139 s.write("over\n".encode("ASCII", "strict"))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001140 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001141 sys.stdout.write(" client: closing connection.\n")
1142 s.close()
1143 finally:
1144 server.stop()
1145 server.join()
1146
Bill Janssen58afe4c2008-09-08 16:45:19 +00001147 def testAllRecvAndSendMethods(self):
1148
1149 if support.verbose:
1150 sys.stdout.write("\n")
1151
1152 server = ThreadedEchoServer(CERTFILE,
1153 certreqs=ssl.CERT_NONE,
1154 ssl_version=ssl.PROTOCOL_TLSv1,
1155 cacerts=CERTFILE,
1156 chatty=True,
1157 connectionchatty=False)
1158 flag = threading.Event()
1159 server.start(flag)
1160 # wait for it to start
1161 flag.wait()
1162 # try to connect
1163 try:
1164 s = ssl.wrap_socket(socket.socket(),
1165 server_side=False,
1166 certfile=CERTFILE,
1167 ca_certs=CERTFILE,
1168 cert_reqs=ssl.CERT_NONE,
1169 ssl_version=ssl.PROTOCOL_TLSv1)
1170 s.connect((HOST, server.port))
1171 except ssl.SSLError as x:
Georg Brandl89fad142010-03-14 10:23:39 +00001172 self.fail("Unexpected SSL error: " + str(x))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001173 except Exception as x:
Georg Brandl89fad142010-03-14 10:23:39 +00001174 self.fail("Unexpected exception: " + str(x))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001175 else:
1176 # helper methods for standardising recv* method signatures
1177 def _recv_into():
1178 b = bytearray(b"\0"*100)
1179 count = s.recv_into(b)
1180 return b[:count]
1181
1182 def _recvfrom_into():
1183 b = bytearray(b"\0"*100)
1184 count, addr = s.recvfrom_into(b)
1185 return b[:count]
1186
1187 # (name, method, whether to expect success, *args)
1188 send_methods = [
1189 ('send', s.send, True, []),
1190 ('sendto', s.sendto, False, ["some.address"]),
1191 ('sendall', s.sendall, True, []),
1192 ]
1193 recv_methods = [
1194 ('recv', s.recv, True, []),
1195 ('recvfrom', s.recvfrom, False, ["some.address"]),
1196 ('recv_into', _recv_into, True, []),
1197 ('recvfrom_into', _recvfrom_into, False, []),
1198 ]
1199 data_prefix = "PREFIX_"
1200
1201 for meth_name, send_meth, expect_success, args in send_methods:
1202 indata = data_prefix + meth_name
1203 try:
1204 send_meth(indata.encode('ASCII', 'strict'), *args)
1205 outdata = s.read()
1206 outdata = str(outdata, 'ASCII', 'strict')
1207 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001208 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001209 "While sending with <<{name:s}>> bad data "
1210 "<<{outdata:s}>> ({nout:d}) received; "
1211 "expected <<{indata:s}>> ({nin:d})\n".format(
1212 name=meth_name, outdata=repr(outdata[:20]),
1213 nout=len(outdata),
1214 indata=repr(indata[:20]), nin=len(indata)
1215 )
1216 )
1217 except ValueError as e:
1218 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001219 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001220 "Failed to send with method <<{name:s}>>; "
1221 "expected to succeed.\n".format(name=meth_name)
1222 )
1223 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001224 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001225 "Method <<{name:s}>> failed with unexpected "
1226 "exception message: {exp:s}\n".format(
1227 name=meth_name, exp=e
1228 )
1229 )
1230
1231 for meth_name, recv_meth, expect_success, args in recv_methods:
1232 indata = data_prefix + meth_name
1233 try:
1234 s.send(indata.encode('ASCII', 'strict'))
1235 outdata = recv_meth(*args)
1236 outdata = str(outdata, 'ASCII', 'strict')
1237 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001238 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001239 "While receiving with <<{name:s}>> bad data "
1240 "<<{outdata:s}>> ({nout:d}) received; "
1241 "expected <<{indata:s}>> ({nin:d})\n".format(
1242 name=meth_name, outdata=repr(outdata[:20]),
1243 nout=len(outdata),
1244 indata=repr(indata[:20]), nin=len(indata)
1245 )
1246 )
1247 except ValueError as e:
1248 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001249 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001250 "Failed to receive with method <<{name:s}>>; "
1251 "expected to succeed.\n".format(name=meth_name)
1252 )
1253 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001254 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001255 "Method <<{name:s}>> failed with unexpected "
1256 "exception message: {exp:s}\n".format(
1257 name=meth_name, exp=e
1258 )
1259 )
1260 # consume data
1261 s.read()
1262
1263 s.write("over\n".encode("ASCII", "strict"))
1264 s.close()
1265 finally:
1266 server.stop()
1267 server.join()
1268
1269
Thomas Woutersed03b412007-08-28 21:37:11 +00001270def test_main(verbose=False):
1271 if skip_expected:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001272 raise unittest.SkipTest("No SSL support")
Thomas Woutersed03b412007-08-28 21:37:11 +00001273
Trent Nelson78520002008-04-10 20:54:35 +00001274 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Thomas Woutersed03b412007-08-28 21:37:11 +00001275 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
1276 "keycert.pem")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001277 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1278 os.path.dirname(__file__) or os.curdir,
1279 "https_svn_python_org_root.pem")
1280
1281 if (not os.path.exists(CERTFILE) or
1282 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001283 raise support.TestFailed("Can't read certificate files!")
Bill Janssen6e027db2007-11-15 22:23:56 +00001284
Thomas Woutersed03b412007-08-28 21:37:11 +00001285 tests = [BasicTests]
1286
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001287 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001288 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001289
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001290 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001291 thread_info = support.threading_setup()
1292 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001293 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001294
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001295 support.run_unittest(*tests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001296
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001297 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001298 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001299
1300if __name__ == "__main__":
1301 test_main()