blob: 12373d19eb6290a36d385da25eee3d5afba14a3b [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
17
Bill Janssen296a59d2007-09-16 22:06:00 +000018from BaseHTTPServer import HTTPServer
19from SimpleHTTPServer import SimpleHTTPRequestHandler
20
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000021# Optionally test SSL support, if we have it in the tested platform
22skip_expected = False
23try:
24 import ssl
25except ImportError:
26 skip_expected = True
27
Trent Nelsone41b0062008-04-08 23:47:30 +000028HOST = test_support.HOST
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000029CERTFILE = None
Bill Janssen296a59d2007-09-16 22:06:00 +000030SVN_PYTHON_ORG_ROOT_CERT = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000031
Neal Norwitz3e533c22007-08-27 01:03:18 +000032def handle_error(prefix):
33 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Bill Janssen98d19da2007-09-10 21:51:02 +000034 if test_support.verbose:
35 sys.stdout.write(prefix + exc_format)
Neal Norwitz3e533c22007-08-27 01:03:18 +000036
Bill Jansseneb257ac2008-09-29 18:56:38 +000037 def testSimpleSSLwrap(self):
38 try:
39 ssl.sslwrap_simple(socket.socket(socket.AF_INET))
40 except IOError, e:
41 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
42 pass
43 else:
44 raise
45 try:
46 ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
47 except IOError, e:
48 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
49 pass
50 else:
51 raise
Neal Norwitz3e533c22007-08-27 01:03:18 +000052
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000053class BasicTests(unittest.TestCase):
54
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000055 def testSSLconnect(self):
Christian Heimes6c29be52008-01-19 16:39:27 +000056 if not test_support.is_resource_enabled('network'):
57 return
Bill Janssen296a59d2007-09-16 22:06:00 +000058 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
59 cert_reqs=ssl.CERT_NONE)
60 s.connect(("svn.python.org", 443))
61 c = s.getpeercert()
62 if c:
63 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
64 s.close()
65
66 # this should fail because we have no verification certs
67 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
68 cert_reqs=ssl.CERT_REQUIRED)
69 try:
70 s.connect(("svn.python.org", 443))
71 except ssl.SSLError:
72 pass
73 finally:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000074 s.close()
75
Bill Janssen98d19da2007-09-10 21:51:02 +000076 def testCrucialConstants(self):
77 ssl.PROTOCOL_SSLv2
78 ssl.PROTOCOL_SSLv23
79 ssl.PROTOCOL_SSLv3
80 ssl.PROTOCOL_TLSv1
81 ssl.CERT_NONE
82 ssl.CERT_OPTIONAL
83 ssl.CERT_REQUIRED
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000084
Bill Janssen98d19da2007-09-10 21:51:02 +000085 def testRAND(self):
86 v = ssl.RAND_status()
87 if test_support.verbose:
88 sys.stdout.write("\n RAND_status is %d (%s)\n"
89 % (v, (v and "sufficient randomness") or
90 "insufficient randomness"))
Guido van Rossume4729332007-08-26 19:35:09 +000091 try:
Bill Janssen98d19da2007-09-10 21:51:02 +000092 ssl.RAND_egd(1)
93 except TypeError:
94 pass
Guido van Rossume4729332007-08-26 19:35:09 +000095 else:
Bill Janssen98d19da2007-09-10 21:51:02 +000096 print "didn't raise TypeError"
97 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000098
Bill Janssen98d19da2007-09-10 21:51:02 +000099 def testParseCert(self):
100 # note that this uses an 'unofficial' function in _ssl.c,
101 # provided solely for this test, to exercise the certificate
102 # parsing code
103 p = ssl._ssl._test_decode_cert(CERTFILE, False)
104 if test_support.verbose:
105 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000106
Bill Janssen296a59d2007-09-16 22:06:00 +0000107 def testDERtoPEM(self):
108
109 pem = open(SVN_PYTHON_ORG_ROOT_CERT, 'r').read()
110 d1 = ssl.PEM_cert_to_DER_cert(pem)
111 p2 = ssl.DER_cert_to_PEM_cert(d1)
112 d2 = ssl.PEM_cert_to_DER_cert(p2)
113 if (d1 != d2):
114 raise test_support.TestFailed("PEM-to-DER or DER-to-PEM translation failed")
115
Bill Janssen934b16d2008-06-28 22:19:33 +0000116class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +0000117
118 def testConnect(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000119 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
120 cert_reqs=ssl.CERT_NONE)
121 s.connect(("svn.python.org", 443))
122 c = s.getpeercert()
123 if c:
124 raise test_support.TestFailed("Peer cert %s shouldn't be here!")
125 s.close()
126
127 # this should fail because we have no verification certs
128 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
129 cert_reqs=ssl.CERT_REQUIRED)
130 try:
131 s.connect(("svn.python.org", 443))
132 except ssl.SSLError:
133 pass
134 finally:
135 s.close()
136
137 # this should succeed because we specify the root cert
138 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
139 cert_reqs=ssl.CERT_REQUIRED,
140 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
141 try:
142 s.connect(("svn.python.org", 443))
143 except ssl.SSLError, x:
144 raise test_support.TestFailed("Unexpected exception %s" % x)
145 finally:
146 s.close()
147
Bill Janssen934b16d2008-06-28 22:19:33 +0000148
149 def testNonBlockingHandshake(self):
150 s = socket.socket(socket.AF_INET)
151 s.connect(("svn.python.org", 443))
152 s.setblocking(False)
153 s = ssl.wrap_socket(s,
154 cert_reqs=ssl.CERT_NONE,
155 do_handshake_on_connect=False)
156 count = 0
157 while True:
158 try:
159 count += 1
160 s.do_handshake()
161 break
162 except ssl.SSLError, err:
163 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
164 select.select([s], [], [])
165 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
166 select.select([], [s], [])
167 else:
168 raise
169 s.close()
170 if test_support.verbose:
171 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
172
Bill Janssen296a59d2007-09-16 22:06:00 +0000173 def testFetchServerCert(self):
174
175 pem = ssl.get_server_certificate(("svn.python.org", 443))
176 if not pem:
177 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
178
179 try:
180 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
181 except ssl.SSLError:
182 #should fail
183 pass
184 else:
185 raise test_support.TestFailed("Got server certificate %s for svn.python.org!" % pem)
186
187 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
188 if not pem:
189 raise test_support.TestFailed("No server certificate on svn.python.org:443!")
190 if test_support.verbose:
191 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
192
Antoine Pitroub7c656f2010-04-22 18:42:58 +0000193 # Test disabled: OPENSSL_VERSION* not available in Python 2.6
Antoine Pitrou878602a2010-04-21 19:41:28 +0000194 def test_algorithms(self):
Antoine Pitroub7c656f2010-04-22 18:42:58 +0000195 if test_support.verbose:
196 sys.stdout.write("test_algorithms disabled, "
197 "as it fails on some old OpenSSL versions")
198 return
Antoine Pitrou878602a2010-04-21 19:41:28 +0000199 # Issue #8484: all algorithms should be available when verifying a
200 # certificate.
201 # NOTE: https://sha256.tbs-internet.com is another possible test host
202 remote = ("sha2.hboeck.de", 443)
203 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
204 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
205 cert_reqs=ssl.CERT_REQUIRED,
206 ca_certs=sha256_cert,)
207 with test_support.transient_internet():
208 try:
209 s.connect(remote)
210 if test_support.verbose:
211 sys.stdout.write("\nCipher with %r is %r\n" %
212 (remote, s.cipher()))
213 sys.stdout.write("Certificate is:\n%s\n" %
214 pprint.pformat(s.getpeercert()))
215 finally:
216 s.close()
217
Bill Janssen296a59d2007-09-16 22:06:00 +0000218
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:
690 if connectionchatty:
691 if test_support.verbose:
692 sys.stdout.write(
693 " client: sending %s...\n" % (repr(indata)))
694 s.write(indata)
695 outdata = s.read()
696 if connectionchatty:
697 if test_support.verbose:
698 sys.stdout.write(" client: read %s\n" % repr(outdata))
699 if outdata != indata.lower():
700 raise test_support.TestFailed(
701 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
702 % (outdata[:min(len(outdata),20)], len(outdata),
703 indata[:min(len(indata),20)].lower(), len(indata)))
704 s.write("over\n")
705 if connectionchatty:
706 if test_support.verbose:
707 sys.stdout.write(" client: closing connection.\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000708 s.close()
709 finally:
710 server.stop()
711 server.join()
712
713 def tryProtocolCombo (server_protocol,
714 client_protocol,
715 expectedToWork,
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000716 certsreqs=None):
717
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000718 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000719 certsreqs = ssl.CERT_NONE
Bill Janssen98d19da2007-09-10 21:51:02 +0000720
721 if certsreqs == ssl.CERT_NONE:
722 certtype = "CERT_NONE"
723 elif certsreqs == ssl.CERT_OPTIONAL:
724 certtype = "CERT_OPTIONAL"
725 elif certsreqs == ssl.CERT_REQUIRED:
726 certtype = "CERT_REQUIRED"
727 if test_support.verbose:
728 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
729 sys.stdout.write(formatstr %
730 (ssl.get_protocol_name(client_protocol),
731 ssl.get_protocol_name(server_protocol),
732 certtype))
733 try:
734 serverParamsTest(CERTFILE, server_protocol, certsreqs,
735 CERTFILE, CERTFILE, client_protocol, chatty=False)
736 except test_support.TestFailed:
737 if expectedToWork:
738 raise
739 else:
740 if not expectedToWork:
741 raise test_support.TestFailed(
742 "Client protocol %s succeeded with server protocol %s!"
743 % (ssl.get_protocol_name(client_protocol),
744 ssl.get_protocol_name(server_protocol)))
745
746
Bill Janssen934b16d2008-06-28 22:19:33 +0000747 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000748
749 def testRudeShutdown(self):
750
751 listener_ready = threading.Event()
752 listener_gone = threading.Event()
Trent Nelsone41b0062008-04-08 23:47:30 +0000753 port = test_support.find_unused_port()
Bill Janssen98d19da2007-09-10 21:51:02 +0000754
755 # `listener` runs in a thread. It opens a socket listening on
756 # PORT, and sits in an accept() until the main thread connects.
757 # Then it rudely closes the socket, and sets Event `listener_gone`
758 # to let the main thread know the socket is gone.
759 def listener():
760 s = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000761 s.bind((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000762 s.listen(5)
763 listener_ready.set()
764 s.accept()
765 s = None # reclaim the socket object, which also closes it
766 listener_gone.set()
767
768 def connector():
769 listener_ready.wait()
770 s = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000771 s.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000772 listener_gone.wait()
773 try:
774 ssl_sock = ssl.wrap_socket(s)
Bill Janssen934b16d2008-06-28 22:19:33 +0000775 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000776 pass
777 else:
778 raise test_support.TestFailed(
779 'connecting to closed SSL socket should have failed')
780
781 t = threading.Thread(target=listener)
782 t.start()
783 connector()
784 t.join()
785
786 def testEcho (self):
787
788 if test_support.verbose:
789 sys.stdout.write("\n")
790 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
791 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
792 chatty=True, connectionchatty=True)
793
794 def testReadCert(self):
795
796 if test_support.verbose:
797 sys.stdout.write("\n")
798 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000799 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000800 certreqs=ssl.CERT_NONE,
801 ssl_version=ssl.PROTOCOL_SSLv23,
802 cacerts=CERTFILE,
803 chatty=False)
804 flag = threading.Event()
805 server.start(flag)
806 # wait for it to start
807 flag.wait()
808 # try to connect
809 try:
810 try:
811 s = ssl.wrap_socket(socket.socket(),
812 certfile=CERTFILE,
813 ca_certs=CERTFILE,
814 cert_reqs=ssl.CERT_REQUIRED,
815 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelsone41b0062008-04-08 23:47:30 +0000816 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000817 except ssl.SSLError, x:
818 raise test_support.TestFailed(
819 "Unexpected SSL error: " + str(x))
820 except Exception, x:
821 raise test_support.TestFailed(
822 "Unexpected exception: " + str(x))
823 else:
824 if not s:
825 raise test_support.TestFailed(
826 "Can't SSL-handshake with test server")
827 cert = s.getpeercert()
828 if not cert:
829 raise test_support.TestFailed(
830 "Can't get peer certificate.")
831 cipher = s.cipher()
832 if test_support.verbose:
833 sys.stdout.write(pprint.pformat(cert) + '\n')
834 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
835 if not cert.has_key('subject'):
836 raise test_support.TestFailed(
837 "No subject field in certificate: %s." %
838 pprint.pformat(cert))
839 if ((('organizationName', 'Python Software Foundation'),)
840 not in cert['subject']):
841 raise test_support.TestFailed(
842 "Missing or invalid 'organizationName' field in certificate subject; "
Neal Norwitz0098c9d2008-03-09 19:03:42 +0000843 "should be 'Python Software Foundation'.")
Bill Janssen98d19da2007-09-10 21:51:02 +0000844 s.close()
845 finally:
846 server.stop()
847 server.join()
848
849 def testNULLcert(self):
850 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
851 "nullcert.pem"))
852 def testMalformedCert(self):
853 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
854 "badcert.pem"))
Bill Janssen934b16d2008-06-28 22:19:33 +0000855 def testWrongCert(self):
856 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
857 "wrongcert.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000858 def testMalformedKey(self):
859 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
860 "badkey.pem"))
861
862 def testProtocolSSL2(self):
863 if test_support.verbose:
864 sys.stdout.write("\n")
865 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
866 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
867 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
868 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
869 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
870 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
871
872 def testProtocolSSL23(self):
873 if test_support.verbose:
874 sys.stdout.write("\n")
875 try:
876 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
877 except test_support.TestFailed, x:
878 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
879 if test_support.verbose:
880 sys.stdout.write(
881 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
882 % str(x))
883 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
884 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
885 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
886
887 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
888 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
889 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
890
891 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
892 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
893 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
894
895 def testProtocolSSL3(self):
896 if test_support.verbose:
897 sys.stdout.write("\n")
898 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
899 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
900 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
901 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
902 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
903 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
904
905 def testProtocolTLS1(self):
906 if test_support.verbose:
907 sys.stdout.write("\n")
908 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
909 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
910 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
911 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
912 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
913 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
914
915 def testSTARTTLS (self):
916
Bill Janssen39295c22008-08-12 16:31:21 +0000917 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +0000918
Trent Nelsone41b0062008-04-08 23:47:30 +0000919 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000920 ssl_version=ssl.PROTOCOL_TLSv1,
921 starttls_server=True,
922 chatty=True,
923 connectionchatty=True)
924 flag = threading.Event()
925 server.start(flag)
926 # wait for it to start
927 flag.wait()
928 # try to connect
929 wrapped = False
930 try:
931 try:
932 s = socket.socket()
933 s.setblocking(1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000934 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000935 except Exception, x:
936 raise test_support.TestFailed("Unexpected exception: " + str(x))
937 else:
938 if test_support.verbose:
939 sys.stdout.write("\n")
940 for indata in msgs:
941 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000942 sys.stdout.write(
943 " client: sending %s...\n" % repr(indata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000944 if wrapped:
945 conn.write(indata)
946 outdata = conn.read()
947 else:
948 s.send(indata)
949 outdata = s.recv(1024)
Bill Janssen296a59d2007-09-16 22:06:00 +0000950 if (indata == "STARTTLS" and
951 outdata.strip().lower().startswith("ok")):
Bill Janssen98d19da2007-09-10 21:51:02 +0000952 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000953 sys.stdout.write(
954 " client: read %s from server, starting TLS...\n"
955 % repr(outdata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000956 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Bill Janssen98d19da2007-09-10 21:51:02 +0000957 wrapped = True
Bill Janssen39295c22008-08-12 16:31:21 +0000958 elif (indata == "ENDTLS" and
959 outdata.strip().lower().startswith("ok")):
960 if test_support.verbose:
961 sys.stdout.write(
962 " client: read %s from server, ending TLS...\n"
963 % repr(outdata))
964 s = conn.unwrap()
965 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +0000966 else:
967 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +0000968 sys.stdout.write(
969 " client: read %s from server\n" % repr(outdata))
Bill Janssen98d19da2007-09-10 21:51:02 +0000970 if test_support.verbose:
971 sys.stdout.write(" client: closing connection.\n")
972 if wrapped:
973 conn.write("over\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000974 else:
975 s.send("over\n")
976 s.close()
977 finally:
978 server.stop()
979 server.join()
980
Bill Janssen934b16d2008-06-28 22:19:33 +0000981 def testSocketServer(self):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000982
Bill Janssen934b16d2008-06-28 22:19:33 +0000983 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +0000984 flag = threading.Event()
985 server.start(flag)
986 # wait for it to start
987 flag.wait()
988 # try to connect
989 try:
990 if test_support.verbose:
991 sys.stdout.write('\n')
Bill Janssenbf10c472007-09-16 23:16:46 +0000992 d1 = open(CERTFILE, 'rb').read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000993 d2 = ''
994 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +0000995 url = 'https://127.0.0.1:%d/%s' % (
996 server.port, os.path.split(CERTFILE)[1])
Bill Janssen296a59d2007-09-16 22:06:00 +0000997 f = urllib.urlopen(url)
998 dlen = f.info().getheader("content-length")
999 if dlen and (int(dlen) > 0):
1000 d2 = f.read(int(dlen))
1001 if test_support.verbose:
1002 sys.stdout.write(
1003 " client: read %d bytes from remote server '%s'\n"
1004 % (len(d2), server))
1005 f.close()
1006 except:
1007 msg = ''.join(traceback.format_exception(*sys.exc_info()))
1008 if test_support.verbose:
1009 sys.stdout.write('\n' + msg)
1010 raise test_support.TestFailed(msg)
1011 else:
1012 if not (d1 == d2):
1013 raise test_support.TestFailed(
1014 "Couldn't fetch data from HTTPS server")
1015 finally:
1016 server.stop()
1017 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001018
Bill Janssen934b16d2008-06-28 22:19:33 +00001019 def testWrappedAccept (self):
1020
1021 if test_support.verbose:
1022 sys.stdout.write("\n")
1023 serverParamsTest(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1024 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1025 chatty=True, connectionchatty=True,
1026 wrap_accepting_socket=True)
1027
1028
1029 def testAsyncoreServer (self):
1030
1031 indata = "TEST MESSAGE of mixed case\n"
1032
1033 if test_support.verbose:
1034 sys.stdout.write("\n")
1035 server = AsyncoreEchoServer(CERTFILE)
1036 flag = threading.Event()
1037 server.start(flag)
1038 # wait for it to start
1039 flag.wait()
1040 # try to connect
1041 try:
1042 try:
1043 s = ssl.wrap_socket(socket.socket())
1044 s.connect(('127.0.0.1', server.port))
1045 except ssl.SSLError, x:
1046 raise test_support.TestFailed("Unexpected SSL error: " + str(x))
1047 except Exception, x:
1048 raise test_support.TestFailed("Unexpected exception: " + str(x))
1049 else:
1050 if test_support.verbose:
1051 sys.stdout.write(
1052 " client: sending %s...\n" % (repr(indata)))
1053 s.write(indata)
1054 outdata = s.read()
1055 if test_support.verbose:
1056 sys.stdout.write(" client: read %s\n" % repr(outdata))
1057 if outdata != indata.lower():
1058 raise test_support.TestFailed(
1059 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1060 % (outdata[:min(len(outdata),20)], len(outdata),
1061 indata[:min(len(indata),20)].lower(), len(indata)))
1062 s.write("over\n")
1063 if test_support.verbose:
1064 sys.stdout.write(" client: closing connection.\n")
1065 s.close()
1066 finally:
1067 server.stop()
1068 # wait for server thread to end
1069 server.join()
1070
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001071
Bill Janssen61c001a2008-09-08 16:37:24 +00001072 def testAllRecvAndSendMethods(self):
1073
1074 if test_support.verbose:
1075 sys.stdout.write("\n")
1076
1077 server = ThreadedEchoServer(CERTFILE,
1078 certreqs=ssl.CERT_NONE,
1079 ssl_version=ssl.PROTOCOL_TLSv1,
1080 cacerts=CERTFILE,
1081 chatty=True,
1082 connectionchatty=False)
1083 flag = threading.Event()
1084 server.start(flag)
1085 # wait for it to start
1086 flag.wait()
1087 # try to connect
1088 try:
1089 s = ssl.wrap_socket(socket.socket(),
1090 server_side=False,
1091 certfile=CERTFILE,
1092 ca_certs=CERTFILE,
1093 cert_reqs=ssl.CERT_NONE,
1094 ssl_version=ssl.PROTOCOL_TLSv1)
1095 s.connect((HOST, server.port))
1096 except ssl.SSLError as x:
1097 raise support.TestFailed("Unexpected SSL error: " + str(x))
1098 except Exception as x:
1099 raise support.TestFailed("Unexpected exception: " + str(x))
1100 else:
1101 # helper methods for standardising recv* method signatures
1102 def _recv_into():
1103 b = bytearray("\0"*100)
1104 count = s.recv_into(b)
1105 return b[:count]
1106
1107 def _recvfrom_into():
1108 b = bytearray("\0"*100)
1109 count, addr = s.recvfrom_into(b)
1110 return b[:count]
1111
1112 # (name, method, whether to expect success, *args)
1113 send_methods = [
1114 ('send', s.send, True, []),
1115 ('sendto', s.sendto, False, ["some.address"]),
1116 ('sendall', s.sendall, True, []),
1117 ]
1118 recv_methods = [
1119 ('recv', s.recv, True, []),
1120 ('recvfrom', s.recvfrom, False, ["some.address"]),
1121 ('recv_into', _recv_into, True, []),
1122 ('recvfrom_into', _recvfrom_into, False, []),
1123 ]
1124 data_prefix = u"PREFIX_"
1125
1126 for meth_name, send_meth, expect_success, args in send_methods:
1127 indata = data_prefix + meth_name
1128 try:
1129 send_meth(indata.encode('ASCII', 'strict'), *args)
1130 outdata = s.read()
1131 outdata = outdata.decode('ASCII', 'strict')
1132 if outdata != indata.lower():
1133 raise support.TestFailed(
1134 "While sending with <<%s>> bad data "
1135 "<<%r>> (%d) received; "
1136 "expected <<%r>> (%d)\n" % (
1137 meth_name, outdata[:20], len(outdata),
1138 indata[:20], len(indata)
1139 )
1140 )
1141 except ValueError as e:
1142 if expect_success:
1143 raise support.TestFailed(
1144 "Failed to send with method <<%s>>; "
1145 "expected to succeed.\n" % (meth_name,)
1146 )
1147 if not str(e).startswith(meth_name):
1148 raise support.TestFailed(
1149 "Method <<%s>> failed with unexpected "
1150 "exception message: %s\n" % (
1151 meth_name, e
1152 )
1153 )
1154
1155 for meth_name, recv_meth, expect_success, args in recv_methods:
1156 indata = data_prefix + meth_name
1157 try:
1158 s.send(indata.encode('ASCII', 'strict'))
1159 outdata = recv_meth(*args)
1160 outdata = outdata.decode('ASCII', 'strict')
1161 if outdata != indata.lower():
1162 raise support.TestFailed(
1163 "While receiving with <<%s>> bad data "
1164 "<<%r>> (%d) received; "
1165 "expected <<%r>> (%d)\n" % (
1166 meth_name, outdata[:20], len(outdata),
1167 indata[:20], len(indata)
1168 )
1169 )
1170 except ValueError as e:
1171 if expect_success:
1172 raise support.TestFailed(
1173 "Failed to receive with method <<%s>>; "
1174 "expected to succeed.\n" % (meth_name,)
1175 )
1176 if not str(e).startswith(meth_name):
1177 raise support.TestFailed(
1178 "Method <<%s>> failed with unexpected "
1179 "exception message: %s\n" % (
1180 meth_name, e
1181 )
1182 )
1183 # consume data
1184 s.read()
1185
1186 s.write("over\n".encode("ASCII", "strict"))
1187 s.close()
1188 finally:
1189 server.stop()
1190 server.join()
1191
1192
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001193def test_main(verbose=False):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001194 if skip_expected:
Bill Janssenffe576d2007-09-05 00:46:27 +00001195 raise test_support.TestSkipped("No SSL support")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001196
Trent Nelsone41b0062008-04-08 23:47:30 +00001197 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001198 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001199 "keycert.pem")
1200 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1201 os.path.dirname(__file__) or os.curdir,
1202 "https_svn_python_org_root.pem")
1203
1204 if (not os.path.exists(CERTFILE) or
1205 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001206 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001207
Bill Janssen934b16d2008-06-28 22:19:33 +00001208 TESTPORT = test_support.find_unused_port()
1209 if not TESTPORT:
1210 raise test_support.TestFailed("Can't find open port to test servers on!")
1211
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001212 tests = [BasicTests]
1213
Bill Janssen296a59d2007-09-16 22:06:00 +00001214 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001215 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001216
Bill Janssen98d19da2007-09-10 21:51:02 +00001217 if _have_threads:
1218 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001219 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001220 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001221
Bill Janssen98d19da2007-09-10 21:51:02 +00001222 test_support.run_unittest(*tests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001223
Bill Janssen98d19da2007-09-10 21:51:02 +00001224 if _have_threads:
1225 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001226
1227if __name__ == "__main__":
1228 test_main()