blob: f299d362898c2f64eb07888651df00dd899e13d2 [file] [log] [blame]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
5from test import test_support
Bill Janssen934b16d2008-06-28 22:19:33 +00006import asyncore
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00007import socket
Bill Janssen934b16d2008-06-28 22:19:33 +00008import select
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00009import time
10import os
11import pprint
Bill Janssen296a59d2007-09-16 22:06:00 +000012import urllib, urlparse
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000013import traceback
14
Bill Janssen296a59d2007-09-16 22:06:00 +000015from BaseHTTPServer import HTTPServer
16from SimpleHTTPServer import SimpleHTTPRequestHandler
17
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000018# Optionally test SSL support, if we have it in the tested platform
19skip_expected = False
20try:
21 import ssl
22except ImportError:
23 skip_expected = True
24
Trent Nelsone41b0062008-04-08 23:47:30 +000025HOST = test_support.HOST
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000026CERTFILE = None
Bill Janssen296a59d2007-09-16 22:06:00 +000027SVN_PYTHON_ORG_ROOT_CERT = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000028
Neal Norwitz3e533c22007-08-27 01:03:18 +000029def handle_error(prefix):
30 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Bill Janssen98d19da2007-09-10 21:51:02 +000031 if test_support.verbose:
32 sys.stdout.write(prefix + exc_format)
Neal Norwitz3e533c22007-08-27 01:03:18 +000033
Bill Jansseneb257ac2008-09-29 18:56:38 +000034 def testSimpleSSLwrap(self):
35 try:
36 ssl.sslwrap_simple(socket.socket(socket.AF_INET))
37 except IOError, e:
38 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
39 pass
40 else:
41 raise
42 try:
43 ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
44 except IOError, e:
45 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
46 pass
47 else:
48 raise
Neal Norwitz3e533c22007-08-27 01:03:18 +000049
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000050class BasicTests(unittest.TestCase):
51
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000052 def testSSLconnect(self):
Christian Heimes6c29be52008-01-19 16:39:27 +000053 if not test_support.is_resource_enabled('network'):
54 return
Bill Janssen296a59d2007-09-16 22:06:00 +000055 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
56 cert_reqs=ssl.CERT_NONE)
57 s.connect(("svn.python.org", 443))
58 c = s.getpeercert()
59 if c:
60 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
61 s.close()
62
63 # this should fail because we have no verification certs
64 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
65 cert_reqs=ssl.CERT_REQUIRED)
66 try:
67 s.connect(("svn.python.org", 443))
68 except ssl.SSLError:
69 pass
70 finally:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000071 s.close()
72
Bill Janssen98d19da2007-09-10 21:51:02 +000073 def testCrucialConstants(self):
74 ssl.PROTOCOL_SSLv2
75 ssl.PROTOCOL_SSLv23
76 ssl.PROTOCOL_SSLv3
77 ssl.PROTOCOL_TLSv1
78 ssl.CERT_NONE
79 ssl.CERT_OPTIONAL
80 ssl.CERT_REQUIRED
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000081
Bill Janssen98d19da2007-09-10 21:51:02 +000082 def testRAND(self):
83 v = ssl.RAND_status()
84 if test_support.verbose:
85 sys.stdout.write("\n RAND_status is %d (%s)\n"
86 % (v, (v and "sufficient randomness") or
87 "insufficient randomness"))
Guido van Rossume4729332007-08-26 19:35:09 +000088 try:
Bill Janssen98d19da2007-09-10 21:51:02 +000089 ssl.RAND_egd(1)
90 except TypeError:
91 pass
Guido van Rossume4729332007-08-26 19:35:09 +000092 else:
Bill Janssen98d19da2007-09-10 21:51:02 +000093 print "didn't raise TypeError"
94 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000095
Bill Janssen98d19da2007-09-10 21:51:02 +000096 def testParseCert(self):
97 # note that this uses an 'unofficial' function in _ssl.c,
98 # provided solely for this test, to exercise the certificate
99 # parsing code
100 p = ssl._ssl._test_decode_cert(CERTFILE, False)
101 if test_support.verbose:
102 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000103
Bill Janssen296a59d2007-09-16 22:06:00 +0000104 def testDERtoPEM(self):
105
106 pem = open(SVN_PYTHON_ORG_ROOT_CERT, 'r').read()
107 d1 = ssl.PEM_cert_to_DER_cert(pem)
108 p2 = ssl.DER_cert_to_PEM_cert(d1)
109 d2 = ssl.PEM_cert_to_DER_cert(p2)
110 if (d1 != d2):
111 raise test_support.TestFailed("PEM-to-DER or DER-to-PEM translation failed")
112
Bill Janssen934b16d2008-06-28 22:19:33 +0000113class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +0000114
115 def testConnect(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000116 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
117 cert_reqs=ssl.CERT_NONE)
118 s.connect(("svn.python.org", 443))
119 c = s.getpeercert()
120 if c:
121 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
122 s.close()
123
124 # this should fail because we have no verification certs
125 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
126 cert_reqs=ssl.CERT_REQUIRED)
127 try:
128 s.connect(("svn.python.org", 443))
129 except ssl.SSLError:
130 pass
131 finally:
132 s.close()
133
134 # this should succeed because we specify the root cert
135 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
136 cert_reqs=ssl.CERT_REQUIRED,
137 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
138 try:
139 s.connect(("svn.python.org", 443))
140 except ssl.SSLError, x:
141 raise test_support.TestFailed("Unexpected exception %s" % x)
142 finally:
143 s.close()
144
Bill Janssen934b16d2008-06-28 22:19:33 +0000145
146 def testNonBlockingHandshake(self):
147 s = socket.socket(socket.AF_INET)
148 s.connect(("svn.python.org", 443))
149 s.setblocking(False)
150 s = ssl.wrap_socket(s,
151 cert_reqs=ssl.CERT_NONE,
152 do_handshake_on_connect=False)
153 count = 0
154 while True:
155 try:
156 count += 1
157 s.do_handshake()
158 break
159 except ssl.SSLError, err:
160 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
161 select.select([s], [], [])
162 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
163 select.select([], [s], [])
164 else:
165 raise
166 s.close()
167 if test_support.verbose:
168 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
169
Bill Janssen296a59d2007-09-16 22:06:00 +0000170 def testFetchServerCert(self):
171
172 pem = ssl.get_server_certificate(("svn.python.org", 443))
173 if not pem:
174 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
175
176 try:
177 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
178 except ssl.SSLError:
179 #should fail
180 pass
181 else:
182 raise test_support.TestFailed("Got server certificate %s for svn.python.org!" % pem)
183
184 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
185 if not pem:
186 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
187 if test_support.verbose:
188 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
189
190
Bill Janssen98d19da2007-09-10 21:51:02 +0000191try:
192 import threading
193except ImportError:
194 _have_threads = False
195else:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000196
Bill Janssen98d19da2007-09-10 21:51:02 +0000197 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000198
Bill Janssen98d19da2007-09-10 21:51:02 +0000199 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000200
Bill Janssen98d19da2007-09-10 21:51:02 +0000201 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000202
Bill Janssen98d19da2007-09-10 21:51:02 +0000203 """A mildly complicated class, because we want it to work both
204 with and without the SSL wrapper around the socket connection, so
205 that we can test the STARTTLS functionality."""
206
207 def __init__(self, server, connsock):
208 self.server = server
209 self.running = False
210 self.sock = connsock
211 self.sock.setblocking(1)
212 self.sslconn = None
213 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000214 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000215
Bill Janssen934b16d2008-06-28 22:19:33 +0000216 def show_conn_details(self):
217 if self.server.certreqs == ssl.CERT_REQUIRED:
218 cert = self.sslconn.getpeercert()
219 if test_support.verbose and self.server.chatty:
220 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
221 cert_binary = self.sslconn.getpeercert(True)
222 if test_support.verbose and self.server.chatty:
223 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
224 cipher = self.sslconn.cipher()
225 if test_support.verbose and self.server.chatty:
226 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
227
Bill Janssen98d19da2007-09-10 21:51:02 +0000228 def wrap_conn (self):
229 try:
230 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
231 certfile=self.server.certificate,
232 ssl_version=self.server.protocol,
233 ca_certs=self.server.cacerts,
234 cert_reqs=self.server.certreqs)
235 except:
236 if self.server.chatty:
237 handle_error("\n server: bad connection attempt from " +
238 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000239 self.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000240 if not self.server.expect_bad_connects:
241 # here, we want to stop the server, because this shouldn't
242 # happen in the context of our test case
243 self.running = False
244 # normally, we'd just stop here, but for the test
245 # harness, we want to stop the server
246 self.server.stop()
247 return False
248
249 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000250 return True
251
252 def read(self):
253 if self.sslconn:
254 return self.sslconn.read()
255 else:
256 return self.sock.recv(1024)
257
258 def write(self, bytes):
259 if self.sslconn:
260 return self.sslconn.write(bytes)
261 else:
262 return self.sock.send(bytes)
263
264 def close(self):
265 if self.sslconn:
266 self.sslconn.close()
267 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000268 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000269
270 def run (self):
271 self.running = True
272 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000273 if isinstance(self.sock, ssl.SSLSocket):
274 self.sslconn = self.sock
275 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000276 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000277 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000278 while self.running:
279 try:
280 msg = self.read()
281 if not msg:
282 # eof, so quit this handler
283 self.running = False
284 self.close()
285 elif msg.strip() == 'over':
286 if test_support.verbose and self.server.connectionchatty:
287 sys.stdout.write(" server: client closed connection\n")
288 self.close()
289 return
290 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
291 if test_support.verbose and self.server.connectionchatty:
292 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
293 self.write("OK\n")
294 if not self.wrap_conn():
295 return
Bill Janssen39295c22008-08-12 16:31:21 +0000296 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
297 if test_support.verbose and self.server.connectionchatty:
298 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
299 self.write("OK\n")
300 self.sslconn.unwrap()
301 self.sslconn = None
302 if test_support.verbose and self.server.connectionchatty:
303 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000304 else:
305 if (test_support.verbose and
306 self.server.connectionchatty):
307 ctype = (self.sslconn and "encrypted") or "unencrypted"
308 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
309 % (repr(msg), ctype, repr(msg.lower()), ctype))
310 self.write(msg.lower())
311 except ssl.SSLError:
312 if self.server.chatty:
313 handle_error("Test server failure:\n")
314 self.close()
315 self.running = False
316 # normally, we'd just stop here, but for the test
317 # harness, we want to stop the server
318 self.server.stop()
319 except:
320 handle_error('')
321
Trent Nelsone41b0062008-04-08 23:47:30 +0000322 def __init__(self, certificate, ssl_version=None,
Bill Janssen98d19da2007-09-10 21:51:02 +0000323 certreqs=None, cacerts=None, expect_bad_connects=False,
Bill Janssen934b16d2008-06-28 22:19:33 +0000324 chatty=True, connectionchatty=False, starttls_server=False,
325 wrap_accepting_socket=False):
326
Bill Janssen98d19da2007-09-10 21:51:02 +0000327 if ssl_version is None:
328 ssl_version = ssl.PROTOCOL_TLSv1
329 if certreqs is None:
330 certreqs = ssl.CERT_NONE
331 self.certificate = certificate
332 self.protocol = ssl_version
333 self.certreqs = certreqs
334 self.cacerts = cacerts
335 self.expect_bad_connects = expect_bad_connects
336 self.chatty = chatty
337 self.connectionchatty = connectionchatty
338 self.starttls_server = starttls_server
339 self.sock = socket.socket()
340 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000341 if wrap_accepting_socket:
342 self.sock = ssl.wrap_socket(self.sock, server_side=True,
343 certfile=self.certificate,
344 cert_reqs = self.certreqs,
345 ca_certs = self.cacerts,
346 ssl_version = self.protocol)
347 if test_support.verbose and self.chatty:
348 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
349 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000350 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000351 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000352 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000353
354 def start (self, flag=None):
355 self.flag = flag
356 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000357
358 def run (self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000359 self.sock.settimeout(0.5)
360 self.sock.listen(5)
361 self.active = True
362 if self.flag:
363 # signal an event
364 self.flag.set()
365 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000366 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000367 newconn, connaddr = self.sock.accept()
368 if test_support.verbose and self.chatty:
369 sys.stdout.write(' server: new connection from '
370 + str(connaddr) + '\n')
371 handler = self.ConnectionHandler(self, newconn)
372 handler.start()
373 except socket.timeout:
374 pass
375 except KeyboardInterrupt:
376 self.stop()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000377 except:
Bill Janssen98d19da2007-09-10 21:51:02 +0000378 if self.chatty:
379 handle_error("Test server failure:\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000380 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000381
Bill Janssen98d19da2007-09-10 21:51:02 +0000382 def stop (self):
383 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000384
Bill Janssen934b16d2008-06-28 22:19:33 +0000385 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000386
Bill Janssen934b16d2008-06-28 22:19:33 +0000387 class EchoServer (asyncore.dispatcher):
388
389 class ConnectionHandler (asyncore.dispatcher_with_send):
390
391 def __init__(self, conn, certfile):
392 asyncore.dispatcher_with_send.__init__(self, conn)
393 self.socket = ssl.wrap_socket(conn, server_side=True,
394 certfile=certfile,
395 do_handshake_on_connect=True)
396
397 def readable(self):
398 if isinstance(self.socket, ssl.SSLSocket):
399 while self.socket.pending() > 0:
400 self.handle_read_event()
401 return True
402
403 def handle_read(self):
404 data = self.recv(1024)
405 self.send(data.lower())
406
407 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000408 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000409 if test_support.verbose:
410 sys.stdout.write(" server: closed connection %s\n" % self.socket)
411
412 def handle_error(self):
413 raise
414
415 def __init__(self, certfile):
416 self.certfile = certfile
417 asyncore.dispatcher.__init__(self)
418 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
419 self.port = test_support.bind_port(self.socket)
420 self.listen(5)
421
422 def handle_accept(self):
423 sock_obj, addr = self.accept()
424 if test_support.verbose:
425 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
426 self.ConnectionHandler(sock_obj, self.certfile)
427
428 def handle_error(self):
429 raise
430
431 def __init__(self, certfile):
432 self.flag = None
433 self.active = False
434 self.server = self.EchoServer(certfile)
435 self.port = self.server.port
436 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000437 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000438
439 def __str__(self):
440 return "<%s %s>" % (self.__class__.__name__, self.server)
441
442 def start (self, flag=None):
443 self.flag = flag
444 threading.Thread.start(self)
445
446 def run (self):
447 self.active = True
448 if self.flag:
449 self.flag.set()
450 while self.active:
451 try:
452 asyncore.loop(1)
453 except:
454 pass
455
456 def stop (self):
457 self.active = False
458 self.server.close()
459
460 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000461
462 class HTTPSServer(HTTPServer):
463
464 def __init__(self, server_address, RequestHandlerClass, certfile):
465
466 HTTPServer.__init__(self, server_address, RequestHandlerClass)
467 # we assume the certfile contains both private key and certificate
468 self.certfile = certfile
469 self.active = False
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000470 self.active_lock = threading.Lock()
Bill Janssen296a59d2007-09-16 22:06:00 +0000471 self.allow_reuse_address = True
472
Bill Janssen934b16d2008-06-28 22:19:33 +0000473 def __str__(self):
474 return ('<%s %s:%s>' %
475 (self.__class__.__name__,
476 self.server_name,
477 self.server_port))
478
Bill Janssen296a59d2007-09-16 22:06:00 +0000479 def get_request (self):
480 # override this to wrap socket with SSL
481 sock, addr = self.socket.accept()
482 sslconn = ssl.wrap_socket(sock, server_side=True,
483 certfile=self.certfile)
484 return sslconn, addr
485
486 # The methods overridden below this are mainly so that we
487 # can run it in a thread and be able to stop it from another
488 # You probably wouldn't need them in other uses.
489
490 def server_activate(self):
491 # We want to run this in a thread for testing purposes,
492 # so we override this to set timeout, so that we get
493 # a chance to stop the server
494 self.socket.settimeout(0.5)
495 HTTPServer.server_activate(self)
496
497 def serve_forever(self):
498 # We want this to run in a thread, so we use a slightly
499 # modified version of "forever".
500 self.active = True
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000501 while 1:
Bill Janssen296a59d2007-09-16 22:06:00 +0000502 try:
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000503 # We need to lock while handling the request.
504 # Another thread can close the socket after self.active
505 # has been checked and before the request is handled.
506 # This causes an exception when using the closed socket.
507 with self.active_lock:
508 if not self.active:
509 break
510 self.handle_request()
Bill Janssen296a59d2007-09-16 22:06:00 +0000511 except socket.timeout:
512 pass
513 except KeyboardInterrupt:
514 self.server_close()
515 return
516 except:
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000517 sys.stdout.write(''.join(traceback.format_exception(*sys.exc_info())))
518 break
Neal Norwitzd0a91af2008-04-02 05:54:27 +0000519 time.sleep(0.1)
Bill Janssen296a59d2007-09-16 22:06:00 +0000520
521 def server_close(self):
522 # Again, we want this to run in a thread, so we need to override
523 # close to clear the "active" flag, so that serve_forever() will
524 # terminate.
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000525 with self.active_lock:
526 HTTPServer.server_close(self)
527 self.active = False
Bill Janssen296a59d2007-09-16 22:06:00 +0000528
529 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
530
531 # need to override translate_path to get a known root,
532 # instead of using os.curdir, since the test could be
533 # run from anywhere
534
535 server_version = "TestHTTPS/1.0"
536
537 root = None
538
539 def translate_path(self, path):
540 """Translate a /-separated PATH to the local filename syntax.
541
542 Components that mean special things to the local file system
543 (e.g. drive or directory names) are ignored. (XXX They should
544 probably be diagnosed.)
545
546 """
547 # abandon query parameters
548 path = urlparse.urlparse(path)[2]
549 path = os.path.normpath(urllib.unquote(path))
550 words = path.split('/')
551 words = filter(None, words)
552 path = self.root
553 for word in words:
554 drive, word = os.path.splitdrive(word)
555 head, word = os.path.split(word)
556 if word in self.root: continue
557 path = os.path.join(path, word)
558 return path
559
560 def log_message(self, format, *args):
561
562 # we override this to suppress logging unless "verbose"
563
564 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000565 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
566 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000567 self.server.server_port,
568 self.request.cipher(),
569 self.log_date_time_string(),
570 format%args))
571
572
Trent Nelsone41b0062008-04-08 23:47:30 +0000573 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000574 self.flag = None
575 self.active = False
576 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
Trent Nelsone41b0062008-04-08 23:47:30 +0000577 self.port = test_support.find_unused_port()
Bill Janssen296a59d2007-09-16 22:06:00 +0000578 self.server = self.HTTPSServer(
Trent Nelsone41b0062008-04-08 23:47:30 +0000579 (HOST, self.port), self.RootedHTTPRequestHandler, certfile)
Bill Janssen296a59d2007-09-16 22:06:00 +0000580 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000581 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000582
583 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000584 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000585
586 def start (self, flag=None):
587 self.flag = flag
588 threading.Thread.start(self)
589
590 def run (self):
591 self.active = True
592 if self.flag:
593 self.flag.set()
594 self.server.serve_forever()
595 self.active = False
596
597 def stop (self):
598 self.active = False
599 self.server.server_close()
600
601
Bill Janssen98d19da2007-09-10 21:51:02 +0000602 def badCertTest (certfile):
Trent Nelsone41b0062008-04-08 23:47:30 +0000603 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000604 certreqs=ssl.CERT_REQUIRED,
605 cacerts=CERTFILE, chatty=False)
606 flag = threading.Event()
607 server.start(flag)
608 # wait for it to start
609 flag.wait()
610 # try to connect
611 try:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000612 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000613 s = ssl.wrap_socket(socket.socket(),
614 certfile=certfile,
615 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000616 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000617 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000618 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000619 sys.stdout.write("\nSSLError is %s\n" % x[1])
Bill Janssen0c1dbf82008-07-17 18:01:57 +0000620 except socket.error, x:
621 if test_support.verbose:
622 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000623 else:
624 raise test_support.TestFailed(
625 "Use of invalid cert should have failed!")
626 finally:
627 server.stop()
628 server.join()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000629
Bill Janssen98d19da2007-09-10 21:51:02 +0000630 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
631 client_certfile, client_protocol=None, indata="FOO\n",
Bill Janssen934b16d2008-06-28 22:19:33 +0000632 chatty=True, connectionchatty=False,
633 wrap_accepting_socket=False):
Bill Janssen98d19da2007-09-10 21:51:02 +0000634
Trent Nelsone41b0062008-04-08 23:47:30 +0000635 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000636 certreqs=certreqs,
637 ssl_version=protocol,
638 cacerts=cacertsfile,
639 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000640 connectionchatty=connectionchatty,
641 wrap_accepting_socket=wrap_accepting_socket)
Bill Janssen98d19da2007-09-10 21:51:02 +0000642 flag = threading.Event()
643 server.start(flag)
644 # wait for it to start
645 flag.wait()
646 # try to connect
647 if client_protocol is None:
648 client_protocol = protocol
649 try:
650 try:
651 s = ssl.wrap_socket(socket.socket(),
652 certfile=client_certfile,
653 ca_certs=cacertsfile,
654 cert_reqs=certreqs,
655 ssl_version=client_protocol)
Trent Nelsone41b0062008-04-08 23:47:30 +0000656 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000657 except ssl.SSLError, x:
658 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
659 except Exception, x:
660 raise test_support.TestFailed("Unexpected exception: " + str(x))
661 else:
Antoine Pitrou5ba84912009-10-19 17:59:07 +0000662 for arg in [indata, bytearray(indata), memoryview(indata)]:
663 if connectionchatty:
664 if test_support.verbose:
665 sys.stdout.write(
666 " client: sending %s...\n" % (repr(arg)))
667 s.write(arg)
668 outdata = s.read()
669 if connectionchatty:
670 if test_support.verbose:
671 sys.stdout.write(" client: read %s\n" % repr(outdata))
672 if outdata != indata.lower():
673 raise test_support.TestFailed(
674 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
675 % (outdata[:min(len(outdata),20)], len(outdata),
676 indata[:min(len(indata),20)].lower(), len(indata)))
Bill Janssen98d19da2007-09-10 21:51:02 +0000677 s.write("over\n")
678 if connectionchatty:
679 if test_support.verbose:
680 sys.stdout.write(" client: closing connection.\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000681 s.close()
682 finally:
683 server.stop()
684 server.join()
685
686 def tryProtocolCombo (server_protocol,
687 client_protocol,
688 expectedToWork,
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000689 certsreqs=None):
690
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000691 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000692 certsreqs = ssl.CERT_NONE
Bill Janssen98d19da2007-09-10 21:51:02 +0000693
694 if certsreqs == ssl.CERT_NONE:
695 certtype = "CERT_NONE"
696 elif certsreqs == ssl.CERT_OPTIONAL:
697 certtype = "CERT_OPTIONAL"
698 elif certsreqs == ssl.CERT_REQUIRED:
699 certtype = "CERT_REQUIRED"
700 if test_support.verbose:
701 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
702 sys.stdout.write(formatstr %
703 (ssl.get_protocol_name(client_protocol),
704 ssl.get_protocol_name(server_protocol),
705 certtype))
706 try:
707 serverParamsTest(CERTFILE, server_protocol, certsreqs,
708 CERTFILE, CERTFILE, client_protocol, chatty=False)
709 except test_support.TestFailed:
710 if expectedToWork:
711 raise
712 else:
713 if not expectedToWork:
714 raise test_support.TestFailed(
715 "Client protocol %s succeeded with server protocol %s!"
716 % (ssl.get_protocol_name(client_protocol),
717 ssl.get_protocol_name(server_protocol)))
718
719
Bill Janssen934b16d2008-06-28 22:19:33 +0000720 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000721
722 def testRudeShutdown(self):
723
724 listener_ready = threading.Event()
725 listener_gone = threading.Event()
Trent Nelsone41b0062008-04-08 23:47:30 +0000726 port = test_support.find_unused_port()
Bill Janssen98d19da2007-09-10 21:51:02 +0000727
728 # `listener` runs in a thread. It opens a socket listening on
729 # PORT, and sits in an accept() until the main thread connects.
730 # Then it rudely closes the socket, and sets Event `listener_gone`
731 # to let the main thread know the socket is gone.
732 def listener():
733 s = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000734 s.bind((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000735 s.listen(5)
736 listener_ready.set()
737 s.accept()
738 s = None # reclaim the socket object, which also closes it
739 listener_gone.set()
740
741 def connector():
742 listener_ready.wait()
743 s = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000744 s.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000745 listener_gone.wait()
746 try:
747 ssl_sock = ssl.wrap_socket(s)
Bill Janssen934b16d2008-06-28 22:19:33 +0000748 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000749 pass
750 else:
751 raise test_support.TestFailed(
752 'connecting to closed SSL socket should have failed')
753
754 t = threading.Thread(target=listener)
755 t.start()
756 connector()
757 t.join()
758
759 def testEcho (self):
760
761 if test_support.verbose:
762 sys.stdout.write("\n")
763 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
764 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
765 chatty=True, connectionchatty=True)
766
767 def testReadCert(self):
768
769 if test_support.verbose:
770 sys.stdout.write("\n")
771 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000772 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000773 certreqs=ssl.CERT_NONE,
774 ssl_version=ssl.PROTOCOL_SSLv23,
775 cacerts=CERTFILE,
776 chatty=False)
777 flag = threading.Event()
778 server.start(flag)
779 # wait for it to start
780 flag.wait()
781 # try to connect
782 try:
783 try:
784 s = ssl.wrap_socket(socket.socket(),
785 certfile=CERTFILE,
786 ca_certs=CERTFILE,
787 cert_reqs=ssl.CERT_REQUIRED,
788 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelsone41b0062008-04-08 23:47:30 +0000789 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000790 except ssl.SSLError, x:
791 raise test_support.TestFailed(
792 "Unexpected SSL error: " + str(x))
793 except Exception, x:
794 raise test_support.TestFailed(
795 "Unexpected exception: " + str(x))
796 else:
797 if not s:
798 raise test_support.TestFailed(
799 "Can't SSL-handshake with test server")
800 cert = s.getpeercert()
801 if not cert:
802 raise test_support.TestFailed(
803 "Can't get peer certificate.")
804 cipher = s.cipher()
805 if test_support.verbose:
806 sys.stdout.write(pprint.pformat(cert) + '\n')
807 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
Florent Xicluna07627882010-03-21 01:14:24 +0000808 if 'subject' not in cert:
Bill Janssen98d19da2007-09-10 21:51:02 +0000809 raise test_support.TestFailed(
810 "No subject field in certificate: %s." %
811 pprint.pformat(cert))
812 if ((('organizationName', 'Python Software Foundation'),)
813 not in cert['subject']):
814 raise test_support.TestFailed(
815 "Missing or invalid 'organizationName' field in certificate subject; "
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000816 "should be 'Python Software Foundation'.")
Bill Janssen98d19da2007-09-10 21:51:02 +0000817 s.close()
818 finally:
819 server.stop()
820 server.join()
821
822 def testNULLcert(self):
823 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
824 "nullcert.pem"))
825 def testMalformedCert(self):
826 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
827 "badcert.pem"))
Bill Janssen934b16d2008-06-28 22:19:33 +0000828 def testWrongCert(self):
829 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
830 "wrongcert.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000831 def testMalformedKey(self):
832 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
833 "badkey.pem"))
834
835 def testProtocolSSL2(self):
836 if test_support.verbose:
837 sys.stdout.write("\n")
838 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
839 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
840 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
841 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
842 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
843 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
844
845 def testProtocolSSL23(self):
846 if test_support.verbose:
847 sys.stdout.write("\n")
848 try:
849 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
850 except test_support.TestFailed, x:
851 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
852 if test_support.verbose:
853 sys.stdout.write(
854 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
855 % str(x))
856 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
857 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
858 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
859
860 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
861 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
862 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
863
864 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
865 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
866 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
867
868 def testProtocolSSL3(self):
869 if test_support.verbose:
870 sys.stdout.write("\n")
871 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
872 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
873 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
874 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
875 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
876 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
877
878 def testProtocolTLS1(self):
879 if test_support.verbose:
880 sys.stdout.write("\n")
881 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
882 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
883 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
884 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
885 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
886 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
887
888 def testSTARTTLS (self):
889
Bill Janssen39295c22008-08-12 16:31:21 +0000890 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +0000891
Trent Nelsone41b0062008-04-08 23:47:30 +0000892 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000893 ssl_version=ssl.PROTOCOL_TLSv1,
894 starttls_server=True,
895 chatty=True,
896 connectionchatty=True)
897 flag = threading.Event()
898 server.start(flag)
899 # wait for it to start
900 flag.wait()
901 # try to connect
902 wrapped = False
903 try:
904 try:
905 s = socket.socket()
906 s.setblocking(1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000907 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000908 except Exception, x:
909 raise test_support.TestFailed("Unexpected exception: " + str(x))
910 else:
911 if test_support.verbose:
912 sys.stdout.write("\n")
913 for indata in msgs:
914 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000915 sys.stdout.write(
916 " client: sending %s...\n" % repr(indata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000917 if wrapped:
918 conn.write(indata)
919 outdata = conn.read()
920 else:
921 s.send(indata)
922 outdata = s.recv(1024)
Bill Janssen296a59d2007-09-16 22:06:00 +0000923 if (indata == "STARTTLS" and
924 outdata.strip().lower().startswith("ok")):
Bill Janssen98d19da2007-09-10 21:51:02 +0000925 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000926 sys.stdout.write(
927 " client: read %s from server, starting TLS...\n"
928 % repr(outdata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000929 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Bill Janssen98d19da2007-09-10 21:51:02 +0000930 wrapped = True
Bill Janssen39295c22008-08-12 16:31:21 +0000931 elif (indata == "ENDTLS" and
932 outdata.strip().lower().startswith("ok")):
933 if test_support.verbose:
934 sys.stdout.write(
935 " client: read %s from server, ending TLS...\n"
936 % repr(outdata))
937 s = conn.unwrap()
938 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +0000939 else:
940 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000941 sys.stdout.write(
942 " client: read %s from server\n" % repr(outdata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000943 if test_support.verbose:
944 sys.stdout.write(" client: closing connection.\n")
945 if wrapped:
946 conn.write("over\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000947 else:
948 s.send("over\n")
949 s.close()
950 finally:
951 server.stop()
952 server.join()
953
Bill Janssen934b16d2008-06-28 22:19:33 +0000954 def testSocketServer(self):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000955
Bill Janssen934b16d2008-06-28 22:19:33 +0000956 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +0000957 flag = threading.Event()
958 server.start(flag)
959 # wait for it to start
960 flag.wait()
961 # try to connect
962 try:
963 if test_support.verbose:
964 sys.stdout.write('\n')
Bill Janssenbf10c472007-09-16 23:16:46 +0000965 d1 = open(CERTFILE, 'rb').read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000966 d2 = ''
967 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +0000968 url = 'https://127.0.0.1:%d/%s' % (
969 server.port, os.path.split(CERTFILE)[1])
Florent Xicluna07627882010-03-21 01:14:24 +0000970 with test_support.check_py3k_warnings():
971 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +0000972 dlen = f.info().getheader("content-length")
973 if dlen and (int(dlen) > 0):
974 d2 = f.read(int(dlen))
975 if test_support.verbose:
976 sys.stdout.write(
977 " client: read %d bytes from remote server '%s'\n"
978 % (len(d2), server))
979 f.close()
980 except:
981 msg = ''.join(traceback.format_exception(*sys.exc_info()))
982 if test_support.verbose:
983 sys.stdout.write('\n' + msg)
984 raise test_support.TestFailed(msg)
985 else:
986 if not (d1 == d2):
987 raise test_support.TestFailed(
988 "Couldn't fetch data from HTTPS server")
989 finally:
990 server.stop()
991 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +0000992
Bill Janssen934b16d2008-06-28 22:19:33 +0000993 def testWrappedAccept (self):
994
995 if test_support.verbose:
996 sys.stdout.write("\n")
997 serverParamsTest(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
998 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
999 chatty=True, connectionchatty=True,
1000 wrap_accepting_socket=True)
1001
1002
1003 def testAsyncoreServer (self):
1004
1005 indata = "TEST MESSAGE of mixed case\n"
1006
1007 if test_support.verbose:
1008 sys.stdout.write("\n")
1009 server = AsyncoreEchoServer(CERTFILE)
1010 flag = threading.Event()
1011 server.start(flag)
1012 # wait for it to start
1013 flag.wait()
1014 # try to connect
1015 try:
1016 try:
1017 s = ssl.wrap_socket(socket.socket())
1018 s.connect(('127.0.0.1', server.port))
1019 except ssl.SSLError, x:
1020 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
1021 except Exception, x:
1022 raise test_support.TestFailed("Unexpected exception: " + str(x))
1023 else:
1024 if test_support.verbose:
1025 sys.stdout.write(
1026 " client: sending %s...\n" % (repr(indata)))
1027 s.write(indata)
1028 outdata = s.read()
1029 if test_support.verbose:
1030 sys.stdout.write(" client: read %s\n" % repr(outdata))
1031 if outdata != indata.lower():
1032 raise test_support.TestFailed(
1033 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1034 % (outdata[:min(len(outdata),20)], len(outdata),
1035 indata[:min(len(indata),20)].lower(), len(indata)))
1036 s.write("over\n")
1037 if test_support.verbose:
1038 sys.stdout.write(" client: closing connection.\n")
1039 s.close()
1040 finally:
1041 server.stop()
1042 # wait for server thread to end
1043 server.join()
1044
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001045
Bill Janssen61c001a2008-09-08 16:37:24 +00001046 def testAllRecvAndSendMethods(self):
1047
1048 if test_support.verbose:
1049 sys.stdout.write("\n")
1050
1051 server = ThreadedEchoServer(CERTFILE,
1052 certreqs=ssl.CERT_NONE,
1053 ssl_version=ssl.PROTOCOL_TLSv1,
1054 cacerts=CERTFILE,
1055 chatty=True,
1056 connectionchatty=False)
1057 flag = threading.Event()
1058 server.start(flag)
1059 # wait for it to start
1060 flag.wait()
1061 # try to connect
1062 try:
1063 s = ssl.wrap_socket(socket.socket(),
1064 server_side=False,
1065 certfile=CERTFILE,
1066 ca_certs=CERTFILE,
1067 cert_reqs=ssl.CERT_NONE,
1068 ssl_version=ssl.PROTOCOL_TLSv1)
1069 s.connect((HOST, server.port))
1070 except ssl.SSLError as x:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001071 self.fail("Unexpected SSL error: " + str(x))
Bill Janssen61c001a2008-09-08 16:37:24 +00001072 except Exception as x:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001073 self.fail("Unexpected exception: " + str(x))
Bill Janssen61c001a2008-09-08 16:37:24 +00001074 else:
1075 # helper methods for standardising recv* method signatures
1076 def _recv_into():
1077 b = bytearray("\0"*100)
1078 count = s.recv_into(b)
1079 return b[:count]
1080
1081 def _recvfrom_into():
1082 b = bytearray("\0"*100)
1083 count, addr = s.recvfrom_into(b)
1084 return b[:count]
1085
1086 # (name, method, whether to expect success, *args)
1087 send_methods = [
1088 ('send', s.send, True, []),
1089 ('sendto', s.sendto, False, ["some.address"]),
1090 ('sendall', s.sendall, True, []),
1091 ]
1092 recv_methods = [
1093 ('recv', s.recv, True, []),
1094 ('recvfrom', s.recvfrom, False, ["some.address"]),
1095 ('recv_into', _recv_into, True, []),
1096 ('recvfrom_into', _recvfrom_into, False, []),
1097 ]
1098 data_prefix = u"PREFIX_"
1099
1100 for meth_name, send_meth, expect_success, args in send_methods:
1101 indata = data_prefix + meth_name
1102 try:
1103 send_meth(indata.encode('ASCII', 'strict'), *args)
1104 outdata = s.read()
1105 outdata = outdata.decode('ASCII', 'strict')
1106 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001107 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001108 "While sending with <<%s>> bad data "
1109 "<<%r>> (%d) received; "
1110 "expected <<%r>> (%d)\n" % (
1111 meth_name, outdata[:20], len(outdata),
1112 indata[:20], len(indata)
1113 )
1114 )
1115 except ValueError as e:
1116 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001117 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001118 "Failed to send with method <<%s>>; "
1119 "expected to succeed.\n" % (meth_name,)
1120 )
1121 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001122 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001123 "Method <<%s>> failed with unexpected "
1124 "exception message: %s\n" % (
1125 meth_name, e
1126 )
1127 )
1128
1129 for meth_name, recv_meth, expect_success, args in recv_methods:
1130 indata = data_prefix + meth_name
1131 try:
1132 s.send(indata.encode('ASCII', 'strict'))
1133 outdata = recv_meth(*args)
1134 outdata = outdata.decode('ASCII', 'strict')
1135 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001136 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001137 "While receiving with <<%s>> bad data "
1138 "<<%r>> (%d) received; "
1139 "expected <<%r>> (%d)\n" % (
1140 meth_name, outdata[:20], len(outdata),
1141 indata[:20], len(indata)
1142 )
1143 )
1144 except ValueError as e:
1145 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001146 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001147 "Failed to receive with method <<%s>>; "
1148 "expected to succeed.\n" % (meth_name,)
1149 )
1150 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001151 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001152 "Method <<%s>> failed with unexpected "
1153 "exception message: %s\n" % (
1154 meth_name, e
1155 )
1156 )
1157 # consume data
1158 s.read()
1159
1160 s.write("over\n".encode("ASCII", "strict"))
1161 s.close()
1162 finally:
1163 server.stop()
1164 server.join()
1165
1166
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001167def test_main(verbose=False):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001168 if skip_expected:
Benjamin Peterson888a39b2009-03-26 20:48:25 +00001169 raise unittest.SkipTest("No SSL support")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001170
Trent Nelsone41b0062008-04-08 23:47:30 +00001171 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001172 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001173 "keycert.pem")
1174 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1175 os.path.dirname(__file__) or os.curdir,
1176 "https_svn_python_org_root.pem")
1177
1178 if (not os.path.exists(CERTFILE) or
1179 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001180 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001181
Bill Janssen934b16d2008-06-28 22:19:33 +00001182 TESTPORT = test_support.find_unused_port()
1183 if not TESTPORT:
1184 raise test_support.TestFailed("Can't find open port to test servers on!")
1185
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001186 tests = [BasicTests]
1187
Bill Janssen296a59d2007-09-16 22:06:00 +00001188 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001189 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001190
Bill Janssen98d19da2007-09-10 21:51:02 +00001191 if _have_threads:
1192 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001193 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001194 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001195
Bill Janssen98d19da2007-09-10 21:51:02 +00001196 test_support.run_unittest(*tests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001197
Bill Janssen98d19da2007-09-10 21:51:02 +00001198 if _have_threads:
1199 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001200
1201if __name__ == "__main__":
1202 test_main()