blob: 20cfe38e360b6262d461a3b56cad24e0fc4f08d0 [file] [log] [blame]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
5from test import test_support
Bill Janssen934b16d2008-06-28 22:19:33 +00006import asyncore
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00007import socket
Bill Janssen934b16d2008-06-28 22:19:33 +00008import select
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00009import time
Antoine Pitroub558f172010-04-23 23:25:45 +000010import gc
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000011import os
Antoine Pitroub558f172010-04-23 23:25:45 +000012import errno
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000013import pprint
Bill Janssen296a59d2007-09-16 22:06:00 +000014import urllib, urlparse
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000015import traceback
Antoine Pitroudfb299b2010-04-23 22:54:59 +000016import weakref
Antoine Pitroud75efd92010-08-04 17:38:33 +000017import functools
18import platform
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000019
Bill Janssen296a59d2007-09-16 22:06:00 +000020from BaseHTTPServer import HTTPServer
21from SimpleHTTPServer import SimpleHTTPRequestHandler
22
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000023# Optionally test SSL support, if we have it in the tested platform
24skip_expected = False
25try:
26 import ssl
27except ImportError:
28 skip_expected = True
29
Trent Nelsone41b0062008-04-08 23:47:30 +000030HOST = test_support.HOST
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000031CERTFILE = None
Bill Janssen296a59d2007-09-16 22:06:00 +000032SVN_PYTHON_ORG_ROOT_CERT = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000033
Neal Norwitz3e533c22007-08-27 01:03:18 +000034def handle_error(prefix):
35 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Bill Janssen98d19da2007-09-10 21:51:02 +000036 if test_support.verbose:
37 sys.stdout.write(prefix + exc_format)
Neal Norwitz3e533c22007-08-27 01:03:18 +000038
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000039
40class BasicTests(unittest.TestCase):
41
Antoine Pitrou3945c862010-04-28 21:11:01 +000042 def test_sslwrap_simple(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000043 # A crude test for the legacy API
Bill Jansseneb257ac2008-09-29 18:56:38 +000044 try:
45 ssl.sslwrap_simple(socket.socket(socket.AF_INET))
46 except IOError, e:
47 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
48 pass
49 else:
50 raise
51 try:
52 ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
53 except IOError, e:
54 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
55 pass
56 else:
57 raise
Neal Norwitz3e533c22007-08-27 01:03:18 +000058
Antoine Pitroud75efd92010-08-04 17:38:33 +000059# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
60def skip_if_broken_ubuntu_ssl(func):
61 # We need to access the lower-level wrapper in order to create an
62 # implicit SSL context without trying to connect or listen.
Antoine Pitrou969fbe32010-08-05 01:30:23 +000063 try:
64 import _ssl
65 except ImportError:
66 # The returned function won't get executed, just ignore the error
67 pass
Antoine Pitroud75efd92010-08-04 17:38:33 +000068 @functools.wraps(func)
69 def f(*args, **kwargs):
70 try:
71 s = socket.socket(socket.AF_INET)
72 _ssl.sslwrap(s._sock, 0, None, None,
73 ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
74 except ssl.SSLError as e:
75 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
76 platform.linux_distribution() == ('debian', 'squeeze/sid', '')
77 and 'Invalid SSL protocol variant specified' in str(e)):
78 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
79 return func(*args, **kwargs)
80 return f
81
82
83class BasicSocketTests(unittest.TestCase):
84
Antoine Pitrou3945c862010-04-28 21:11:01 +000085 def test_constants(self):
Bill Janssen98d19da2007-09-10 21:51:02 +000086 ssl.PROTOCOL_SSLv2
87 ssl.PROTOCOL_SSLv23
88 ssl.PROTOCOL_SSLv3
89 ssl.PROTOCOL_TLSv1
90 ssl.CERT_NONE
91 ssl.CERT_OPTIONAL
92 ssl.CERT_REQUIRED
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000093
Antoine Pitrou3945c862010-04-28 21:11:01 +000094 def test_random(self):
Bill Janssen98d19da2007-09-10 21:51:02 +000095 v = ssl.RAND_status()
96 if test_support.verbose:
97 sys.stdout.write("\n RAND_status is %d (%s)\n"
98 % (v, (v and "sufficient randomness") or
99 "insufficient randomness"))
Guido van Rossume4729332007-08-26 19:35:09 +0000100 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000101 ssl.RAND_egd(1)
102 except TypeError:
103 pass
Guido van Rossume4729332007-08-26 19:35:09 +0000104 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000105 print "didn't raise TypeError"
106 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000107
Antoine Pitrou3945c862010-04-28 21:11:01 +0000108 def test_parse_cert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000109 # note that this uses an 'unofficial' function in _ssl.c,
110 # provided solely for this test, to exercise the certificate
111 # parsing code
112 p = ssl._ssl._test_decode_cert(CERTFILE, False)
113 if test_support.verbose:
114 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000115
Antoine Pitrou3945c862010-04-28 21:11:01 +0000116 def test_DER_to_PEM(self):
117 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
118 pem = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000119 d1 = ssl.PEM_cert_to_DER_cert(pem)
120 p2 = ssl.DER_cert_to_PEM_cert(d1)
121 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitroudb187842010-04-27 10:32:58 +0000122 self.assertEqual(d1, d2)
Antoine Pitrou4c7bcf12010-04-27 22:03:37 +0000123 if not p2.startswith(ssl.PEM_HEADER + '\n'):
124 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
125 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
126 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Bill Janssen296a59d2007-09-16 22:06:00 +0000127
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000128 def test_openssl_version(self):
129 n = ssl.OPENSSL_VERSION_NUMBER
130 t = ssl.OPENSSL_VERSION_INFO
131 s = ssl.OPENSSL_VERSION
132 self.assertIsInstance(n, (int, long))
133 self.assertIsInstance(t, tuple)
134 self.assertIsInstance(s, str)
135 # Some sanity checks follow
136 # >= 0.9
137 self.assertGreaterEqual(n, 0x900000)
138 # < 2.0
139 self.assertLess(n, 0x20000000)
140 major, minor, fix, patch, status = t
141 self.assertGreaterEqual(major, 0)
142 self.assertLess(major, 2)
143 self.assertGreaterEqual(minor, 0)
144 self.assertLess(minor, 256)
145 self.assertGreaterEqual(fix, 0)
146 self.assertLess(fix, 256)
147 self.assertGreaterEqual(patch, 0)
148 self.assertLessEqual(patch, 26)
149 self.assertGreaterEqual(status, 0)
150 self.assertLessEqual(status, 15)
151 # Version string as returned by OpenSSL, the format might change
152 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
153 (s, t))
154
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000155 def test_ciphers(self):
156 if not test_support.is_resource_enabled('network'):
157 return
158 remote = ("svn.python.org", 443)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000159 with test_support.transient_internet(remote[0]):
160 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
161 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000162 s.connect(remote)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000163 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
164 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
165 s.connect(remote)
166 # Error checking occurs when connecting, because the SSL context
167 # isn't created before.
168 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
169 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
170 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
171 s.connect(remote)
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000172
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000173 @test_support.cpython_only
174 def test_refcycle(self):
175 # Issue #7943: an SSL object doesn't create reference cycles with
176 # itself.
177 s = socket.socket(socket.AF_INET)
178 ss = ssl.wrap_socket(s)
179 wr = weakref.ref(ss)
180 del ss
181 self.assertEqual(wr(), None)
182
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000183 def test_wrapped_unconnected(self):
184 # The _delegate_methods in socket.py are correctly delegated to by an
185 # unconnected SSLSocket, so they will raise a socket.error rather than
186 # something unexpected like TypeError.
187 s = socket.socket(socket.AF_INET)
188 ss = ssl.wrap_socket(s)
189 self.assertRaises(socket.error, ss.recv, 1)
190 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
191 self.assertRaises(socket.error, ss.recvfrom, 1)
192 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
193 self.assertRaises(socket.error, ss.send, b'x')
194 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
195
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000196
Bill Janssen934b16d2008-06-28 22:19:33 +0000197class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +0000198
Antoine Pitrou3945c862010-04-28 21:11:01 +0000199 def test_connect(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000200 with test_support.transient_internet("svn.python.org"):
201 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
202 cert_reqs=ssl.CERT_NONE)
Bill Janssen296a59d2007-09-16 22:06:00 +0000203 s.connect(("svn.python.org", 443))
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000204 c = s.getpeercert()
205 if c:
206 self.fail("Peer cert %s shouldn't be here!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000207 s.close()
208
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000209 # this should fail because we have no verification certs
210 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
211 cert_reqs=ssl.CERT_REQUIRED)
212 try:
213 s.connect(("svn.python.org", 443))
214 except ssl.SSLError:
215 pass
216 finally:
217 s.close()
218
219 # this should succeed because we specify the root cert
220 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
221 cert_reqs=ssl.CERT_REQUIRED,
222 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
223 try:
224 s.connect(("svn.python.org", 443))
225 finally:
226 s.close()
Bill Janssen296a59d2007-09-16 22:06:00 +0000227
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000228 def test_connect_ex(self):
229 # Issue #11326: check connect_ex() implementation
230 with test_support.transient_internet("svn.python.org"):
231 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
232 cert_reqs=ssl.CERT_REQUIRED,
233 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
234 try:
235 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
236 self.assertTrue(s.getpeercert())
237 finally:
238 s.close()
239
240 def test_non_blocking_connect_ex(self):
241 # Issue #11326: non-blocking connect_ex() should allow handshake
242 # to proceed after the socket gets ready.
243 with test_support.transient_internet("svn.python.org"):
244 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
245 cert_reqs=ssl.CERT_REQUIRED,
246 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
247 do_handshake_on_connect=False)
248 try:
249 s.setblocking(False)
250 rc = s.connect_ex(('svn.python.org', 443))
251 self.assertIn(rc, (0, errno.EINPROGRESS))
252 # Wait for connect to finish
253 select.select([], [s], [], 5.0)
254 # Non-blocking handshake
255 while True:
256 try:
257 s.do_handshake()
258 break
259 except ssl.SSLError as err:
260 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
261 select.select([s], [], [], 5.0)
262 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
263 select.select([], [s], [], 5.0)
264 else:
265 raise
266 # SSL established
267 self.assertTrue(s.getpeercert())
268 finally:
269 s.close()
270
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000271 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
272 def test_makefile_close(self):
273 # Issue #5238: creating a file-like object with makefile() shouldn't
274 # delay closing the underlying "real socket" (here tested with its
275 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000276 with test_support.transient_internet("svn.python.org"):
277 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
278 ss.connect(("svn.python.org", 443))
279 fd = ss.fileno()
280 f = ss.makefile()
281 f.close()
282 # The fd is still open
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000283 os.read(fd, 0)
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000284 # Closing the SSL socket should close the fd too
285 ss.close()
286 gc.collect()
287 with self.assertRaises(OSError) as e:
288 os.read(fd, 0)
289 self.assertEqual(e.exception.errno, errno.EBADF)
Bill Janssen934b16d2008-06-28 22:19:33 +0000290
Antoine Pitrou3945c862010-04-28 21:11:01 +0000291 def test_non_blocking_handshake(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000292 with test_support.transient_internet("svn.python.org"):
293 s = socket.socket(socket.AF_INET)
294 s.connect(("svn.python.org", 443))
295 s.setblocking(False)
296 s = ssl.wrap_socket(s,
297 cert_reqs=ssl.CERT_NONE,
298 do_handshake_on_connect=False)
299 count = 0
300 while True:
301 try:
302 count += 1
303 s.do_handshake()
304 break
305 except ssl.SSLError, err:
306 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
307 select.select([s], [], [])
308 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
309 select.select([], [s], [])
310 else:
311 raise
312 s.close()
313 if test_support.verbose:
314 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Bill Janssen934b16d2008-06-28 22:19:33 +0000315
Antoine Pitrou3945c862010-04-28 21:11:01 +0000316 def test_get_server_certificate(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000317 with test_support.transient_internet("svn.python.org"):
318 pem = ssl.get_server_certificate(("svn.python.org", 443))
319 if not pem:
320 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000321
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000322 try:
323 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
324 except ssl.SSLError:
325 #should fail
326 pass
327 else:
328 self.fail("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000329
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000330 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
331 if not pem:
332 self.fail("No server certificate on svn.python.org:443!")
333 if test_support.verbose:
334 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000335
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000336 def test_algorithms(self):
337 # Issue #8484: all algorithms should be available when verifying a
338 # certificate.
Antoine Pitrou9aed6042010-04-22 18:00:41 +0000339 # SHA256 was added in OpenSSL 0.9.8
340 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
341 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000342 # NOTE: https://sha256.tbs-internet.com is another possible test host
Antoine Pitroud43245a2011-01-08 10:32:51 +0000343 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000344 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitroud43245a2011-01-08 10:32:51 +0000345 with test_support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrouc818ed42010-09-07 21:40:25 +0000346 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
347 cert_reqs=ssl.CERT_REQUIRED,
348 ca_certs=sha256_cert,)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000349 try:
350 s.connect(remote)
351 if test_support.verbose:
352 sys.stdout.write("\nCipher with %r is %r\n" %
353 (remote, s.cipher()))
354 sys.stdout.write("Certificate is:\n%s\n" %
355 pprint.pformat(s.getpeercert()))
356 finally:
357 s.close()
358
Bill Janssen296a59d2007-09-16 22:06:00 +0000359
Bill Janssen98d19da2007-09-10 21:51:02 +0000360try:
361 import threading
362except ImportError:
363 _have_threads = False
364else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000365 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000366
Bill Janssen98d19da2007-09-10 21:51:02 +0000367 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000368
Bill Janssen98d19da2007-09-10 21:51:02 +0000369 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000370
Bill Janssen98d19da2007-09-10 21:51:02 +0000371 """A mildly complicated class, because we want it to work both
372 with and without the SSL wrapper around the socket connection, so
373 that we can test the STARTTLS functionality."""
374
375 def __init__(self, server, connsock):
376 self.server = server
377 self.running = False
378 self.sock = connsock
379 self.sock.setblocking(1)
380 self.sslconn = None
381 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000382 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000383
Bill Janssen934b16d2008-06-28 22:19:33 +0000384 def show_conn_details(self):
385 if self.server.certreqs == ssl.CERT_REQUIRED:
386 cert = self.sslconn.getpeercert()
387 if test_support.verbose and self.server.chatty:
388 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
389 cert_binary = self.sslconn.getpeercert(True)
390 if test_support.verbose and self.server.chatty:
391 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
392 cipher = self.sslconn.cipher()
393 if test_support.verbose and self.server.chatty:
394 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
395
Antoine Pitrou3945c862010-04-28 21:11:01 +0000396 def wrap_conn(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000397 try:
398 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
399 certfile=self.server.certificate,
400 ssl_version=self.server.protocol,
401 ca_certs=self.server.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000402 cert_reqs=self.server.certreqs,
403 ciphers=self.server.ciphers)
Antoine Pitroudb187842010-04-27 10:32:58 +0000404 except ssl.SSLError:
405 # XXX Various errors can have happened here, for example
406 # a mismatching protocol version, an invalid certificate,
407 # or a low-level bug. This should be made more discriminating.
Bill Janssen98d19da2007-09-10 21:51:02 +0000408 if self.server.chatty:
409 handle_error("\n server: bad connection attempt from " +
410 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000411 self.close()
Antoine Pitroudb187842010-04-27 10:32:58 +0000412 self.running = False
413 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000414 return False
Bill Janssen98d19da2007-09-10 21:51:02 +0000415 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000416 return True
417
418 def read(self):
419 if self.sslconn:
420 return self.sslconn.read()
421 else:
422 return self.sock.recv(1024)
423
424 def write(self, bytes):
425 if self.sslconn:
426 return self.sslconn.write(bytes)
427 else:
428 return self.sock.send(bytes)
429
430 def close(self):
431 if self.sslconn:
432 self.sslconn.close()
433 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000434 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000435
Antoine Pitrou3945c862010-04-28 21:11:01 +0000436 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000437 self.running = True
438 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000439 if isinstance(self.sock, ssl.SSLSocket):
440 self.sslconn = self.sock
441 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000442 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000443 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000444 while self.running:
445 try:
446 msg = self.read()
447 if not msg:
448 # eof, so quit this handler
449 self.running = False
450 self.close()
451 elif msg.strip() == 'over':
452 if test_support.verbose and self.server.connectionchatty:
453 sys.stdout.write(" server: client closed connection\n")
454 self.close()
455 return
456 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
457 if test_support.verbose and self.server.connectionchatty:
458 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
459 self.write("OK\n")
460 if not self.wrap_conn():
461 return
Bill Janssen39295c22008-08-12 16:31:21 +0000462 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
463 if test_support.verbose and self.server.connectionchatty:
464 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
465 self.write("OK\n")
466 self.sslconn.unwrap()
467 self.sslconn = None
468 if test_support.verbose and self.server.connectionchatty:
469 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000470 else:
471 if (test_support.verbose and
472 self.server.connectionchatty):
473 ctype = (self.sslconn and "encrypted") or "unencrypted"
474 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
475 % (repr(msg), ctype, repr(msg.lower()), ctype))
476 self.write(msg.lower())
477 except ssl.SSLError:
478 if self.server.chatty:
479 handle_error("Test server failure:\n")
480 self.close()
481 self.running = False
482 # normally, we'd just stop here, but for the test
483 # harness, we want to stop the server
484 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000485
Trent Nelsone41b0062008-04-08 23:47:30 +0000486 def __init__(self, certificate, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +0000487 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000488 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000489 wrap_accepting_socket=False, ciphers=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000490
Bill Janssen98d19da2007-09-10 21:51:02 +0000491 if ssl_version is None:
492 ssl_version = ssl.PROTOCOL_TLSv1
493 if certreqs is None:
494 certreqs = ssl.CERT_NONE
495 self.certificate = certificate
496 self.protocol = ssl_version
497 self.certreqs = certreqs
498 self.cacerts = cacerts
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000499 self.ciphers = ciphers
Bill Janssen98d19da2007-09-10 21:51:02 +0000500 self.chatty = chatty
501 self.connectionchatty = connectionchatty
502 self.starttls_server = starttls_server
503 self.sock = socket.socket()
504 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000505 if wrap_accepting_socket:
506 self.sock = ssl.wrap_socket(self.sock, server_side=True,
507 certfile=self.certificate,
508 cert_reqs = self.certreqs,
509 ca_certs = self.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000510 ssl_version = self.protocol,
511 ciphers = self.ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000512 if test_support.verbose and self.chatty:
513 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
514 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000515 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000516 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000517 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000518
Antoine Pitrou3945c862010-04-28 21:11:01 +0000519 def start(self, flag=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000520 self.flag = flag
521 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000522
Antoine Pitrou3945c862010-04-28 21:11:01 +0000523 def run(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000524 self.sock.settimeout(0.05)
Bill Janssen98d19da2007-09-10 21:51:02 +0000525 self.sock.listen(5)
526 self.active = True
527 if self.flag:
528 # signal an event
529 self.flag.set()
530 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000531 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000532 newconn, connaddr = self.sock.accept()
533 if test_support.verbose and self.chatty:
534 sys.stdout.write(' server: new connection from '
535 + str(connaddr) + '\n')
536 handler = self.ConnectionHandler(self, newconn)
537 handler.start()
538 except socket.timeout:
539 pass
540 except KeyboardInterrupt:
541 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +0000542 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000543
Antoine Pitrou3945c862010-04-28 21:11:01 +0000544 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000545 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000546
Bill Janssen934b16d2008-06-28 22:19:33 +0000547 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000548
Antoine Pitrou3945c862010-04-28 21:11:01 +0000549 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +0000550
Antoine Pitrou3945c862010-04-28 21:11:01 +0000551 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +0000552
553 def __init__(self, conn, certfile):
554 asyncore.dispatcher_with_send.__init__(self, conn)
555 self.socket = ssl.wrap_socket(conn, server_side=True,
556 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +0000557 do_handshake_on_connect=False)
558 self._ssl_accepting = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000559
560 def readable(self):
561 if isinstance(self.socket, ssl.SSLSocket):
562 while self.socket.pending() > 0:
563 self.handle_read_event()
564 return True
565
Antoine Pitroufc69af12010-04-24 20:04:58 +0000566 def _do_ssl_handshake(self):
567 try:
568 self.socket.do_handshake()
569 except ssl.SSLError, err:
570 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
571 ssl.SSL_ERROR_WANT_WRITE):
572 return
573 elif err.args[0] == ssl.SSL_ERROR_EOF:
574 return self.handle_close()
575 raise
576 except socket.error, err:
577 if err.args[0] == errno.ECONNABORTED:
578 return self.handle_close()
579 else:
580 self._ssl_accepting = False
581
Bill Janssen934b16d2008-06-28 22:19:33 +0000582 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +0000583 if self._ssl_accepting:
584 self._do_ssl_handshake()
585 else:
586 data = self.recv(1024)
Antoine Pitroudb187842010-04-27 10:32:58 +0000587 if data and data.strip() != 'over':
588 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +0000589
590 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000591 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000592 if test_support.verbose:
593 sys.stdout.write(" server: closed connection %s\n" % self.socket)
594
595 def handle_error(self):
596 raise
597
598 def __init__(self, certfile):
599 self.certfile = certfile
600 asyncore.dispatcher.__init__(self)
601 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
602 self.port = test_support.bind_port(self.socket)
603 self.listen(5)
604
605 def handle_accept(self):
606 sock_obj, addr = self.accept()
607 if test_support.verbose:
608 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
609 self.ConnectionHandler(sock_obj, self.certfile)
610
611 def handle_error(self):
612 raise
613
614 def __init__(self, certfile):
615 self.flag = None
616 self.active = False
617 self.server = self.EchoServer(certfile)
618 self.port = self.server.port
619 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000620 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000621
622 def __str__(self):
623 return "<%s %s>" % (self.__class__.__name__, self.server)
624
Antoine Pitrou3945c862010-04-28 21:11:01 +0000625 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000626 self.flag = flag
627 threading.Thread.start(self)
628
Antoine Pitrou3945c862010-04-28 21:11:01 +0000629 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000630 self.active = True
631 if self.flag:
632 self.flag.set()
633 while self.active:
Antoine Pitroudb187842010-04-27 10:32:58 +0000634 asyncore.loop(0.05)
Bill Janssen934b16d2008-06-28 22:19:33 +0000635
Antoine Pitrou3945c862010-04-28 21:11:01 +0000636 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000637 self.active = False
638 self.server.close()
639
640 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000641
642 class HTTPSServer(HTTPServer):
643
644 def __init__(self, server_address, RequestHandlerClass, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000645 HTTPServer.__init__(self, server_address, RequestHandlerClass)
646 # we assume the certfile contains both private key and certificate
647 self.certfile = certfile
Bill Janssen296a59d2007-09-16 22:06:00 +0000648 self.allow_reuse_address = True
649
Bill Janssen934b16d2008-06-28 22:19:33 +0000650 def __str__(self):
651 return ('<%s %s:%s>' %
652 (self.__class__.__name__,
653 self.server_name,
654 self.server_port))
655
Antoine Pitrou3945c862010-04-28 21:11:01 +0000656 def get_request(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000657 # override this to wrap socket with SSL
658 sock, addr = self.socket.accept()
659 sslconn = ssl.wrap_socket(sock, server_side=True,
660 certfile=self.certfile)
661 return sslconn, addr
662
Bill Janssen296a59d2007-09-16 22:06:00 +0000663 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Bill Janssen296a59d2007-09-16 22:06:00 +0000664 # need to override translate_path to get a known root,
665 # instead of using os.curdir, since the test could be
666 # run from anywhere
667
668 server_version = "TestHTTPS/1.0"
669
670 root = None
671
672 def translate_path(self, path):
673 """Translate a /-separated PATH to the local filename syntax.
674
675 Components that mean special things to the local file system
676 (e.g. drive or directory names) are ignored. (XXX They should
677 probably be diagnosed.)
678
679 """
680 # abandon query parameters
681 path = urlparse.urlparse(path)[2]
682 path = os.path.normpath(urllib.unquote(path))
683 words = path.split('/')
684 words = filter(None, words)
685 path = self.root
686 for word in words:
687 drive, word = os.path.splitdrive(word)
688 head, word = os.path.split(word)
689 if word in self.root: continue
690 path = os.path.join(path, word)
691 return path
692
693 def log_message(self, format, *args):
694
695 # we override this to suppress logging unless "verbose"
696
697 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000698 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
699 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000700 self.server.server_port,
701 self.request.cipher(),
702 self.log_date_time_string(),
703 format%args))
704
705
Trent Nelsone41b0062008-04-08 23:47:30 +0000706 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000707 self.flag = None
Bill Janssen296a59d2007-09-16 22:06:00 +0000708 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
709 self.server = self.HTTPSServer(
Antoine Pitrou150acda2010-04-27 08:40:51 +0000710 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
711 self.port = self.server.server_port
Bill Janssen296a59d2007-09-16 22:06:00 +0000712 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000713 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000714
715 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000716 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000717
Antoine Pitrou3945c862010-04-28 21:11:01 +0000718 def start(self, flag=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000719 self.flag = flag
720 threading.Thread.start(self)
721
Antoine Pitrou3945c862010-04-28 21:11:01 +0000722 def run(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000723 if self.flag:
724 self.flag.set()
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000725 self.server.serve_forever(0.05)
Bill Janssen296a59d2007-09-16 22:06:00 +0000726
Antoine Pitrou3945c862010-04-28 21:11:01 +0000727 def stop(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000728 self.server.shutdown()
Bill Janssen296a59d2007-09-16 22:06:00 +0000729
730
Antoine Pitrou3945c862010-04-28 21:11:01 +0000731 def bad_cert_test(certfile):
732 """
733 Launch a server with CERT_REQUIRED, and check that trying to
734 connect to it with the given client certificate fails.
735 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000736 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000737 certreqs=ssl.CERT_REQUIRED,
738 cacerts=CERTFILE, chatty=False)
739 flag = threading.Event()
740 server.start(flag)
741 # wait for it to start
742 flag.wait()
743 # try to connect
744 try:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000745 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000746 s = ssl.wrap_socket(socket.socket(),
747 certfile=certfile,
748 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000749 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000750 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000751 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000752 sys.stdout.write("\nSSLError is %s\n" % x[1])
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000753 except socket.error, x:
754 if test_support.verbose:
755 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000756 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000757 raise AssertionError("Use of invalid cert should have failed!")
Bill Janssen98d19da2007-09-10 21:51:02 +0000758 finally:
759 server.stop()
760 server.join()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000761
Antoine Pitrou3945c862010-04-28 21:11:01 +0000762 def server_params_test(certfile, protocol, certreqs, cacertsfile,
763 client_certfile, client_protocol=None, indata="FOO\n",
764 ciphers=None, chatty=True, connectionchatty=False,
765 wrap_accepting_socket=False):
766 """
767 Launch a server, connect a client to it and try various reads
768 and writes.
769 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000770 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000771 certreqs=certreqs,
772 ssl_version=protocol,
773 cacerts=cacertsfile,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000774 ciphers=ciphers,
Bill Janssen98d19da2007-09-10 21:51:02 +0000775 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000776 connectionchatty=connectionchatty,
777 wrap_accepting_socket=wrap_accepting_socket)
Bill Janssen98d19da2007-09-10 21:51:02 +0000778 flag = threading.Event()
779 server.start(flag)
780 # wait for it to start
781 flag.wait()
782 # try to connect
783 if client_protocol is None:
784 client_protocol = protocol
785 try:
Antoine Pitroudb187842010-04-27 10:32:58 +0000786 s = ssl.wrap_socket(socket.socket(),
787 certfile=client_certfile,
788 ca_certs=cacertsfile,
789 ciphers=ciphers,
790 cert_reqs=certreqs,
791 ssl_version=client_protocol)
792 s.connect((HOST, server.port))
793 for arg in [indata, bytearray(indata), memoryview(indata)]:
Bill Janssen98d19da2007-09-10 21:51:02 +0000794 if connectionchatty:
795 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +0000796 sys.stdout.write(
797 " client: sending %s...\n" % (repr(arg)))
798 s.write(arg)
799 outdata = s.read()
800 if connectionchatty:
801 if test_support.verbose:
802 sys.stdout.write(" client: read %s\n" % repr(outdata))
803 if outdata != indata.lower():
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000804 raise AssertionError(
Antoine Pitroudb187842010-04-27 10:32:58 +0000805 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
806 % (outdata[:min(len(outdata),20)], len(outdata),
807 indata[:min(len(indata),20)].lower(), len(indata)))
808 s.write("over\n")
809 if connectionchatty:
810 if test_support.verbose:
811 sys.stdout.write(" client: closing connection.\n")
812 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000813 finally:
814 server.stop()
815 server.join()
816
Antoine Pitrou3945c862010-04-28 21:11:01 +0000817 def try_protocol_combo(server_protocol,
818 client_protocol,
819 expect_success,
820 certsreqs=None):
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000821 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000822 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +0000823 certtype = {
824 ssl.CERT_NONE: "CERT_NONE",
825 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
826 ssl.CERT_REQUIRED: "CERT_REQUIRED",
827 }[certsreqs]
Bill Janssen98d19da2007-09-10 21:51:02 +0000828 if test_support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000829 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +0000830 sys.stdout.write(formatstr %
831 (ssl.get_protocol_name(client_protocol),
832 ssl.get_protocol_name(server_protocol),
833 certtype))
834 try:
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000835 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
836 # will send an SSLv3 hello (rather than SSLv2) starting from
837 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou3945c862010-04-28 21:11:01 +0000838 server_params_test(CERTFILE, server_protocol, certsreqs,
839 CERTFILE, CERTFILE, client_protocol,
840 ciphers="ALL", chatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +0000841 # Protocol mismatch can result in either an SSLError, or a
842 # "Connection reset by peer" error.
843 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000844 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +0000845 raise
Antoine Pitroudb187842010-04-27 10:32:58 +0000846 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000847 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +0000848 raise
Bill Janssen98d19da2007-09-10 21:51:02 +0000849 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000850 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000851 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +0000852 "Client protocol %s succeeded with server protocol %s!"
853 % (ssl.get_protocol_name(client_protocol),
854 ssl.get_protocol_name(server_protocol)))
855
856
Bill Janssen934b16d2008-06-28 22:19:33 +0000857 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000858
Antoine Pitrou3945c862010-04-28 21:11:01 +0000859 def test_rude_shutdown(self):
860 """A brutal shutdown of an SSL server should raise an IOError
861 in the client when attempting handshake.
862 """
Bill Janssen98d19da2007-09-10 21:51:02 +0000863 listener_ready = threading.Event()
864 listener_gone = threading.Event()
865
Antoine Pitrou150acda2010-04-27 08:40:51 +0000866 s = socket.socket()
867 port = test_support.bind_port(s, HOST)
868
869 # `listener` runs in a thread. It sits in an accept() until
870 # the main thread connects. Then it rudely closes the socket,
871 # and sets Event `listener_gone` to let the main thread know
872 # the socket is gone.
Bill Janssen98d19da2007-09-10 21:51:02 +0000873 def listener():
Bill Janssen98d19da2007-09-10 21:51:02 +0000874 s.listen(5)
875 listener_ready.set()
876 s.accept()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000877 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000878 listener_gone.set()
879
880 def connector():
881 listener_ready.wait()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000882 c = socket.socket()
883 c.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000884 listener_gone.wait()
885 try:
Antoine Pitrou150acda2010-04-27 08:40:51 +0000886 ssl_sock = ssl.wrap_socket(c)
Bill Janssen934b16d2008-06-28 22:19:33 +0000887 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000888 pass
889 else:
Antoine Pitroudb187842010-04-27 10:32:58 +0000890 self.fail('connecting to closed SSL socket should have failed')
Bill Janssen98d19da2007-09-10 21:51:02 +0000891
892 t = threading.Thread(target=listener)
893 t.start()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000894 try:
895 connector()
896 finally:
897 t.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000898
Antoine Pitroud75efd92010-08-04 17:38:33 +0000899 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000900 def test_echo(self):
901 """Basic test of an SSL client connecting to a server"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000902 if test_support.verbose:
903 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000904 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
905 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
906 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000907
Antoine Pitrou3945c862010-04-28 21:11:01 +0000908 def test_getpeercert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000909 if test_support.verbose:
910 sys.stdout.write("\n")
911 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000912 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000913 certreqs=ssl.CERT_NONE,
914 ssl_version=ssl.PROTOCOL_SSLv23,
915 cacerts=CERTFILE,
916 chatty=False)
917 flag = threading.Event()
918 server.start(flag)
919 # wait for it to start
920 flag.wait()
921 # try to connect
922 try:
Antoine Pitroudb187842010-04-27 10:32:58 +0000923 s = ssl.wrap_socket(socket.socket(),
924 certfile=CERTFILE,
925 ca_certs=CERTFILE,
926 cert_reqs=ssl.CERT_REQUIRED,
927 ssl_version=ssl.PROTOCOL_SSLv23)
928 s.connect((HOST, server.port))
929 cert = s.getpeercert()
930 self.assertTrue(cert, "Can't get peer certificate.")
931 cipher = s.cipher()
932 if test_support.verbose:
933 sys.stdout.write(pprint.pformat(cert) + '\n')
934 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
935 if 'subject' not in cert:
936 self.fail("No subject field in certificate: %s." %
937 pprint.pformat(cert))
938 if ((('organizationName', 'Python Software Foundation'),)
939 not in cert['subject']):
940 self.fail(
941 "Missing or invalid 'organizationName' field in certificate subject; "
942 "should be 'Python Software Foundation'.")
943 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000944 finally:
945 server.stop()
946 server.join()
947
Antoine Pitrou3945c862010-04-28 21:11:01 +0000948 def test_empty_cert(self):
949 """Connecting with an empty cert file"""
950 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
951 "nullcert.pem"))
952 def test_malformed_cert(self):
953 """Connecting with a badly formatted certificate (syntax error)"""
954 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
955 "badcert.pem"))
956 def test_nonexisting_cert(self):
957 """Connecting with a non-existing cert file"""
958 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
959 "wrongcert.pem"))
960 def test_malformed_key(self):
961 """Connecting with a badly formatted key (syntax error)"""
962 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
963 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000964
Antoine Pitroud75efd92010-08-04 17:38:33 +0000965 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000966 def test_protocol_sslv2(self):
967 """Connecting to an SSLv2 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000968 if test_support.verbose:
969 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000970 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
971 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
972 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
973 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
974 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
975 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000976
Antoine Pitroud75efd92010-08-04 17:38:33 +0000977 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000978 def test_protocol_sslv23(self):
979 """Connecting to an SSLv23 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000980 if test_support.verbose:
981 sys.stdout.write("\n")
982 try:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000983 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000984 except (ssl.SSLError, socket.error), x:
Bill Janssen98d19da2007-09-10 21:51:02 +0000985 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
986 if test_support.verbose:
987 sys.stdout.write(
988 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
989 % str(x))
Antoine Pitrou3945c862010-04-28 21:11:01 +0000990 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
991 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
992 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000993
Antoine Pitrou3945c862010-04-28 21:11:01 +0000994 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
995 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
996 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +0000997
Antoine Pitrou3945c862010-04-28 21:11:01 +0000998 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
999 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1000 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00001001
Antoine Pitroud75efd92010-08-04 17:38:33 +00001002 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001003 def test_protocol_sslv3(self):
1004 """Connecting to an SSLv3 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001005 if test_support.verbose:
1006 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001007 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1008 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1009 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1010 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1011 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1012 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001013
Antoine Pitroud75efd92010-08-04 17:38:33 +00001014 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001015 def test_protocol_tlsv1(self):
1016 """Connecting to a TLSv1 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001017 if test_support.verbose:
1018 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001019 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1020 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1021 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1022 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1023 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1024 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001025
Antoine Pitrou3945c862010-04-28 21:11:01 +00001026 def test_starttls(self):
1027 """Switching from clear text to encrypted and back again."""
Bill Janssen39295c22008-08-12 16:31:21 +00001028 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +00001029
Trent Nelsone41b0062008-04-08 23:47:30 +00001030 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00001031 ssl_version=ssl.PROTOCOL_TLSv1,
1032 starttls_server=True,
1033 chatty=True,
1034 connectionchatty=True)
1035 flag = threading.Event()
1036 server.start(flag)
1037 # wait for it to start
1038 flag.wait()
1039 # try to connect
1040 wrapped = False
1041 try:
Antoine Pitroudb187842010-04-27 10:32:58 +00001042 s = socket.socket()
1043 s.setblocking(1)
1044 s.connect((HOST, server.port))
1045 if test_support.verbose:
1046 sys.stdout.write("\n")
1047 for indata in msgs:
Bill Janssen98d19da2007-09-10 21:51:02 +00001048 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00001049 sys.stdout.write(
1050 " client: sending %s...\n" % repr(indata))
1051 if wrapped:
1052 conn.write(indata)
1053 outdata = conn.read()
1054 else:
1055 s.send(indata)
1056 outdata = s.recv(1024)
1057 if (indata == "STARTTLS" and
1058 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001059 # STARTTLS ok, switch to secure mode
Bill Janssen98d19da2007-09-10 21:51:02 +00001060 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00001061 sys.stdout.write(
Antoine Pitroudb187842010-04-27 10:32:58 +00001062 " client: read %s from server, starting TLS...\n"
1063 % repr(outdata))
1064 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1065 wrapped = True
1066 elif (indata == "ENDTLS" and
1067 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001068 # ENDTLS ok, switch back to clear text
Antoine Pitroudb187842010-04-27 10:32:58 +00001069 if test_support.verbose:
1070 sys.stdout.write(
1071 " client: read %s from server, ending TLS...\n"
1072 % repr(outdata))
1073 s = conn.unwrap()
1074 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00001075 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001076 if test_support.verbose:
1077 sys.stdout.write(
1078 " client: read %s from server\n" % repr(outdata))
1079 if test_support.verbose:
1080 sys.stdout.write(" client: closing connection.\n")
1081 if wrapped:
1082 conn.write("over\n")
1083 else:
1084 s.send("over\n")
1085 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001086 finally:
1087 server.stop()
1088 server.join()
1089
Antoine Pitrou3945c862010-04-28 21:11:01 +00001090 def test_socketserver(self):
1091 """Using a SocketServer to create and manage SSL connections."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001092 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +00001093 flag = threading.Event()
1094 server.start(flag)
1095 # wait for it to start
1096 flag.wait()
1097 # try to connect
1098 try:
1099 if test_support.verbose:
1100 sys.stdout.write('\n')
Antoine Pitrou3945c862010-04-28 21:11:01 +00001101 with open(CERTFILE, 'rb') as f:
1102 d1 = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +00001103 d2 = ''
1104 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +00001105 url = 'https://127.0.0.1:%d/%s' % (
1106 server.port, os.path.split(CERTFILE)[1])
Florent Xicluna07627882010-03-21 01:14:24 +00001107 with test_support.check_py3k_warnings():
1108 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +00001109 dlen = f.info().getheader("content-length")
1110 if dlen and (int(dlen) > 0):
1111 d2 = f.read(int(dlen))
1112 if test_support.verbose:
1113 sys.stdout.write(
1114 " client: read %d bytes from remote server '%s'\n"
1115 % (len(d2), server))
1116 f.close()
Antoine Pitroudb187842010-04-27 10:32:58 +00001117 self.assertEqual(d1, d2)
Bill Janssen296a59d2007-09-16 22:06:00 +00001118 finally:
1119 server.stop()
1120 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001121
Antoine Pitrou3945c862010-04-28 21:11:01 +00001122 def test_wrapped_accept(self):
1123 """Check the accept() method on SSL sockets."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001124 if test_support.verbose:
1125 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001126 server_params_test(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1127 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1128 chatty=True, connectionchatty=True,
1129 wrap_accepting_socket=True)
Bill Janssen934b16d2008-06-28 22:19:33 +00001130
Antoine Pitrou3945c862010-04-28 21:11:01 +00001131 def test_asyncore_server(self):
1132 """Check the example asyncore integration."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001133 indata = "TEST MESSAGE of mixed case\n"
1134
1135 if test_support.verbose:
1136 sys.stdout.write("\n")
1137 server = AsyncoreEchoServer(CERTFILE)
1138 flag = threading.Event()
1139 server.start(flag)
1140 # wait for it to start
1141 flag.wait()
1142 # try to connect
1143 try:
Antoine Pitroudb187842010-04-27 10:32:58 +00001144 s = ssl.wrap_socket(socket.socket())
1145 s.connect(('127.0.0.1', server.port))
1146 if test_support.verbose:
1147 sys.stdout.write(
1148 " client: sending %s...\n" % (repr(indata)))
1149 s.write(indata)
1150 outdata = s.read()
1151 if test_support.verbose:
1152 sys.stdout.write(" client: read %s\n" % repr(outdata))
1153 if outdata != indata.lower():
1154 self.fail(
1155 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1156 % (outdata[:min(len(outdata),20)], len(outdata),
1157 indata[:min(len(indata),20)].lower(), len(indata)))
1158 s.write("over\n")
1159 if test_support.verbose:
1160 sys.stdout.write(" client: closing connection.\n")
1161 s.close()
Bill Janssen934b16d2008-06-28 22:19:33 +00001162 finally:
1163 server.stop()
1164 # wait for server thread to end
1165 server.join()
1166
Antoine Pitrou3945c862010-04-28 21:11:01 +00001167 def test_recv_send(self):
1168 """Test recv(), send() and friends."""
Bill Janssen61c001a2008-09-08 16:37:24 +00001169 if test_support.verbose:
1170 sys.stdout.write("\n")
1171
1172 server = ThreadedEchoServer(CERTFILE,
1173 certreqs=ssl.CERT_NONE,
1174 ssl_version=ssl.PROTOCOL_TLSv1,
1175 cacerts=CERTFILE,
1176 chatty=True,
1177 connectionchatty=False)
1178 flag = threading.Event()
1179 server.start(flag)
1180 # wait for it to start
1181 flag.wait()
1182 # try to connect
Antoine Pitroudb187842010-04-27 10:32:58 +00001183 s = ssl.wrap_socket(socket.socket(),
1184 server_side=False,
1185 certfile=CERTFILE,
1186 ca_certs=CERTFILE,
1187 cert_reqs=ssl.CERT_NONE,
1188 ssl_version=ssl.PROTOCOL_TLSv1)
1189 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00001190 try:
Bill Janssen61c001a2008-09-08 16:37:24 +00001191 # helper methods for standardising recv* method signatures
1192 def _recv_into():
1193 b = bytearray("\0"*100)
1194 count = s.recv_into(b)
1195 return b[:count]
1196
1197 def _recvfrom_into():
1198 b = bytearray("\0"*100)
1199 count, addr = s.recvfrom_into(b)
1200 return b[:count]
1201
1202 # (name, method, whether to expect success, *args)
1203 send_methods = [
1204 ('send', s.send, True, []),
1205 ('sendto', s.sendto, False, ["some.address"]),
1206 ('sendall', s.sendall, True, []),
1207 ]
1208 recv_methods = [
1209 ('recv', s.recv, True, []),
1210 ('recvfrom', s.recvfrom, False, ["some.address"]),
1211 ('recv_into', _recv_into, True, []),
1212 ('recvfrom_into', _recvfrom_into, False, []),
1213 ]
1214 data_prefix = u"PREFIX_"
1215
1216 for meth_name, send_meth, expect_success, args in send_methods:
1217 indata = data_prefix + meth_name
1218 try:
1219 send_meth(indata.encode('ASCII', 'strict'), *args)
1220 outdata = s.read()
1221 outdata = outdata.decode('ASCII', 'strict')
1222 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001223 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001224 "While sending with <<%s>> bad data "
1225 "<<%r>> (%d) received; "
1226 "expected <<%r>> (%d)\n" % (
1227 meth_name, outdata[:20], len(outdata),
1228 indata[:20], len(indata)
1229 )
1230 )
1231 except ValueError as e:
1232 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001233 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001234 "Failed to send with method <<%s>>; "
1235 "expected to succeed.\n" % (meth_name,)
1236 )
1237 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001238 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001239 "Method <<%s>> failed with unexpected "
1240 "exception message: %s\n" % (
1241 meth_name, e
1242 )
1243 )
1244
1245 for meth_name, recv_meth, expect_success, args in recv_methods:
1246 indata = data_prefix + meth_name
1247 try:
1248 s.send(indata.encode('ASCII', 'strict'))
1249 outdata = recv_meth(*args)
1250 outdata = outdata.decode('ASCII', 'strict')
1251 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001252 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001253 "While receiving with <<%s>> bad data "
1254 "<<%r>> (%d) received; "
1255 "expected <<%r>> (%d)\n" % (
1256 meth_name, outdata[:20], len(outdata),
1257 indata[:20], len(indata)
1258 )
1259 )
1260 except ValueError as e:
1261 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001262 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001263 "Failed to receive with method <<%s>>; "
1264 "expected to succeed.\n" % (meth_name,)
1265 )
1266 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001267 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001268 "Method <<%s>> failed with unexpected "
1269 "exception message: %s\n" % (
1270 meth_name, e
1271 )
1272 )
1273 # consume data
1274 s.read()
1275
1276 s.write("over\n".encode("ASCII", "strict"))
1277 s.close()
1278 finally:
1279 server.stop()
1280 server.join()
1281
Antoine Pitroufc69af12010-04-24 20:04:58 +00001282 def test_handshake_timeout(self):
1283 # Issue #5103: SSL handshake must respect the socket timeout
1284 server = socket.socket(socket.AF_INET)
1285 host = "127.0.0.1"
1286 port = test_support.bind_port(server)
1287 started = threading.Event()
1288 finish = False
1289
1290 def serve():
1291 server.listen(5)
1292 started.set()
1293 conns = []
1294 while not finish:
1295 r, w, e = select.select([server], [], [], 0.1)
1296 if server in r:
1297 # Let the socket hang around rather than having
1298 # it closed by garbage collection.
1299 conns.append(server.accept()[0])
1300
1301 t = threading.Thread(target=serve)
1302 t.start()
1303 started.wait()
1304
1305 try:
1306 try:
1307 c = socket.socket(socket.AF_INET)
1308 c.settimeout(0.2)
1309 c.connect((host, port))
1310 # Will attempt handshake and time out
1311 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1312 ssl.wrap_socket, c)
1313 finally:
1314 c.close()
1315 try:
1316 c = socket.socket(socket.AF_INET)
1317 c.settimeout(0.2)
1318 c = ssl.wrap_socket(c)
1319 # Will attempt handshake and time out
1320 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1321 c.connect, (host, port))
1322 finally:
1323 c.close()
1324 finally:
1325 finish = True
1326 t.join()
1327 server.close()
1328
Bill Janssen61c001a2008-09-08 16:37:24 +00001329
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001330def test_main(verbose=False):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001331 if skip_expected:
Benjamin Peterson888a39b2009-03-26 20:48:25 +00001332 raise unittest.SkipTest("No SSL support")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001333
Trent Nelsone41b0062008-04-08 23:47:30 +00001334 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001335 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001336 "keycert.pem")
1337 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1338 os.path.dirname(__file__) or os.curdir,
1339 "https_svn_python_org_root.pem")
1340
1341 if (not os.path.exists(CERTFILE) or
1342 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001343 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001344
Antoine Pitroude30f702010-09-14 12:54:08 +00001345 tests = [BasicTests, BasicSocketTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001346
Bill Janssen296a59d2007-09-16 22:06:00 +00001347 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001348 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001349
Bill Janssen98d19da2007-09-10 21:51:02 +00001350 if _have_threads:
1351 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001352 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001353 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001354
Antoine Pitrou3945c862010-04-28 21:11:01 +00001355 try:
1356 test_support.run_unittest(*tests)
1357 finally:
1358 if _have_threads:
1359 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001360
1361if __name__ == "__main__":
1362 test_main()