blob: e5addf807778bc6b688db949bb88c7dfcdd016d6 [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
Victor Stinner2e7f39e2011-05-22 13:22:28 +020023ssl = test_support.import_module("ssl")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000024
Trent Nelsone41b0062008-04-08 23:47:30 +000025HOST = test_support.HOST
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000026CERTFILE = None
Bill Janssen296a59d2007-09-16 22:06:00 +000027SVN_PYTHON_ORG_ROOT_CERT = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000028
Neal Norwitz3e533c22007-08-27 01:03:18 +000029def handle_error(prefix):
30 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Bill Janssen98d19da2007-09-10 21:51:02 +000031 if test_support.verbose:
32 sys.stdout.write(prefix + exc_format)
Neal Norwitz3e533c22007-08-27 01:03:18 +000033
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000034
35class BasicTests(unittest.TestCase):
36
Antoine Pitrou3945c862010-04-28 21:11:01 +000037 def test_sslwrap_simple(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000038 # A crude test for the legacy API
Bill Jansseneb257ac2008-09-29 18:56:38 +000039 try:
40 ssl.sslwrap_simple(socket.socket(socket.AF_INET))
41 except IOError, e:
42 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
43 pass
44 else:
45 raise
46 try:
47 ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
48 except IOError, e:
49 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
50 pass
51 else:
52 raise
Neal Norwitz3e533c22007-08-27 01:03:18 +000053
Antoine Pitroud75efd92010-08-04 17:38:33 +000054# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
55def skip_if_broken_ubuntu_ssl(func):
Victor Stinnerb1241f92011-05-10 01:52:03 +020056 if hasattr(ssl, 'PROTOCOL_SSLv2'):
57 # We need to access the lower-level wrapper in order to create an
58 # implicit SSL context without trying to connect or listen.
Antoine Pitroud75efd92010-08-04 17:38:33 +000059 try:
Victor Stinnerb1241f92011-05-10 01:52:03 +020060 import _ssl
61 except ImportError:
62 # The returned function won't get executed, just ignore the error
63 pass
64 @functools.wraps(func)
65 def f(*args, **kwargs):
66 try:
67 s = socket.socket(socket.AF_INET)
68 _ssl.sslwrap(s._sock, 0, None, None,
69 ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
70 except ssl.SSLError as e:
71 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
72 platform.linux_distribution() == ('debian', 'squeeze/sid', '')
73 and 'Invalid SSL protocol variant specified' in str(e)):
74 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
75 return func(*args, **kwargs)
76 return f
77 else:
78 return func
Antoine Pitroud75efd92010-08-04 17:38:33 +000079
80
81class BasicSocketTests(unittest.TestCase):
82
Antoine Pitrou3945c862010-04-28 21:11:01 +000083 def test_constants(self):
Victor Stinnerb1241f92011-05-10 01:52:03 +020084 #ssl.PROTOCOL_SSLv2
Bill Janssen98d19da2007-09-10 21:51:02 +000085 ssl.PROTOCOL_SSLv23
86 ssl.PROTOCOL_SSLv3
87 ssl.PROTOCOL_TLSv1
88 ssl.CERT_NONE
89 ssl.CERT_OPTIONAL
90 ssl.CERT_REQUIRED
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000091
Antoine Pitrou3945c862010-04-28 21:11:01 +000092 def test_random(self):
Bill Janssen98d19da2007-09-10 21:51:02 +000093 v = ssl.RAND_status()
94 if test_support.verbose:
95 sys.stdout.write("\n RAND_status is %d (%s)\n"
96 % (v, (v and "sufficient randomness") or
97 "insufficient randomness"))
Guido van Rossume4729332007-08-26 19:35:09 +000098 try:
Bill Janssen98d19da2007-09-10 21:51:02 +000099 ssl.RAND_egd(1)
100 except TypeError:
101 pass
Guido van Rossume4729332007-08-26 19:35:09 +0000102 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000103 print "didn't raise TypeError"
104 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000105
Antoine Pitrou3945c862010-04-28 21:11:01 +0000106 def test_parse_cert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000107 # note that this uses an 'unofficial' function in _ssl.c,
108 # provided solely for this test, to exercise the certificate
109 # parsing code
110 p = ssl._ssl._test_decode_cert(CERTFILE, False)
111 if test_support.verbose:
112 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200113 self.assertEqual(p['subject'],
114 ((('countryName', u'US'),),
115 (('stateOrProvinceName', u'Delaware'),),
116 (('localityName', u'Wilmington'),),
117 (('organizationName', u'Python Software Foundation'),),
118 (('organizationalUnitName', u'SSL'),),
119 (('commonName', u'somemachine.python.org'),)),
120 )
121 # Issue #13034: the subjectAltName in some certificates
122 # (notably projects.developer.nokia.com:443) wasn't parsed
123 p = ssl._ssl._test_decode_cert(NOKIACERT)
124 if test_support.verbose:
125 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
126 self.assertEqual(p['subjectAltName'],
127 (('DNS', 'projects.developer.nokia.com'),
128 ('DNS', 'projects.forum.nokia.com'))
129 )
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000130
Antoine Pitrou3945c862010-04-28 21:11:01 +0000131 def test_DER_to_PEM(self):
132 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
133 pem = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000134 d1 = ssl.PEM_cert_to_DER_cert(pem)
135 p2 = ssl.DER_cert_to_PEM_cert(d1)
136 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitroudb187842010-04-27 10:32:58 +0000137 self.assertEqual(d1, d2)
Antoine Pitrou4c7bcf12010-04-27 22:03:37 +0000138 if not p2.startswith(ssl.PEM_HEADER + '\n'):
139 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
140 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
141 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Bill Janssen296a59d2007-09-16 22:06:00 +0000142
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000143 def test_openssl_version(self):
144 n = ssl.OPENSSL_VERSION_NUMBER
145 t = ssl.OPENSSL_VERSION_INFO
146 s = ssl.OPENSSL_VERSION
147 self.assertIsInstance(n, (int, long))
148 self.assertIsInstance(t, tuple)
149 self.assertIsInstance(s, str)
150 # Some sanity checks follow
151 # >= 0.9
152 self.assertGreaterEqual(n, 0x900000)
153 # < 2.0
154 self.assertLess(n, 0x20000000)
155 major, minor, fix, patch, status = t
156 self.assertGreaterEqual(major, 0)
157 self.assertLess(major, 2)
158 self.assertGreaterEqual(minor, 0)
159 self.assertLess(minor, 256)
160 self.assertGreaterEqual(fix, 0)
161 self.assertLess(fix, 256)
162 self.assertGreaterEqual(patch, 0)
163 self.assertLessEqual(patch, 26)
164 self.assertGreaterEqual(status, 0)
165 self.assertLessEqual(status, 15)
166 # Version string as returned by OpenSSL, the format might change
167 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
168 (s, t))
169
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000170 def test_ciphers(self):
171 if not test_support.is_resource_enabled('network'):
172 return
173 remote = ("svn.python.org", 443)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000174 with test_support.transient_internet(remote[0]):
175 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
176 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000177 s.connect(remote)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000178 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
179 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
180 s.connect(remote)
181 # Error checking occurs when connecting, because the SSL context
182 # isn't created before.
183 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
184 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
185 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
186 s.connect(remote)
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000187
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000188 @test_support.cpython_only
189 def test_refcycle(self):
190 # Issue #7943: an SSL object doesn't create reference cycles with
191 # itself.
192 s = socket.socket(socket.AF_INET)
193 ss = ssl.wrap_socket(s)
194 wr = weakref.ref(ss)
195 del ss
196 self.assertEqual(wr(), None)
197
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000198 def test_wrapped_unconnected(self):
199 # The _delegate_methods in socket.py are correctly delegated to by an
200 # unconnected SSLSocket, so they will raise a socket.error rather than
201 # something unexpected like TypeError.
202 s = socket.socket(socket.AF_INET)
203 ss = ssl.wrap_socket(s)
204 self.assertRaises(socket.error, ss.recv, 1)
205 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
206 self.assertRaises(socket.error, ss.recvfrom, 1)
207 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
208 self.assertRaises(socket.error, ss.send, b'x')
209 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
210
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000211
Bill Janssen934b16d2008-06-28 22:19:33 +0000212class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +0000213
Antoine Pitrou3945c862010-04-28 21:11:01 +0000214 def test_connect(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000215 with test_support.transient_internet("svn.python.org"):
216 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
217 cert_reqs=ssl.CERT_NONE)
Bill Janssen296a59d2007-09-16 22:06:00 +0000218 s.connect(("svn.python.org", 443))
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000219 c = s.getpeercert()
220 if c:
221 self.fail("Peer cert %s shouldn't be here!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000222 s.close()
223
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000224 # this should fail because we have no verification certs
225 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
226 cert_reqs=ssl.CERT_REQUIRED)
227 try:
228 s.connect(("svn.python.org", 443))
229 except ssl.SSLError:
230 pass
231 finally:
232 s.close()
233
234 # this should succeed because we specify the root cert
235 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
236 cert_reqs=ssl.CERT_REQUIRED,
237 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
238 try:
239 s.connect(("svn.python.org", 443))
240 finally:
241 s.close()
Bill Janssen296a59d2007-09-16 22:06:00 +0000242
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000243 def test_connect_ex(self):
244 # Issue #11326: check connect_ex() implementation
245 with test_support.transient_internet("svn.python.org"):
246 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
247 cert_reqs=ssl.CERT_REQUIRED,
248 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
249 try:
250 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
251 self.assertTrue(s.getpeercert())
252 finally:
253 s.close()
254
255 def test_non_blocking_connect_ex(self):
256 # Issue #11326: non-blocking connect_ex() should allow handshake
257 # to proceed after the socket gets ready.
258 with test_support.transient_internet("svn.python.org"):
259 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
260 cert_reqs=ssl.CERT_REQUIRED,
261 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
262 do_handshake_on_connect=False)
263 try:
264 s.setblocking(False)
265 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitrou8ef39072011-02-27 15:45:22 +0000266 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
267 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000268 # Wait for connect to finish
269 select.select([], [s], [], 5.0)
270 # Non-blocking handshake
271 while True:
272 try:
273 s.do_handshake()
274 break
275 except ssl.SSLError as err:
276 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
277 select.select([s], [], [], 5.0)
278 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
279 select.select([], [s], [], 5.0)
280 else:
281 raise
282 # SSL established
283 self.assertTrue(s.getpeercert())
284 finally:
285 s.close()
286
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000287 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
288 def test_makefile_close(self):
289 # Issue #5238: creating a file-like object with makefile() shouldn't
290 # delay closing the underlying "real socket" (here tested with its
291 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000292 with test_support.transient_internet("svn.python.org"):
293 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
294 ss.connect(("svn.python.org", 443))
295 fd = ss.fileno()
296 f = ss.makefile()
297 f.close()
298 # The fd is still open
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000299 os.read(fd, 0)
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000300 # Closing the SSL socket should close the fd too
301 ss.close()
302 gc.collect()
303 with self.assertRaises(OSError) as e:
304 os.read(fd, 0)
305 self.assertEqual(e.exception.errno, errno.EBADF)
Bill Janssen934b16d2008-06-28 22:19:33 +0000306
Antoine Pitrou3945c862010-04-28 21:11:01 +0000307 def test_non_blocking_handshake(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000308 with test_support.transient_internet("svn.python.org"):
309 s = socket.socket(socket.AF_INET)
310 s.connect(("svn.python.org", 443))
311 s.setblocking(False)
312 s = ssl.wrap_socket(s,
313 cert_reqs=ssl.CERT_NONE,
314 do_handshake_on_connect=False)
315 count = 0
316 while True:
317 try:
318 count += 1
319 s.do_handshake()
320 break
321 except ssl.SSLError, err:
322 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
323 select.select([s], [], [])
324 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
325 select.select([], [s], [])
326 else:
327 raise
328 s.close()
329 if test_support.verbose:
330 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Bill Janssen934b16d2008-06-28 22:19:33 +0000331
Antoine Pitrou3945c862010-04-28 21:11:01 +0000332 def test_get_server_certificate(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000333 with test_support.transient_internet("svn.python.org"):
334 pem = ssl.get_server_certificate(("svn.python.org", 443))
335 if not pem:
336 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000337
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000338 try:
339 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
340 except ssl.SSLError:
341 #should fail
342 pass
343 else:
344 self.fail("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000345
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000346 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
347 if not pem:
348 self.fail("No server certificate on svn.python.org:443!")
349 if test_support.verbose:
350 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000351
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000352 def test_algorithms(self):
353 # Issue #8484: all algorithms should be available when verifying a
354 # certificate.
Antoine Pitrou9aed6042010-04-22 18:00:41 +0000355 # SHA256 was added in OpenSSL 0.9.8
356 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
357 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000358 # NOTE: https://sha256.tbs-internet.com is another possible test host
Antoine Pitroud43245a2011-01-08 10:32:51 +0000359 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000360 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitroud43245a2011-01-08 10:32:51 +0000361 with test_support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrouc818ed42010-09-07 21:40:25 +0000362 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
363 cert_reqs=ssl.CERT_REQUIRED,
364 ca_certs=sha256_cert,)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000365 try:
366 s.connect(remote)
367 if test_support.verbose:
368 sys.stdout.write("\nCipher with %r is %r\n" %
369 (remote, s.cipher()))
370 sys.stdout.write("Certificate is:\n%s\n" %
371 pprint.pformat(s.getpeercert()))
372 finally:
373 s.close()
374
Bill Janssen296a59d2007-09-16 22:06:00 +0000375
Bill Janssen98d19da2007-09-10 21:51:02 +0000376try:
377 import threading
378except ImportError:
379 _have_threads = False
380else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000381 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000382
Bill Janssen98d19da2007-09-10 21:51:02 +0000383 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000384
Bill Janssen98d19da2007-09-10 21:51:02 +0000385 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000386
Bill Janssen98d19da2007-09-10 21:51:02 +0000387 """A mildly complicated class, because we want it to work both
388 with and without the SSL wrapper around the socket connection, so
389 that we can test the STARTTLS functionality."""
390
391 def __init__(self, server, connsock):
392 self.server = server
393 self.running = False
394 self.sock = connsock
395 self.sock.setblocking(1)
396 self.sslconn = None
397 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000398 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000399
Bill Janssen934b16d2008-06-28 22:19:33 +0000400 def show_conn_details(self):
401 if self.server.certreqs == ssl.CERT_REQUIRED:
402 cert = self.sslconn.getpeercert()
403 if test_support.verbose and self.server.chatty:
404 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
405 cert_binary = self.sslconn.getpeercert(True)
406 if test_support.verbose and self.server.chatty:
407 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
408 cipher = self.sslconn.cipher()
409 if test_support.verbose and self.server.chatty:
410 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
411
Antoine Pitrou3945c862010-04-28 21:11:01 +0000412 def wrap_conn(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000413 try:
414 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
415 certfile=self.server.certificate,
416 ssl_version=self.server.protocol,
417 ca_certs=self.server.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000418 cert_reqs=self.server.certreqs,
419 ciphers=self.server.ciphers)
Antoine Pitroudb187842010-04-27 10:32:58 +0000420 except ssl.SSLError:
421 # XXX Various errors can have happened here, for example
422 # a mismatching protocol version, an invalid certificate,
423 # or a low-level bug. This should be made more discriminating.
Bill Janssen98d19da2007-09-10 21:51:02 +0000424 if self.server.chatty:
425 handle_error("\n server: bad connection attempt from " +
426 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000427 self.close()
Antoine Pitroudb187842010-04-27 10:32:58 +0000428 self.running = False
429 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000430 return False
Bill Janssen98d19da2007-09-10 21:51:02 +0000431 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000432 return True
433
434 def read(self):
435 if self.sslconn:
436 return self.sslconn.read()
437 else:
438 return self.sock.recv(1024)
439
440 def write(self, bytes):
441 if self.sslconn:
442 return self.sslconn.write(bytes)
443 else:
444 return self.sock.send(bytes)
445
446 def close(self):
447 if self.sslconn:
448 self.sslconn.close()
449 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000450 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000451
Antoine Pitrou3945c862010-04-28 21:11:01 +0000452 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000453 self.running = True
454 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000455 if isinstance(self.sock, ssl.SSLSocket):
456 self.sslconn = self.sock
457 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000458 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000459 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000460 while self.running:
461 try:
462 msg = self.read()
463 if not msg:
464 # eof, so quit this handler
465 self.running = False
466 self.close()
467 elif msg.strip() == 'over':
468 if test_support.verbose and self.server.connectionchatty:
469 sys.stdout.write(" server: client closed connection\n")
470 self.close()
471 return
472 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
473 if test_support.verbose and self.server.connectionchatty:
474 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
475 self.write("OK\n")
476 if not self.wrap_conn():
477 return
Bill Janssen39295c22008-08-12 16:31:21 +0000478 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
479 if test_support.verbose and self.server.connectionchatty:
480 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
481 self.write("OK\n")
482 self.sslconn.unwrap()
483 self.sslconn = None
484 if test_support.verbose and self.server.connectionchatty:
485 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000486 else:
487 if (test_support.verbose and
488 self.server.connectionchatty):
489 ctype = (self.sslconn and "encrypted") or "unencrypted"
490 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
491 % (repr(msg), ctype, repr(msg.lower()), ctype))
492 self.write(msg.lower())
493 except ssl.SSLError:
494 if self.server.chatty:
495 handle_error("Test server failure:\n")
496 self.close()
497 self.running = False
498 # normally, we'd just stop here, but for the test
499 # harness, we want to stop the server
500 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000501
Trent Nelsone41b0062008-04-08 23:47:30 +0000502 def __init__(self, certificate, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +0000503 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000504 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000505 wrap_accepting_socket=False, ciphers=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000506
Bill Janssen98d19da2007-09-10 21:51:02 +0000507 if ssl_version is None:
508 ssl_version = ssl.PROTOCOL_TLSv1
509 if certreqs is None:
510 certreqs = ssl.CERT_NONE
511 self.certificate = certificate
512 self.protocol = ssl_version
513 self.certreqs = certreqs
514 self.cacerts = cacerts
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000515 self.ciphers = ciphers
Bill Janssen98d19da2007-09-10 21:51:02 +0000516 self.chatty = chatty
517 self.connectionchatty = connectionchatty
518 self.starttls_server = starttls_server
519 self.sock = socket.socket()
520 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000521 if wrap_accepting_socket:
522 self.sock = ssl.wrap_socket(self.sock, server_side=True,
523 certfile=self.certificate,
524 cert_reqs = self.certreqs,
525 ca_certs = self.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000526 ssl_version = self.protocol,
527 ciphers = self.ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000528 if test_support.verbose and self.chatty:
529 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
530 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000531 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000532 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000533 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000534
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100535 def __enter__(self):
536 self.start(threading.Event())
537 self.flag.wait()
538
539 def __exit__(self, *args):
540 self.stop()
541 self.join()
542
Antoine Pitrou3945c862010-04-28 21:11:01 +0000543 def start(self, flag=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000544 self.flag = flag
545 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000546
Antoine Pitrou3945c862010-04-28 21:11:01 +0000547 def run(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000548 self.sock.settimeout(0.05)
Bill Janssen98d19da2007-09-10 21:51:02 +0000549 self.sock.listen(5)
550 self.active = True
551 if self.flag:
552 # signal an event
553 self.flag.set()
554 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000555 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000556 newconn, connaddr = self.sock.accept()
557 if test_support.verbose and self.chatty:
558 sys.stdout.write(' server: new connection from '
559 + str(connaddr) + '\n')
560 handler = self.ConnectionHandler(self, newconn)
561 handler.start()
562 except socket.timeout:
563 pass
564 except KeyboardInterrupt:
565 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +0000566 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000567
Antoine Pitrou3945c862010-04-28 21:11:01 +0000568 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000569 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000570
Bill Janssen934b16d2008-06-28 22:19:33 +0000571 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000572
Antoine Pitrou3945c862010-04-28 21:11:01 +0000573 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +0000574
Antoine Pitrou3945c862010-04-28 21:11:01 +0000575 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +0000576
577 def __init__(self, conn, certfile):
578 asyncore.dispatcher_with_send.__init__(self, conn)
579 self.socket = ssl.wrap_socket(conn, server_side=True,
580 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +0000581 do_handshake_on_connect=False)
582 self._ssl_accepting = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000583
584 def readable(self):
585 if isinstance(self.socket, ssl.SSLSocket):
586 while self.socket.pending() > 0:
587 self.handle_read_event()
588 return True
589
Antoine Pitroufc69af12010-04-24 20:04:58 +0000590 def _do_ssl_handshake(self):
591 try:
592 self.socket.do_handshake()
593 except ssl.SSLError, err:
594 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
595 ssl.SSL_ERROR_WANT_WRITE):
596 return
597 elif err.args[0] == ssl.SSL_ERROR_EOF:
598 return self.handle_close()
599 raise
600 except socket.error, err:
601 if err.args[0] == errno.ECONNABORTED:
602 return self.handle_close()
603 else:
604 self._ssl_accepting = False
605
Bill Janssen934b16d2008-06-28 22:19:33 +0000606 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +0000607 if self._ssl_accepting:
608 self._do_ssl_handshake()
609 else:
610 data = self.recv(1024)
Antoine Pitroudb187842010-04-27 10:32:58 +0000611 if data and data.strip() != 'over':
612 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +0000613
614 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000615 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000616 if test_support.verbose:
617 sys.stdout.write(" server: closed connection %s\n" % self.socket)
618
619 def handle_error(self):
620 raise
621
622 def __init__(self, certfile):
623 self.certfile = certfile
624 asyncore.dispatcher.__init__(self)
625 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
626 self.port = test_support.bind_port(self.socket)
627 self.listen(5)
628
629 def handle_accept(self):
630 sock_obj, addr = self.accept()
631 if test_support.verbose:
632 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
633 self.ConnectionHandler(sock_obj, self.certfile)
634
635 def handle_error(self):
636 raise
637
638 def __init__(self, certfile):
639 self.flag = None
640 self.active = False
641 self.server = self.EchoServer(certfile)
642 self.port = self.server.port
643 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000644 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000645
646 def __str__(self):
647 return "<%s %s>" % (self.__class__.__name__, self.server)
648
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100649 def __enter__(self):
650 self.start(threading.Event())
651 self.flag.wait()
652
653 def __exit__(self, *args):
654 if test_support.verbose:
655 sys.stdout.write(" cleanup: stopping server.\n")
656 self.stop()
657 if test_support.verbose:
658 sys.stdout.write(" cleanup: joining server thread.\n")
659 self.join()
660 if test_support.verbose:
661 sys.stdout.write(" cleanup: successfully joined.\n")
662
Antoine Pitrou3945c862010-04-28 21:11:01 +0000663 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000664 self.flag = flag
665 threading.Thread.start(self)
666
Antoine Pitrou3945c862010-04-28 21:11:01 +0000667 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000668 self.active = True
669 if self.flag:
670 self.flag.set()
671 while self.active:
Antoine Pitroudb187842010-04-27 10:32:58 +0000672 asyncore.loop(0.05)
Bill Janssen934b16d2008-06-28 22:19:33 +0000673
Antoine Pitrou3945c862010-04-28 21:11:01 +0000674 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000675 self.active = False
676 self.server.close()
677
678 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000679
680 class HTTPSServer(HTTPServer):
681
682 def __init__(self, server_address, RequestHandlerClass, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000683 HTTPServer.__init__(self, server_address, RequestHandlerClass)
684 # we assume the certfile contains both private key and certificate
685 self.certfile = certfile
Bill Janssen296a59d2007-09-16 22:06:00 +0000686 self.allow_reuse_address = True
687
Bill Janssen934b16d2008-06-28 22:19:33 +0000688 def __str__(self):
689 return ('<%s %s:%s>' %
690 (self.__class__.__name__,
691 self.server_name,
692 self.server_port))
693
Antoine Pitrou3945c862010-04-28 21:11:01 +0000694 def get_request(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000695 # override this to wrap socket with SSL
696 sock, addr = self.socket.accept()
697 sslconn = ssl.wrap_socket(sock, server_side=True,
698 certfile=self.certfile)
699 return sslconn, addr
700
Bill Janssen296a59d2007-09-16 22:06:00 +0000701 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Bill Janssen296a59d2007-09-16 22:06:00 +0000702 # need to override translate_path to get a known root,
703 # instead of using os.curdir, since the test could be
704 # run from anywhere
705
706 server_version = "TestHTTPS/1.0"
707
708 root = None
709
710 def translate_path(self, path):
711 """Translate a /-separated PATH to the local filename syntax.
712
713 Components that mean special things to the local file system
714 (e.g. drive or directory names) are ignored. (XXX They should
715 probably be diagnosed.)
716
717 """
718 # abandon query parameters
719 path = urlparse.urlparse(path)[2]
720 path = os.path.normpath(urllib.unquote(path))
721 words = path.split('/')
722 words = filter(None, words)
723 path = self.root
724 for word in words:
725 drive, word = os.path.splitdrive(word)
726 head, word = os.path.split(word)
727 if word in self.root: continue
728 path = os.path.join(path, word)
729 return path
730
731 def log_message(self, format, *args):
732
733 # we override this to suppress logging unless "verbose"
734
735 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000736 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
737 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000738 self.server.server_port,
739 self.request.cipher(),
740 self.log_date_time_string(),
741 format%args))
742
743
Trent Nelsone41b0062008-04-08 23:47:30 +0000744 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000745 self.flag = None
Bill Janssen296a59d2007-09-16 22:06:00 +0000746 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
747 self.server = self.HTTPSServer(
Antoine Pitrou150acda2010-04-27 08:40:51 +0000748 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
749 self.port = self.server.server_port
Bill Janssen296a59d2007-09-16 22:06:00 +0000750 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000751 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000752
753 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000754 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000755
Antoine Pitrou3945c862010-04-28 21:11:01 +0000756 def start(self, flag=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000757 self.flag = flag
758 threading.Thread.start(self)
759
Antoine Pitrou3945c862010-04-28 21:11:01 +0000760 def run(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000761 if self.flag:
762 self.flag.set()
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000763 self.server.serve_forever(0.05)
Bill Janssen296a59d2007-09-16 22:06:00 +0000764
Antoine Pitrou3945c862010-04-28 21:11:01 +0000765 def stop(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000766 self.server.shutdown()
Bill Janssen296a59d2007-09-16 22:06:00 +0000767
768
Antoine Pitrou3945c862010-04-28 21:11:01 +0000769 def bad_cert_test(certfile):
770 """
771 Launch a server with CERT_REQUIRED, and check that trying to
772 connect to it with the given client certificate fails.
773 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000774 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000775 certreqs=ssl.CERT_REQUIRED,
776 cacerts=CERTFILE, chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100777 with server:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000778 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000779 s = ssl.wrap_socket(socket.socket(),
780 certfile=certfile,
781 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000782 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000783 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000784 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000785 sys.stdout.write("\nSSLError is %s\n" % x[1])
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000786 except socket.error, x:
787 if test_support.verbose:
788 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000789 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000790 raise AssertionError("Use of invalid cert should have failed!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000791
Antoine Pitrou3945c862010-04-28 21:11:01 +0000792 def server_params_test(certfile, protocol, certreqs, cacertsfile,
793 client_certfile, client_protocol=None, indata="FOO\n",
794 ciphers=None, chatty=True, connectionchatty=False,
795 wrap_accepting_socket=False):
796 """
797 Launch a server, connect a client to it and try various reads
798 and writes.
799 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000800 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000801 certreqs=certreqs,
802 ssl_version=protocol,
803 cacerts=cacertsfile,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000804 ciphers=ciphers,
Bill Janssen98d19da2007-09-10 21:51:02 +0000805 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000806 connectionchatty=connectionchatty,
807 wrap_accepting_socket=wrap_accepting_socket)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100808 with server:
809 # try to connect
810 if client_protocol is None:
811 client_protocol = protocol
Antoine Pitroudb187842010-04-27 10:32:58 +0000812 s = ssl.wrap_socket(socket.socket(),
813 certfile=client_certfile,
814 ca_certs=cacertsfile,
815 ciphers=ciphers,
816 cert_reqs=certreqs,
817 ssl_version=client_protocol)
818 s.connect((HOST, server.port))
819 for arg in [indata, bytearray(indata), memoryview(indata)]:
Bill Janssen98d19da2007-09-10 21:51:02 +0000820 if connectionchatty:
821 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +0000822 sys.stdout.write(
823 " client: sending %s...\n" % (repr(arg)))
824 s.write(arg)
825 outdata = s.read()
826 if connectionchatty:
827 if test_support.verbose:
828 sys.stdout.write(" client: read %s\n" % repr(outdata))
829 if outdata != indata.lower():
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000830 raise AssertionError(
Antoine Pitroudb187842010-04-27 10:32:58 +0000831 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
832 % (outdata[:min(len(outdata),20)], len(outdata),
833 indata[:min(len(indata),20)].lower(), len(indata)))
834 s.write("over\n")
835 if connectionchatty:
836 if test_support.verbose:
837 sys.stdout.write(" client: closing connection.\n")
838 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000839
Antoine Pitrou3945c862010-04-28 21:11:01 +0000840 def try_protocol_combo(server_protocol,
841 client_protocol,
842 expect_success,
843 certsreqs=None):
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000844 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000845 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +0000846 certtype = {
847 ssl.CERT_NONE: "CERT_NONE",
848 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
849 ssl.CERT_REQUIRED: "CERT_REQUIRED",
850 }[certsreqs]
Bill Janssen98d19da2007-09-10 21:51:02 +0000851 if test_support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000852 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +0000853 sys.stdout.write(formatstr %
854 (ssl.get_protocol_name(client_protocol),
855 ssl.get_protocol_name(server_protocol),
856 certtype))
857 try:
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000858 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
859 # will send an SSLv3 hello (rather than SSLv2) starting from
860 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou3945c862010-04-28 21:11:01 +0000861 server_params_test(CERTFILE, server_protocol, certsreqs,
862 CERTFILE, CERTFILE, client_protocol,
863 ciphers="ALL", chatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +0000864 # Protocol mismatch can result in either an SSLError, or a
865 # "Connection reset by peer" error.
866 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000867 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +0000868 raise
Antoine Pitroudb187842010-04-27 10:32:58 +0000869 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000870 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +0000871 raise
Bill Janssen98d19da2007-09-10 21:51:02 +0000872 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000873 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000874 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +0000875 "Client protocol %s succeeded with server protocol %s!"
876 % (ssl.get_protocol_name(client_protocol),
877 ssl.get_protocol_name(server_protocol)))
878
879
Bill Janssen934b16d2008-06-28 22:19:33 +0000880 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000881
Antoine Pitrou3945c862010-04-28 21:11:01 +0000882 def test_rude_shutdown(self):
883 """A brutal shutdown of an SSL server should raise an IOError
884 in the client when attempting handshake.
885 """
Bill Janssen98d19da2007-09-10 21:51:02 +0000886 listener_ready = threading.Event()
887 listener_gone = threading.Event()
888
Antoine Pitrou150acda2010-04-27 08:40:51 +0000889 s = socket.socket()
890 port = test_support.bind_port(s, HOST)
891
892 # `listener` runs in a thread. It sits in an accept() until
893 # the main thread connects. Then it rudely closes the socket,
894 # and sets Event `listener_gone` to let the main thread know
895 # the socket is gone.
Bill Janssen98d19da2007-09-10 21:51:02 +0000896 def listener():
Bill Janssen98d19da2007-09-10 21:51:02 +0000897 s.listen(5)
898 listener_ready.set()
899 s.accept()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000900 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000901 listener_gone.set()
902
903 def connector():
904 listener_ready.wait()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000905 c = socket.socket()
906 c.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000907 listener_gone.wait()
908 try:
Antoine Pitrou150acda2010-04-27 08:40:51 +0000909 ssl_sock = ssl.wrap_socket(c)
Bill Janssen934b16d2008-06-28 22:19:33 +0000910 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000911 pass
912 else:
Antoine Pitroudb187842010-04-27 10:32:58 +0000913 self.fail('connecting to closed SSL socket should have failed')
Bill Janssen98d19da2007-09-10 21:51:02 +0000914
915 t = threading.Thread(target=listener)
916 t.start()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000917 try:
918 connector()
919 finally:
920 t.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000921
Antoine Pitroud75efd92010-08-04 17:38:33 +0000922 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000923 def test_echo(self):
924 """Basic test of an SSL client connecting to a server"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000925 if test_support.verbose:
926 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000927 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
928 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
929 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000930
Antoine Pitrou3945c862010-04-28 21:11:01 +0000931 def test_getpeercert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000932 if test_support.verbose:
933 sys.stdout.write("\n")
934 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000935 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000936 certreqs=ssl.CERT_NONE,
937 ssl_version=ssl.PROTOCOL_SSLv23,
938 cacerts=CERTFILE,
939 chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100940 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +0000941 s = ssl.wrap_socket(socket.socket(),
942 certfile=CERTFILE,
943 ca_certs=CERTFILE,
944 cert_reqs=ssl.CERT_REQUIRED,
945 ssl_version=ssl.PROTOCOL_SSLv23)
946 s.connect((HOST, server.port))
947 cert = s.getpeercert()
948 self.assertTrue(cert, "Can't get peer certificate.")
949 cipher = s.cipher()
950 if test_support.verbose:
951 sys.stdout.write(pprint.pformat(cert) + '\n')
952 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
953 if 'subject' not in cert:
954 self.fail("No subject field in certificate: %s." %
955 pprint.pformat(cert))
956 if ((('organizationName', 'Python Software Foundation'),)
957 not in cert['subject']):
958 self.fail(
959 "Missing or invalid 'organizationName' field in certificate subject; "
960 "should be 'Python Software Foundation'.")
961 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000962
Antoine Pitrou3945c862010-04-28 21:11:01 +0000963 def test_empty_cert(self):
964 """Connecting with an empty cert file"""
965 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
966 "nullcert.pem"))
967 def test_malformed_cert(self):
968 """Connecting with a badly formatted certificate (syntax error)"""
969 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
970 "badcert.pem"))
971 def test_nonexisting_cert(self):
972 """Connecting with a non-existing cert file"""
973 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
974 "wrongcert.pem"))
975 def test_malformed_key(self):
976 """Connecting with a badly formatted key (syntax error)"""
977 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
978 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000979
Antoine Pitroud75efd92010-08-04 17:38:33 +0000980 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000981 def test_protocol_sslv2(self):
982 """Connecting to an SSLv2 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000983 if test_support.verbose:
984 sys.stdout.write("\n")
Antoine Pitrou6361ea22011-10-30 21:31:34 +0100985 if not hasattr(ssl, 'PROTOCOL_SSLv2'):
986 self.skipTest("PROTOCOL_SSLv2 needed")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000987 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
988 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
989 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
990 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
991 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
992 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000993
Antoine Pitroud75efd92010-08-04 17:38:33 +0000994 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000995 def test_protocol_sslv23(self):
996 """Connecting to an SSLv23 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000997 if test_support.verbose:
998 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000999 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1000 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1001 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Bill Janssen98d19da2007-09-10 21:51:02 +00001002
Antoine Pitrou3945c862010-04-28 21:11:01 +00001003 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1004 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1005 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +00001006
Antoine Pitrou3945c862010-04-28 21:11:01 +00001007 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1008 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1009 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00001010
Antoine Pitroud75efd92010-08-04 17:38:33 +00001011 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001012 def test_protocol_sslv3(self):
1013 """Connecting to an SSLv3 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001014 if test_support.verbose:
1015 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001016 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1017 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1018 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001019 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1020 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001021 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001022
Antoine Pitroud75efd92010-08-04 17:38:33 +00001023 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001024 def test_protocol_tlsv1(self):
1025 """Connecting to a TLSv1 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001026 if test_support.verbose:
1027 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001028 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1029 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1030 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001031 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1032 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001033 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001034
Antoine Pitrou3945c862010-04-28 21:11:01 +00001035 def test_starttls(self):
1036 """Switching from clear text to encrypted and back again."""
Bill Janssen39295c22008-08-12 16:31:21 +00001037 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +00001038
Trent Nelsone41b0062008-04-08 23:47:30 +00001039 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00001040 ssl_version=ssl.PROTOCOL_TLSv1,
1041 starttls_server=True,
1042 chatty=True,
1043 connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +00001044 wrapped = False
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001045 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001046 s = socket.socket()
1047 s.setblocking(1)
1048 s.connect((HOST, server.port))
1049 if test_support.verbose:
1050 sys.stdout.write("\n")
1051 for indata in msgs:
Bill Janssen98d19da2007-09-10 21:51:02 +00001052 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00001053 sys.stdout.write(
1054 " client: sending %s...\n" % repr(indata))
1055 if wrapped:
1056 conn.write(indata)
1057 outdata = conn.read()
1058 else:
1059 s.send(indata)
1060 outdata = s.recv(1024)
1061 if (indata == "STARTTLS" and
1062 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001063 # STARTTLS ok, switch to secure mode
Bill Janssen98d19da2007-09-10 21:51:02 +00001064 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00001065 sys.stdout.write(
Antoine Pitroudb187842010-04-27 10:32:58 +00001066 " client: read %s from server, starting TLS...\n"
1067 % repr(outdata))
1068 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1069 wrapped = True
1070 elif (indata == "ENDTLS" and
1071 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001072 # ENDTLS ok, switch back to clear text
Antoine Pitroudb187842010-04-27 10:32:58 +00001073 if test_support.verbose:
1074 sys.stdout.write(
1075 " client: read %s from server, ending TLS...\n"
1076 % repr(outdata))
1077 s = conn.unwrap()
1078 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00001079 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001080 if test_support.verbose:
1081 sys.stdout.write(
1082 " client: read %s from server\n" % repr(outdata))
1083 if test_support.verbose:
1084 sys.stdout.write(" client: closing connection.\n")
1085 if wrapped:
1086 conn.write("over\n")
1087 else:
1088 s.send("over\n")
1089 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001090
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)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001139 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001140 s = ssl.wrap_socket(socket.socket())
1141 s.connect(('127.0.0.1', server.port))
1142 if test_support.verbose:
1143 sys.stdout.write(
1144 " client: sending %s...\n" % (repr(indata)))
1145 s.write(indata)
1146 outdata = s.read()
1147 if test_support.verbose:
1148 sys.stdout.write(" client: read %s\n" % repr(outdata))
1149 if outdata != indata.lower():
1150 self.fail(
1151 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1152 % (outdata[:min(len(outdata),20)], len(outdata),
1153 indata[:min(len(indata),20)].lower(), len(indata)))
1154 s.write("over\n")
1155 if test_support.verbose:
1156 sys.stdout.write(" client: closing connection.\n")
1157 s.close()
Bill Janssen934b16d2008-06-28 22:19:33 +00001158
Antoine Pitrou3945c862010-04-28 21:11:01 +00001159 def test_recv_send(self):
1160 """Test recv(), send() and friends."""
Bill Janssen61c001a2008-09-08 16:37:24 +00001161 if test_support.verbose:
1162 sys.stdout.write("\n")
1163
1164 server = ThreadedEchoServer(CERTFILE,
1165 certreqs=ssl.CERT_NONE,
1166 ssl_version=ssl.PROTOCOL_TLSv1,
1167 cacerts=CERTFILE,
1168 chatty=True,
1169 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001170 with server:
1171 s = ssl.wrap_socket(socket.socket(),
1172 server_side=False,
1173 certfile=CERTFILE,
1174 ca_certs=CERTFILE,
1175 cert_reqs=ssl.CERT_NONE,
1176 ssl_version=ssl.PROTOCOL_TLSv1)
1177 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00001178 # helper methods for standardising recv* method signatures
1179 def _recv_into():
1180 b = bytearray("\0"*100)
1181 count = s.recv_into(b)
1182 return b[:count]
1183
1184 def _recvfrom_into():
1185 b = bytearray("\0"*100)
1186 count, addr = s.recvfrom_into(b)
1187 return b[:count]
1188
1189 # (name, method, whether to expect success, *args)
1190 send_methods = [
1191 ('send', s.send, True, []),
1192 ('sendto', s.sendto, False, ["some.address"]),
1193 ('sendall', s.sendall, True, []),
1194 ]
1195 recv_methods = [
1196 ('recv', s.recv, True, []),
1197 ('recvfrom', s.recvfrom, False, ["some.address"]),
1198 ('recv_into', _recv_into, True, []),
1199 ('recvfrom_into', _recvfrom_into, False, []),
1200 ]
1201 data_prefix = u"PREFIX_"
1202
1203 for meth_name, send_meth, expect_success, args in send_methods:
1204 indata = data_prefix + meth_name
1205 try:
1206 send_meth(indata.encode('ASCII', 'strict'), *args)
1207 outdata = s.read()
1208 outdata = outdata.decode('ASCII', 'strict')
1209 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001210 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001211 "While sending with <<%s>> bad data "
1212 "<<%r>> (%d) received; "
1213 "expected <<%r>> (%d)\n" % (
1214 meth_name, outdata[:20], len(outdata),
1215 indata[:20], len(indata)
1216 )
1217 )
1218 except ValueError as e:
1219 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001220 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001221 "Failed to send with method <<%s>>; "
1222 "expected to succeed.\n" % (meth_name,)
1223 )
1224 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001225 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001226 "Method <<%s>> failed with unexpected "
1227 "exception message: %s\n" % (
1228 meth_name, e
1229 )
1230 )
1231
1232 for meth_name, recv_meth, expect_success, args in recv_methods:
1233 indata = data_prefix + meth_name
1234 try:
1235 s.send(indata.encode('ASCII', 'strict'))
1236 outdata = recv_meth(*args)
1237 outdata = outdata.decode('ASCII', 'strict')
1238 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001239 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001240 "While receiving with <<%s>> bad data "
1241 "<<%r>> (%d) received; "
1242 "expected <<%r>> (%d)\n" % (
1243 meth_name, outdata[:20], len(outdata),
1244 indata[:20], len(indata)
1245 )
1246 )
1247 except ValueError as e:
1248 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001249 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001250 "Failed to receive with method <<%s>>; "
1251 "expected to succeed.\n" % (meth_name,)
1252 )
1253 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001254 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001255 "Method <<%s>> failed with unexpected "
1256 "exception message: %s\n" % (
1257 meth_name, e
1258 )
1259 )
1260 # consume data
1261 s.read()
1262
1263 s.write("over\n".encode("ASCII", "strict"))
1264 s.close()
Bill Janssen61c001a2008-09-08 16:37:24 +00001265
Antoine Pitroufc69af12010-04-24 20:04:58 +00001266 def test_handshake_timeout(self):
1267 # Issue #5103: SSL handshake must respect the socket timeout
1268 server = socket.socket(socket.AF_INET)
1269 host = "127.0.0.1"
1270 port = test_support.bind_port(server)
1271 started = threading.Event()
1272 finish = False
1273
1274 def serve():
1275 server.listen(5)
1276 started.set()
1277 conns = []
1278 while not finish:
1279 r, w, e = select.select([server], [], [], 0.1)
1280 if server in r:
1281 # Let the socket hang around rather than having
1282 # it closed by garbage collection.
1283 conns.append(server.accept()[0])
1284
1285 t = threading.Thread(target=serve)
1286 t.start()
1287 started.wait()
1288
1289 try:
1290 try:
1291 c = socket.socket(socket.AF_INET)
1292 c.settimeout(0.2)
1293 c.connect((host, port))
1294 # Will attempt handshake and time out
1295 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1296 ssl.wrap_socket, c)
1297 finally:
1298 c.close()
1299 try:
1300 c = socket.socket(socket.AF_INET)
1301 c.settimeout(0.2)
1302 c = ssl.wrap_socket(c)
1303 # Will attempt handshake and time out
1304 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1305 c.connect, (host, port))
1306 finally:
1307 c.close()
1308 finally:
1309 finish = True
1310 t.join()
1311 server.close()
1312
Bill Janssen61c001a2008-09-08 16:37:24 +00001313
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001314def test_main(verbose=False):
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001315 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, NOKIACERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001316 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001317 "keycert.pem")
1318 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1319 os.path.dirname(__file__) or os.curdir,
1320 "https_svn_python_org_root.pem")
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001321 NOKIACERT = os.path.join(os.path.dirname(__file__) or os.curdir,
1322 "nokia.pem")
Bill Janssen296a59d2007-09-16 22:06:00 +00001323
1324 if (not os.path.exists(CERTFILE) or
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001325 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT) or
1326 not os.path.exists(NOKIACERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001327 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001328
Antoine Pitroude30f702010-09-14 12:54:08 +00001329 tests = [BasicTests, BasicSocketTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001330
Bill Janssen296a59d2007-09-16 22:06:00 +00001331 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001332 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001333
Bill Janssen98d19da2007-09-10 21:51:02 +00001334 if _have_threads:
1335 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001336 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001337 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001338
Antoine Pitrou3945c862010-04-28 21:11:01 +00001339 try:
1340 test_support.run_unittest(*tests)
1341 finally:
1342 if _have_threads:
1343 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001344
1345if __name__ == "__main__":
1346 test_main()