blob: 59bf57dd4d69f5b348bebc3e81650e1e895f2b6c [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
Trent Nelson78520002008-04-10 20:54:35 +000028HOST = test_support.HOST
Thomas Woutersed03b412007-08-28 21:37:11 +000029CERTFILE = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +000030SVN_PYTHON_ORG_ROOT_CERT = None
Thomas Woutersed03b412007-08-28 21:37:11 +000031
Thomas Woutersed03b412007-08-28 21:37:11 +000032def handle_error(prefix):
33 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Thomas Wouters1b7f8912007-09-19 03:06:30 +000034 if test_support.verbose:
35 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000036
37
38class BasicTests(unittest.TestCase):
39
Georg Brandlfceab5a2008-01-19 20:08:23 +000040 def testSSLconnect(self):
41 if not test_support.is_resource_enabled('network'):
42 return
43 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
44 cert_reqs=ssl.CERT_NONE)
45 s.connect(("svn.python.org", 443))
46 c = s.getpeercert()
47 if c:
48 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
49 s.close()
50
51 # this should fail because we have no verification certs
52 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
53 cert_reqs=ssl.CERT_REQUIRED)
54 try:
55 s.connect(("svn.python.org", 443))
56 except ssl.SSLError:
57 pass
58 finally:
59 s.close()
60
Thomas Wouters1b7f8912007-09-19 03:06:30 +000061 def testCrucialConstants(self):
62 ssl.PROTOCOL_SSLv2
63 ssl.PROTOCOL_SSLv23
64 ssl.PROTOCOL_SSLv3
65 ssl.PROTOCOL_TLSv1
66 ssl.CERT_NONE
67 ssl.CERT_OPTIONAL
68 ssl.CERT_REQUIRED
Thomas Woutersed03b412007-08-28 21:37:11 +000069
Thomas Wouters1b7f8912007-09-19 03:06:30 +000070 def testRAND(self):
71 v = ssl.RAND_status()
72 if test_support.verbose:
73 sys.stdout.write("\n RAND_status is %d (%s)\n"
74 % (v, (v and "sufficient randomness") or
75 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +000076 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000077 ssl.RAND_egd(1)
78 except TypeError:
79 pass
Thomas Woutersed03b412007-08-28 21:37:11 +000080 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000081 print("didn't raise TypeError")
82 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +000083
Thomas Wouters1b7f8912007-09-19 03:06:30 +000084 def testParseCert(self):
85 # note that this uses an 'unofficial' function in _ssl.c,
86 # provided solely for this test, to exercise the certificate
87 # parsing code
88 p = ssl._ssl._test_decode_cert(CERTFILE, False)
89 if test_support.verbose:
90 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +000091
Thomas Wouters1b7f8912007-09-19 03:06:30 +000092 def testDERtoPEM(self):
93
94 pem = open(SVN_PYTHON_ORG_ROOT_CERT, 'r').read()
95 d1 = ssl.PEM_cert_to_DER_cert(pem)
96 p2 = ssl.DER_cert_to_PEM_cert(d1)
97 d2 = ssl.PEM_cert_to_DER_cert(p2)
98 if (d1 != d2):
99 raise test_support.TestFailed("PEM-to-DER or DER-to-PEM translation failed")
100
Bill Janssen6e027db2007-11-15 22:23:56 +0000101class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000102
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000103 def testConnect(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000104 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
105 cert_reqs=ssl.CERT_NONE)
106 s.connect(("svn.python.org", 443))
107 c = s.getpeercert()
108 if c:
109 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
110 s.close()
111
112 # this should fail because we have no verification certs
113 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
114 cert_reqs=ssl.CERT_REQUIRED)
Thomas Woutersed03b412007-08-28 21:37:11 +0000115 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000116 s.connect(("svn.python.org", 443))
117 except ssl.SSLError:
118 pass
119 finally:
120 s.close()
121
122 # this should succeed because we specify the root cert
123 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
124 cert_reqs=ssl.CERT_REQUIRED,
125 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
126 try:
127 s.connect(("svn.python.org", 443))
128 except ssl.SSLError as x:
129 raise test_support.TestFailed("Unexpected exception %s" % x)
130 finally:
131 s.close()
132
Bill Janssen6e027db2007-11-15 22:23:56 +0000133 def testNonBlockingHandshake(self):
134 s = socket.socket(socket.AF_INET)
135 s.connect(("svn.python.org", 443))
136 s.setblocking(False)
137 s = ssl.wrap_socket(s,
138 cert_reqs=ssl.CERT_NONE,
139 do_handshake_on_connect=False)
140 count = 0
141 while True:
142 try:
143 count += 1
144 s.do_handshake()
145 break
146 except ssl.SSLError as err:
147 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
148 select.select([s], [], [])
149 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
150 select.select([], [s], [])
151 else:
152 raise
153 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000154 if test_support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000155 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000156
Bill Janssen54cc54c2007-12-14 22:08:56 +0000157 def testFetchServerCert(self):
158
159 pem = ssl.get_server_certificate(("svn.python.org", 443))
160 if not pem:
161 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
162
163 return
164
165 try:
166 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
167 except ssl.SSLError as x:
168 #should fail
169 if test_support.verbose:
170 sys.stdout.write("%s\n" % x)
171 else:
172 raise test_support.TestFailed("Got server certificate %s for svn.python.org!" % pem)
173
174 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
175 if not pem:
176 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
177 if test_support.verbose:
178 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
179
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000180
181try:
182 import threading
183except ImportError:
184 _have_threads = False
185else:
186
187 _have_threads = True
188
189 class ThreadedEchoServer(threading.Thread):
190
191 class ConnectionHandler(threading.Thread):
192
193 """A mildly complicated class, because we want it to work both
194 with and without the SSL wrapper around the socket connection, so
195 that we can test the STARTTLS functionality."""
196
Bill Janssen6e027db2007-11-15 22:23:56 +0000197 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000198 self.server = server
199 self.running = False
200 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000201 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000202 self.sock.setblocking(1)
203 self.sslconn = None
204 threading.Thread.__init__(self)
205 self.setDaemon(True)
206
207 def wrap_conn (self):
208 try:
209 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
210 certfile=self.server.certificate,
211 ssl_version=self.server.protocol,
212 ca_certs=self.server.cacerts,
213 cert_reqs=self.server.certreqs)
214 except:
215 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000216 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000217 if not self.server.expect_bad_connects:
218 # here, we want to stop the server, because this shouldn't
219 # happen in the context of our test case
220 self.running = False
221 # normally, we'd just stop here, but for the test
222 # harness, we want to stop the server
223 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000224 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000225 return False
226
227 else:
228 if self.server.certreqs == ssl.CERT_REQUIRED:
229 cert = self.sslconn.getpeercert()
230 if test_support.verbose and self.server.chatty:
231 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
232 cert_binary = self.sslconn.getpeercert(True)
233 if test_support.verbose and self.server.chatty:
234 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
235 cipher = self.sslconn.cipher()
236 if test_support.verbose and self.server.chatty:
237 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
238 return True
239
240 def read(self):
241 if self.sslconn:
242 return self.sslconn.read()
243 else:
244 return self.sock.recv(1024)
245
246 def write(self, bytes):
247 if self.sslconn:
248 return self.sslconn.write(bytes)
249 else:
250 return self.sock.send(bytes)
251
252 def close(self):
253 if self.sslconn:
254 self.sslconn.close()
255 else:
256 self.sock.close()
257
258 def run (self):
259 self.running = True
260 if not self.server.starttls_server:
261 if not self.wrap_conn():
262 return
263 while self.running:
264 try:
265 msg = self.read()
Bill Janssen6e027db2007-11-15 22:23:56 +0000266 amsg = (msg and str(msg, 'ASCII', 'strict')) or ''
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000267 if not msg:
268 # eof, so quit this handler
269 self.running = False
270 self.close()
Bill Janssen6e027db2007-11-15 22:23:56 +0000271 elif amsg.strip() == 'over':
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000272 if test_support.verbose and self.server.connectionchatty:
273 sys.stdout.write(" server: client closed connection\n")
274 self.close()
275 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000276 elif (self.server.starttls_server and
277 amsg.strip() == 'STARTTLS'):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000278 if test_support.verbose and self.server.connectionchatty:
279 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000280 self.write("OK\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000281 if not self.wrap_conn():
282 return
283 else:
284 if (test_support.verbose and
285 self.server.connectionchatty):
286 ctype = (self.sslconn and "encrypted") or "unencrypted"
287 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
288 % (repr(msg), ctype, repr(msg.lower()), ctype))
Bill Janssen6e027db2007-11-15 22:23:56 +0000289 self.write(amsg.lower().encode('ASCII', 'strict'))
290 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000291 if self.server.chatty:
292 handle_error("Test server failure:\n")
293 self.close()
294 self.running = False
295 # normally, we'd just stop here, but for the test
296 # harness, we want to stop the server
297 self.server.stop()
298 except:
299 handle_error('')
300
Trent Nelson78520002008-04-10 20:54:35 +0000301 def __init__(self, certificate, ssl_version=None,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000302 certreqs=None, cacerts=None, expect_bad_connects=False,
303 chatty=True, connectionchatty=False, starttls_server=False):
304 if ssl_version is None:
305 ssl_version = ssl.PROTOCOL_TLSv1
306 if certreqs is None:
307 certreqs = ssl.CERT_NONE
308 self.certificate = certificate
309 self.protocol = ssl_version
310 self.certreqs = certreqs
311 self.cacerts = cacerts
312 self.expect_bad_connects = expect_bad_connects
313 self.chatty = chatty
314 self.connectionchatty = connectionchatty
315 self.starttls_server = starttls_server
316 self.sock = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000317 self.port = test_support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000318 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000319 self.active = False
320 threading.Thread.__init__(self)
321 self.setDaemon(False)
322
323 def start (self, flag=None):
324 self.flag = flag
325 threading.Thread.start(self)
326
327 def run (self):
328 self.sock.settimeout(0.5)
329 self.sock.listen(5)
330 self.active = True
331 if self.flag:
332 # signal an event
333 self.flag.set()
334 while self.active:
335 try:
336 newconn, connaddr = self.sock.accept()
337 if test_support.verbose and self.chatty:
338 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000339 + repr(connaddr) + '\n')
340 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000341 handler.start()
342 except socket.timeout:
343 pass
344 except KeyboardInterrupt:
345 self.stop()
346 except:
347 if self.chatty:
348 handle_error("Test server failure:\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000349 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000350
351 def stop (self):
352 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000353
Bill Janssen54cc54c2007-12-14 22:08:56 +0000354 class OurHTTPSServer(threading.Thread):
355
356 # This one's based on HTTPServer, which is based on SocketServer
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000357
358 class HTTPSServer(HTTPServer):
359
360 def __init__(self, server_address, RequestHandlerClass, certfile):
361
362 HTTPServer.__init__(self, server_address, RequestHandlerClass)
363 # we assume the certfile contains both private key and certificate
364 self.certfile = certfile
365 self.active = False
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000366 self.active_lock = threading.Lock()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000367 self.allow_reuse_address = True
368
Bill Janssen6e027db2007-11-15 22:23:56 +0000369 def __str__(self):
370 return ('<%s %s:%s>' %
371 (self.__class__.__name__,
372 self.server_name,
373 self.server_port))
374
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000375 def get_request (self):
376 # override this to wrap socket with SSL
377 sock, addr = self.socket.accept()
378 sslconn = ssl.wrap_socket(sock, server_side=True,
379 certfile=self.certfile)
380 return sslconn, addr
381
382 # The methods overridden below this are mainly so that we
383 # can run it in a thread and be able to stop it from another
384 # You probably wouldn't need them in other uses.
385
386 def server_activate(self):
387 # We want to run this in a thread for testing purposes,
388 # so we override this to set timeout, so that we get
389 # a chance to stop the server
390 self.socket.settimeout(0.5)
391 HTTPServer.server_activate(self)
392
393 def serve_forever(self):
394 # We want this to run in a thread, so we use a slightly
395 # modified version of "forever".
396 self.active = True
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000397 while 1:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000398 try:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000399 # We need to lock while handling the request.
400 # Another thread can close the socket after self.active
401 # has been checked and before the request is handled.
402 # This causes an exception when using the closed socket.
403 with self.active_lock:
404 if not self.active:
405 break
406 self.handle_request()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000407 except socket.timeout:
408 pass
409 except KeyboardInterrupt:
410 self.server_close()
411 return
412 except:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000413 sys.stdout.write(''.join(traceback.format_exception(*sys.exc_info())))
414 break
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000415 time.sleep(0.1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000416
417 def server_close(self):
418 # Again, we want this to run in a thread, so we need to override
419 # close to clear the "active" flag, so that serve_forever() will
420 # terminate.
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000421 with self.active_lock:
422 HTTPServer.server_close(self)
423 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000424
425 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
426
427 # need to override translate_path to get a known root,
428 # instead of using os.curdir, since the test could be
429 # run from anywhere
430
431 server_version = "TestHTTPS/1.0"
432
433 root = None
434
435 def translate_path(self, path):
436 """Translate a /-separated PATH to the local filename syntax.
437
438 Components that mean special things to the local file system
439 (e.g. drive or directory names) are ignored. (XXX They should
440 probably be diagnosed.)
441
442 """
443 # abandon query parameters
444 path = urlparse.urlparse(path)[2]
445 path = os.path.normpath(urllib.unquote(path))
446 words = path.split('/')
447 words = filter(None, words)
448 path = self.root
449 for word in words:
450 drive, word = os.path.splitdrive(word)
451 head, word = os.path.split(word)
452 if word in self.root: continue
453 path = os.path.join(path, word)
454 return path
455
456 def log_message(self, format, *args):
457
458 # we override this to suppress logging unless "verbose"
459
Thomas Wouters89d996e2007-09-08 17:39:28 +0000460 if test_support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000461 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
462 (self.server.server_address,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000463 self.server.server_port,
464 self.request.cipher(),
465 self.log_date_time_string(),
466 format%args))
Thomas Woutersed03b412007-08-28 21:37:11 +0000467
468
Trent Nelson78520002008-04-10 20:54:35 +0000469 def __init__(self, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000470 self.flag = None
471 self.active = False
472 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
Trent Nelson78520002008-04-10 20:54:35 +0000473 self.port = test_support.find_unused_port()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000474 self.server = self.HTTPSServer(
Trent Nelson78520002008-04-10 20:54:35 +0000475 (HOST, self.port), self.RootedHTTPRequestHandler, certfile)
Thomas Woutersed03b412007-08-28 21:37:11 +0000476 threading.Thread.__init__(self)
477 self.setDaemon(True)
478
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000479 def __str__(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000480 return "<%s %s>" % (self.__class__.__name__, self.server)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000481
482 def start (self, flag=None):
483 self.flag = flag
484 threading.Thread.start(self)
485
Thomas Woutersed03b412007-08-28 21:37:11 +0000486 def run (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000487 self.active = True
488 if self.flag:
489 self.flag.set()
490 self.server.serve_forever()
491 self.active = False
492
493 def stop (self):
494 self.active = False
495 self.server.server_close()
496
497
Bill Janssen54cc54c2007-12-14 22:08:56 +0000498 class AsyncoreEchoServer(threading.Thread):
499
500 # this one's based on asyncore.dispatcher
501
502 class EchoServer (asyncore.dispatcher):
503
504 class ConnectionHandler (asyncore.dispatcher_with_send):
505
506 def __init__(self, conn, certfile):
507 self.socket = ssl.wrap_socket(conn, server_side=True,
508 certfile=certfile,
509 do_handshake_on_connect=False)
510 asyncore.dispatcher_with_send.__init__(self, self.socket)
511 # now we have to do the handshake
512 # we'll just do it the easy way, and block the connection
513 # till it's finished. If we were doing it right, we'd
514 # do this in multiple calls to handle_read...
515 self.do_handshake(block=True)
516
517 def readable(self):
518 if isinstance(self.socket, ssl.SSLSocket):
519 while self.socket.pending() > 0:
520 self.handle_read_event()
521 return True
522
523 def handle_read(self):
524 data = self.recv(1024)
525 if test_support.verbose:
526 sys.stdout.write(" server: read %s from client\n" % repr(data))
527 if not data:
528 self.close()
529 else:
530 self.send(str(data, 'ASCII', 'strict').lower().encode('ASCII', 'strict'))
531
532 def handle_close(self):
533 if test_support.verbose:
534 sys.stdout.write(" server: closed connection %s\n" % self.socket)
535
536 def handle_error(self):
537 raise
538
539 def __init__(self, port, certfile):
540 self.port = port
541 self.certfile = certfile
542 asyncore.dispatcher.__init__(self)
543 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
544 self.bind(('', port))
545 self.listen(5)
546
547 def handle_accept(self):
548 sock_obj, addr = self.accept()
549 if test_support.verbose:
550 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
551 self.ConnectionHandler(sock_obj, self.certfile)
552
553 def handle_error(self):
554 raise
555
Trent Nelson78520002008-04-10 20:54:35 +0000556 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000557 self.flag = None
558 self.active = False
Trent Nelson78520002008-04-10 20:54:35 +0000559 self.port = test_support.find_unused_port()
560 self.server = self.EchoServer(self.port, certfile)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000561 threading.Thread.__init__(self)
562 self.setDaemon(True)
563
564 def __str__(self):
565 return "<%s %s>" % (self.__class__.__name__, self.server)
566
567 def start (self, flag=None):
568 self.flag = flag
569 threading.Thread.start(self)
570
571 def run (self):
572 self.active = True
573 if self.flag:
574 self.flag.set()
575 while self.active:
576 try:
577 asyncore.loop(1)
578 except:
579 pass
580
581 def stop (self):
582 self.active = False
583 self.server.close()
584
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000585 def badCertTest (certfile):
Trent Nelson78520002008-04-10 20:54:35 +0000586 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000587 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000588 cacerts=CERTFILE, chatty=False,
589 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000590 flag = threading.Event()
591 server.start(flag)
592 # wait for it to start
593 flag.wait()
594 # try to connect
595 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000596 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000597 s = ssl.wrap_socket(socket.socket(),
598 certfile=certfile,
599 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelson78520002008-04-10 20:54:35 +0000600 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000601 except ssl.SSLError as x:
Thomas Woutersed03b412007-08-28 21:37:11 +0000602 if test_support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000603 sys.stdout.write("\nSSLError is %s\n" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000604 else:
605 raise test_support.TestFailed(
606 "Use of invalid cert should have failed!")
607 finally:
608 server.stop()
609 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000610
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000611 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
Bill Janssen6e027db2007-11-15 22:23:56 +0000612 client_certfile, client_protocol=None,
613 indata="FOO\n",
614 chatty=False, connectionchatty=False):
Thomas Woutersed03b412007-08-28 21:37:11 +0000615
Trent Nelson78520002008-04-10 20:54:35 +0000616 server = ThreadedEchoServer(certfile,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000617 certreqs=certreqs,
618 ssl_version=protocol,
619 cacerts=cacertsfile,
620 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000621 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000622 flag = threading.Event()
623 server.start(flag)
624 # wait for it to start
625 flag.wait()
626 # try to connect
627 if client_protocol is None:
628 client_protocol = protocol
629 try:
Bill Janssen6e027db2007-11-15 22:23:56 +0000630 s = ssl.wrap_socket(socket.socket(),
Trent Nelson6b240cd2008-04-10 20:12:06 +0000631 server_side=False,
Bill Janssen6e027db2007-11-15 22:23:56 +0000632 certfile=client_certfile,
633 ca_certs=cacertsfile,
634 cert_reqs=certreqs,
635 ssl_version=client_protocol)
Trent Nelson78520002008-04-10 20:54:35 +0000636 s.connect((HOST, server.port))
Bill Janssen6e027db2007-11-15 22:23:56 +0000637 except ssl.SSLError as x:
638 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
639 except Exception as x:
640 raise test_support.TestFailed("Unexpected exception: " + str(x))
641 else:
642 if connectionchatty:
643 if test_support.verbose:
644 sys.stdout.write(
645 " client: sending %s...\n" % (repr(indata)))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000646 s.write(indata.encode('ASCII', 'strict'))
Bill Janssen6e027db2007-11-15 22:23:56 +0000647 outdata = s.read()
648 if connectionchatty:
649 if test_support.verbose:
650 sys.stdout.write(" client: read %s\n" % repr(outdata))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000651 outdata = str(outdata, 'ASCII', 'strict')
Bill Janssen6e027db2007-11-15 22:23:56 +0000652 if outdata != indata.lower():
653 raise test_support.TestFailed(
654 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +0000655 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
656 repr(indata[:min(len(indata),20)].lower()), len(indata)))
657 s.write("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +0000658 if connectionchatty:
659 if test_support.verbose:
660 sys.stdout.write(" client: closing connection.\n")
661 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000662 finally:
663 server.stop()
664 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000665
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000666 def tryProtocolCombo (server_protocol,
667 client_protocol,
668 expectedToWork,
669 certsreqs=None):
Thomas Woutersed03b412007-08-28 21:37:11 +0000670
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000671 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000672 certsreqs = ssl.CERT_NONE
Thomas Woutersed03b412007-08-28 21:37:11 +0000673
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000674 if certsreqs == ssl.CERT_NONE:
675 certtype = "CERT_NONE"
676 elif certsreqs == ssl.CERT_OPTIONAL:
677 certtype = "CERT_OPTIONAL"
678 elif certsreqs == ssl.CERT_REQUIRED:
679 certtype = "CERT_REQUIRED"
Thomas Woutersed03b412007-08-28 21:37:11 +0000680 if test_support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000681 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
682 sys.stdout.write(formatstr %
683 (ssl.get_protocol_name(client_protocol),
684 ssl.get_protocol_name(server_protocol),
685 certtype))
686 try:
687 serverParamsTest(CERTFILE, server_protocol, certsreqs,
Bill Janssen6e027db2007-11-15 22:23:56 +0000688 CERTFILE, CERTFILE, client_protocol,
689 chatty=False, connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000690 except test_support.TestFailed:
691 if expectedToWork:
692 raise
693 else:
694 if not expectedToWork:
695 raise test_support.TestFailed(
696 "Client protocol %s succeeded with server protocol %s!"
697 % (ssl.get_protocol_name(client_protocol),
698 ssl.get_protocol_name(server_protocol)))
699
700
Bill Janssen6e027db2007-11-15 22:23:56 +0000701 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000702
Trent Nelson6b240cd2008-04-10 20:12:06 +0000703 def testEcho (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000704
705 if test_support.verbose:
706 sys.stdout.write("\n")
707 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
708 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
709 chatty=True, connectionchatty=True)
710
711 def testReadCert(self):
712
713 if test_support.verbose:
714 sys.stdout.write("\n")
715 s2 = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000716 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000717 certreqs=ssl.CERT_NONE,
718 ssl_version=ssl.PROTOCOL_SSLv23,
719 cacerts=CERTFILE,
720 chatty=False)
721 flag = threading.Event()
722 server.start(flag)
723 # wait for it to start
724 flag.wait()
725 # try to connect
726 try:
727 try:
728 s = ssl.wrap_socket(socket.socket(),
729 certfile=CERTFILE,
730 ca_certs=CERTFILE,
731 cert_reqs=ssl.CERT_REQUIRED,
732 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelson78520002008-04-10 20:54:35 +0000733 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000734 except ssl.SSLError as x:
735 raise test_support.TestFailed(
736 "Unexpected SSL error: " + str(x))
737 except Exception as x:
738 raise test_support.TestFailed(
739 "Unexpected exception: " + str(x))
740 else:
741 if not s:
742 raise test_support.TestFailed(
743 "Can't SSL-handshake with test server")
744 cert = s.getpeercert()
745 if not cert:
746 raise test_support.TestFailed(
747 "Can't get peer certificate.")
748 cipher = s.cipher()
749 if test_support.verbose:
750 sys.stdout.write(pprint.pformat(cert) + '\n')
751 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
Bill Janssen6e027db2007-11-15 22:23:56 +0000752 if 'subject' not in cert:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000753 raise test_support.TestFailed(
754 "No subject field in certificate: %s." %
755 pprint.pformat(cert))
756 if ((('organizationName', 'Python Software Foundation'),)
757 not in cert['subject']):
758 raise test_support.TestFailed(
759 "Missing or invalid 'organizationName' field in certificate subject; "
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000760 "should be 'Python Software Foundation'.")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000761 s.close()
762 finally:
763 server.stop()
764 server.join()
765
766 def testNULLcert(self):
767 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
768 "nullcert.pem"))
769 def testMalformedCert(self):
770 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
771 "badcert.pem"))
772 def testMalformedKey(self):
773 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
774 "badkey.pem"))
775
Trent Nelson6b240cd2008-04-10 20:12:06 +0000776 def testRudeShutdown(self):
777
778 listener_ready = threading.Event()
779 listener_gone = threading.Event()
Trent Nelson78520002008-04-10 20:54:35 +0000780 port = test_support.find_unused_port()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000781
782 # `listener` runs in a thread. It opens a socket listening on
783 # PORT, and sits in an accept() until the main thread connects.
784 # Then it rudely closes the socket, and sets Event `listener_gone`
785 # to let the main thread know the socket is gone.
786 def listener():
787 s = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000788 s.bind((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000789 s.listen(5)
790 listener_ready.set()
791 s.accept()
792 s = None # reclaim the socket object, which also closes it
793 listener_gone.set()
794
795 def connector():
796 listener_ready.wait()
797 s = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000798 s.connect((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000799 listener_gone.wait()
800 try:
801 ssl_sock = ssl.wrap_socket(s)
802 except IOError:
803 pass
804 else:
805 raise test_support.TestFailed(
806 'connecting to closed SSL socket should have failed')
807
808 t = threading.Thread(target=listener)
809 t.start()
810 connector()
811 t.join()
812
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000813 def testProtocolSSL2(self):
814 if test_support.verbose:
815 sys.stdout.write("\n")
816 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
817 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
818 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
819 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
820 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
821 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
822
823 def testProtocolSSL23(self):
824 if test_support.verbose:
825 sys.stdout.write("\n")
826 try:
827 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
828 except test_support.TestFailed as x:
829 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
830 if test_support.verbose:
831 sys.stdout.write(
832 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
833 % str(x))
834 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
835 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
836 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
837
838 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
839 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
840 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
841
842 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
843 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
844 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
845
846 def testProtocolSSL3(self):
847 if test_support.verbose:
848 sys.stdout.write("\n")
849 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
850 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
851 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
852 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
853 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
854 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
855
856 def testProtocolTLS1(self):
857 if test_support.verbose:
858 sys.stdout.write("\n")
859 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
860 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
861 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
862 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
863 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
864 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
865
866 def testSTARTTLS (self):
867
868 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4")
869
Trent Nelson78520002008-04-10 20:54:35 +0000870 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000871 ssl_version=ssl.PROTOCOL_TLSv1,
872 starttls_server=True,
873 chatty=True,
874 connectionchatty=True)
875 flag = threading.Event()
876 server.start(flag)
877 # wait for it to start
878 flag.wait()
879 # try to connect
880 wrapped = False
881 try:
882 try:
883 s = socket.socket()
884 s.setblocking(1)
Trent Nelson78520002008-04-10 20:54:35 +0000885 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000886 except Exception as x:
887 raise test_support.TestFailed("Unexpected exception: " + str(x))
888 else:
889 if test_support.verbose:
890 sys.stdout.write("\n")
891 for indata in msgs:
Bill Janssen6e027db2007-11-15 22:23:56 +0000892 msg = indata.encode('ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000893 if test_support.verbose:
894 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +0000895 " client: sending %s...\n" % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000896 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +0000897 conn.write(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000898 outdata = conn.read()
899 else:
Bill Janssen6e027db2007-11-15 22:23:56 +0000900 s.send(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000901 outdata = s.recv(1024)
902 if (indata == "STARTTLS" and
Bill Janssen6e027db2007-11-15 22:23:56 +0000903 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000904 if test_support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000905 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000906 sys.stdout.write(
907 " client: read %s from server, starting TLS...\n"
Bill Janssen6e027db2007-11-15 22:23:56 +0000908 % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000909 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
910
911 wrapped = True
912 else:
913 if test_support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000914 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000915 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +0000916 " client: read %s from server\n" % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000917 if test_support.verbose:
918 sys.stdout.write(" client: closing connection.\n")
919 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +0000920 conn.write("over\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000921 else:
922 s.send("over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000923 if wrapped:
924 conn.close()
925 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000926 s.close()
927 finally:
928 server.stop()
929 server.join()
930
Bill Janssen54cc54c2007-12-14 22:08:56 +0000931 def testSocketServer(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000932
Trent Nelson78520002008-04-10 20:54:35 +0000933 server = OurHTTPSServer(CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000934 flag = threading.Event()
935 server.start(flag)
936 # wait for it to start
937 flag.wait()
938 # try to connect
939 try:
940 if test_support.verbose:
941 sys.stdout.write('\n')
942 d1 = open(CERTFILE, 'rb').read()
943 d2 = ''
944 # now fetch the same data from the HTTPS server
Trent Nelson78520002008-04-10 20:54:35 +0000945 url = 'https://%s:%d/%s' % (
946 HOST, server.port, os.path.split(CERTFILE)[1])
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000947 f = urllib.urlopen(url)
948 dlen = f.info().getheader("content-length")
949 if dlen and (int(dlen) > 0):
950 d2 = f.read(int(dlen))
951 if test_support.verbose:
952 sys.stdout.write(
953 " client: read %d bytes from remote server '%s'\n"
954 % (len(d2), server))
955 f.close()
956 except:
957 msg = ''.join(traceback.format_exception(*sys.exc_info()))
958 if test_support.verbose:
959 sys.stdout.write('\n' + msg)
960 raise test_support.TestFailed(msg)
961 else:
962 if not (d1 == d2):
Bill Janssen6e027db2007-11-15 22:23:56 +0000963 print("d1 is", len(d1), repr(d1))
964 print("d2 is", len(d2), repr(d2))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000965 raise test_support.TestFailed(
966 "Couldn't fetch data from HTTPS server")
967 finally:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000968 if test_support.verbose:
969 sys.stdout.write('stopping server\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000970 server.stop()
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000971 if test_support.verbose:
972 sys.stdout.write('joining thread\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000973 server.join()
974
Trent Nelson6b240cd2008-04-10 20:12:06 +0000975 def testAsyncoreServer(self):
976
977 if test_support.verbose:
978 sys.stdout.write("\n")
979
980 indata="FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +0000981 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000982 flag = threading.Event()
983 server.start(flag)
984 # wait for it to start
985 flag.wait()
986 # try to connect
987 try:
988 s = ssl.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +0000989 s.connect((HOST, server.port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000990 except ssl.SSLError as x:
991 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
992 except Exception as x:
993 raise test_support.TestFailed("Unexpected exception: " + str(x))
994 else:
995 if test_support.verbose:
996 sys.stdout.write(
997 " client: sending %s...\n" % (repr(indata)))
998 s.sendall(indata.encode('ASCII', 'strict'))
999 outdata = s.recv()
1000 if test_support.verbose:
1001 sys.stdout.write(" client: read %s\n" % repr(outdata))
1002 outdata = str(outdata, 'ASCII', 'strict')
1003 if outdata != indata.lower():
1004 raise test_support.TestFailed(
1005 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1006 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
1007 repr(indata[:min(len(indata),20)].lower()), len(indata)))
1008 s.write("over\n".encode("ASCII", "strict"))
1009 if test_support.verbose:
1010 sys.stdout.write(" client: closing connection.\n")
1011 s.close()
1012 finally:
1013 server.stop()
1014 server.join()
1015
Thomas Woutersed03b412007-08-28 21:37:11 +00001016def test_main(verbose=False):
1017 if skip_expected:
Thomas Wouters89d996e2007-09-08 17:39:28 +00001018 raise test_support.TestSkipped("No SSL support")
Thomas Woutersed03b412007-08-28 21:37:11 +00001019
Trent Nelson78520002008-04-10 20:54:35 +00001020 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Thomas Woutersed03b412007-08-28 21:37:11 +00001021 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
1022 "keycert.pem")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001023 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1024 os.path.dirname(__file__) or os.curdir,
1025 "https_svn_python_org_root.pem")
1026
1027 if (not os.path.exists(CERTFILE) or
1028 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
1029 raise test_support.TestFailed("Can't read certificate files!")
Bill Janssen6e027db2007-11-15 22:23:56 +00001030
Thomas Woutersed03b412007-08-28 21:37:11 +00001031 tests = [BasicTests]
1032
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001033 if test_support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001034 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001035
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001036 if _have_threads:
1037 thread_info = test_support.threading_setup()
1038 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001039 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001040
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001041 test_support.run_unittest(*tests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001042
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001043 if _have_threads:
1044 test_support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001045
1046if __name__ == "__main__":
1047 test_main()