blob: 25672184156fbf1dddcb9f61a548992bde31b082 [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))
Antoine Pitrou8ef39072011-02-27 15:45:22 +0000251 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
252 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000253 # Wait for connect to finish
254 select.select([], [s], [], 5.0)
255 # Non-blocking handshake
256 while True:
257 try:
258 s.do_handshake()
259 break
260 except ssl.SSLError as err:
261 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
262 select.select([s], [], [], 5.0)
263 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
264 select.select([], [s], [], 5.0)
265 else:
266 raise
267 # SSL established
268 self.assertTrue(s.getpeercert())
269 finally:
270 s.close()
271
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000272 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
273 def test_makefile_close(self):
274 # Issue #5238: creating a file-like object with makefile() shouldn't
275 # delay closing the underlying "real socket" (here tested with its
276 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000277 with test_support.transient_internet("svn.python.org"):
278 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
279 ss.connect(("svn.python.org", 443))
280 fd = ss.fileno()
281 f = ss.makefile()
282 f.close()
283 # The fd is still open
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000284 os.read(fd, 0)
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000285 # Closing the SSL socket should close the fd too
286 ss.close()
287 gc.collect()
288 with self.assertRaises(OSError) as e:
289 os.read(fd, 0)
290 self.assertEqual(e.exception.errno, errno.EBADF)
Bill Janssen934b16d2008-06-28 22:19:33 +0000291
Antoine Pitrou3945c862010-04-28 21:11:01 +0000292 def test_non_blocking_handshake(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000293 with test_support.transient_internet("svn.python.org"):
294 s = socket.socket(socket.AF_INET)
295 s.connect(("svn.python.org", 443))
296 s.setblocking(False)
297 s = ssl.wrap_socket(s,
298 cert_reqs=ssl.CERT_NONE,
299 do_handshake_on_connect=False)
300 count = 0
301 while True:
302 try:
303 count += 1
304 s.do_handshake()
305 break
306 except ssl.SSLError, err:
307 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
308 select.select([s], [], [])
309 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
310 select.select([], [s], [])
311 else:
312 raise
313 s.close()
314 if test_support.verbose:
315 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Bill Janssen934b16d2008-06-28 22:19:33 +0000316
Antoine Pitrou3945c862010-04-28 21:11:01 +0000317 def test_get_server_certificate(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000318 with test_support.transient_internet("svn.python.org"):
319 pem = ssl.get_server_certificate(("svn.python.org", 443))
320 if not pem:
321 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000322
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000323 try:
324 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
325 except ssl.SSLError:
326 #should fail
327 pass
328 else:
329 self.fail("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000330
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000331 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
332 if not pem:
333 self.fail("No server certificate on svn.python.org:443!")
334 if test_support.verbose:
335 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000336
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000337 def test_algorithms(self):
338 # Issue #8484: all algorithms should be available when verifying a
339 # certificate.
Antoine Pitrou9aed6042010-04-22 18:00:41 +0000340 # SHA256 was added in OpenSSL 0.9.8
341 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
342 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000343 # NOTE: https://sha256.tbs-internet.com is another possible test host
Antoine Pitroud43245a2011-01-08 10:32:51 +0000344 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000345 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitroud43245a2011-01-08 10:32:51 +0000346 with test_support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrouc818ed42010-09-07 21:40:25 +0000347 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
348 cert_reqs=ssl.CERT_REQUIRED,
349 ca_certs=sha256_cert,)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000350 try:
351 s.connect(remote)
352 if test_support.verbose:
353 sys.stdout.write("\nCipher with %r is %r\n" %
354 (remote, s.cipher()))
355 sys.stdout.write("Certificate is:\n%s\n" %
356 pprint.pformat(s.getpeercert()))
357 finally:
358 s.close()
359
Bill Janssen296a59d2007-09-16 22:06:00 +0000360
Bill Janssen98d19da2007-09-10 21:51:02 +0000361try:
362 import threading
363except ImportError:
364 _have_threads = False
365else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000366 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000367
Bill Janssen98d19da2007-09-10 21:51:02 +0000368 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000369
Bill Janssen98d19da2007-09-10 21:51:02 +0000370 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000371
Bill Janssen98d19da2007-09-10 21:51:02 +0000372 """A mildly complicated class, because we want it to work both
373 with and without the SSL wrapper around the socket connection, so
374 that we can test the STARTTLS functionality."""
375
376 def __init__(self, server, connsock):
377 self.server = server
378 self.running = False
379 self.sock = connsock
380 self.sock.setblocking(1)
381 self.sslconn = None
382 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000383 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000384
Bill Janssen934b16d2008-06-28 22:19:33 +0000385 def show_conn_details(self):
386 if self.server.certreqs == ssl.CERT_REQUIRED:
387 cert = self.sslconn.getpeercert()
388 if test_support.verbose and self.server.chatty:
389 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
390 cert_binary = self.sslconn.getpeercert(True)
391 if test_support.verbose and self.server.chatty:
392 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
393 cipher = self.sslconn.cipher()
394 if test_support.verbose and self.server.chatty:
395 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
396
Antoine Pitrou3945c862010-04-28 21:11:01 +0000397 def wrap_conn(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000398 try:
399 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
400 certfile=self.server.certificate,
401 ssl_version=self.server.protocol,
402 ca_certs=self.server.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000403 cert_reqs=self.server.certreqs,
404 ciphers=self.server.ciphers)
Antoine Pitroudb187842010-04-27 10:32:58 +0000405 except ssl.SSLError:
406 # XXX Various errors can have happened here, for example
407 # a mismatching protocol version, an invalid certificate,
408 # or a low-level bug. This should be made more discriminating.
Bill Janssen98d19da2007-09-10 21:51:02 +0000409 if self.server.chatty:
410 handle_error("\n server: bad connection attempt from " +
411 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000412 self.close()
Antoine Pitroudb187842010-04-27 10:32:58 +0000413 self.running = False
414 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000415 return False
Bill Janssen98d19da2007-09-10 21:51:02 +0000416 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000417 return True
418
419 def read(self):
420 if self.sslconn:
421 return self.sslconn.read()
422 else:
423 return self.sock.recv(1024)
424
425 def write(self, bytes):
426 if self.sslconn:
427 return self.sslconn.write(bytes)
428 else:
429 return self.sock.send(bytes)
430
431 def close(self):
432 if self.sslconn:
433 self.sslconn.close()
434 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000435 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000436
Antoine Pitrou3945c862010-04-28 21:11:01 +0000437 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000438 self.running = True
439 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000440 if isinstance(self.sock, ssl.SSLSocket):
441 self.sslconn = self.sock
442 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000443 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000444 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000445 while self.running:
446 try:
447 msg = self.read()
448 if not msg:
449 # eof, so quit this handler
450 self.running = False
451 self.close()
452 elif msg.strip() == 'over':
453 if test_support.verbose and self.server.connectionchatty:
454 sys.stdout.write(" server: client closed connection\n")
455 self.close()
456 return
457 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
458 if test_support.verbose and self.server.connectionchatty:
459 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
460 self.write("OK\n")
461 if not self.wrap_conn():
462 return
Bill Janssen39295c22008-08-12 16:31:21 +0000463 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
464 if test_support.verbose and self.server.connectionchatty:
465 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
466 self.write("OK\n")
467 self.sslconn.unwrap()
468 self.sslconn = None
469 if test_support.verbose and self.server.connectionchatty:
470 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000471 else:
472 if (test_support.verbose and
473 self.server.connectionchatty):
474 ctype = (self.sslconn and "encrypted") or "unencrypted"
475 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
476 % (repr(msg), ctype, repr(msg.lower()), ctype))
477 self.write(msg.lower())
478 except ssl.SSLError:
479 if self.server.chatty:
480 handle_error("Test server failure:\n")
481 self.close()
482 self.running = False
483 # normally, we'd just stop here, but for the test
484 # harness, we want to stop the server
485 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000486
Trent Nelsone41b0062008-04-08 23:47:30 +0000487 def __init__(self, certificate, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +0000488 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000489 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000490 wrap_accepting_socket=False, ciphers=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000491
Bill Janssen98d19da2007-09-10 21:51:02 +0000492 if ssl_version is None:
493 ssl_version = ssl.PROTOCOL_TLSv1
494 if certreqs is None:
495 certreqs = ssl.CERT_NONE
496 self.certificate = certificate
497 self.protocol = ssl_version
498 self.certreqs = certreqs
499 self.cacerts = cacerts
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000500 self.ciphers = ciphers
Bill Janssen98d19da2007-09-10 21:51:02 +0000501 self.chatty = chatty
502 self.connectionchatty = connectionchatty
503 self.starttls_server = starttls_server
504 self.sock = socket.socket()
505 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000506 if wrap_accepting_socket:
507 self.sock = ssl.wrap_socket(self.sock, server_side=True,
508 certfile=self.certificate,
509 cert_reqs = self.certreqs,
510 ca_certs = self.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000511 ssl_version = self.protocol,
512 ciphers = self.ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000513 if test_support.verbose and self.chatty:
514 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
515 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000516 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000517 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000518 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000519
Antoine Pitrou3945c862010-04-28 21:11:01 +0000520 def start(self, flag=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000521 self.flag = flag
522 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000523
Antoine Pitrou3945c862010-04-28 21:11:01 +0000524 def run(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000525 self.sock.settimeout(0.05)
Bill Janssen98d19da2007-09-10 21:51:02 +0000526 self.sock.listen(5)
527 self.active = True
528 if self.flag:
529 # signal an event
530 self.flag.set()
531 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000532 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000533 newconn, connaddr = self.sock.accept()
534 if test_support.verbose and self.chatty:
535 sys.stdout.write(' server: new connection from '
536 + str(connaddr) + '\n')
537 handler = self.ConnectionHandler(self, newconn)
538 handler.start()
539 except socket.timeout:
540 pass
541 except KeyboardInterrupt:
542 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +0000543 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000544
Antoine Pitrou3945c862010-04-28 21:11:01 +0000545 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000546 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000547
Bill Janssen934b16d2008-06-28 22:19:33 +0000548 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000549
Antoine Pitrou3945c862010-04-28 21:11:01 +0000550 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +0000551
Antoine Pitrou3945c862010-04-28 21:11:01 +0000552 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +0000553
554 def __init__(self, conn, certfile):
555 asyncore.dispatcher_with_send.__init__(self, conn)
556 self.socket = ssl.wrap_socket(conn, server_side=True,
557 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +0000558 do_handshake_on_connect=False)
559 self._ssl_accepting = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000560
561 def readable(self):
562 if isinstance(self.socket, ssl.SSLSocket):
563 while self.socket.pending() > 0:
564 self.handle_read_event()
565 return True
566
Antoine Pitroufc69af12010-04-24 20:04:58 +0000567 def _do_ssl_handshake(self):
568 try:
569 self.socket.do_handshake()
570 except ssl.SSLError, err:
571 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
572 ssl.SSL_ERROR_WANT_WRITE):
573 return
574 elif err.args[0] == ssl.SSL_ERROR_EOF:
575 return self.handle_close()
576 raise
577 except socket.error, err:
578 if err.args[0] == errno.ECONNABORTED:
579 return self.handle_close()
580 else:
581 self._ssl_accepting = False
582
Bill Janssen934b16d2008-06-28 22:19:33 +0000583 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +0000584 if self._ssl_accepting:
585 self._do_ssl_handshake()
586 else:
587 data = self.recv(1024)
Antoine Pitroudb187842010-04-27 10:32:58 +0000588 if data and data.strip() != 'over':
589 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +0000590
591 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000592 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000593 if test_support.verbose:
594 sys.stdout.write(" server: closed connection %s\n" % self.socket)
595
596 def handle_error(self):
597 raise
598
599 def __init__(self, certfile):
600 self.certfile = certfile
601 asyncore.dispatcher.__init__(self)
602 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
603 self.port = test_support.bind_port(self.socket)
604 self.listen(5)
605
606 def handle_accept(self):
607 sock_obj, addr = self.accept()
608 if test_support.verbose:
609 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
610 self.ConnectionHandler(sock_obj, self.certfile)
611
612 def handle_error(self):
613 raise
614
615 def __init__(self, certfile):
616 self.flag = None
617 self.active = False
618 self.server = self.EchoServer(certfile)
619 self.port = self.server.port
620 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000621 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000622
623 def __str__(self):
624 return "<%s %s>" % (self.__class__.__name__, self.server)
625
Antoine Pitrou3945c862010-04-28 21:11:01 +0000626 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000627 self.flag = flag
628 threading.Thread.start(self)
629
Antoine Pitrou3945c862010-04-28 21:11:01 +0000630 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000631 self.active = True
632 if self.flag:
633 self.flag.set()
634 while self.active:
Antoine Pitroudb187842010-04-27 10:32:58 +0000635 asyncore.loop(0.05)
Bill Janssen934b16d2008-06-28 22:19:33 +0000636
Antoine Pitrou3945c862010-04-28 21:11:01 +0000637 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000638 self.active = False
639 self.server.close()
640
641 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000642
643 class HTTPSServer(HTTPServer):
644
645 def __init__(self, server_address, RequestHandlerClass, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000646 HTTPServer.__init__(self, server_address, RequestHandlerClass)
647 # we assume the certfile contains both private key and certificate
648 self.certfile = certfile
Bill Janssen296a59d2007-09-16 22:06:00 +0000649 self.allow_reuse_address = True
650
Bill Janssen934b16d2008-06-28 22:19:33 +0000651 def __str__(self):
652 return ('<%s %s:%s>' %
653 (self.__class__.__name__,
654 self.server_name,
655 self.server_port))
656
Antoine Pitrou3945c862010-04-28 21:11:01 +0000657 def get_request(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000658 # override this to wrap socket with SSL
659 sock, addr = self.socket.accept()
660 sslconn = ssl.wrap_socket(sock, server_side=True,
661 certfile=self.certfile)
662 return sslconn, addr
663
Bill Janssen296a59d2007-09-16 22:06:00 +0000664 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Bill Janssen296a59d2007-09-16 22:06:00 +0000665 # need to override translate_path to get a known root,
666 # instead of using os.curdir, since the test could be
667 # run from anywhere
668
669 server_version = "TestHTTPS/1.0"
670
671 root = None
672
673 def translate_path(self, path):
674 """Translate a /-separated PATH to the local filename syntax.
675
676 Components that mean special things to the local file system
677 (e.g. drive or directory names) are ignored. (XXX They should
678 probably be diagnosed.)
679
680 """
681 # abandon query parameters
682 path = urlparse.urlparse(path)[2]
683 path = os.path.normpath(urllib.unquote(path))
684 words = path.split('/')
685 words = filter(None, words)
686 path = self.root
687 for word in words:
688 drive, word = os.path.splitdrive(word)
689 head, word = os.path.split(word)
690 if word in self.root: continue
691 path = os.path.join(path, word)
692 return path
693
694 def log_message(self, format, *args):
695
696 # we override this to suppress logging unless "verbose"
697
698 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000699 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
700 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000701 self.server.server_port,
702 self.request.cipher(),
703 self.log_date_time_string(),
704 format%args))
705
706
Trent Nelsone41b0062008-04-08 23:47:30 +0000707 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000708 self.flag = None
Bill Janssen296a59d2007-09-16 22:06:00 +0000709 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
710 self.server = self.HTTPSServer(
Antoine Pitrou150acda2010-04-27 08:40:51 +0000711 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
712 self.port = self.server.server_port
Bill Janssen296a59d2007-09-16 22:06:00 +0000713 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000714 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000715
716 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000717 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000718
Antoine Pitrou3945c862010-04-28 21:11:01 +0000719 def start(self, flag=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000720 self.flag = flag
721 threading.Thread.start(self)
722
Antoine Pitrou3945c862010-04-28 21:11:01 +0000723 def run(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000724 if self.flag:
725 self.flag.set()
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000726 self.server.serve_forever(0.05)
Bill Janssen296a59d2007-09-16 22:06:00 +0000727
Antoine Pitrou3945c862010-04-28 21:11:01 +0000728 def stop(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000729 self.server.shutdown()
Bill Janssen296a59d2007-09-16 22:06:00 +0000730
731
Antoine Pitrou3945c862010-04-28 21:11:01 +0000732 def bad_cert_test(certfile):
733 """
734 Launch a server with CERT_REQUIRED, and check that trying to
735 connect to it with the given client certificate fails.
736 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000737 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000738 certreqs=ssl.CERT_REQUIRED,
739 cacerts=CERTFILE, chatty=False)
740 flag = threading.Event()
741 server.start(flag)
742 # wait for it to start
743 flag.wait()
744 # try to connect
745 try:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000746 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000747 s = ssl.wrap_socket(socket.socket(),
748 certfile=certfile,
749 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000750 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000751 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000752 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000753 sys.stdout.write("\nSSLError is %s\n" % x[1])
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000754 except socket.error, x:
755 if test_support.verbose:
756 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000757 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000758 raise AssertionError("Use of invalid cert should have failed!")
Bill Janssen98d19da2007-09-10 21:51:02 +0000759 finally:
760 server.stop()
761 server.join()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000762
Antoine Pitrou3945c862010-04-28 21:11:01 +0000763 def server_params_test(certfile, protocol, certreqs, cacertsfile,
764 client_certfile, client_protocol=None, indata="FOO\n",
765 ciphers=None, chatty=True, connectionchatty=False,
766 wrap_accepting_socket=False):
767 """
768 Launch a server, connect a client to it and try various reads
769 and writes.
770 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000771 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000772 certreqs=certreqs,
773 ssl_version=protocol,
774 cacerts=cacertsfile,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000775 ciphers=ciphers,
Bill Janssen98d19da2007-09-10 21:51:02 +0000776 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000777 connectionchatty=connectionchatty,
778 wrap_accepting_socket=wrap_accepting_socket)
Bill Janssen98d19da2007-09-10 21:51:02 +0000779 flag = threading.Event()
780 server.start(flag)
781 # wait for it to start
782 flag.wait()
783 # try to connect
784 if client_protocol is None:
785 client_protocol = protocol
786 try:
Antoine Pitroudb187842010-04-27 10:32:58 +0000787 s = ssl.wrap_socket(socket.socket(),
788 certfile=client_certfile,
789 ca_certs=cacertsfile,
790 ciphers=ciphers,
791 cert_reqs=certreqs,
792 ssl_version=client_protocol)
793 s.connect((HOST, server.port))
794 for arg in [indata, bytearray(indata), memoryview(indata)]:
Bill Janssen98d19da2007-09-10 21:51:02 +0000795 if connectionchatty:
796 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +0000797 sys.stdout.write(
798 " client: sending %s...\n" % (repr(arg)))
799 s.write(arg)
800 outdata = s.read()
801 if connectionchatty:
802 if test_support.verbose:
803 sys.stdout.write(" client: read %s\n" % repr(outdata))
804 if outdata != indata.lower():
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000805 raise AssertionError(
Antoine Pitroudb187842010-04-27 10:32:58 +0000806 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
807 % (outdata[:min(len(outdata),20)], len(outdata),
808 indata[:min(len(indata),20)].lower(), len(indata)))
809 s.write("over\n")
810 if connectionchatty:
811 if test_support.verbose:
812 sys.stdout.write(" client: closing connection.\n")
813 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000814 finally:
815 server.stop()
816 server.join()
817
Antoine Pitrou3945c862010-04-28 21:11:01 +0000818 def try_protocol_combo(server_protocol,
819 client_protocol,
820 expect_success,
821 certsreqs=None):
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000822 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000823 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +0000824 certtype = {
825 ssl.CERT_NONE: "CERT_NONE",
826 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
827 ssl.CERT_REQUIRED: "CERT_REQUIRED",
828 }[certsreqs]
Bill Janssen98d19da2007-09-10 21:51:02 +0000829 if test_support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000830 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +0000831 sys.stdout.write(formatstr %
832 (ssl.get_protocol_name(client_protocol),
833 ssl.get_protocol_name(server_protocol),
834 certtype))
835 try:
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000836 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
837 # will send an SSLv3 hello (rather than SSLv2) starting from
838 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou3945c862010-04-28 21:11:01 +0000839 server_params_test(CERTFILE, server_protocol, certsreqs,
840 CERTFILE, CERTFILE, client_protocol,
841 ciphers="ALL", chatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +0000842 # Protocol mismatch can result in either an SSLError, or a
843 # "Connection reset by peer" error.
844 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000845 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +0000846 raise
Antoine Pitroudb187842010-04-27 10:32:58 +0000847 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000848 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +0000849 raise
Bill Janssen98d19da2007-09-10 21:51:02 +0000850 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000851 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000852 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +0000853 "Client protocol %s succeeded with server protocol %s!"
854 % (ssl.get_protocol_name(client_protocol),
855 ssl.get_protocol_name(server_protocol)))
856
857
Bill Janssen934b16d2008-06-28 22:19:33 +0000858 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000859
Antoine Pitrou3945c862010-04-28 21:11:01 +0000860 def test_rude_shutdown(self):
861 """A brutal shutdown of an SSL server should raise an IOError
862 in the client when attempting handshake.
863 """
Bill Janssen98d19da2007-09-10 21:51:02 +0000864 listener_ready = threading.Event()
865 listener_gone = threading.Event()
866
Antoine Pitrou150acda2010-04-27 08:40:51 +0000867 s = socket.socket()
868 port = test_support.bind_port(s, HOST)
869
870 # `listener` runs in a thread. It sits in an accept() until
871 # the main thread connects. Then it rudely closes the socket,
872 # and sets Event `listener_gone` to let the main thread know
873 # the socket is gone.
Bill Janssen98d19da2007-09-10 21:51:02 +0000874 def listener():
Bill Janssen98d19da2007-09-10 21:51:02 +0000875 s.listen(5)
876 listener_ready.set()
877 s.accept()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000878 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000879 listener_gone.set()
880
881 def connector():
882 listener_ready.wait()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000883 c = socket.socket()
884 c.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000885 listener_gone.wait()
886 try:
Antoine Pitrou150acda2010-04-27 08:40:51 +0000887 ssl_sock = ssl.wrap_socket(c)
Bill Janssen934b16d2008-06-28 22:19:33 +0000888 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000889 pass
890 else:
Antoine Pitroudb187842010-04-27 10:32:58 +0000891 self.fail('connecting to closed SSL socket should have failed')
Bill Janssen98d19da2007-09-10 21:51:02 +0000892
893 t = threading.Thread(target=listener)
894 t.start()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000895 try:
896 connector()
897 finally:
898 t.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000899
Antoine Pitroud75efd92010-08-04 17:38:33 +0000900 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000901 def test_echo(self):
902 """Basic test of an SSL client connecting to a server"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000903 if test_support.verbose:
904 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000905 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
906 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
907 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000908
Antoine Pitrou3945c862010-04-28 21:11:01 +0000909 def test_getpeercert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000910 if test_support.verbose:
911 sys.stdout.write("\n")
912 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000913 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000914 certreqs=ssl.CERT_NONE,
915 ssl_version=ssl.PROTOCOL_SSLv23,
916 cacerts=CERTFILE,
917 chatty=False)
918 flag = threading.Event()
919 server.start(flag)
920 # wait for it to start
921 flag.wait()
922 # try to connect
923 try:
Antoine Pitroudb187842010-04-27 10:32:58 +0000924 s = ssl.wrap_socket(socket.socket(),
925 certfile=CERTFILE,
926 ca_certs=CERTFILE,
927 cert_reqs=ssl.CERT_REQUIRED,
928 ssl_version=ssl.PROTOCOL_SSLv23)
929 s.connect((HOST, server.port))
930 cert = s.getpeercert()
931 self.assertTrue(cert, "Can't get peer certificate.")
932 cipher = s.cipher()
933 if test_support.verbose:
934 sys.stdout.write(pprint.pformat(cert) + '\n')
935 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
936 if 'subject' not in cert:
937 self.fail("No subject field in certificate: %s." %
938 pprint.pformat(cert))
939 if ((('organizationName', 'Python Software Foundation'),)
940 not in cert['subject']):
941 self.fail(
942 "Missing or invalid 'organizationName' field in certificate subject; "
943 "should be 'Python Software Foundation'.")
944 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000945 finally:
946 server.stop()
947 server.join()
948
Antoine Pitrou3945c862010-04-28 21:11:01 +0000949 def test_empty_cert(self):
950 """Connecting with an empty cert file"""
951 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
952 "nullcert.pem"))
953 def test_malformed_cert(self):
954 """Connecting with a badly formatted certificate (syntax error)"""
955 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
956 "badcert.pem"))
957 def test_nonexisting_cert(self):
958 """Connecting with a non-existing cert file"""
959 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
960 "wrongcert.pem"))
961 def test_malformed_key(self):
962 """Connecting with a badly formatted key (syntax error)"""
963 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
964 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000965
Antoine Pitroud75efd92010-08-04 17:38:33 +0000966 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000967 def test_protocol_sslv2(self):
968 """Connecting to an SSLv2 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000969 if test_support.verbose:
970 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000971 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
972 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
973 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
974 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
975 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
976 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000977
Antoine Pitroud75efd92010-08-04 17:38:33 +0000978 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000979 def test_protocol_sslv23(self):
980 """Connecting to an SSLv23 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000981 if test_support.verbose:
982 sys.stdout.write("\n")
983 try:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000984 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000985 except (ssl.SSLError, socket.error), x:
Bill Janssen98d19da2007-09-10 21:51:02 +0000986 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
987 if test_support.verbose:
988 sys.stdout.write(
989 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
990 % str(x))
Antoine Pitrou3945c862010-04-28 21:11:01 +0000991 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
992 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
993 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000994
Antoine Pitrou3945c862010-04-28 21:11:01 +0000995 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
996 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
997 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +0000998
Antoine Pitrou3945c862010-04-28 21:11:01 +0000999 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1000 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1001 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00001002
Antoine Pitroud75efd92010-08-04 17:38:33 +00001003 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001004 def test_protocol_sslv3(self):
1005 """Connecting to an SSLv3 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001006 if test_support.verbose:
1007 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001008 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1009 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1010 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1011 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1012 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1013 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001014
Antoine Pitroud75efd92010-08-04 17:38:33 +00001015 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001016 def test_protocol_tlsv1(self):
1017 """Connecting to a TLSv1 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001018 if test_support.verbose:
1019 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001020 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1021 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1022 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1023 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1024 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1025 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001026
Antoine Pitrou3945c862010-04-28 21:11:01 +00001027 def test_starttls(self):
1028 """Switching from clear text to encrypted and back again."""
Bill Janssen39295c22008-08-12 16:31:21 +00001029 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +00001030
Trent Nelsone41b0062008-04-08 23:47:30 +00001031 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00001032 ssl_version=ssl.PROTOCOL_TLSv1,
1033 starttls_server=True,
1034 chatty=True,
1035 connectionchatty=True)
1036 flag = threading.Event()
1037 server.start(flag)
1038 # wait for it to start
1039 flag.wait()
1040 # try to connect
1041 wrapped = False
1042 try:
Antoine Pitroudb187842010-04-27 10:32:58 +00001043 s = socket.socket()
1044 s.setblocking(1)
1045 s.connect((HOST, server.port))
1046 if test_support.verbose:
1047 sys.stdout.write("\n")
1048 for indata in msgs:
Bill Janssen98d19da2007-09-10 21:51:02 +00001049 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00001050 sys.stdout.write(
1051 " client: sending %s...\n" % repr(indata))
1052 if wrapped:
1053 conn.write(indata)
1054 outdata = conn.read()
1055 else:
1056 s.send(indata)
1057 outdata = s.recv(1024)
1058 if (indata == "STARTTLS" and
1059 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001060 # STARTTLS ok, switch to secure mode
Bill Janssen98d19da2007-09-10 21:51:02 +00001061 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00001062 sys.stdout.write(
Antoine Pitroudb187842010-04-27 10:32:58 +00001063 " client: read %s from server, starting TLS...\n"
1064 % repr(outdata))
1065 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1066 wrapped = True
1067 elif (indata == "ENDTLS" and
1068 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001069 # ENDTLS ok, switch back to clear text
Antoine Pitroudb187842010-04-27 10:32:58 +00001070 if test_support.verbose:
1071 sys.stdout.write(
1072 " client: read %s from server, ending TLS...\n"
1073 % repr(outdata))
1074 s = conn.unwrap()
1075 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00001076 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001077 if test_support.verbose:
1078 sys.stdout.write(
1079 " client: read %s from server\n" % repr(outdata))
1080 if test_support.verbose:
1081 sys.stdout.write(" client: closing connection.\n")
1082 if wrapped:
1083 conn.write("over\n")
1084 else:
1085 s.send("over\n")
1086 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001087 finally:
1088 server.stop()
1089 server.join()
1090
Antoine Pitrou3945c862010-04-28 21:11:01 +00001091 def test_socketserver(self):
1092 """Using a SocketServer to create and manage SSL connections."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001093 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +00001094 flag = threading.Event()
1095 server.start(flag)
1096 # wait for it to start
1097 flag.wait()
1098 # try to connect
1099 try:
1100 if test_support.verbose:
1101 sys.stdout.write('\n')
Antoine Pitrou3945c862010-04-28 21:11:01 +00001102 with open(CERTFILE, 'rb') as f:
1103 d1 = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +00001104 d2 = ''
1105 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +00001106 url = 'https://127.0.0.1:%d/%s' % (
1107 server.port, os.path.split(CERTFILE)[1])
Florent Xicluna07627882010-03-21 01:14:24 +00001108 with test_support.check_py3k_warnings():
1109 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +00001110 dlen = f.info().getheader("content-length")
1111 if dlen and (int(dlen) > 0):
1112 d2 = f.read(int(dlen))
1113 if test_support.verbose:
1114 sys.stdout.write(
1115 " client: read %d bytes from remote server '%s'\n"
1116 % (len(d2), server))
1117 f.close()
Antoine Pitroudb187842010-04-27 10:32:58 +00001118 self.assertEqual(d1, d2)
Bill Janssen296a59d2007-09-16 22:06:00 +00001119 finally:
1120 server.stop()
1121 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001122
Antoine Pitrou3945c862010-04-28 21:11:01 +00001123 def test_wrapped_accept(self):
1124 """Check the accept() method on SSL sockets."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001125 if test_support.verbose:
1126 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001127 server_params_test(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1128 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1129 chatty=True, connectionchatty=True,
1130 wrap_accepting_socket=True)
Bill Janssen934b16d2008-06-28 22:19:33 +00001131
Antoine Pitrou3945c862010-04-28 21:11:01 +00001132 def test_asyncore_server(self):
1133 """Check the example asyncore integration."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001134 indata = "TEST MESSAGE of mixed case\n"
1135
1136 if test_support.verbose:
1137 sys.stdout.write("\n")
1138 server = AsyncoreEchoServer(CERTFILE)
1139 flag = threading.Event()
1140 server.start(flag)
1141 # wait for it to start
1142 flag.wait()
1143 # try to connect
1144 try:
Antoine Pitroudb187842010-04-27 10:32:58 +00001145 s = ssl.wrap_socket(socket.socket())
1146 s.connect(('127.0.0.1', server.port))
1147 if test_support.verbose:
1148 sys.stdout.write(
1149 " client: sending %s...\n" % (repr(indata)))
1150 s.write(indata)
1151 outdata = s.read()
1152 if test_support.verbose:
1153 sys.stdout.write(" client: read %s\n" % repr(outdata))
1154 if outdata != indata.lower():
1155 self.fail(
1156 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1157 % (outdata[:min(len(outdata),20)], len(outdata),
1158 indata[:min(len(indata),20)].lower(), len(indata)))
1159 s.write("over\n")
1160 if test_support.verbose:
1161 sys.stdout.write(" client: closing connection.\n")
1162 s.close()
Bill Janssen934b16d2008-06-28 22:19:33 +00001163 finally:
1164 server.stop()
1165 # wait for server thread to end
1166 server.join()
1167
Antoine Pitrou3945c862010-04-28 21:11:01 +00001168 def test_recv_send(self):
1169 """Test recv(), send() and friends."""
Bill Janssen61c001a2008-09-08 16:37:24 +00001170 if test_support.verbose:
1171 sys.stdout.write("\n")
1172
1173 server = ThreadedEchoServer(CERTFILE,
1174 certreqs=ssl.CERT_NONE,
1175 ssl_version=ssl.PROTOCOL_TLSv1,
1176 cacerts=CERTFILE,
1177 chatty=True,
1178 connectionchatty=False)
1179 flag = threading.Event()
1180 server.start(flag)
1181 # wait for it to start
1182 flag.wait()
1183 # try to connect
Antoine Pitroudb187842010-04-27 10:32:58 +00001184 s = ssl.wrap_socket(socket.socket(),
1185 server_side=False,
1186 certfile=CERTFILE,
1187 ca_certs=CERTFILE,
1188 cert_reqs=ssl.CERT_NONE,
1189 ssl_version=ssl.PROTOCOL_TLSv1)
1190 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00001191 try:
Bill Janssen61c001a2008-09-08 16:37:24 +00001192 # helper methods for standardising recv* method signatures
1193 def _recv_into():
1194 b = bytearray("\0"*100)
1195 count = s.recv_into(b)
1196 return b[:count]
1197
1198 def _recvfrom_into():
1199 b = bytearray("\0"*100)
1200 count, addr = s.recvfrom_into(b)
1201 return b[:count]
1202
1203 # (name, method, whether to expect success, *args)
1204 send_methods = [
1205 ('send', s.send, True, []),
1206 ('sendto', s.sendto, False, ["some.address"]),
1207 ('sendall', s.sendall, True, []),
1208 ]
1209 recv_methods = [
1210 ('recv', s.recv, True, []),
1211 ('recvfrom', s.recvfrom, False, ["some.address"]),
1212 ('recv_into', _recv_into, True, []),
1213 ('recvfrom_into', _recvfrom_into, False, []),
1214 ]
1215 data_prefix = u"PREFIX_"
1216
1217 for meth_name, send_meth, expect_success, args in send_methods:
1218 indata = data_prefix + meth_name
1219 try:
1220 send_meth(indata.encode('ASCII', 'strict'), *args)
1221 outdata = s.read()
1222 outdata = outdata.decode('ASCII', 'strict')
1223 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001224 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001225 "While sending with <<%s>> bad data "
1226 "<<%r>> (%d) received; "
1227 "expected <<%r>> (%d)\n" % (
1228 meth_name, outdata[:20], len(outdata),
1229 indata[:20], len(indata)
1230 )
1231 )
1232 except ValueError as e:
1233 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001234 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001235 "Failed to send with method <<%s>>; "
1236 "expected to succeed.\n" % (meth_name,)
1237 )
1238 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001239 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001240 "Method <<%s>> failed with unexpected "
1241 "exception message: %s\n" % (
1242 meth_name, e
1243 )
1244 )
1245
1246 for meth_name, recv_meth, expect_success, args in recv_methods:
1247 indata = data_prefix + meth_name
1248 try:
1249 s.send(indata.encode('ASCII', 'strict'))
1250 outdata = recv_meth(*args)
1251 outdata = outdata.decode('ASCII', 'strict')
1252 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001253 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001254 "While receiving with <<%s>> bad data "
1255 "<<%r>> (%d) received; "
1256 "expected <<%r>> (%d)\n" % (
1257 meth_name, outdata[:20], len(outdata),
1258 indata[:20], len(indata)
1259 )
1260 )
1261 except ValueError as e:
1262 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001263 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001264 "Failed to receive with method <<%s>>; "
1265 "expected to succeed.\n" % (meth_name,)
1266 )
1267 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001268 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001269 "Method <<%s>> failed with unexpected "
1270 "exception message: %s\n" % (
1271 meth_name, e
1272 )
1273 )
1274 # consume data
1275 s.read()
1276
1277 s.write("over\n".encode("ASCII", "strict"))
1278 s.close()
1279 finally:
1280 server.stop()
1281 server.join()
1282
Antoine Pitroufc69af12010-04-24 20:04:58 +00001283 def test_handshake_timeout(self):
1284 # Issue #5103: SSL handshake must respect the socket timeout
1285 server = socket.socket(socket.AF_INET)
1286 host = "127.0.0.1"
1287 port = test_support.bind_port(server)
1288 started = threading.Event()
1289 finish = False
1290
1291 def serve():
1292 server.listen(5)
1293 started.set()
1294 conns = []
1295 while not finish:
1296 r, w, e = select.select([server], [], [], 0.1)
1297 if server in r:
1298 # Let the socket hang around rather than having
1299 # it closed by garbage collection.
1300 conns.append(server.accept()[0])
1301
1302 t = threading.Thread(target=serve)
1303 t.start()
1304 started.wait()
1305
1306 try:
1307 try:
1308 c = socket.socket(socket.AF_INET)
1309 c.settimeout(0.2)
1310 c.connect((host, port))
1311 # Will attempt handshake and time out
1312 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1313 ssl.wrap_socket, c)
1314 finally:
1315 c.close()
1316 try:
1317 c = socket.socket(socket.AF_INET)
1318 c.settimeout(0.2)
1319 c = ssl.wrap_socket(c)
1320 # Will attempt handshake and time out
1321 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1322 c.connect, (host, port))
1323 finally:
1324 c.close()
1325 finally:
1326 finish = True
1327 t.join()
1328 server.close()
1329
Bill Janssen61c001a2008-09-08 16:37:24 +00001330
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001331def test_main(verbose=False):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001332 if skip_expected:
Benjamin Peterson888a39b2009-03-26 20:48:25 +00001333 raise unittest.SkipTest("No SSL support")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001334
Trent Nelsone41b0062008-04-08 23:47:30 +00001335 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001336 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001337 "keycert.pem")
1338 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1339 os.path.dirname(__file__) or os.curdir,
1340 "https_svn_python_org_root.pem")
1341
1342 if (not os.path.exists(CERTFILE) or
1343 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001344 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001345
Antoine Pitroude30f702010-09-14 12:54:08 +00001346 tests = [BasicTests, BasicSocketTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001347
Bill Janssen296a59d2007-09-16 22:06:00 +00001348 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001349 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001350
Bill Janssen98d19da2007-09-10 21:51:02 +00001351 if _have_threads:
1352 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001353 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001354 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001355
Antoine Pitrou3945c862010-04-28 21:11:01 +00001356 try:
1357 test_support.run_unittest(*tests)
1358 finally:
1359 if _have_threads:
1360 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001361
1362if __name__ == "__main__":
1363 test_main()