blob: 0f9822ab85f9f7aa238a65945b9d0fce999545aa [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
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000113 def test_openssl_version(self):
114 n = ssl.OPENSSL_VERSION_NUMBER
115 t = ssl.OPENSSL_VERSION_INFO
116 s = ssl.OPENSSL_VERSION
117 self.assertIsInstance(n, (int, long))
118 self.assertIsInstance(t, tuple)
119 self.assertIsInstance(s, str)
120 # Some sanity checks follow
121 # >= 0.9
122 self.assertGreaterEqual(n, 0x900000)
123 # < 2.0
124 self.assertLess(n, 0x20000000)
125 major, minor, fix, patch, status = t
126 self.assertGreaterEqual(major, 0)
127 self.assertLess(major, 2)
128 self.assertGreaterEqual(minor, 0)
129 self.assertLess(minor, 256)
130 self.assertGreaterEqual(fix, 0)
131 self.assertLess(fix, 256)
132 self.assertGreaterEqual(patch, 0)
133 self.assertLessEqual(patch, 26)
134 self.assertGreaterEqual(status, 0)
135 self.assertLessEqual(status, 15)
136 # Version string as returned by OpenSSL, the format might change
137 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
138 (s, t))
139
140
Bill Janssen934b16d2008-06-28 22:19:33 +0000141class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +0000142
143 def testConnect(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000144 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
145 cert_reqs=ssl.CERT_NONE)
146 s.connect(("svn.python.org", 443))
147 c = s.getpeercert()
148 if c:
149 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
150 s.close()
151
152 # this should fail because we have no verification certs
153 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
154 cert_reqs=ssl.CERT_REQUIRED)
155 try:
156 s.connect(("svn.python.org", 443))
157 except ssl.SSLError:
158 pass
159 finally:
160 s.close()
161
162 # this should succeed because we specify the root cert
163 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
164 cert_reqs=ssl.CERT_REQUIRED,
165 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
166 try:
167 s.connect(("svn.python.org", 443))
168 except ssl.SSLError, x:
169 raise test_support.TestFailed("Unexpected exception %s" % x)
170 finally:
171 s.close()
172
Bill Janssen934b16d2008-06-28 22:19:33 +0000173
174 def testNonBlockingHandshake(self):
175 s = socket.socket(socket.AF_INET)
176 s.connect(("svn.python.org", 443))
177 s.setblocking(False)
178 s = ssl.wrap_socket(s,
179 cert_reqs=ssl.CERT_NONE,
180 do_handshake_on_connect=False)
181 count = 0
182 while True:
183 try:
184 count += 1
185 s.do_handshake()
186 break
187 except ssl.SSLError, err:
188 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
189 select.select([s], [], [])
190 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
191 select.select([], [s], [])
192 else:
193 raise
194 s.close()
195 if test_support.verbose:
196 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
197
Bill Janssen296a59d2007-09-16 22:06:00 +0000198 def testFetchServerCert(self):
199
200 pem = ssl.get_server_certificate(("svn.python.org", 443))
201 if not pem:
202 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
203
204 try:
205 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
206 except ssl.SSLError:
207 #should fail
208 pass
209 else:
210 raise test_support.TestFailed("Got server certificate %s for svn.python.org!" % pem)
211
212 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
213 if not pem:
214 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
215 if test_support.verbose:
216 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
217
218
Bill Janssen98d19da2007-09-10 21:51:02 +0000219try:
220 import threading
221except ImportError:
222 _have_threads = False
223else:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000224
Bill Janssen98d19da2007-09-10 21:51:02 +0000225 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000226
Bill Janssen98d19da2007-09-10 21:51:02 +0000227 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000228
Bill Janssen98d19da2007-09-10 21:51:02 +0000229 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000230
Bill Janssen98d19da2007-09-10 21:51:02 +0000231 """A mildly complicated class, because we want it to work both
232 with and without the SSL wrapper around the socket connection, so
233 that we can test the STARTTLS functionality."""
234
235 def __init__(self, server, connsock):
236 self.server = server
237 self.running = False
238 self.sock = connsock
239 self.sock.setblocking(1)
240 self.sslconn = None
241 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000242 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000243
Bill Janssen934b16d2008-06-28 22:19:33 +0000244 def show_conn_details(self):
245 if self.server.certreqs == ssl.CERT_REQUIRED:
246 cert = self.sslconn.getpeercert()
247 if test_support.verbose and self.server.chatty:
248 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
249 cert_binary = self.sslconn.getpeercert(True)
250 if test_support.verbose and self.server.chatty:
251 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
252 cipher = self.sslconn.cipher()
253 if test_support.verbose and self.server.chatty:
254 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
255
Bill Janssen98d19da2007-09-10 21:51:02 +0000256 def wrap_conn (self):
257 try:
258 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
259 certfile=self.server.certificate,
260 ssl_version=self.server.protocol,
261 ca_certs=self.server.cacerts,
262 cert_reqs=self.server.certreqs)
263 except:
264 if self.server.chatty:
265 handle_error("\n server: bad connection attempt from " +
266 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000267 self.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000268 if not self.server.expect_bad_connects:
269 # here, we want to stop the server, because this shouldn't
270 # happen in the context of our test case
271 self.running = False
272 # normally, we'd just stop here, but for the test
273 # harness, we want to stop the server
274 self.server.stop()
275 return False
276
277 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000278 return True
279
280 def read(self):
281 if self.sslconn:
282 return self.sslconn.read()
283 else:
284 return self.sock.recv(1024)
285
286 def write(self, bytes):
287 if self.sslconn:
288 return self.sslconn.write(bytes)
289 else:
290 return self.sock.send(bytes)
291
292 def close(self):
293 if self.sslconn:
294 self.sslconn.close()
295 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000296 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000297
298 def run (self):
299 self.running = True
300 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000301 if isinstance(self.sock, ssl.SSLSocket):
302 self.sslconn = self.sock
303 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000304 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000305 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000306 while self.running:
307 try:
308 msg = self.read()
309 if not msg:
310 # eof, so quit this handler
311 self.running = False
312 self.close()
313 elif msg.strip() == 'over':
314 if test_support.verbose and self.server.connectionchatty:
315 sys.stdout.write(" server: client closed connection\n")
316 self.close()
317 return
318 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
319 if test_support.verbose and self.server.connectionchatty:
320 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
321 self.write("OK\n")
322 if not self.wrap_conn():
323 return
Bill Janssen39295c22008-08-12 16:31:21 +0000324 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
325 if test_support.verbose and self.server.connectionchatty:
326 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
327 self.write("OK\n")
328 self.sslconn.unwrap()
329 self.sslconn = None
330 if test_support.verbose and self.server.connectionchatty:
331 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000332 else:
333 if (test_support.verbose and
334 self.server.connectionchatty):
335 ctype = (self.sslconn and "encrypted") or "unencrypted"
336 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
337 % (repr(msg), ctype, repr(msg.lower()), ctype))
338 self.write(msg.lower())
339 except ssl.SSLError:
340 if self.server.chatty:
341 handle_error("Test server failure:\n")
342 self.close()
343 self.running = False
344 # normally, we'd just stop here, but for the test
345 # harness, we want to stop the server
346 self.server.stop()
347 except:
348 handle_error('')
349
Trent Nelsone41b0062008-04-08 23:47:30 +0000350 def __init__(self, certificate, ssl_version=None,
Bill Janssen98d19da2007-09-10 21:51:02 +0000351 certreqs=None, cacerts=None, expect_bad_connects=False,
Bill Janssen934b16d2008-06-28 22:19:33 +0000352 chatty=True, connectionchatty=False, starttls_server=False,
353 wrap_accepting_socket=False):
354
Bill Janssen98d19da2007-09-10 21:51:02 +0000355 if ssl_version is None:
356 ssl_version = ssl.PROTOCOL_TLSv1
357 if certreqs is None:
358 certreqs = ssl.CERT_NONE
359 self.certificate = certificate
360 self.protocol = ssl_version
361 self.certreqs = certreqs
362 self.cacerts = cacerts
363 self.expect_bad_connects = expect_bad_connects
364 self.chatty = chatty
365 self.connectionchatty = connectionchatty
366 self.starttls_server = starttls_server
367 self.sock = socket.socket()
368 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000369 if wrap_accepting_socket:
370 self.sock = ssl.wrap_socket(self.sock, server_side=True,
371 certfile=self.certificate,
372 cert_reqs = self.certreqs,
373 ca_certs = self.cacerts,
374 ssl_version = self.protocol)
375 if test_support.verbose and self.chatty:
376 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
377 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000378 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000379 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000380 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000381
382 def start (self, flag=None):
383 self.flag = flag
384 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000385
386 def run (self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000387 self.sock.settimeout(0.5)
388 self.sock.listen(5)
389 self.active = True
390 if self.flag:
391 # signal an event
392 self.flag.set()
393 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000394 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000395 newconn, connaddr = self.sock.accept()
396 if test_support.verbose and self.chatty:
397 sys.stdout.write(' server: new connection from '
398 + str(connaddr) + '\n')
399 handler = self.ConnectionHandler(self, newconn)
400 handler.start()
401 except socket.timeout:
402 pass
403 except KeyboardInterrupt:
404 self.stop()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000405 except:
Bill Janssen98d19da2007-09-10 21:51:02 +0000406 if self.chatty:
407 handle_error("Test server failure:\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000408 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000409
Bill Janssen98d19da2007-09-10 21:51:02 +0000410 def stop (self):
411 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000412
Bill Janssen934b16d2008-06-28 22:19:33 +0000413 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000414
Bill Janssen934b16d2008-06-28 22:19:33 +0000415 class EchoServer (asyncore.dispatcher):
416
417 class ConnectionHandler (asyncore.dispatcher_with_send):
418
419 def __init__(self, conn, certfile):
420 asyncore.dispatcher_with_send.__init__(self, conn)
421 self.socket = ssl.wrap_socket(conn, server_side=True,
422 certfile=certfile,
423 do_handshake_on_connect=True)
424
425 def readable(self):
426 if isinstance(self.socket, ssl.SSLSocket):
427 while self.socket.pending() > 0:
428 self.handle_read_event()
429 return True
430
431 def handle_read(self):
432 data = self.recv(1024)
433 self.send(data.lower())
434
435 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000436 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000437 if test_support.verbose:
438 sys.stdout.write(" server: closed connection %s\n" % self.socket)
439
440 def handle_error(self):
441 raise
442
443 def __init__(self, certfile):
444 self.certfile = certfile
445 asyncore.dispatcher.__init__(self)
446 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
447 self.port = test_support.bind_port(self.socket)
448 self.listen(5)
449
450 def handle_accept(self):
451 sock_obj, addr = self.accept()
452 if test_support.verbose:
453 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
454 self.ConnectionHandler(sock_obj, self.certfile)
455
456 def handle_error(self):
457 raise
458
459 def __init__(self, certfile):
460 self.flag = None
461 self.active = False
462 self.server = self.EchoServer(certfile)
463 self.port = self.server.port
464 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000465 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000466
467 def __str__(self):
468 return "<%s %s>" % (self.__class__.__name__, self.server)
469
470 def start (self, flag=None):
471 self.flag = flag
472 threading.Thread.start(self)
473
474 def run (self):
475 self.active = True
476 if self.flag:
477 self.flag.set()
478 while self.active:
479 try:
480 asyncore.loop(1)
481 except:
482 pass
483
484 def stop (self):
485 self.active = False
486 self.server.close()
487
488 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000489
490 class HTTPSServer(HTTPServer):
491
492 def __init__(self, server_address, RequestHandlerClass, certfile):
493
494 HTTPServer.__init__(self, server_address, RequestHandlerClass)
495 # we assume the certfile contains both private key and certificate
496 self.certfile = certfile
497 self.active = False
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000498 self.active_lock = threading.Lock()
Bill Janssen296a59d2007-09-16 22:06:00 +0000499 self.allow_reuse_address = True
500
Bill Janssen934b16d2008-06-28 22:19:33 +0000501 def __str__(self):
502 return ('<%s %s:%s>' %
503 (self.__class__.__name__,
504 self.server_name,
505 self.server_port))
506
Bill Janssen296a59d2007-09-16 22:06:00 +0000507 def get_request (self):
508 # override this to wrap socket with SSL
509 sock, addr = self.socket.accept()
510 sslconn = ssl.wrap_socket(sock, server_side=True,
511 certfile=self.certfile)
512 return sslconn, addr
513
514 # The methods overridden below this are mainly so that we
515 # can run it in a thread and be able to stop it from another
516 # You probably wouldn't need them in other uses.
517
518 def server_activate(self):
519 # We want to run this in a thread for testing purposes,
520 # so we override this to set timeout, so that we get
521 # a chance to stop the server
522 self.socket.settimeout(0.5)
523 HTTPServer.server_activate(self)
524
525 def serve_forever(self):
526 # We want this to run in a thread, so we use a slightly
527 # modified version of "forever".
528 self.active = True
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000529 while 1:
Bill Janssen296a59d2007-09-16 22:06:00 +0000530 try:
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000531 # We need to lock while handling the request.
532 # Another thread can close the socket after self.active
533 # has been checked and before the request is handled.
534 # This causes an exception when using the closed socket.
535 with self.active_lock:
536 if not self.active:
537 break
538 self.handle_request()
Bill Janssen296a59d2007-09-16 22:06:00 +0000539 except socket.timeout:
540 pass
541 except KeyboardInterrupt:
542 self.server_close()
543 return
544 except:
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000545 sys.stdout.write(''.join(traceback.format_exception(*sys.exc_info())))
546 break
Neal Norwitzd0a91af2008-04-02 05:54:27 +0000547 time.sleep(0.1)
Bill Janssen296a59d2007-09-16 22:06:00 +0000548
549 def server_close(self):
550 # Again, we want this to run in a thread, so we need to override
551 # close to clear the "active" flag, so that serve_forever() will
552 # terminate.
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000553 with self.active_lock:
554 HTTPServer.server_close(self)
555 self.active = False
Bill Janssen296a59d2007-09-16 22:06:00 +0000556
557 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
558
559 # need to override translate_path to get a known root,
560 # instead of using os.curdir, since the test could be
561 # run from anywhere
562
563 server_version = "TestHTTPS/1.0"
564
565 root = None
566
567 def translate_path(self, path):
568 """Translate a /-separated PATH to the local filename syntax.
569
570 Components that mean special things to the local file system
571 (e.g. drive or directory names) are ignored. (XXX They should
572 probably be diagnosed.)
573
574 """
575 # abandon query parameters
576 path = urlparse.urlparse(path)[2]
577 path = os.path.normpath(urllib.unquote(path))
578 words = path.split('/')
579 words = filter(None, words)
580 path = self.root
581 for word in words:
582 drive, word = os.path.splitdrive(word)
583 head, word = os.path.split(word)
584 if word in self.root: continue
585 path = os.path.join(path, word)
586 return path
587
588 def log_message(self, format, *args):
589
590 # we override this to suppress logging unless "verbose"
591
592 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000593 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
594 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000595 self.server.server_port,
596 self.request.cipher(),
597 self.log_date_time_string(),
598 format%args))
599
600
Trent Nelsone41b0062008-04-08 23:47:30 +0000601 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000602 self.flag = None
603 self.active = False
604 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
Trent Nelsone41b0062008-04-08 23:47:30 +0000605 self.port = test_support.find_unused_port()
Bill Janssen296a59d2007-09-16 22:06:00 +0000606 self.server = self.HTTPSServer(
Trent Nelsone41b0062008-04-08 23:47:30 +0000607 (HOST, self.port), self.RootedHTTPRequestHandler, certfile)
Bill Janssen296a59d2007-09-16 22:06:00 +0000608 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000609 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000610
611 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000612 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000613
614 def start (self, flag=None):
615 self.flag = flag
616 threading.Thread.start(self)
617
618 def run (self):
619 self.active = True
620 if self.flag:
621 self.flag.set()
622 self.server.serve_forever()
623 self.active = False
624
625 def stop (self):
626 self.active = False
627 self.server.server_close()
628
629
Bill Janssen98d19da2007-09-10 21:51:02 +0000630 def badCertTest (certfile):
Trent Nelsone41b0062008-04-08 23:47:30 +0000631 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000632 certreqs=ssl.CERT_REQUIRED,
633 cacerts=CERTFILE, chatty=False)
634 flag = threading.Event()
635 server.start(flag)
636 # wait for it to start
637 flag.wait()
638 # try to connect
639 try:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000640 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000641 s = ssl.wrap_socket(socket.socket(),
642 certfile=certfile,
643 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000644 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000645 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000646 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000647 sys.stdout.write("\nSSLError is %s\n" % x[1])
Bill Janssen0c1dbf82008-07-17 18:01:57 +0000648 except socket.error, x:
649 if test_support.verbose:
650 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000651 else:
652 raise test_support.TestFailed(
653 "Use of invalid cert should have failed!")
654 finally:
655 server.stop()
656 server.join()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000657
Bill Janssen98d19da2007-09-10 21:51:02 +0000658 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
659 client_certfile, client_protocol=None, indata="FOO\n",
Bill Janssen934b16d2008-06-28 22:19:33 +0000660 chatty=True, connectionchatty=False,
661 wrap_accepting_socket=False):
Bill Janssen98d19da2007-09-10 21:51:02 +0000662
Trent Nelsone41b0062008-04-08 23:47:30 +0000663 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000664 certreqs=certreqs,
665 ssl_version=protocol,
666 cacerts=cacertsfile,
667 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000668 connectionchatty=connectionchatty,
669 wrap_accepting_socket=wrap_accepting_socket)
Bill Janssen98d19da2007-09-10 21:51:02 +0000670 flag = threading.Event()
671 server.start(flag)
672 # wait for it to start
673 flag.wait()
674 # try to connect
675 if client_protocol is None:
676 client_protocol = protocol
677 try:
678 try:
679 s = ssl.wrap_socket(socket.socket(),
680 certfile=client_certfile,
681 ca_certs=cacertsfile,
682 cert_reqs=certreqs,
683 ssl_version=client_protocol)
Trent Nelsone41b0062008-04-08 23:47:30 +0000684 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000685 except ssl.SSLError, x:
686 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
687 except Exception, x:
688 raise test_support.TestFailed("Unexpected exception: " + str(x))
689 else:
Antoine Pitrou5ba84912009-10-19 17:59:07 +0000690 for arg in [indata, bytearray(indata), memoryview(indata)]:
691 if connectionchatty:
692 if test_support.verbose:
693 sys.stdout.write(
694 " client: sending %s...\n" % (repr(arg)))
695 s.write(arg)
696 outdata = s.read()
697 if connectionchatty:
698 if test_support.verbose:
699 sys.stdout.write(" client: read %s\n" % repr(outdata))
700 if outdata != indata.lower():
701 raise test_support.TestFailed(
702 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
703 % (outdata[:min(len(outdata),20)], len(outdata),
704 indata[:min(len(indata),20)].lower(), len(indata)))
Bill Janssen98d19da2007-09-10 21:51:02 +0000705 s.write("over\n")
706 if connectionchatty:
707 if test_support.verbose:
708 sys.stdout.write(" client: closing connection.\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000709 s.close()
710 finally:
711 server.stop()
712 server.join()
713
714 def tryProtocolCombo (server_protocol,
715 client_protocol,
716 expectedToWork,
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000717 certsreqs=None):
718
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000719 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000720 certsreqs = ssl.CERT_NONE
Bill Janssen98d19da2007-09-10 21:51:02 +0000721
722 if certsreqs == ssl.CERT_NONE:
723 certtype = "CERT_NONE"
724 elif certsreqs == ssl.CERT_OPTIONAL:
725 certtype = "CERT_OPTIONAL"
726 elif certsreqs == ssl.CERT_REQUIRED:
727 certtype = "CERT_REQUIRED"
728 if test_support.verbose:
729 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
730 sys.stdout.write(formatstr %
731 (ssl.get_protocol_name(client_protocol),
732 ssl.get_protocol_name(server_protocol),
733 certtype))
734 try:
735 serverParamsTest(CERTFILE, server_protocol, certsreqs,
736 CERTFILE, CERTFILE, client_protocol, chatty=False)
737 except test_support.TestFailed:
738 if expectedToWork:
739 raise
740 else:
741 if not expectedToWork:
742 raise test_support.TestFailed(
743 "Client protocol %s succeeded with server protocol %s!"
744 % (ssl.get_protocol_name(client_protocol),
745 ssl.get_protocol_name(server_protocol)))
746
747
Bill Janssen934b16d2008-06-28 22:19:33 +0000748 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000749
750 def testRudeShutdown(self):
751
752 listener_ready = threading.Event()
753 listener_gone = threading.Event()
Trent Nelsone41b0062008-04-08 23:47:30 +0000754 port = test_support.find_unused_port()
Bill Janssen98d19da2007-09-10 21:51:02 +0000755
756 # `listener` runs in a thread. It opens a socket listening on
757 # PORT, and sits in an accept() until the main thread connects.
758 # Then it rudely closes the socket, and sets Event `listener_gone`
759 # to let the main thread know the socket is gone.
760 def listener():
761 s = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000762 s.bind((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000763 s.listen(5)
764 listener_ready.set()
765 s.accept()
766 s = None # reclaim the socket object, which also closes it
767 listener_gone.set()
768
769 def connector():
770 listener_ready.wait()
771 s = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000772 s.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000773 listener_gone.wait()
774 try:
775 ssl_sock = ssl.wrap_socket(s)
Bill Janssen934b16d2008-06-28 22:19:33 +0000776 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000777 pass
778 else:
779 raise test_support.TestFailed(
780 'connecting to closed SSL socket should have failed')
781
782 t = threading.Thread(target=listener)
783 t.start()
784 connector()
785 t.join()
786
787 def testEcho (self):
788
789 if test_support.verbose:
790 sys.stdout.write("\n")
791 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
792 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
793 chatty=True, connectionchatty=True)
794
795 def testReadCert(self):
796
797 if test_support.verbose:
798 sys.stdout.write("\n")
799 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000800 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000801 certreqs=ssl.CERT_NONE,
802 ssl_version=ssl.PROTOCOL_SSLv23,
803 cacerts=CERTFILE,
804 chatty=False)
805 flag = threading.Event()
806 server.start(flag)
807 # wait for it to start
808 flag.wait()
809 # try to connect
810 try:
811 try:
812 s = ssl.wrap_socket(socket.socket(),
813 certfile=CERTFILE,
814 ca_certs=CERTFILE,
815 cert_reqs=ssl.CERT_REQUIRED,
816 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelsone41b0062008-04-08 23:47:30 +0000817 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000818 except ssl.SSLError, x:
819 raise test_support.TestFailed(
820 "Unexpected SSL error: " + str(x))
821 except Exception, x:
822 raise test_support.TestFailed(
823 "Unexpected exception: " + str(x))
824 else:
825 if not s:
826 raise test_support.TestFailed(
827 "Can't SSL-handshake with test server")
828 cert = s.getpeercert()
829 if not cert:
830 raise test_support.TestFailed(
831 "Can't get peer certificate.")
832 cipher = s.cipher()
833 if test_support.verbose:
834 sys.stdout.write(pprint.pformat(cert) + '\n')
835 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
Florent Xicluna07627882010-03-21 01:14:24 +0000836 if 'subject' not in cert:
Bill Janssen98d19da2007-09-10 21:51:02 +0000837 raise test_support.TestFailed(
838 "No subject field in certificate: %s." %
839 pprint.pformat(cert))
840 if ((('organizationName', 'Python Software Foundation'),)
841 not in cert['subject']):
842 raise test_support.TestFailed(
843 "Missing or invalid 'organizationName' field in certificate subject; "
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000844 "should be 'Python Software Foundation'.")
Bill Janssen98d19da2007-09-10 21:51:02 +0000845 s.close()
846 finally:
847 server.stop()
848 server.join()
849
850 def testNULLcert(self):
851 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
852 "nullcert.pem"))
853 def testMalformedCert(self):
854 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
855 "badcert.pem"))
Bill Janssen934b16d2008-06-28 22:19:33 +0000856 def testWrongCert(self):
857 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
858 "wrongcert.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000859 def testMalformedKey(self):
860 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
861 "badkey.pem"))
862
863 def testProtocolSSL2(self):
864 if test_support.verbose:
865 sys.stdout.write("\n")
866 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
867 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
868 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
869 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
870 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
871 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
872
873 def testProtocolSSL23(self):
874 if test_support.verbose:
875 sys.stdout.write("\n")
876 try:
877 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
878 except test_support.TestFailed, x:
879 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
880 if test_support.verbose:
881 sys.stdout.write(
882 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
883 % str(x))
884 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
885 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
886 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
887
888 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
889 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
890 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
891
892 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
893 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
894 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
895
896 def testProtocolSSL3(self):
897 if test_support.verbose:
898 sys.stdout.write("\n")
899 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
900 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
901 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
902 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
903 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
904 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
905
906 def testProtocolTLS1(self):
907 if test_support.verbose:
908 sys.stdout.write("\n")
909 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
910 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
911 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
912 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
913 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
914 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
915
916 def testSTARTTLS (self):
917
Bill Janssen39295c22008-08-12 16:31:21 +0000918 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +0000919
Trent Nelsone41b0062008-04-08 23:47:30 +0000920 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000921 ssl_version=ssl.PROTOCOL_TLSv1,
922 starttls_server=True,
923 chatty=True,
924 connectionchatty=True)
925 flag = threading.Event()
926 server.start(flag)
927 # wait for it to start
928 flag.wait()
929 # try to connect
930 wrapped = False
931 try:
932 try:
933 s = socket.socket()
934 s.setblocking(1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000935 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000936 except Exception, x:
937 raise test_support.TestFailed("Unexpected exception: " + str(x))
938 else:
939 if test_support.verbose:
940 sys.stdout.write("\n")
941 for indata in msgs:
942 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000943 sys.stdout.write(
944 " client: sending %s...\n" % repr(indata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000945 if wrapped:
946 conn.write(indata)
947 outdata = conn.read()
948 else:
949 s.send(indata)
950 outdata = s.recv(1024)
Bill Janssen296a59d2007-09-16 22:06:00 +0000951 if (indata == "STARTTLS" and
952 outdata.strip().lower().startswith("ok")):
Bill Janssen98d19da2007-09-10 21:51:02 +0000953 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000954 sys.stdout.write(
955 " client: read %s from server, starting TLS...\n"
956 % repr(outdata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000957 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Bill Janssen98d19da2007-09-10 21:51:02 +0000958 wrapped = True
Bill Janssen39295c22008-08-12 16:31:21 +0000959 elif (indata == "ENDTLS" and
960 outdata.strip().lower().startswith("ok")):
961 if test_support.verbose:
962 sys.stdout.write(
963 " client: read %s from server, ending TLS...\n"
964 % repr(outdata))
965 s = conn.unwrap()
966 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +0000967 else:
968 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000969 sys.stdout.write(
970 " client: read %s from server\n" % repr(outdata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000971 if test_support.verbose:
972 sys.stdout.write(" client: closing connection.\n")
973 if wrapped:
974 conn.write("over\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000975 else:
976 s.send("over\n")
977 s.close()
978 finally:
979 server.stop()
980 server.join()
981
Bill Janssen934b16d2008-06-28 22:19:33 +0000982 def testSocketServer(self):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000983
Bill Janssen934b16d2008-06-28 22:19:33 +0000984 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +0000985 flag = threading.Event()
986 server.start(flag)
987 # wait for it to start
988 flag.wait()
989 # try to connect
990 try:
991 if test_support.verbose:
992 sys.stdout.write('\n')
Bill Janssenbf10c472007-09-16 23:16:46 +0000993 d1 = open(CERTFILE, 'rb').read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000994 d2 = ''
995 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +0000996 url = 'https://127.0.0.1:%d/%s' % (
997 server.port, os.path.split(CERTFILE)[1])
Florent Xicluna07627882010-03-21 01:14:24 +0000998 with test_support.check_py3k_warnings():
999 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +00001000 dlen = f.info().getheader("content-length")
1001 if dlen and (int(dlen) > 0):
1002 d2 = f.read(int(dlen))
1003 if test_support.verbose:
1004 sys.stdout.write(
1005 " client: read %d bytes from remote server '%s'\n"
1006 % (len(d2), server))
1007 f.close()
1008 except:
1009 msg = ''.join(traceback.format_exception(*sys.exc_info()))
1010 if test_support.verbose:
1011 sys.stdout.write('\n' + msg)
1012 raise test_support.TestFailed(msg)
1013 else:
1014 if not (d1 == d2):
1015 raise test_support.TestFailed(
1016 "Couldn't fetch data from HTTPS server")
1017 finally:
1018 server.stop()
1019 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001020
Bill Janssen934b16d2008-06-28 22:19:33 +00001021 def testWrappedAccept (self):
1022
1023 if test_support.verbose:
1024 sys.stdout.write("\n")
1025 serverParamsTest(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1026 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1027 chatty=True, connectionchatty=True,
1028 wrap_accepting_socket=True)
1029
1030
1031 def testAsyncoreServer (self):
1032
1033 indata = "TEST MESSAGE of mixed case\n"
1034
1035 if test_support.verbose:
1036 sys.stdout.write("\n")
1037 server = AsyncoreEchoServer(CERTFILE)
1038 flag = threading.Event()
1039 server.start(flag)
1040 # wait for it to start
1041 flag.wait()
1042 # try to connect
1043 try:
1044 try:
1045 s = ssl.wrap_socket(socket.socket())
1046 s.connect(('127.0.0.1', server.port))
1047 except ssl.SSLError, x:
1048 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
1049 except Exception, x:
1050 raise test_support.TestFailed("Unexpected exception: " + str(x))
1051 else:
1052 if test_support.verbose:
1053 sys.stdout.write(
1054 " client: sending %s...\n" % (repr(indata)))
1055 s.write(indata)
1056 outdata = s.read()
1057 if test_support.verbose:
1058 sys.stdout.write(" client: read %s\n" % repr(outdata))
1059 if outdata != indata.lower():
1060 raise test_support.TestFailed(
1061 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1062 % (outdata[:min(len(outdata),20)], len(outdata),
1063 indata[:min(len(indata),20)].lower(), len(indata)))
1064 s.write("over\n")
1065 if test_support.verbose:
1066 sys.stdout.write(" client: closing connection.\n")
1067 s.close()
1068 finally:
1069 server.stop()
1070 # wait for server thread to end
1071 server.join()
1072
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001073
Bill Janssen61c001a2008-09-08 16:37:24 +00001074 def testAllRecvAndSendMethods(self):
1075
1076 if test_support.verbose:
1077 sys.stdout.write("\n")
1078
1079 server = ThreadedEchoServer(CERTFILE,
1080 certreqs=ssl.CERT_NONE,
1081 ssl_version=ssl.PROTOCOL_TLSv1,
1082 cacerts=CERTFILE,
1083 chatty=True,
1084 connectionchatty=False)
1085 flag = threading.Event()
1086 server.start(flag)
1087 # wait for it to start
1088 flag.wait()
1089 # try to connect
1090 try:
1091 s = ssl.wrap_socket(socket.socket(),
1092 server_side=False,
1093 certfile=CERTFILE,
1094 ca_certs=CERTFILE,
1095 cert_reqs=ssl.CERT_NONE,
1096 ssl_version=ssl.PROTOCOL_TLSv1)
1097 s.connect((HOST, server.port))
1098 except ssl.SSLError as x:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001099 self.fail("Unexpected SSL error: " + str(x))
Bill Janssen61c001a2008-09-08 16:37:24 +00001100 except Exception as x:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001101 self.fail("Unexpected exception: " + str(x))
Bill Janssen61c001a2008-09-08 16:37:24 +00001102 else:
1103 # helper methods for standardising recv* method signatures
1104 def _recv_into():
1105 b = bytearray("\0"*100)
1106 count = s.recv_into(b)
1107 return b[:count]
1108
1109 def _recvfrom_into():
1110 b = bytearray("\0"*100)
1111 count, addr = s.recvfrom_into(b)
1112 return b[:count]
1113
1114 # (name, method, whether to expect success, *args)
1115 send_methods = [
1116 ('send', s.send, True, []),
1117 ('sendto', s.sendto, False, ["some.address"]),
1118 ('sendall', s.sendall, True, []),
1119 ]
1120 recv_methods = [
1121 ('recv', s.recv, True, []),
1122 ('recvfrom', s.recvfrom, False, ["some.address"]),
1123 ('recv_into', _recv_into, True, []),
1124 ('recvfrom_into', _recvfrom_into, False, []),
1125 ]
1126 data_prefix = u"PREFIX_"
1127
1128 for meth_name, send_meth, expect_success, args in send_methods:
1129 indata = data_prefix + meth_name
1130 try:
1131 send_meth(indata.encode('ASCII', 'strict'), *args)
1132 outdata = s.read()
1133 outdata = outdata.decode('ASCII', 'strict')
1134 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001135 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001136 "While sending with <<%s>> bad data "
1137 "<<%r>> (%d) received; "
1138 "expected <<%r>> (%d)\n" % (
1139 meth_name, outdata[:20], len(outdata),
1140 indata[:20], len(indata)
1141 )
1142 )
1143 except ValueError as e:
1144 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001145 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001146 "Failed to send with method <<%s>>; "
1147 "expected to succeed.\n" % (meth_name,)
1148 )
1149 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001150 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001151 "Method <<%s>> failed with unexpected "
1152 "exception message: %s\n" % (
1153 meth_name, e
1154 )
1155 )
1156
1157 for meth_name, recv_meth, expect_success, args in recv_methods:
1158 indata = data_prefix + meth_name
1159 try:
1160 s.send(indata.encode('ASCII', 'strict'))
1161 outdata = recv_meth(*args)
1162 outdata = outdata.decode('ASCII', 'strict')
1163 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001164 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001165 "While receiving with <<%s>> bad data "
1166 "<<%r>> (%d) received; "
1167 "expected <<%r>> (%d)\n" % (
1168 meth_name, outdata[:20], len(outdata),
1169 indata[:20], len(indata)
1170 )
1171 )
1172 except ValueError as e:
1173 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001174 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001175 "Failed to receive with method <<%s>>; "
1176 "expected to succeed.\n" % (meth_name,)
1177 )
1178 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001179 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001180 "Method <<%s>> failed with unexpected "
1181 "exception message: %s\n" % (
1182 meth_name, e
1183 )
1184 )
1185 # consume data
1186 s.read()
1187
1188 s.write("over\n".encode("ASCII", "strict"))
1189 s.close()
1190 finally:
1191 server.stop()
1192 server.join()
1193
1194
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001195def test_main(verbose=False):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001196 if skip_expected:
Benjamin Peterson888a39b2009-03-26 20:48:25 +00001197 raise unittest.SkipTest("No SSL support")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001198
Trent Nelsone41b0062008-04-08 23:47:30 +00001199 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001200 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001201 "keycert.pem")
1202 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1203 os.path.dirname(__file__) or os.curdir,
1204 "https_svn_python_org_root.pem")
1205
1206 if (not os.path.exists(CERTFILE) or
1207 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001208 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001209
Bill Janssen934b16d2008-06-28 22:19:33 +00001210 TESTPORT = test_support.find_unused_port()
1211 if not TESTPORT:
1212 raise test_support.TestFailed("Can't find open port to test servers on!")
1213
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001214 tests = [BasicTests]
1215
Bill Janssen296a59d2007-09-16 22:06:00 +00001216 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001217 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001218
Bill Janssen98d19da2007-09-10 21:51:02 +00001219 if _have_threads:
1220 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001221 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001222 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001223
Bill Janssen98d19da2007-09-10 21:51:02 +00001224 test_support.run_unittest(*tests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001225
Bill Janssen98d19da2007-09-10 21:51:02 +00001226 if _have_threads:
1227 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001228
1229if __name__ == "__main__":
1230 test_main()