blob: ef82ed3e92455f2d73535fa4b525519fec18856f [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 errno
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000010import subprocess
11import time
12import os
13import pprint
Bill Janssen296a59d2007-09-16 22:06:00 +000014import urllib, urlparse
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000015import shutil
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000016import traceback
Antoine Pitrou3df58d12010-04-23 23:07:37 +000017import weakref
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000018
Bill Janssen296a59d2007-09-16 22:06:00 +000019from BaseHTTPServer import HTTPServer
20from SimpleHTTPServer import SimpleHTTPRequestHandler
21
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000022# Optionally test SSL support, if we have it in the tested platform
23skip_expected = False
24try:
25 import ssl
26except ImportError:
27 skip_expected = True
28
Trent Nelsone41b0062008-04-08 23:47:30 +000029HOST = test_support.HOST
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000030CERTFILE = None
Bill Janssen296a59d2007-09-16 22:06:00 +000031SVN_PYTHON_ORG_ROOT_CERT = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000032
Neal Norwitz3e533c22007-08-27 01:03:18 +000033def handle_error(prefix):
34 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Bill Janssen98d19da2007-09-10 21:51:02 +000035 if test_support.verbose:
36 sys.stdout.write(prefix + exc_format)
Neal Norwitz3e533c22007-08-27 01:03:18 +000037
Bill Jansseneb257ac2008-09-29 18:56:38 +000038 def testSimpleSSLwrap(self):
39 try:
40 ssl.sslwrap_simple(socket.socket(socket.AF_INET))
41 except IOError, e:
42 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
43 pass
44 else:
45 raise
46 try:
47 ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
48 except IOError, e:
49 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
50 pass
51 else:
52 raise
Neal Norwitz3e533c22007-08-27 01:03:18 +000053
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000054class BasicTests(unittest.TestCase):
55
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000056 def testSSLconnect(self):
Christian Heimes6c29be52008-01-19 16:39:27 +000057 if not test_support.is_resource_enabled('network'):
58 return
Bill Janssen296a59d2007-09-16 22:06:00 +000059 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
60 cert_reqs=ssl.CERT_NONE)
61 s.connect(("svn.python.org", 443))
62 c = s.getpeercert()
63 if c:
64 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
65 s.close()
66
67 # this should fail because we have no verification certs
68 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
69 cert_reqs=ssl.CERT_REQUIRED)
70 try:
71 s.connect(("svn.python.org", 443))
72 except ssl.SSLError:
73 pass
74 finally:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000075 s.close()
76
Bill Janssen98d19da2007-09-10 21:51:02 +000077 def testCrucialConstants(self):
78 ssl.PROTOCOL_SSLv2
79 ssl.PROTOCOL_SSLv23
80 ssl.PROTOCOL_SSLv3
81 ssl.PROTOCOL_TLSv1
82 ssl.CERT_NONE
83 ssl.CERT_OPTIONAL
84 ssl.CERT_REQUIRED
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000085
Bill Janssen98d19da2007-09-10 21:51:02 +000086 def testRAND(self):
87 v = ssl.RAND_status()
88 if test_support.verbose:
89 sys.stdout.write("\n RAND_status is %d (%s)\n"
90 % (v, (v and "sufficient randomness") or
91 "insufficient randomness"))
Guido van Rossume4729332007-08-26 19:35:09 +000092 try:
Bill Janssen98d19da2007-09-10 21:51:02 +000093 ssl.RAND_egd(1)
94 except TypeError:
95 pass
Guido van Rossume4729332007-08-26 19:35:09 +000096 else:
Bill Janssen98d19da2007-09-10 21:51:02 +000097 print "didn't raise TypeError"
98 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000099
Bill Janssen98d19da2007-09-10 21:51:02 +0000100 def testParseCert(self):
101 # note that this uses an 'unofficial' function in _ssl.c,
102 # provided solely for this test, to exercise the certificate
103 # parsing code
104 p = ssl._ssl._test_decode_cert(CERTFILE, False)
105 if test_support.verbose:
106 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000107
Bill Janssen296a59d2007-09-16 22:06:00 +0000108 def testDERtoPEM(self):
109
110 pem = open(SVN_PYTHON_ORG_ROOT_CERT, 'r').read()
111 d1 = ssl.PEM_cert_to_DER_cert(pem)
112 p2 = ssl.DER_cert_to_PEM_cert(d1)
113 d2 = ssl.PEM_cert_to_DER_cert(p2)
114 if (d1 != d2):
115 raise test_support.TestFailed("PEM-to-DER or DER-to-PEM translation failed")
116
Antoine Pitrou3df58d12010-04-23 23:07:37 +0000117 def test_refcycle(self):
118 # Issue #7943: an SSL object doesn't create reference cycles with
119 # itself.
120 s = socket.socket(socket.AF_INET)
121 ss = ssl.wrap_socket(s)
122 wr = weakref.ref(ss)
123 del ss
124 self.assertEqual(wr(), None)
125
Bill Janssen934b16d2008-06-28 22:19:33 +0000126class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +0000127
128 def testConnect(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000129 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
130 cert_reqs=ssl.CERT_NONE)
131 s.connect(("svn.python.org", 443))
132 c = s.getpeercert()
133 if c:
134 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
135 s.close()
136
137 # this should fail because we have no verification certs
138 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
139 cert_reqs=ssl.CERT_REQUIRED)
140 try:
141 s.connect(("svn.python.org", 443))
142 except ssl.SSLError:
143 pass
144 finally:
145 s.close()
146
147 # this should succeed because we specify the root cert
148 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
149 cert_reqs=ssl.CERT_REQUIRED,
150 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
151 try:
152 s.connect(("svn.python.org", 443))
153 except ssl.SSLError, x:
154 raise test_support.TestFailed("Unexpected exception %s" % x)
155 finally:
156 s.close()
157
Bill Janssen934b16d2008-06-28 22:19:33 +0000158
159 def testNonBlockingHandshake(self):
160 s = socket.socket(socket.AF_INET)
161 s.connect(("svn.python.org", 443))
162 s.setblocking(False)
163 s = ssl.wrap_socket(s,
164 cert_reqs=ssl.CERT_NONE,
165 do_handshake_on_connect=False)
166 count = 0
167 while True:
168 try:
169 count += 1
170 s.do_handshake()
171 break
172 except ssl.SSLError, err:
173 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
174 select.select([s], [], [])
175 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
176 select.select([], [s], [])
177 else:
178 raise
179 s.close()
180 if test_support.verbose:
181 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
182
Bill Janssen296a59d2007-09-16 22:06:00 +0000183 def testFetchServerCert(self):
184
185 pem = ssl.get_server_certificate(("svn.python.org", 443))
186 if not pem:
187 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
188
189 try:
190 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
191 except ssl.SSLError:
192 #should fail
193 pass
194 else:
195 raise test_support.TestFailed("Got server certificate %s for svn.python.org!" % pem)
196
197 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
198 if not pem:
199 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
200 if test_support.verbose:
201 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
202
Antoine Pitroub7c656f2010-04-22 18:42:58 +0000203 # Test disabled: OPENSSL_VERSION* not available in Python 2.6
Antoine Pitrou878602a2010-04-21 19:41:28 +0000204 def test_algorithms(self):
Antoine Pitroub7c656f2010-04-22 18:42:58 +0000205 if test_support.verbose:
206 sys.stdout.write("test_algorithms disabled, "
207 "as it fails on some old OpenSSL versions")
208 return
Antoine Pitrou878602a2010-04-21 19:41:28 +0000209 # Issue #8484: all algorithms should be available when verifying a
210 # certificate.
211 # NOTE: https://sha256.tbs-internet.com is another possible test host
212 remote = ("sha2.hboeck.de", 443)
213 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
214 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
215 cert_reqs=ssl.CERT_REQUIRED,
216 ca_certs=sha256_cert,)
217 with test_support.transient_internet():
218 try:
219 s.connect(remote)
220 if test_support.verbose:
221 sys.stdout.write("\nCipher with %r is %r\n" %
222 (remote, s.cipher()))
223 sys.stdout.write("Certificate is:\n%s\n" %
224 pprint.pformat(s.getpeercert()))
225 finally:
226 s.close()
227
Bill Janssen296a59d2007-09-16 22:06:00 +0000228
Bill Janssen98d19da2007-09-10 21:51:02 +0000229try:
230 import threading
231except ImportError:
232 _have_threads = False
233else:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000234
Bill Janssen98d19da2007-09-10 21:51:02 +0000235 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000236
Bill Janssen98d19da2007-09-10 21:51:02 +0000237 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000238
Bill Janssen98d19da2007-09-10 21:51:02 +0000239 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000240
Bill Janssen98d19da2007-09-10 21:51:02 +0000241 """A mildly complicated class, because we want it to work both
242 with and without the SSL wrapper around the socket connection, so
243 that we can test the STARTTLS functionality."""
244
245 def __init__(self, server, connsock):
246 self.server = server
247 self.running = False
248 self.sock = connsock
249 self.sock.setblocking(1)
250 self.sslconn = None
251 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000252 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000253
Bill Janssen934b16d2008-06-28 22:19:33 +0000254 def show_conn_details(self):
255 if self.server.certreqs == ssl.CERT_REQUIRED:
256 cert = self.sslconn.getpeercert()
257 if test_support.verbose and self.server.chatty:
258 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
259 cert_binary = self.sslconn.getpeercert(True)
260 if test_support.verbose and self.server.chatty:
261 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
262 cipher = self.sslconn.cipher()
263 if test_support.verbose and self.server.chatty:
264 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
265
Bill Janssen98d19da2007-09-10 21:51:02 +0000266 def wrap_conn (self):
267 try:
268 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
269 certfile=self.server.certificate,
270 ssl_version=self.server.protocol,
271 ca_certs=self.server.cacerts,
272 cert_reqs=self.server.certreqs)
273 except:
274 if self.server.chatty:
275 handle_error("\n server: bad connection attempt from " +
276 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000277 self.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000278 if not self.server.expect_bad_connects:
279 # here, we want to stop the server, because this shouldn't
280 # happen in the context of our test case
281 self.running = False
282 # normally, we'd just stop here, but for the test
283 # harness, we want to stop the server
284 self.server.stop()
285 return False
286
287 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000288 return True
289
290 def read(self):
291 if self.sslconn:
292 return self.sslconn.read()
293 else:
294 return self.sock.recv(1024)
295
296 def write(self, bytes):
297 if self.sslconn:
298 return self.sslconn.write(bytes)
299 else:
300 return self.sock.send(bytes)
301
302 def close(self):
303 if self.sslconn:
304 self.sslconn.close()
305 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000306 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000307
308 def run (self):
309 self.running = True
310 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000311 if isinstance(self.sock, ssl.SSLSocket):
312 self.sslconn = self.sock
313 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000314 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000315 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000316 while self.running:
317 try:
318 msg = self.read()
319 if not msg:
320 # eof, so quit this handler
321 self.running = False
322 self.close()
323 elif msg.strip() == 'over':
324 if test_support.verbose and self.server.connectionchatty:
325 sys.stdout.write(" server: client closed connection\n")
326 self.close()
327 return
328 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
329 if test_support.verbose and self.server.connectionchatty:
330 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
331 self.write("OK\n")
332 if not self.wrap_conn():
333 return
Bill Janssen39295c22008-08-12 16:31:21 +0000334 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
335 if test_support.verbose and self.server.connectionchatty:
336 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
337 self.write("OK\n")
338 self.sslconn.unwrap()
339 self.sslconn = None
340 if test_support.verbose and self.server.connectionchatty:
341 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000342 else:
343 if (test_support.verbose and
344 self.server.connectionchatty):
345 ctype = (self.sslconn and "encrypted") or "unencrypted"
346 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
347 % (repr(msg), ctype, repr(msg.lower()), ctype))
348 self.write(msg.lower())
349 except ssl.SSLError:
350 if self.server.chatty:
351 handle_error("Test server failure:\n")
352 self.close()
353 self.running = False
354 # normally, we'd just stop here, but for the test
355 # harness, we want to stop the server
356 self.server.stop()
357 except:
358 handle_error('')
359
Trent Nelsone41b0062008-04-08 23:47:30 +0000360 def __init__(self, certificate, ssl_version=None,
Bill Janssen98d19da2007-09-10 21:51:02 +0000361 certreqs=None, cacerts=None, expect_bad_connects=False,
Bill Janssen934b16d2008-06-28 22:19:33 +0000362 chatty=True, connectionchatty=False, starttls_server=False,
363 wrap_accepting_socket=False):
364
Bill Janssen98d19da2007-09-10 21:51:02 +0000365 if ssl_version is None:
366 ssl_version = ssl.PROTOCOL_TLSv1
367 if certreqs is None:
368 certreqs = ssl.CERT_NONE
369 self.certificate = certificate
370 self.protocol = ssl_version
371 self.certreqs = certreqs
372 self.cacerts = cacerts
373 self.expect_bad_connects = expect_bad_connects
374 self.chatty = chatty
375 self.connectionchatty = connectionchatty
376 self.starttls_server = starttls_server
377 self.sock = socket.socket()
378 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000379 if wrap_accepting_socket:
380 self.sock = ssl.wrap_socket(self.sock, server_side=True,
381 certfile=self.certificate,
382 cert_reqs = self.certreqs,
383 ca_certs = self.cacerts,
384 ssl_version = self.protocol)
385 if test_support.verbose and self.chatty:
386 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
387 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000388 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000389 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000390 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000391
392 def start (self, flag=None):
393 self.flag = flag
394 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000395
396 def run (self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000397 self.sock.settimeout(0.5)
398 self.sock.listen(5)
399 self.active = True
400 if self.flag:
401 # signal an event
402 self.flag.set()
403 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000404 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000405 newconn, connaddr = self.sock.accept()
406 if test_support.verbose and self.chatty:
407 sys.stdout.write(' server: new connection from '
408 + str(connaddr) + '\n')
409 handler = self.ConnectionHandler(self, newconn)
410 handler.start()
411 except socket.timeout:
412 pass
413 except KeyboardInterrupt:
414 self.stop()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000415 except:
Bill Janssen98d19da2007-09-10 21:51:02 +0000416 if self.chatty:
417 handle_error("Test server failure:\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000418 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000419
Bill Janssen98d19da2007-09-10 21:51:02 +0000420 def stop (self):
421 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000422
Bill Janssen934b16d2008-06-28 22:19:33 +0000423 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000424
Bill Janssen934b16d2008-06-28 22:19:33 +0000425 class EchoServer (asyncore.dispatcher):
426
427 class ConnectionHandler (asyncore.dispatcher_with_send):
428
429 def __init__(self, conn, certfile):
430 asyncore.dispatcher_with_send.__init__(self, conn)
431 self.socket = ssl.wrap_socket(conn, server_side=True,
432 certfile=certfile,
433 do_handshake_on_connect=True)
434
435 def readable(self):
436 if isinstance(self.socket, ssl.SSLSocket):
437 while self.socket.pending() > 0:
438 self.handle_read_event()
439 return True
440
441 def handle_read(self):
442 data = self.recv(1024)
443 self.send(data.lower())
444
445 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000446 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000447 if test_support.verbose:
448 sys.stdout.write(" server: closed connection %s\n" % self.socket)
449
450 def handle_error(self):
451 raise
452
453 def __init__(self, certfile):
454 self.certfile = certfile
455 asyncore.dispatcher.__init__(self)
456 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
457 self.port = test_support.bind_port(self.socket)
458 self.listen(5)
459
460 def handle_accept(self):
461 sock_obj, addr = self.accept()
462 if test_support.verbose:
463 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
464 self.ConnectionHandler(sock_obj, self.certfile)
465
466 def handle_error(self):
467 raise
468
469 def __init__(self, certfile):
470 self.flag = None
471 self.active = False
472 self.server = self.EchoServer(certfile)
473 self.port = self.server.port
474 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000475 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000476
477 def __str__(self):
478 return "<%s %s>" % (self.__class__.__name__, self.server)
479
480 def start (self, flag=None):
481 self.flag = flag
482 threading.Thread.start(self)
483
484 def run (self):
485 self.active = True
486 if self.flag:
487 self.flag.set()
488 while self.active:
489 try:
490 asyncore.loop(1)
491 except:
492 pass
493
494 def stop (self):
495 self.active = False
496 self.server.close()
497
498 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000499
500 class HTTPSServer(HTTPServer):
501
502 def __init__(self, server_address, RequestHandlerClass, certfile):
503
504 HTTPServer.__init__(self, server_address, RequestHandlerClass)
505 # we assume the certfile contains both private key and certificate
506 self.certfile = certfile
507 self.active = False
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000508 self.active_lock = threading.Lock()
Bill Janssen296a59d2007-09-16 22:06:00 +0000509 self.allow_reuse_address = True
510
Bill Janssen934b16d2008-06-28 22:19:33 +0000511 def __str__(self):
512 return ('<%s %s:%s>' %
513 (self.__class__.__name__,
514 self.server_name,
515 self.server_port))
516
Bill Janssen296a59d2007-09-16 22:06:00 +0000517 def get_request (self):
518 # override this to wrap socket with SSL
519 sock, addr = self.socket.accept()
520 sslconn = ssl.wrap_socket(sock, server_side=True,
521 certfile=self.certfile)
522 return sslconn, addr
523
524 # The methods overridden below this are mainly so that we
525 # can run it in a thread and be able to stop it from another
526 # You probably wouldn't need them in other uses.
527
528 def server_activate(self):
529 # We want to run this in a thread for testing purposes,
530 # so we override this to set timeout, so that we get
531 # a chance to stop the server
532 self.socket.settimeout(0.5)
533 HTTPServer.server_activate(self)
534
535 def serve_forever(self):
536 # We want this to run in a thread, so we use a slightly
537 # modified version of "forever".
538 self.active = True
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000539 while 1:
Bill Janssen296a59d2007-09-16 22:06:00 +0000540 try:
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000541 # We need to lock while handling the request.
542 # Another thread can close the socket after self.active
543 # has been checked and before the request is handled.
544 # This causes an exception when using the closed socket.
545 with self.active_lock:
546 if not self.active:
547 break
548 self.handle_request()
Bill Janssen296a59d2007-09-16 22:06:00 +0000549 except socket.timeout:
550 pass
551 except KeyboardInterrupt:
552 self.server_close()
553 return
554 except:
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000555 sys.stdout.write(''.join(traceback.format_exception(*sys.exc_info())))
556 break
Neal Norwitzd0a91af2008-04-02 05:54:27 +0000557 time.sleep(0.1)
Bill Janssen296a59d2007-09-16 22:06:00 +0000558
559 def server_close(self):
560 # Again, we want this to run in a thread, so we need to override
561 # close to clear the "active" flag, so that serve_forever() will
562 # terminate.
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000563 with self.active_lock:
564 HTTPServer.server_close(self)
565 self.active = False
Bill Janssen296a59d2007-09-16 22:06:00 +0000566
567 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
568
569 # need to override translate_path to get a known root,
570 # instead of using os.curdir, since the test could be
571 # run from anywhere
572
573 server_version = "TestHTTPS/1.0"
574
575 root = None
576
577 def translate_path(self, path):
578 """Translate a /-separated PATH to the local filename syntax.
579
580 Components that mean special things to the local file system
581 (e.g. drive or directory names) are ignored. (XXX They should
582 probably be diagnosed.)
583
584 """
585 # abandon query parameters
586 path = urlparse.urlparse(path)[2]
587 path = os.path.normpath(urllib.unquote(path))
588 words = path.split('/')
589 words = filter(None, words)
590 path = self.root
591 for word in words:
592 drive, word = os.path.splitdrive(word)
593 head, word = os.path.split(word)
594 if word in self.root: continue
595 path = os.path.join(path, word)
596 return path
597
598 def log_message(self, format, *args):
599
600 # we override this to suppress logging unless "verbose"
601
602 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000603 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
604 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000605 self.server.server_port,
606 self.request.cipher(),
607 self.log_date_time_string(),
608 format%args))
609
610
Trent Nelsone41b0062008-04-08 23:47:30 +0000611 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000612 self.flag = None
613 self.active = False
614 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
Trent Nelsone41b0062008-04-08 23:47:30 +0000615 self.port = test_support.find_unused_port()
Bill Janssen296a59d2007-09-16 22:06:00 +0000616 self.server = self.HTTPSServer(
Trent Nelsone41b0062008-04-08 23:47:30 +0000617 (HOST, self.port), self.RootedHTTPRequestHandler, certfile)
Bill Janssen296a59d2007-09-16 22:06:00 +0000618 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000619 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000620
621 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000622 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000623
624 def start (self, flag=None):
625 self.flag = flag
626 threading.Thread.start(self)
627
628 def run (self):
629 self.active = True
630 if self.flag:
631 self.flag.set()
632 self.server.serve_forever()
633 self.active = False
634
635 def stop (self):
636 self.active = False
637 self.server.server_close()
638
639
Bill Janssen98d19da2007-09-10 21:51:02 +0000640 def badCertTest (certfile):
Trent Nelsone41b0062008-04-08 23:47:30 +0000641 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000642 certreqs=ssl.CERT_REQUIRED,
643 cacerts=CERTFILE, chatty=False)
644 flag = threading.Event()
645 server.start(flag)
646 # wait for it to start
647 flag.wait()
648 # try to connect
649 try:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000650 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000651 s = ssl.wrap_socket(socket.socket(),
652 certfile=certfile,
653 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000654 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000655 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000656 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000657 sys.stdout.write("\nSSLError is %s\n" % x[1])
Bill Janssen0c1dbf82008-07-17 18:01:57 +0000658 except socket.error, x:
659 if test_support.verbose:
660 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000661 else:
662 raise test_support.TestFailed(
663 "Use of invalid cert should have failed!")
664 finally:
665 server.stop()
666 server.join()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000667
Bill Janssen98d19da2007-09-10 21:51:02 +0000668 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
669 client_certfile, client_protocol=None, indata="FOO\n",
Bill Janssen934b16d2008-06-28 22:19:33 +0000670 chatty=True, connectionchatty=False,
671 wrap_accepting_socket=False):
Bill Janssen98d19da2007-09-10 21:51:02 +0000672
Trent Nelsone41b0062008-04-08 23:47:30 +0000673 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000674 certreqs=certreqs,
675 ssl_version=protocol,
676 cacerts=cacertsfile,
677 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000678 connectionchatty=connectionchatty,
679 wrap_accepting_socket=wrap_accepting_socket)
Bill Janssen98d19da2007-09-10 21:51:02 +0000680 flag = threading.Event()
681 server.start(flag)
682 # wait for it to start
683 flag.wait()
684 # try to connect
685 if client_protocol is None:
686 client_protocol = protocol
687 try:
688 try:
689 s = ssl.wrap_socket(socket.socket(),
690 certfile=client_certfile,
691 ca_certs=cacertsfile,
692 cert_reqs=certreqs,
693 ssl_version=client_protocol)
Trent Nelsone41b0062008-04-08 23:47:30 +0000694 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000695 except ssl.SSLError, x:
696 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
697 except Exception, x:
698 raise test_support.TestFailed("Unexpected exception: " + str(x))
699 else:
700 if connectionchatty:
701 if test_support.verbose:
702 sys.stdout.write(
703 " client: sending %s...\n" % (repr(indata)))
704 s.write(indata)
705 outdata = s.read()
706 if connectionchatty:
707 if test_support.verbose:
708 sys.stdout.write(" client: read %s\n" % repr(outdata))
709 if outdata != indata.lower():
710 raise test_support.TestFailed(
711 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
712 % (outdata[:min(len(outdata),20)], len(outdata),
713 indata[:min(len(indata),20)].lower(), len(indata)))
714 s.write("over\n")
715 if connectionchatty:
716 if test_support.verbose:
717 sys.stdout.write(" client: closing connection.\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000718 s.close()
719 finally:
720 server.stop()
721 server.join()
722
723 def tryProtocolCombo (server_protocol,
724 client_protocol,
725 expectedToWork,
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000726 certsreqs=None):
727
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000728 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000729 certsreqs = ssl.CERT_NONE
Bill Janssen98d19da2007-09-10 21:51:02 +0000730
731 if certsreqs == ssl.CERT_NONE:
732 certtype = "CERT_NONE"
733 elif certsreqs == ssl.CERT_OPTIONAL:
734 certtype = "CERT_OPTIONAL"
735 elif certsreqs == ssl.CERT_REQUIRED:
736 certtype = "CERT_REQUIRED"
737 if test_support.verbose:
738 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
739 sys.stdout.write(formatstr %
740 (ssl.get_protocol_name(client_protocol),
741 ssl.get_protocol_name(server_protocol),
742 certtype))
743 try:
744 serverParamsTest(CERTFILE, server_protocol, certsreqs,
745 CERTFILE, CERTFILE, client_protocol, chatty=False)
746 except test_support.TestFailed:
747 if expectedToWork:
748 raise
749 else:
750 if not expectedToWork:
751 raise test_support.TestFailed(
752 "Client protocol %s succeeded with server protocol %s!"
753 % (ssl.get_protocol_name(client_protocol),
754 ssl.get_protocol_name(server_protocol)))
755
756
Bill Janssen934b16d2008-06-28 22:19:33 +0000757 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000758
759 def testRudeShutdown(self):
760
761 listener_ready = threading.Event()
762 listener_gone = threading.Event()
Trent Nelsone41b0062008-04-08 23:47:30 +0000763 port = test_support.find_unused_port()
Bill Janssen98d19da2007-09-10 21:51:02 +0000764
765 # `listener` runs in a thread. It opens a socket listening on
766 # PORT, and sits in an accept() until the main thread connects.
767 # Then it rudely closes the socket, and sets Event `listener_gone`
768 # to let the main thread know the socket is gone.
769 def listener():
770 s = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000771 s.bind((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000772 s.listen(5)
773 listener_ready.set()
774 s.accept()
775 s = None # reclaim the socket object, which also closes it
776 listener_gone.set()
777
778 def connector():
779 listener_ready.wait()
780 s = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000781 s.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000782 listener_gone.wait()
783 try:
784 ssl_sock = ssl.wrap_socket(s)
Bill Janssen934b16d2008-06-28 22:19:33 +0000785 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000786 pass
787 else:
788 raise test_support.TestFailed(
789 'connecting to closed SSL socket should have failed')
790
791 t = threading.Thread(target=listener)
792 t.start()
793 connector()
794 t.join()
795
796 def testEcho (self):
797
798 if test_support.verbose:
799 sys.stdout.write("\n")
800 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
801 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
802 chatty=True, connectionchatty=True)
803
804 def testReadCert(self):
805
806 if test_support.verbose:
807 sys.stdout.write("\n")
808 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000809 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000810 certreqs=ssl.CERT_NONE,
811 ssl_version=ssl.PROTOCOL_SSLv23,
812 cacerts=CERTFILE,
813 chatty=False)
814 flag = threading.Event()
815 server.start(flag)
816 # wait for it to start
817 flag.wait()
818 # try to connect
819 try:
820 try:
821 s = ssl.wrap_socket(socket.socket(),
822 certfile=CERTFILE,
823 ca_certs=CERTFILE,
824 cert_reqs=ssl.CERT_REQUIRED,
825 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelsone41b0062008-04-08 23:47:30 +0000826 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000827 except ssl.SSLError, x:
828 raise test_support.TestFailed(
829 "Unexpected SSL error: " + str(x))
830 except Exception, x:
831 raise test_support.TestFailed(
832 "Unexpected exception: " + str(x))
833 else:
834 if not s:
835 raise test_support.TestFailed(
836 "Can't SSL-handshake with test server")
837 cert = s.getpeercert()
838 if not cert:
839 raise test_support.TestFailed(
840 "Can't get peer certificate.")
841 cipher = s.cipher()
842 if test_support.verbose:
843 sys.stdout.write(pprint.pformat(cert) + '\n')
844 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
845 if not cert.has_key('subject'):
846 raise test_support.TestFailed(
847 "No subject field in certificate: %s." %
848 pprint.pformat(cert))
849 if ((('organizationName', 'Python Software Foundation'),)
850 not in cert['subject']):
851 raise test_support.TestFailed(
852 "Missing or invalid 'organizationName' field in certificate subject; "
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000853 "should be 'Python Software Foundation'.")
Bill Janssen98d19da2007-09-10 21:51:02 +0000854 s.close()
855 finally:
856 server.stop()
857 server.join()
858
859 def testNULLcert(self):
860 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
861 "nullcert.pem"))
862 def testMalformedCert(self):
863 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
864 "badcert.pem"))
Bill Janssen934b16d2008-06-28 22:19:33 +0000865 def testWrongCert(self):
866 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
867 "wrongcert.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000868 def testMalformedKey(self):
869 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
870 "badkey.pem"))
871
872 def testProtocolSSL2(self):
873 if test_support.verbose:
874 sys.stdout.write("\n")
875 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
876 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
877 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
878 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
879 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
880 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
881
882 def testProtocolSSL23(self):
883 if test_support.verbose:
884 sys.stdout.write("\n")
885 try:
886 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
887 except test_support.TestFailed, x:
888 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
889 if test_support.verbose:
890 sys.stdout.write(
891 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
892 % str(x))
893 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
894 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
895 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
896
897 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
898 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
899 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
900
901 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
902 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
903 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
904
905 def testProtocolSSL3(self):
906 if test_support.verbose:
907 sys.stdout.write("\n")
908 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
909 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
910 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
911 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
912 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
913 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
914
915 def testProtocolTLS1(self):
916 if test_support.verbose:
917 sys.stdout.write("\n")
918 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
919 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
920 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
921 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
922 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
923 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
924
925 def testSTARTTLS (self):
926
Bill Janssen39295c22008-08-12 16:31:21 +0000927 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +0000928
Trent Nelsone41b0062008-04-08 23:47:30 +0000929 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000930 ssl_version=ssl.PROTOCOL_TLSv1,
931 starttls_server=True,
932 chatty=True,
933 connectionchatty=True)
934 flag = threading.Event()
935 server.start(flag)
936 # wait for it to start
937 flag.wait()
938 # try to connect
939 wrapped = False
940 try:
941 try:
942 s = socket.socket()
943 s.setblocking(1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000944 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000945 except Exception, x:
946 raise test_support.TestFailed("Unexpected exception: " + str(x))
947 else:
948 if test_support.verbose:
949 sys.stdout.write("\n")
950 for indata in msgs:
951 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000952 sys.stdout.write(
953 " client: sending %s...\n" % repr(indata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000954 if wrapped:
955 conn.write(indata)
956 outdata = conn.read()
957 else:
958 s.send(indata)
959 outdata = s.recv(1024)
Bill Janssen296a59d2007-09-16 22:06:00 +0000960 if (indata == "STARTTLS" and
961 outdata.strip().lower().startswith("ok")):
Bill Janssen98d19da2007-09-10 21:51:02 +0000962 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000963 sys.stdout.write(
964 " client: read %s from server, starting TLS...\n"
965 % repr(outdata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000966 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Bill Janssen98d19da2007-09-10 21:51:02 +0000967 wrapped = True
Bill Janssen39295c22008-08-12 16:31:21 +0000968 elif (indata == "ENDTLS" and
969 outdata.strip().lower().startswith("ok")):
970 if test_support.verbose:
971 sys.stdout.write(
972 " client: read %s from server, ending TLS...\n"
973 % repr(outdata))
974 s = conn.unwrap()
975 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +0000976 else:
977 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000978 sys.stdout.write(
979 " client: read %s from server\n" % repr(outdata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000980 if test_support.verbose:
981 sys.stdout.write(" client: closing connection.\n")
982 if wrapped:
983 conn.write("over\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000984 else:
985 s.send("over\n")
986 s.close()
987 finally:
988 server.stop()
989 server.join()
990
Bill Janssen934b16d2008-06-28 22:19:33 +0000991 def testSocketServer(self):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000992
Bill Janssen934b16d2008-06-28 22:19:33 +0000993 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +0000994 flag = threading.Event()
995 server.start(flag)
996 # wait for it to start
997 flag.wait()
998 # try to connect
999 try:
1000 if test_support.verbose:
1001 sys.stdout.write('\n')
Bill Janssenbf10c472007-09-16 23:16:46 +00001002 d1 = open(CERTFILE, 'rb').read()
Bill Janssen296a59d2007-09-16 22:06:00 +00001003 d2 = ''
1004 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +00001005 url = 'https://127.0.0.1:%d/%s' % (
1006 server.port, os.path.split(CERTFILE)[1])
Bill Janssen296a59d2007-09-16 22:06:00 +00001007 f = urllib.urlopen(url)
1008 dlen = f.info().getheader("content-length")
1009 if dlen and (int(dlen) > 0):
1010 d2 = f.read(int(dlen))
1011 if test_support.verbose:
1012 sys.stdout.write(
1013 " client: read %d bytes from remote server '%s'\n"
1014 % (len(d2), server))
1015 f.close()
1016 except:
1017 msg = ''.join(traceback.format_exception(*sys.exc_info()))
1018 if test_support.verbose:
1019 sys.stdout.write('\n' + msg)
1020 raise test_support.TestFailed(msg)
1021 else:
1022 if not (d1 == d2):
1023 raise test_support.TestFailed(
1024 "Couldn't fetch data from HTTPS server")
1025 finally:
1026 server.stop()
1027 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001028
Bill Janssen934b16d2008-06-28 22:19:33 +00001029 def testWrappedAccept (self):
1030
1031 if test_support.verbose:
1032 sys.stdout.write("\n")
1033 serverParamsTest(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1034 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1035 chatty=True, connectionchatty=True,
1036 wrap_accepting_socket=True)
1037
1038
1039 def testAsyncoreServer (self):
1040
1041 indata = "TEST MESSAGE of mixed case\n"
1042
1043 if test_support.verbose:
1044 sys.stdout.write("\n")
1045 server = AsyncoreEchoServer(CERTFILE)
1046 flag = threading.Event()
1047 server.start(flag)
1048 # wait for it to start
1049 flag.wait()
1050 # try to connect
1051 try:
1052 try:
1053 s = ssl.wrap_socket(socket.socket())
1054 s.connect(('127.0.0.1', server.port))
1055 except ssl.SSLError, x:
1056 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
1057 except Exception, x:
1058 raise test_support.TestFailed("Unexpected exception: " + str(x))
1059 else:
1060 if test_support.verbose:
1061 sys.stdout.write(
1062 " client: sending %s...\n" % (repr(indata)))
1063 s.write(indata)
1064 outdata = s.read()
1065 if test_support.verbose:
1066 sys.stdout.write(" client: read %s\n" % repr(outdata))
1067 if outdata != indata.lower():
1068 raise test_support.TestFailed(
1069 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1070 % (outdata[:min(len(outdata),20)], len(outdata),
1071 indata[:min(len(indata),20)].lower(), len(indata)))
1072 s.write("over\n")
1073 if test_support.verbose:
1074 sys.stdout.write(" client: closing connection.\n")
1075 s.close()
1076 finally:
1077 server.stop()
1078 # wait for server thread to end
1079 server.join()
1080
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001081
Bill Janssen61c001a2008-09-08 16:37:24 +00001082 def testAllRecvAndSendMethods(self):
1083
1084 if test_support.verbose:
1085 sys.stdout.write("\n")
1086
1087 server = ThreadedEchoServer(CERTFILE,
1088 certreqs=ssl.CERT_NONE,
1089 ssl_version=ssl.PROTOCOL_TLSv1,
1090 cacerts=CERTFILE,
1091 chatty=True,
1092 connectionchatty=False)
1093 flag = threading.Event()
1094 server.start(flag)
1095 # wait for it to start
1096 flag.wait()
1097 # try to connect
1098 try:
1099 s = ssl.wrap_socket(socket.socket(),
1100 server_side=False,
1101 certfile=CERTFILE,
1102 ca_certs=CERTFILE,
1103 cert_reqs=ssl.CERT_NONE,
1104 ssl_version=ssl.PROTOCOL_TLSv1)
1105 s.connect((HOST, server.port))
1106 except ssl.SSLError as x:
1107 raise support.TestFailed("Unexpected SSL error: " + str(x))
1108 except Exception as x:
1109 raise support.TestFailed("Unexpected exception: " + str(x))
1110 else:
1111 # helper methods for standardising recv* method signatures
1112 def _recv_into():
1113 b = bytearray("\0"*100)
1114 count = s.recv_into(b)
1115 return b[:count]
1116
1117 def _recvfrom_into():
1118 b = bytearray("\0"*100)
1119 count, addr = s.recvfrom_into(b)
1120 return b[:count]
1121
1122 # (name, method, whether to expect success, *args)
1123 send_methods = [
1124 ('send', s.send, True, []),
1125 ('sendto', s.sendto, False, ["some.address"]),
1126 ('sendall', s.sendall, True, []),
1127 ]
1128 recv_methods = [
1129 ('recv', s.recv, True, []),
1130 ('recvfrom', s.recvfrom, False, ["some.address"]),
1131 ('recv_into', _recv_into, True, []),
1132 ('recvfrom_into', _recvfrom_into, False, []),
1133 ]
1134 data_prefix = u"PREFIX_"
1135
1136 for meth_name, send_meth, expect_success, args in send_methods:
1137 indata = data_prefix + meth_name
1138 try:
1139 send_meth(indata.encode('ASCII', 'strict'), *args)
1140 outdata = s.read()
1141 outdata = outdata.decode('ASCII', 'strict')
1142 if outdata != indata.lower():
1143 raise support.TestFailed(
1144 "While sending with <<%s>> bad data "
1145 "<<%r>> (%d) received; "
1146 "expected <<%r>> (%d)\n" % (
1147 meth_name, outdata[:20], len(outdata),
1148 indata[:20], len(indata)
1149 )
1150 )
1151 except ValueError as e:
1152 if expect_success:
1153 raise support.TestFailed(
1154 "Failed to send with method <<%s>>; "
1155 "expected to succeed.\n" % (meth_name,)
1156 )
1157 if not str(e).startswith(meth_name):
1158 raise support.TestFailed(
1159 "Method <<%s>> failed with unexpected "
1160 "exception message: %s\n" % (
1161 meth_name, e
1162 )
1163 )
1164
1165 for meth_name, recv_meth, expect_success, args in recv_methods:
1166 indata = data_prefix + meth_name
1167 try:
1168 s.send(indata.encode('ASCII', 'strict'))
1169 outdata = recv_meth(*args)
1170 outdata = outdata.decode('ASCII', 'strict')
1171 if outdata != indata.lower():
1172 raise support.TestFailed(
1173 "While receiving with <<%s>> bad data "
1174 "<<%r>> (%d) received; "
1175 "expected <<%r>> (%d)\n" % (
1176 meth_name, outdata[:20], len(outdata),
1177 indata[:20], len(indata)
1178 )
1179 )
1180 except ValueError as e:
1181 if expect_success:
1182 raise support.TestFailed(
1183 "Failed to receive with method <<%s>>; "
1184 "expected to succeed.\n" % (meth_name,)
1185 )
1186 if not str(e).startswith(meth_name):
1187 raise support.TestFailed(
1188 "Method <<%s>> failed with unexpected "
1189 "exception message: %s\n" % (
1190 meth_name, e
1191 )
1192 )
1193 # consume data
1194 s.read()
1195
1196 s.write("over\n".encode("ASCII", "strict"))
1197 s.close()
1198 finally:
1199 server.stop()
1200 server.join()
1201
1202
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001203def test_main(verbose=False):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001204 if skip_expected:
Bill Janssenffe576d2007-09-05 00:46:27 +00001205 raise test_support.TestSkipped("No SSL support")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001206
Trent Nelsone41b0062008-04-08 23:47:30 +00001207 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001208 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001209 "keycert.pem")
1210 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1211 os.path.dirname(__file__) or os.curdir,
1212 "https_svn_python_org_root.pem")
1213
1214 if (not os.path.exists(CERTFILE) or
1215 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001216 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001217
Bill Janssen934b16d2008-06-28 22:19:33 +00001218 TESTPORT = test_support.find_unused_port()
1219 if not TESTPORT:
1220 raise test_support.TestFailed("Can't find open port to test servers on!")
1221
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001222 tests = [BasicTests]
1223
Bill Janssen296a59d2007-09-16 22:06:00 +00001224 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001225 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001226
Bill Janssen98d19da2007-09-10 21:51:02 +00001227 if _have_threads:
1228 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001229 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001230 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001231
Bill Janssen98d19da2007-09-10 21:51:02 +00001232 test_support.run_unittest(*tests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001233
Bill Janssen98d19da2007-09-10 21:51:02 +00001234 if _have_threads:
1235 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001236
1237if __name__ == "__main__":
1238 test_main()