blob: 520f440d2ab7e6830ed800b30e9e8cc43d3b8d93 [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
5from test import test_support
6import 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
11import os
12import pprint
Thomas Wouters1b7f8912007-09-19 03:06:30 +000013import urllib, urlparse
Thomas Woutersed03b412007-08-28 21:37:11 +000014import shutil
15import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000016import asyncore
Thomas Woutersed03b412007-08-28 21:37:11 +000017
Thomas Wouters1b7f8912007-09-19 03:06:30 +000018from BaseHTTPServer import HTTPServer
19from SimpleHTTPServer import SimpleHTTPRequestHandler
20
Thomas Woutersed03b412007-08-28 21:37:11 +000021# Optionally test SSL support, if we have it in the tested platform
22skip_expected = False
23try:
24 import ssl
25except ImportError:
26 skip_expected = True
27
28CERTFILE = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +000029SVN_PYTHON_ORG_ROOT_CERT = None
Thomas Woutersed03b412007-08-28 21:37:11 +000030
Thomas Wouters1b7f8912007-09-19 03:06:30 +000031TESTPORT = 10025
Thomas Woutersed03b412007-08-28 21:37:11 +000032
33def handle_error(prefix):
34 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Thomas Wouters1b7f8912007-09-19 03:06:30 +000035 if test_support.verbose:
36 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000037
38
39class BasicTests(unittest.TestCase):
40
Georg Brandlfceab5a2008-01-19 20:08:23 +000041 def testSSLconnect(self):
42 if not test_support.is_resource_enabled('network'):
43 return
44 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
45 cert_reqs=ssl.CERT_NONE)
46 s.connect(("svn.python.org", 443))
47 c = s.getpeercert()
48 if c:
49 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
50 s.close()
51
52 # this should fail because we have no verification certs
53 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
54 cert_reqs=ssl.CERT_REQUIRED)
55 try:
56 s.connect(("svn.python.org", 443))
57 except ssl.SSLError:
58 pass
59 finally:
60 s.close()
61
Thomas Wouters1b7f8912007-09-19 03:06:30 +000062 def testCrucialConstants(self):
63 ssl.PROTOCOL_SSLv2
64 ssl.PROTOCOL_SSLv23
65 ssl.PROTOCOL_SSLv3
66 ssl.PROTOCOL_TLSv1
67 ssl.CERT_NONE
68 ssl.CERT_OPTIONAL
69 ssl.CERT_REQUIRED
Thomas Woutersed03b412007-08-28 21:37:11 +000070
Thomas Wouters1b7f8912007-09-19 03:06:30 +000071 def testRAND(self):
72 v = ssl.RAND_status()
73 if test_support.verbose:
74 sys.stdout.write("\n RAND_status is %d (%s)\n"
75 % (v, (v and "sufficient randomness") or
76 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +000077 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000078 ssl.RAND_egd(1)
79 except TypeError:
80 pass
Thomas Woutersed03b412007-08-28 21:37:11 +000081 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000082 print("didn't raise TypeError")
83 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +000084
Thomas Wouters1b7f8912007-09-19 03:06:30 +000085 def testParseCert(self):
86 # note that this uses an 'unofficial' function in _ssl.c,
87 # provided solely for this test, to exercise the certificate
88 # parsing code
89 p = ssl._ssl._test_decode_cert(CERTFILE, False)
90 if test_support.verbose:
91 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +000092
Thomas Wouters1b7f8912007-09-19 03:06:30 +000093 def testDERtoPEM(self):
94
95 pem = open(SVN_PYTHON_ORG_ROOT_CERT, 'r').read()
96 d1 = ssl.PEM_cert_to_DER_cert(pem)
97 p2 = ssl.DER_cert_to_PEM_cert(d1)
98 d2 = ssl.PEM_cert_to_DER_cert(p2)
99 if (d1 != d2):
100 raise test_support.TestFailed("PEM-to-DER or DER-to-PEM translation failed")
101
Bill Janssen6e027db2007-11-15 22:23:56 +0000102class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000103
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000104 def testConnect(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000105 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
106 cert_reqs=ssl.CERT_NONE)
107 s.connect(("svn.python.org", 443))
108 c = s.getpeercert()
109 if c:
110 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
111 s.close()
112
113 # this should fail because we have no verification certs
114 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
115 cert_reqs=ssl.CERT_REQUIRED)
Thomas Woutersed03b412007-08-28 21:37:11 +0000116 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000117 s.connect(("svn.python.org", 443))
118 except ssl.SSLError:
119 pass
120 finally:
121 s.close()
122
123 # this should succeed because we specify the root cert
124 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
125 cert_reqs=ssl.CERT_REQUIRED,
126 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
127 try:
128 s.connect(("svn.python.org", 443))
129 except ssl.SSLError as x:
130 raise test_support.TestFailed("Unexpected exception %s" % x)
131 finally:
132 s.close()
133
Bill Janssen6e027db2007-11-15 22:23:56 +0000134 def testNonBlockingHandshake(self):
135 s = socket.socket(socket.AF_INET)
136 s.connect(("svn.python.org", 443))
137 s.setblocking(False)
138 s = ssl.wrap_socket(s,
139 cert_reqs=ssl.CERT_NONE,
140 do_handshake_on_connect=False)
141 count = 0
142 while True:
143 try:
144 count += 1
145 s.do_handshake()
146 break
147 except ssl.SSLError as err:
148 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
149 select.select([s], [], [])
150 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
151 select.select([], [s], [])
152 else:
153 raise
154 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000155 if test_support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000156 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000157
Bill Janssen54cc54c2007-12-14 22:08:56 +0000158 def testFetchServerCert(self):
159
160 pem = ssl.get_server_certificate(("svn.python.org", 443))
161 if not pem:
162 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
163
164 return
165
166 try:
167 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
168 except ssl.SSLError as x:
169 #should fail
170 if test_support.verbose:
171 sys.stdout.write("%s\n" % x)
172 else:
173 raise test_support.TestFailed("Got server certificate %s for svn.python.org!" % pem)
174
175 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
176 if not pem:
177 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
178 if test_support.verbose:
179 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
180
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000181
182try:
183 import threading
184except ImportError:
185 _have_threads = False
186else:
187
188 _have_threads = True
189
190 class ThreadedEchoServer(threading.Thread):
191
192 class ConnectionHandler(threading.Thread):
193
194 """A mildly complicated class, because we want it to work both
195 with and without the SSL wrapper around the socket connection, so
196 that we can test the STARTTLS functionality."""
197
Bill Janssen6e027db2007-11-15 22:23:56 +0000198 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000199 self.server = server
200 self.running = False
201 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000202 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000203 self.sock.setblocking(1)
204 self.sslconn = None
205 threading.Thread.__init__(self)
206 self.setDaemon(True)
207
208 def wrap_conn (self):
209 try:
210 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
211 certfile=self.server.certificate,
212 ssl_version=self.server.protocol,
213 ca_certs=self.server.cacerts,
214 cert_reqs=self.server.certreqs)
215 except:
216 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000217 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000218 if not self.server.expect_bad_connects:
219 # here, we want to stop the server, because this shouldn't
220 # happen in the context of our test case
221 self.running = False
222 # normally, we'd just stop here, but for the test
223 # harness, we want to stop the server
224 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000225 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000226 return False
227
228 else:
229 if self.server.certreqs == ssl.CERT_REQUIRED:
230 cert = self.sslconn.getpeercert()
231 if test_support.verbose and self.server.chatty:
232 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
233 cert_binary = self.sslconn.getpeercert(True)
234 if test_support.verbose and self.server.chatty:
235 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
236 cipher = self.sslconn.cipher()
237 if test_support.verbose and self.server.chatty:
238 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
239 return True
240
241 def read(self):
242 if self.sslconn:
243 return self.sslconn.read()
244 else:
245 return self.sock.recv(1024)
246
247 def write(self, bytes):
248 if self.sslconn:
249 return self.sslconn.write(bytes)
250 else:
251 return self.sock.send(bytes)
252
253 def close(self):
254 if self.sslconn:
255 self.sslconn.close()
256 else:
257 self.sock.close()
258
259 def run (self):
260 self.running = True
261 if not self.server.starttls_server:
262 if not self.wrap_conn():
263 return
264 while self.running:
265 try:
266 msg = self.read()
Bill Janssen6e027db2007-11-15 22:23:56 +0000267 amsg = (msg and str(msg, 'ASCII', 'strict')) or ''
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000268 if not msg:
269 # eof, so quit this handler
270 self.running = False
271 self.close()
Bill Janssen6e027db2007-11-15 22:23:56 +0000272 elif amsg.strip() == 'over':
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000273 if test_support.verbose and self.server.connectionchatty:
274 sys.stdout.write(" server: client closed connection\n")
275 self.close()
276 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000277 elif (self.server.starttls_server and
278 amsg.strip() == 'STARTTLS'):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000279 if test_support.verbose and self.server.connectionchatty:
280 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000281 self.write("OK\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000282 if not self.wrap_conn():
283 return
284 else:
285 if (test_support.verbose and
286 self.server.connectionchatty):
287 ctype = (self.sslconn and "encrypted") or "unencrypted"
288 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
289 % (repr(msg), ctype, repr(msg.lower()), ctype))
Bill Janssen6e027db2007-11-15 22:23:56 +0000290 self.write(amsg.lower().encode('ASCII', 'strict'))
291 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000292 if self.server.chatty:
293 handle_error("Test server failure:\n")
294 self.close()
295 self.running = False
296 # normally, we'd just stop here, but for the test
297 # harness, we want to stop the server
298 self.server.stop()
299 except:
300 handle_error('')
301
302 def __init__(self, port, certificate, ssl_version=None,
303 certreqs=None, cacerts=None, expect_bad_connects=False,
304 chatty=True, connectionchatty=False, starttls_server=False):
305 if ssl_version is None:
306 ssl_version = ssl.PROTOCOL_TLSv1
307 if certreqs is None:
308 certreqs = ssl.CERT_NONE
309 self.certificate = certificate
310 self.protocol = ssl_version
311 self.certreqs = certreqs
312 self.cacerts = cacerts
313 self.expect_bad_connects = expect_bad_connects
314 self.chatty = chatty
315 self.connectionchatty = connectionchatty
316 self.starttls_server = starttls_server
317 self.sock = socket.socket()
318 self.flag = None
319 if hasattr(socket, 'SO_REUSEADDR'):
320 self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
321 if hasattr(socket, 'SO_REUSEPORT'):
322 self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
323 self.sock.bind(('127.0.0.1', port))
324 self.active = False
325 threading.Thread.__init__(self)
326 self.setDaemon(False)
327
328 def start (self, flag=None):
329 self.flag = flag
330 threading.Thread.start(self)
331
332 def run (self):
333 self.sock.settimeout(0.5)
334 self.sock.listen(5)
335 self.active = True
336 if self.flag:
337 # signal an event
338 self.flag.set()
339 while self.active:
340 try:
341 newconn, connaddr = self.sock.accept()
342 if test_support.verbose and self.chatty:
343 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000344 + repr(connaddr) + '\n')
345 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000346 handler.start()
347 except socket.timeout:
348 pass
349 except KeyboardInterrupt:
350 self.stop()
351 except:
352 if self.chatty:
353 handle_error("Test server failure:\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000354 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000355
356 def stop (self):
357 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000358
Bill Janssen54cc54c2007-12-14 22:08:56 +0000359 class OurHTTPSServer(threading.Thread):
360
361 # This one's based on HTTPServer, which is based on SocketServer
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000362
363 class HTTPSServer(HTTPServer):
364
365 def __init__(self, server_address, RequestHandlerClass, certfile):
366
367 HTTPServer.__init__(self, server_address, RequestHandlerClass)
368 # we assume the certfile contains both private key and certificate
369 self.certfile = certfile
370 self.active = False
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000371 self.active_lock = threading.Lock()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000372 self.allow_reuse_address = True
373
Bill Janssen6e027db2007-11-15 22:23:56 +0000374 def __str__(self):
375 return ('<%s %s:%s>' %
376 (self.__class__.__name__,
377 self.server_name,
378 self.server_port))
379
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000380 def get_request (self):
381 # override this to wrap socket with SSL
382 sock, addr = self.socket.accept()
383 sslconn = ssl.wrap_socket(sock, server_side=True,
384 certfile=self.certfile)
385 return sslconn, addr
386
387 # The methods overridden below this are mainly so that we
388 # can run it in a thread and be able to stop it from another
389 # You probably wouldn't need them in other uses.
390
391 def server_activate(self):
392 # We want to run this in a thread for testing purposes,
393 # so we override this to set timeout, so that we get
394 # a chance to stop the server
395 self.socket.settimeout(0.5)
396 HTTPServer.server_activate(self)
397
398 def serve_forever(self):
399 # We want this to run in a thread, so we use a slightly
400 # modified version of "forever".
401 self.active = True
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000402 while 1:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000403 try:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000404 # We need to lock while handling the request.
405 # Another thread can close the socket after self.active
406 # has been checked and before the request is handled.
407 # This causes an exception when using the closed socket.
408 with self.active_lock:
409 if not self.active:
410 break
411 self.handle_request()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000412 except socket.timeout:
413 pass
414 except KeyboardInterrupt:
415 self.server_close()
416 return
417 except:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000418 sys.stdout.write(''.join(traceback.format_exception(*sys.exc_info())))
419 break
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000420 time.sleep(0.1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000421
422 def server_close(self):
423 # Again, we want this to run in a thread, so we need to override
424 # close to clear the "active" flag, so that serve_forever() will
425 # terminate.
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000426 with self.active_lock:
427 HTTPServer.server_close(self)
428 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000429
430 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
431
432 # need to override translate_path to get a known root,
433 # instead of using os.curdir, since the test could be
434 # run from anywhere
435
436 server_version = "TestHTTPS/1.0"
437
438 root = None
439
440 def translate_path(self, path):
441 """Translate a /-separated PATH to the local filename syntax.
442
443 Components that mean special things to the local file system
444 (e.g. drive or directory names) are ignored. (XXX They should
445 probably be diagnosed.)
446
447 """
448 # abandon query parameters
449 path = urlparse.urlparse(path)[2]
450 path = os.path.normpath(urllib.unquote(path))
451 words = path.split('/')
452 words = filter(None, words)
453 path = self.root
454 for word in words:
455 drive, word = os.path.splitdrive(word)
456 head, word = os.path.split(word)
457 if word in self.root: continue
458 path = os.path.join(path, word)
459 return path
460
461 def log_message(self, format, *args):
462
463 # we override this to suppress logging unless "verbose"
464
Thomas Wouters89d996e2007-09-08 17:39:28 +0000465 if test_support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000466 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
467 (self.server.server_address,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000468 self.server.server_port,
469 self.request.cipher(),
470 self.log_date_time_string(),
471 format%args))
Thomas Woutersed03b412007-08-28 21:37:11 +0000472
473
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000474 def __init__(self, port, certfile):
475 self.flag = None
476 self.active = False
477 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
478 self.server = self.HTTPSServer(
479 ('', port), self.RootedHTTPRequestHandler, certfile)
Thomas Woutersed03b412007-08-28 21:37:11 +0000480 threading.Thread.__init__(self)
481 self.setDaemon(True)
482
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000483 def __str__(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000484 return "<%s %s>" % (self.__class__.__name__, self.server)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000485
486 def start (self, flag=None):
487 self.flag = flag
488 threading.Thread.start(self)
489
Thomas Woutersed03b412007-08-28 21:37:11 +0000490 def run (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000491 self.active = True
492 if self.flag:
493 self.flag.set()
494 self.server.serve_forever()
495 self.active = False
496
497 def stop (self):
498 self.active = False
499 self.server.server_close()
500
501
Bill Janssen54cc54c2007-12-14 22:08:56 +0000502 class AsyncoreEchoServer(threading.Thread):
503
504 # this one's based on asyncore.dispatcher
505
506 class EchoServer (asyncore.dispatcher):
507
508 class ConnectionHandler (asyncore.dispatcher_with_send):
509
510 def __init__(self, conn, certfile):
511 self.socket = ssl.wrap_socket(conn, server_side=True,
512 certfile=certfile,
513 do_handshake_on_connect=False)
514 asyncore.dispatcher_with_send.__init__(self, self.socket)
515 # now we have to do the handshake
516 # we'll just do it the easy way, and block the connection
517 # till it's finished. If we were doing it right, we'd
518 # do this in multiple calls to handle_read...
519 self.do_handshake(block=True)
520
521 def readable(self):
522 if isinstance(self.socket, ssl.SSLSocket):
523 while self.socket.pending() > 0:
524 self.handle_read_event()
525 return True
526
527 def handle_read(self):
528 data = self.recv(1024)
529 if test_support.verbose:
530 sys.stdout.write(" server: read %s from client\n" % repr(data))
531 if not data:
532 self.close()
533 else:
534 self.send(str(data, 'ASCII', 'strict').lower().encode('ASCII', 'strict'))
535
536 def handle_close(self):
537 if test_support.verbose:
538 sys.stdout.write(" server: closed connection %s\n" % self.socket)
539
540 def handle_error(self):
541 raise
542
543 def __init__(self, port, certfile):
544 self.port = port
545 self.certfile = certfile
546 asyncore.dispatcher.__init__(self)
547 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
548 self.bind(('', port))
549 self.listen(5)
550
551 def handle_accept(self):
552 sock_obj, addr = self.accept()
553 if test_support.verbose:
554 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
555 self.ConnectionHandler(sock_obj, self.certfile)
556
557 def handle_error(self):
558 raise
559
560 def __init__(self, port, certfile):
561 self.flag = None
562 self.active = False
563 self.server = self.EchoServer(port, certfile)
564 threading.Thread.__init__(self)
565 self.setDaemon(True)
566
567 def __str__(self):
568 return "<%s %s>" % (self.__class__.__name__, self.server)
569
570 def start (self, flag=None):
571 self.flag = flag
572 threading.Thread.start(self)
573
574 def run (self):
575 self.active = True
576 if self.flag:
577 self.flag.set()
578 while self.active:
579 try:
580 asyncore.loop(1)
581 except:
582 pass
583
584 def stop (self):
585 self.active = False
586 self.server.close()
587
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000588 def badCertTest (certfile):
589 server = ThreadedEchoServer(TESTPORT, CERTFILE,
590 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000591 cacerts=CERTFILE, chatty=False,
592 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000593 flag = threading.Event()
594 server.start(flag)
595 # wait for it to start
596 flag.wait()
597 # try to connect
598 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000599 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000600 s = ssl.wrap_socket(socket.socket(),
601 certfile=certfile,
602 ssl_version=ssl.PROTOCOL_TLSv1)
603 s.connect(('127.0.0.1', TESTPORT))
604 except ssl.SSLError as x:
Thomas Woutersed03b412007-08-28 21:37:11 +0000605 if test_support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000606 sys.stdout.write("\nSSLError is %s\n" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000607 else:
608 raise test_support.TestFailed(
609 "Use of invalid cert should have failed!")
610 finally:
611 server.stop()
612 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000613
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000614 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
Bill Janssen6e027db2007-11-15 22:23:56 +0000615 client_certfile, client_protocol=None,
616 indata="FOO\n",
617 chatty=False, connectionchatty=False):
Thomas Woutersed03b412007-08-28 21:37:11 +0000618
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000619 server = ThreadedEchoServer(TESTPORT, certfile,
620 certreqs=certreqs,
621 ssl_version=protocol,
622 cacerts=cacertsfile,
623 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000624 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000625 flag = threading.Event()
626 server.start(flag)
627 # wait for it to start
628 flag.wait()
629 # try to connect
630 if client_protocol is None:
631 client_protocol = protocol
632 try:
Bill Janssen6e027db2007-11-15 22:23:56 +0000633 s = ssl.wrap_socket(socket.socket(),
Bill Janssen54cc54c2007-12-14 22:08:56 +0000634 server_side=False,
Bill Janssen6e027db2007-11-15 22:23:56 +0000635 certfile=client_certfile,
636 ca_certs=cacertsfile,
637 cert_reqs=certreqs,
638 ssl_version=client_protocol)
639 s.connect(('127.0.0.1', TESTPORT))
640 except ssl.SSLError as x:
641 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
642 except Exception as x:
643 raise test_support.TestFailed("Unexpected exception: " + str(x))
644 else:
645 if connectionchatty:
646 if test_support.verbose:
647 sys.stdout.write(
648 " client: sending %s...\n" % (repr(indata)))
649 s.write(indata.encode('ASCII', 'strict'))
650 outdata = s.read()
651 if connectionchatty:
652 if test_support.verbose:
653 sys.stdout.write(" client: read %s\n" % repr(outdata))
654 outdata = str(outdata, 'ASCII', 'strict')
655 if outdata != indata.lower():
656 raise test_support.TestFailed(
657 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
658 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
659 repr(indata[:min(len(indata),20)].lower()), len(indata)))
660 s.write("over\n".encode("ASCII", "strict"))
661 if connectionchatty:
662 if test_support.verbose:
663 sys.stdout.write(" client: closing connection.\n")
664 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000665 finally:
666 server.stop()
667 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000668
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000669 def tryProtocolCombo (server_protocol,
670 client_protocol,
671 expectedToWork,
672 certsreqs=None):
Thomas Woutersed03b412007-08-28 21:37:11 +0000673
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000674 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000675 certsreqs = ssl.CERT_NONE
Thomas Woutersed03b412007-08-28 21:37:11 +0000676
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000677 if certsreqs == ssl.CERT_NONE:
678 certtype = "CERT_NONE"
679 elif certsreqs == ssl.CERT_OPTIONAL:
680 certtype = "CERT_OPTIONAL"
681 elif certsreqs == ssl.CERT_REQUIRED:
682 certtype = "CERT_REQUIRED"
Thomas Woutersed03b412007-08-28 21:37:11 +0000683 if test_support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000684 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
685 sys.stdout.write(formatstr %
686 (ssl.get_protocol_name(client_protocol),
687 ssl.get_protocol_name(server_protocol),
688 certtype))
689 try:
690 serverParamsTest(CERTFILE, server_protocol, certsreqs,
Bill Janssen6e027db2007-11-15 22:23:56 +0000691 CERTFILE, CERTFILE, client_protocol,
692 chatty=False, connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000693 except test_support.TestFailed:
694 if expectedToWork:
695 raise
696 else:
697 if not expectedToWork:
698 raise test_support.TestFailed(
699 "Client protocol %s succeeded with server protocol %s!"
700 % (ssl.get_protocol_name(client_protocol),
701 ssl.get_protocol_name(server_protocol)))
702
703
Bill Janssen6e027db2007-11-15 22:23:56 +0000704 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000705
706 def testEcho (self):
707
708 if test_support.verbose:
709 sys.stdout.write("\n")
710 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
711 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
712 chatty=True, connectionchatty=True)
713
714 def testReadCert(self):
715
716 if test_support.verbose:
717 sys.stdout.write("\n")
718 s2 = socket.socket()
719 server = ThreadedEchoServer(TESTPORT, CERTFILE,
720 certreqs=ssl.CERT_NONE,
721 ssl_version=ssl.PROTOCOL_SSLv23,
722 cacerts=CERTFILE,
723 chatty=False)
724 flag = threading.Event()
725 server.start(flag)
726 # wait for it to start
727 flag.wait()
728 # try to connect
729 try:
730 try:
731 s = ssl.wrap_socket(socket.socket(),
732 certfile=CERTFILE,
733 ca_certs=CERTFILE,
734 cert_reqs=ssl.CERT_REQUIRED,
735 ssl_version=ssl.PROTOCOL_SSLv23)
736 s.connect(('127.0.0.1', TESTPORT))
737 except ssl.SSLError as x:
738 raise test_support.TestFailed(
739 "Unexpected SSL error: " + str(x))
740 except Exception as x:
741 raise test_support.TestFailed(
742 "Unexpected exception: " + str(x))
743 else:
744 if not s:
745 raise test_support.TestFailed(
746 "Can't SSL-handshake with test server")
747 cert = s.getpeercert()
748 if not cert:
749 raise test_support.TestFailed(
750 "Can't get peer certificate.")
751 cipher = s.cipher()
752 if test_support.verbose:
753 sys.stdout.write(pprint.pformat(cert) + '\n')
754 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
Bill Janssen6e027db2007-11-15 22:23:56 +0000755 if 'subject' not in cert:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000756 raise test_support.TestFailed(
757 "No subject field in certificate: %s." %
758 pprint.pformat(cert))
759 if ((('organizationName', 'Python Software Foundation'),)
760 not in cert['subject']):
761 raise test_support.TestFailed(
762 "Missing or invalid 'organizationName' field in certificate subject; "
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000763 "should be 'Python Software Foundation'.")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000764 s.close()
765 finally:
766 server.stop()
767 server.join()
768
769 def testNULLcert(self):
770 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
771 "nullcert.pem"))
772 def testMalformedCert(self):
773 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
774 "badcert.pem"))
775 def testMalformedKey(self):
776 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
777 "badkey.pem"))
778
Bill Janssen6e027db2007-11-15 22:23:56 +0000779 def testRudeShutdown(self):
780
781 listener_ready = threading.Event()
782 listener_gone = threading.Event()
783
784 # `listener` runs in a thread. It opens a socket listening on
785 # PORT, and sits in an accept() until the main thread connects.
786 # Then it rudely closes the socket, and sets Event `listener_gone`
787 # to let the main thread know the socket is gone.
788 def listener():
789 s = socket.socket()
790 if hasattr(socket, 'SO_REUSEADDR'):
791 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
792 if hasattr(socket, 'SO_REUSEPORT'):
793 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
794 s.bind(('127.0.0.1', TESTPORT))
795 s.listen(5)
796 listener_ready.set()
797 s.accept()
798 s = None # reclaim the socket object, which also closes it
799 listener_gone.set()
800
801 def connector():
802 listener_ready.wait()
803 s = socket.socket()
804 s.connect(('127.0.0.1', TESTPORT))
805 listener_gone.wait()
806 try:
807 ssl_sock = ssl.wrap_socket(s)
808 except IOError:
809 pass
810 else:
811 raise test_support.TestFailed(
812 'connecting to closed SSL socket should have failed')
813
814 t = threading.Thread(target=listener)
815 t.start()
816 connector()
817 t.join()
818
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000819 def testProtocolSSL2(self):
820 if test_support.verbose:
821 sys.stdout.write("\n")
822 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
823 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
824 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
825 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
826 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
827 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
828
829 def testProtocolSSL23(self):
830 if test_support.verbose:
831 sys.stdout.write("\n")
832 try:
833 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
834 except test_support.TestFailed as x:
835 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
836 if test_support.verbose:
837 sys.stdout.write(
838 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
839 % str(x))
840 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
841 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
842 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
843
844 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
845 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
846 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
847
848 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
849 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
850 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
851
852 def testProtocolSSL3(self):
853 if test_support.verbose:
854 sys.stdout.write("\n")
855 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
856 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
857 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
858 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
859 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
860 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
861
862 def testProtocolTLS1(self):
863 if test_support.verbose:
864 sys.stdout.write("\n")
865 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
866 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
867 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
868 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
869 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
870 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
871
872 def testSTARTTLS (self):
873
874 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4")
875
876 server = ThreadedEchoServer(TESTPORT, CERTFILE,
877 ssl_version=ssl.PROTOCOL_TLSv1,
878 starttls_server=True,
879 chatty=True,
880 connectionchatty=True)
881 flag = threading.Event()
882 server.start(flag)
883 # wait for it to start
884 flag.wait()
885 # try to connect
886 wrapped = False
887 try:
888 try:
889 s = socket.socket()
890 s.setblocking(1)
891 s.connect(('127.0.0.1', TESTPORT))
892 except Exception as x:
893 raise test_support.TestFailed("Unexpected exception: " + str(x))
894 else:
895 if test_support.verbose:
896 sys.stdout.write("\n")
897 for indata in msgs:
Bill Janssen6e027db2007-11-15 22:23:56 +0000898 msg = indata.encode('ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000899 if test_support.verbose:
900 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +0000901 " client: sending %s...\n" % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000902 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +0000903 conn.write(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000904 outdata = conn.read()
905 else:
Bill Janssen6e027db2007-11-15 22:23:56 +0000906 s.send(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000907 outdata = s.recv(1024)
908 if (indata == "STARTTLS" and
Bill Janssen6e027db2007-11-15 22:23:56 +0000909 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000910 if test_support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000911 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000912 sys.stdout.write(
913 " client: read %s from server, starting TLS...\n"
Bill Janssen6e027db2007-11-15 22:23:56 +0000914 % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000915 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
916
917 wrapped = True
918 else:
919 if test_support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000920 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000921 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +0000922 " client: read %s from server\n" % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000923 if test_support.verbose:
924 sys.stdout.write(" client: closing connection.\n")
925 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +0000926 conn.write("over\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000927 else:
928 s.send("over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000929 if wrapped:
930 conn.close()
931 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000932 s.close()
933 finally:
934 server.stop()
935 server.join()
936
Bill Janssen54cc54c2007-12-14 22:08:56 +0000937 def testSocketServer(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000938
Bill Janssen54cc54c2007-12-14 22:08:56 +0000939 server = OurHTTPSServer(TESTPORT, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000940 flag = threading.Event()
941 server.start(flag)
942 # wait for it to start
943 flag.wait()
944 # try to connect
945 try:
946 if test_support.verbose:
947 sys.stdout.write('\n')
948 d1 = open(CERTFILE, 'rb').read()
949 d2 = ''
950 # now fetch the same data from the HTTPS server
951 url = 'https://127.0.0.1:%d/%s' % (
952 TESTPORT, os.path.split(CERTFILE)[1])
953 f = urllib.urlopen(url)
954 dlen = f.info().getheader("content-length")
955 if dlen and (int(dlen) > 0):
956 d2 = f.read(int(dlen))
957 if test_support.verbose:
958 sys.stdout.write(
959 " client: read %d bytes from remote server '%s'\n"
960 % (len(d2), server))
961 f.close()
962 except:
963 msg = ''.join(traceback.format_exception(*sys.exc_info()))
964 if test_support.verbose:
965 sys.stdout.write('\n' + msg)
966 raise test_support.TestFailed(msg)
967 else:
968 if not (d1 == d2):
Bill Janssen6e027db2007-11-15 22:23:56 +0000969 print("d1 is", len(d1), repr(d1))
970 print("d2 is", len(d2), repr(d2))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000971 raise test_support.TestFailed(
972 "Couldn't fetch data from HTTPS server")
973 finally:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000974 if test_support.verbose:
975 sys.stdout.write('stopping server\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000976 server.stop()
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000977 if test_support.verbose:
978 sys.stdout.write('joining thread\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000979 server.join()
980
Bill Janssen54cc54c2007-12-14 22:08:56 +0000981 def testAsyncoreServer(self):
982
983 if test_support.verbose:
984 sys.stdout.write("\n")
985
986 indata="FOO\n"
987 server = AsyncoreEchoServer(TESTPORT, CERTFILE)
988 flag = threading.Event()
989 server.start(flag)
990 # wait for it to start
991 flag.wait()
992 # try to connect
993 try:
994 s = ssl.wrap_socket(socket.socket())
995 s.connect(('127.0.0.1', TESTPORT))
996 except ssl.SSLError as x:
997 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
998 except Exception as x:
999 raise test_support.TestFailed("Unexpected exception: " + str(x))
1000 else:
1001 if test_support.verbose:
1002 sys.stdout.write(
1003 " client: sending %s...\n" % (repr(indata)))
1004 s.sendall(indata.encode('ASCII', 'strict'))
1005 outdata = s.recv()
1006 if test_support.verbose:
1007 sys.stdout.write(" client: read %s\n" % repr(outdata))
1008 outdata = str(outdata, 'ASCII', 'strict')
1009 if outdata != indata.lower():
1010 raise test_support.TestFailed(
1011 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1012 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
1013 repr(indata[:min(len(indata),20)].lower()), len(indata)))
1014 s.write("over\n".encode("ASCII", "strict"))
1015 if test_support.verbose:
1016 sys.stdout.write(" client: closing connection.\n")
1017 s.close()
1018 finally:
1019 server.stop()
1020 server.join()
1021
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001022
1023def findtestsocket(start, end):
1024 def testbind(i):
1025 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1026 try:
1027 s.bind(("127.0.0.1", i))
1028 except:
1029 return 0
1030 else:
1031 return 1
1032 finally:
1033 s.close()
1034
1035 for i in range(start, end):
1036 if testbind(i) and testbind(i+1):
1037 return i
1038 return 0
Thomas Woutersed03b412007-08-28 21:37:11 +00001039
1040
1041def test_main(verbose=False):
1042 if skip_expected:
Thomas Wouters89d996e2007-09-08 17:39:28 +00001043 raise test_support.TestSkipped("No SSL support")
Thomas Woutersed03b412007-08-28 21:37:11 +00001044
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001045 global CERTFILE, TESTPORT, SVN_PYTHON_ORG_ROOT_CERT
Thomas Woutersed03b412007-08-28 21:37:11 +00001046 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
1047 "keycert.pem")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001048 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1049 os.path.dirname(__file__) or os.curdir,
1050 "https_svn_python_org_root.pem")
1051
1052 if (not os.path.exists(CERTFILE) or
1053 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
1054 raise test_support.TestFailed("Can't read certificate files!")
Bill Janssen6e027db2007-11-15 22:23:56 +00001055
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001056 TESTPORT = findtestsocket(10025, 12000)
1057 if not TESTPORT:
1058 raise test_support.TestFailed("Can't find open port to test servers on!")
Thomas Woutersed03b412007-08-28 21:37:11 +00001059
1060 tests = [BasicTests]
1061
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001062 if test_support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001063 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001064
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001065 if _have_threads:
1066 thread_info = test_support.threading_setup()
1067 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001068 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001069
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001070 test_support.run_unittest(*tests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001071
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001072 if _have_threads:
1073 test_support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001074
1075if __name__ == "__main__":
1076 test_main()