blob: 58da942f4923d3e473da1717d12d13d60057749d [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"))
Jesus Ceaa8a5b392012-09-11 01:55:04 +020098 self.assertRaises(TypeError, ssl.RAND_egd, 1)
99 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Bill Janssen98d19da2007-09-10 21:51:02 +0000100 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000101
Antoine Pitrou3945c862010-04-28 21:11:01 +0000102 def test_parse_cert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000103 # note that this uses an 'unofficial' function in _ssl.c,
104 # provided solely for this test, to exercise the certificate
105 # parsing code
106 p = ssl._ssl._test_decode_cert(CERTFILE, False)
107 if test_support.verbose:
108 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200109 self.assertEqual(p['subject'],
110 ((('countryName', u'US'),),
111 (('stateOrProvinceName', u'Delaware'),),
112 (('localityName', u'Wilmington'),),
113 (('organizationName', u'Python Software Foundation'),),
114 (('organizationalUnitName', u'SSL'),),
115 (('commonName', u'somemachine.python.org'),)),
116 )
117 # Issue #13034: the subjectAltName in some certificates
118 # (notably projects.developer.nokia.com:443) wasn't parsed
119 p = ssl._ssl._test_decode_cert(NOKIACERT)
120 if test_support.verbose:
121 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
122 self.assertEqual(p['subjectAltName'],
123 (('DNS', 'projects.developer.nokia.com'),
124 ('DNS', 'projects.forum.nokia.com'))
125 )
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000126
Antoine Pitrou3945c862010-04-28 21:11:01 +0000127 def test_DER_to_PEM(self):
128 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
129 pem = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000130 d1 = ssl.PEM_cert_to_DER_cert(pem)
131 p2 = ssl.DER_cert_to_PEM_cert(d1)
132 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitroudb187842010-04-27 10:32:58 +0000133 self.assertEqual(d1, d2)
Antoine Pitrou4c7bcf12010-04-27 22:03:37 +0000134 if not p2.startswith(ssl.PEM_HEADER + '\n'):
135 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
136 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
137 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Bill Janssen296a59d2007-09-16 22:06:00 +0000138
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000139 def test_openssl_version(self):
140 n = ssl.OPENSSL_VERSION_NUMBER
141 t = ssl.OPENSSL_VERSION_INFO
142 s = ssl.OPENSSL_VERSION
143 self.assertIsInstance(n, (int, long))
144 self.assertIsInstance(t, tuple)
145 self.assertIsInstance(s, str)
146 # Some sanity checks follow
147 # >= 0.9
148 self.assertGreaterEqual(n, 0x900000)
149 # < 2.0
150 self.assertLess(n, 0x20000000)
151 major, minor, fix, patch, status = t
152 self.assertGreaterEqual(major, 0)
153 self.assertLess(major, 2)
154 self.assertGreaterEqual(minor, 0)
155 self.assertLess(minor, 256)
156 self.assertGreaterEqual(fix, 0)
157 self.assertLess(fix, 256)
158 self.assertGreaterEqual(patch, 0)
159 self.assertLessEqual(patch, 26)
160 self.assertGreaterEqual(status, 0)
161 self.assertLessEqual(status, 15)
162 # Version string as returned by OpenSSL, the format might change
163 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
164 (s, t))
165
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000166 def test_ciphers(self):
167 if not test_support.is_resource_enabled('network'):
168 return
169 remote = ("svn.python.org", 443)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000170 with test_support.transient_internet(remote[0]):
171 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
172 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000173 s.connect(remote)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000174 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
175 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
176 s.connect(remote)
177 # Error checking occurs when connecting, because the SSL context
178 # isn't created before.
179 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
180 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
181 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
182 s.connect(remote)
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000183
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000184 @test_support.cpython_only
185 def test_refcycle(self):
186 # Issue #7943: an SSL object doesn't create reference cycles with
187 # itself.
188 s = socket.socket(socket.AF_INET)
189 ss = ssl.wrap_socket(s)
190 wr = weakref.ref(ss)
191 del ss
192 self.assertEqual(wr(), None)
193
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000194 def test_wrapped_unconnected(self):
195 # The _delegate_methods in socket.py are correctly delegated to by an
196 # unconnected SSLSocket, so they will raise a socket.error rather than
197 # something unexpected like TypeError.
198 s = socket.socket(socket.AF_INET)
199 ss = ssl.wrap_socket(s)
200 self.assertRaises(socket.error, ss.recv, 1)
201 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
202 self.assertRaises(socket.error, ss.recvfrom, 1)
203 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
204 self.assertRaises(socket.error, ss.send, b'x')
205 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
206
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000207
Bill Janssen934b16d2008-06-28 22:19:33 +0000208class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +0000209
Antoine Pitrou3945c862010-04-28 21:11:01 +0000210 def test_connect(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000211 with test_support.transient_internet("svn.python.org"):
212 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
213 cert_reqs=ssl.CERT_NONE)
Bill Janssen296a59d2007-09-16 22:06:00 +0000214 s.connect(("svn.python.org", 443))
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000215 c = s.getpeercert()
216 if c:
217 self.fail("Peer cert %s shouldn't be here!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000218 s.close()
219
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000220 # this should fail because we have no verification certs
221 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
222 cert_reqs=ssl.CERT_REQUIRED)
223 try:
224 s.connect(("svn.python.org", 443))
225 except ssl.SSLError:
226 pass
227 finally:
228 s.close()
229
230 # this should succeed because we specify the root cert
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 s.connect(("svn.python.org", 443))
236 finally:
237 s.close()
Bill Janssen296a59d2007-09-16 22:06:00 +0000238
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000239 def test_connect_ex(self):
240 # Issue #11326: check connect_ex() implementation
241 with test_support.transient_internet("svn.python.org"):
242 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
243 cert_reqs=ssl.CERT_REQUIRED,
244 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
245 try:
246 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
247 self.assertTrue(s.getpeercert())
248 finally:
249 s.close()
250
251 def test_non_blocking_connect_ex(self):
252 # Issue #11326: non-blocking connect_ex() should allow handshake
253 # to proceed after the socket gets ready.
254 with test_support.transient_internet("svn.python.org"):
255 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
256 cert_reqs=ssl.CERT_REQUIRED,
257 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
258 do_handshake_on_connect=False)
259 try:
260 s.setblocking(False)
261 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitrou8ef39072011-02-27 15:45:22 +0000262 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
263 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000264 # Wait for connect to finish
265 select.select([], [s], [], 5.0)
266 # Non-blocking handshake
267 while True:
268 try:
269 s.do_handshake()
270 break
271 except ssl.SSLError as err:
272 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
273 select.select([s], [], [], 5.0)
274 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
275 select.select([], [s], [], 5.0)
276 else:
277 raise
278 # SSL established
279 self.assertTrue(s.getpeercert())
280 finally:
281 s.close()
282
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000283 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
284 def test_makefile_close(self):
285 # Issue #5238: creating a file-like object with makefile() shouldn't
286 # delay closing the underlying "real socket" (here tested with its
287 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000288 with test_support.transient_internet("svn.python.org"):
289 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
290 ss.connect(("svn.python.org", 443))
291 fd = ss.fileno()
292 f = ss.makefile()
293 f.close()
294 # The fd is still open
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000295 os.read(fd, 0)
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000296 # Closing the SSL socket should close the fd too
297 ss.close()
298 gc.collect()
299 with self.assertRaises(OSError) as e:
300 os.read(fd, 0)
301 self.assertEqual(e.exception.errno, errno.EBADF)
Bill Janssen934b16d2008-06-28 22:19:33 +0000302
Antoine Pitrou3945c862010-04-28 21:11:01 +0000303 def test_non_blocking_handshake(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000304 with test_support.transient_internet("svn.python.org"):
305 s = socket.socket(socket.AF_INET)
306 s.connect(("svn.python.org", 443))
307 s.setblocking(False)
308 s = ssl.wrap_socket(s,
309 cert_reqs=ssl.CERT_NONE,
310 do_handshake_on_connect=False)
311 count = 0
312 while True:
313 try:
314 count += 1
315 s.do_handshake()
316 break
317 except ssl.SSLError, err:
318 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
319 select.select([s], [], [])
320 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
321 select.select([], [s], [])
322 else:
323 raise
324 s.close()
325 if test_support.verbose:
326 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Bill Janssen934b16d2008-06-28 22:19:33 +0000327
Antoine Pitrou3945c862010-04-28 21:11:01 +0000328 def test_get_server_certificate(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000329 with test_support.transient_internet("svn.python.org"):
330 pem = ssl.get_server_certificate(("svn.python.org", 443))
331 if not pem:
332 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000333
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000334 try:
335 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
336 except ssl.SSLError:
337 #should fail
338 pass
339 else:
340 self.fail("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000341
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000342 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
343 if not pem:
344 self.fail("No server certificate on svn.python.org:443!")
345 if test_support.verbose:
346 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000347
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000348 def test_algorithms(self):
349 # Issue #8484: all algorithms should be available when verifying a
350 # certificate.
Antoine Pitrou9aed6042010-04-22 18:00:41 +0000351 # SHA256 was added in OpenSSL 0.9.8
352 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
353 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrouc642f672012-05-04 16:33:30 +0200354 self.skipTest("remote host needs SNI, only available on Python 3.2+")
355 # NOTE: https://sha2.hboeck.de is another possible test host
Antoine Pitroud43245a2011-01-08 10:32:51 +0000356 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000357 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitroud43245a2011-01-08 10:32:51 +0000358 with test_support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrouc818ed42010-09-07 21:40:25 +0000359 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
360 cert_reqs=ssl.CERT_REQUIRED,
361 ca_certs=sha256_cert,)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000362 try:
363 s.connect(remote)
364 if test_support.verbose:
365 sys.stdout.write("\nCipher with %r is %r\n" %
366 (remote, s.cipher()))
367 sys.stdout.write("Certificate is:\n%s\n" %
368 pprint.pformat(s.getpeercert()))
369 finally:
370 s.close()
371
Bill Janssen296a59d2007-09-16 22:06:00 +0000372
Bill Janssen98d19da2007-09-10 21:51:02 +0000373try:
374 import threading
375except ImportError:
376 _have_threads = False
377else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000378 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000379
Bill Janssen98d19da2007-09-10 21:51:02 +0000380 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000381
Bill Janssen98d19da2007-09-10 21:51:02 +0000382 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000383
Bill Janssen98d19da2007-09-10 21:51:02 +0000384 """A mildly complicated class, because we want it to work both
385 with and without the SSL wrapper around the socket connection, so
386 that we can test the STARTTLS functionality."""
387
388 def __init__(self, server, connsock):
389 self.server = server
390 self.running = False
391 self.sock = connsock
392 self.sock.setblocking(1)
393 self.sslconn = None
394 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000395 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000396
Bill Janssen934b16d2008-06-28 22:19:33 +0000397 def show_conn_details(self):
398 if self.server.certreqs == ssl.CERT_REQUIRED:
399 cert = self.sslconn.getpeercert()
400 if test_support.verbose and self.server.chatty:
401 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
402 cert_binary = self.sslconn.getpeercert(True)
403 if test_support.verbose and self.server.chatty:
404 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
405 cipher = self.sslconn.cipher()
406 if test_support.verbose and self.server.chatty:
407 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
408
Antoine Pitrou3945c862010-04-28 21:11:01 +0000409 def wrap_conn(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000410 try:
411 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
412 certfile=self.server.certificate,
413 ssl_version=self.server.protocol,
414 ca_certs=self.server.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000415 cert_reqs=self.server.certreqs,
416 ciphers=self.server.ciphers)
Antoine Pitroud76088d2012-01-03 22:46:48 +0100417 except ssl.SSLError as e:
Antoine Pitroudb187842010-04-27 10:32:58 +0000418 # XXX Various errors can have happened here, for example
419 # a mismatching protocol version, an invalid certificate,
420 # or a low-level bug. This should be made more discriminating.
Antoine Pitroud76088d2012-01-03 22:46:48 +0100421 self.server.conn_errors.append(e)
Bill Janssen98d19da2007-09-10 21:51:02 +0000422 if self.server.chatty:
423 handle_error("\n server: bad connection attempt from " +
424 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000425 self.close()
Antoine Pitroudb187842010-04-27 10:32:58 +0000426 self.running = False
427 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000428 return False
Bill Janssen98d19da2007-09-10 21:51:02 +0000429 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000430 return True
431
432 def read(self):
433 if self.sslconn:
434 return self.sslconn.read()
435 else:
436 return self.sock.recv(1024)
437
438 def write(self, bytes):
439 if self.sslconn:
440 return self.sslconn.write(bytes)
441 else:
442 return self.sock.send(bytes)
443
444 def close(self):
445 if self.sslconn:
446 self.sslconn.close()
447 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000448 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000449
Antoine Pitrou3945c862010-04-28 21:11:01 +0000450 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000451 self.running = True
452 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000453 if isinstance(self.sock, ssl.SSLSocket):
454 self.sslconn = self.sock
455 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000456 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000457 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000458 while self.running:
459 try:
460 msg = self.read()
461 if not msg:
462 # eof, so quit this handler
463 self.running = False
464 self.close()
465 elif msg.strip() == 'over':
466 if test_support.verbose and self.server.connectionchatty:
467 sys.stdout.write(" server: client closed connection\n")
468 self.close()
469 return
470 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
471 if test_support.verbose and self.server.connectionchatty:
472 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
473 self.write("OK\n")
474 if not self.wrap_conn():
475 return
Bill Janssen39295c22008-08-12 16:31:21 +0000476 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
477 if test_support.verbose and self.server.connectionchatty:
478 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
479 self.write("OK\n")
480 self.sslconn.unwrap()
481 self.sslconn = None
482 if test_support.verbose and self.server.connectionchatty:
483 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000484 else:
485 if (test_support.verbose and
486 self.server.connectionchatty):
487 ctype = (self.sslconn and "encrypted") or "unencrypted"
488 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
489 % (repr(msg), ctype, repr(msg.lower()), ctype))
490 self.write(msg.lower())
491 except ssl.SSLError:
492 if self.server.chatty:
493 handle_error("Test server failure:\n")
494 self.close()
495 self.running = False
496 # normally, we'd just stop here, but for the test
497 # harness, we want to stop the server
498 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000499
Trent Nelsone41b0062008-04-08 23:47:30 +0000500 def __init__(self, certificate, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +0000501 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000502 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000503 wrap_accepting_socket=False, ciphers=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000504
Bill Janssen98d19da2007-09-10 21:51:02 +0000505 if ssl_version is None:
506 ssl_version = ssl.PROTOCOL_TLSv1
507 if certreqs is None:
508 certreqs = ssl.CERT_NONE
509 self.certificate = certificate
510 self.protocol = ssl_version
511 self.certreqs = certreqs
512 self.cacerts = cacerts
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000513 self.ciphers = ciphers
Bill Janssen98d19da2007-09-10 21:51:02 +0000514 self.chatty = chatty
515 self.connectionchatty = connectionchatty
516 self.starttls_server = starttls_server
517 self.sock = socket.socket()
518 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000519 if wrap_accepting_socket:
520 self.sock = ssl.wrap_socket(self.sock, server_side=True,
521 certfile=self.certificate,
522 cert_reqs = self.certreqs,
523 ca_certs = self.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000524 ssl_version = self.protocol,
525 ciphers = self.ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000526 if test_support.verbose and self.chatty:
527 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
528 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000529 self.active = False
Antoine Pitroud76088d2012-01-03 22:46:48 +0100530 self.conn_errors = []
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000531 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000532 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000533
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100534 def __enter__(self):
535 self.start(threading.Event())
536 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +0100537 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100538
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()
Antoine Pitrou7a556842012-01-27 17:33:01 +0100562 handler.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000563 except socket.timeout:
564 pass
565 except KeyboardInterrupt:
566 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +0000567 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000568
Antoine Pitrou3945c862010-04-28 21:11:01 +0000569 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000570 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000571
Bill Janssen934b16d2008-06-28 22:19:33 +0000572 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000573
Antoine Pitrou3945c862010-04-28 21:11:01 +0000574 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +0000575
Antoine Pitrou3945c862010-04-28 21:11:01 +0000576 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +0000577
578 def __init__(self, conn, certfile):
579 asyncore.dispatcher_with_send.__init__(self, conn)
580 self.socket = ssl.wrap_socket(conn, server_side=True,
581 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +0000582 do_handshake_on_connect=False)
583 self._ssl_accepting = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000584
585 def readable(self):
586 if isinstance(self.socket, ssl.SSLSocket):
587 while self.socket.pending() > 0:
588 self.handle_read_event()
589 return True
590
Antoine Pitroufc69af12010-04-24 20:04:58 +0000591 def _do_ssl_handshake(self):
592 try:
593 self.socket.do_handshake()
594 except ssl.SSLError, err:
595 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
596 ssl.SSL_ERROR_WANT_WRITE):
597 return
598 elif err.args[0] == ssl.SSL_ERROR_EOF:
599 return self.handle_close()
600 raise
601 except socket.error, err:
602 if err.args[0] == errno.ECONNABORTED:
603 return self.handle_close()
604 else:
605 self._ssl_accepting = False
606
Bill Janssen934b16d2008-06-28 22:19:33 +0000607 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +0000608 if self._ssl_accepting:
609 self._do_ssl_handshake()
610 else:
611 data = self.recv(1024)
Antoine Pitroudb187842010-04-27 10:32:58 +0000612 if data and data.strip() != 'over':
613 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +0000614
615 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000616 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000617 if test_support.verbose:
618 sys.stdout.write(" server: closed connection %s\n" % self.socket)
619
620 def handle_error(self):
621 raise
622
623 def __init__(self, certfile):
624 self.certfile = certfile
625 asyncore.dispatcher.__init__(self)
626 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
627 self.port = test_support.bind_port(self.socket)
628 self.listen(5)
629
630 def handle_accept(self):
631 sock_obj, addr = self.accept()
632 if test_support.verbose:
633 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
634 self.ConnectionHandler(sock_obj, self.certfile)
635
636 def handle_error(self):
637 raise
638
639 def __init__(self, certfile):
640 self.flag = None
641 self.active = False
642 self.server = self.EchoServer(certfile)
643 self.port = self.server.port
644 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000645 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000646
647 def __str__(self):
648 return "<%s %s>" % (self.__class__.__name__, self.server)
649
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100650 def __enter__(self):
651 self.start(threading.Event())
652 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +0100653 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100654
655 def __exit__(self, *args):
656 if test_support.verbose:
657 sys.stdout.write(" cleanup: stopping server.\n")
658 self.stop()
659 if test_support.verbose:
660 sys.stdout.write(" cleanup: joining server thread.\n")
661 self.join()
662 if test_support.verbose:
663 sys.stdout.write(" cleanup: successfully joined.\n")
664
Antoine Pitrou3945c862010-04-28 21:11:01 +0000665 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000666 self.flag = flag
667 threading.Thread.start(self)
668
Antoine Pitrou3945c862010-04-28 21:11:01 +0000669 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000670 self.active = True
671 if self.flag:
672 self.flag.set()
673 while self.active:
Antoine Pitroudb187842010-04-27 10:32:58 +0000674 asyncore.loop(0.05)
Bill Janssen934b16d2008-06-28 22:19:33 +0000675
Antoine Pitrou3945c862010-04-28 21:11:01 +0000676 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000677 self.active = False
678 self.server.close()
679
680 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000681
682 class HTTPSServer(HTTPServer):
683
684 def __init__(self, server_address, RequestHandlerClass, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000685 HTTPServer.__init__(self, server_address, RequestHandlerClass)
686 # we assume the certfile contains both private key and certificate
687 self.certfile = certfile
Bill Janssen296a59d2007-09-16 22:06:00 +0000688 self.allow_reuse_address = True
689
Bill Janssen934b16d2008-06-28 22:19:33 +0000690 def __str__(self):
691 return ('<%s %s:%s>' %
692 (self.__class__.__name__,
693 self.server_name,
694 self.server_port))
695
Antoine Pitrou3945c862010-04-28 21:11:01 +0000696 def get_request(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000697 # override this to wrap socket with SSL
698 sock, addr = self.socket.accept()
699 sslconn = ssl.wrap_socket(sock, server_side=True,
700 certfile=self.certfile)
701 return sslconn, addr
702
Bill Janssen296a59d2007-09-16 22:06:00 +0000703 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Bill Janssen296a59d2007-09-16 22:06:00 +0000704 # need to override translate_path to get a known root,
705 # instead of using os.curdir, since the test could be
706 # run from anywhere
707
708 server_version = "TestHTTPS/1.0"
709
710 root = None
711
712 def translate_path(self, path):
713 """Translate a /-separated PATH to the local filename syntax.
714
715 Components that mean special things to the local file system
716 (e.g. drive or directory names) are ignored. (XXX They should
717 probably be diagnosed.)
718
719 """
720 # abandon query parameters
721 path = urlparse.urlparse(path)[2]
722 path = os.path.normpath(urllib.unquote(path))
723 words = path.split('/')
724 words = filter(None, words)
725 path = self.root
726 for word in words:
727 drive, word = os.path.splitdrive(word)
728 head, word = os.path.split(word)
729 if word in self.root: continue
730 path = os.path.join(path, word)
731 return path
732
733 def log_message(self, format, *args):
734
735 # we override this to suppress logging unless "verbose"
736
737 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000738 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
739 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000740 self.server.server_port,
741 self.request.cipher(),
742 self.log_date_time_string(),
743 format%args))
744
745
Trent Nelsone41b0062008-04-08 23:47:30 +0000746 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000747 self.flag = None
Bill Janssen296a59d2007-09-16 22:06:00 +0000748 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
749 self.server = self.HTTPSServer(
Antoine Pitrou150acda2010-04-27 08:40:51 +0000750 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
751 self.port = self.server.server_port
Bill Janssen296a59d2007-09-16 22:06:00 +0000752 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000753 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000754
755 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000756 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000757
Antoine Pitrou3945c862010-04-28 21:11:01 +0000758 def start(self, flag=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000759 self.flag = flag
760 threading.Thread.start(self)
761
Antoine Pitrou3945c862010-04-28 21:11:01 +0000762 def run(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000763 if self.flag:
764 self.flag.set()
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000765 self.server.serve_forever(0.05)
Bill Janssen296a59d2007-09-16 22:06:00 +0000766
Antoine Pitrou3945c862010-04-28 21:11:01 +0000767 def stop(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000768 self.server.shutdown()
Bill Janssen296a59d2007-09-16 22:06:00 +0000769
770
Antoine Pitrou3945c862010-04-28 21:11:01 +0000771 def bad_cert_test(certfile):
772 """
773 Launch a server with CERT_REQUIRED, and check that trying to
774 connect to it with the given client certificate fails.
775 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000776 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000777 certreqs=ssl.CERT_REQUIRED,
778 cacerts=CERTFILE, chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100779 with server:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000780 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000781 s = ssl.wrap_socket(socket.socket(),
782 certfile=certfile,
783 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000784 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000785 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000786 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000787 sys.stdout.write("\nSSLError is %s\n" % x[1])
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000788 except socket.error, x:
789 if test_support.verbose:
790 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000791 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000792 raise AssertionError("Use of invalid cert should have failed!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000793
Antoine Pitrou3945c862010-04-28 21:11:01 +0000794 def server_params_test(certfile, protocol, certreqs, cacertsfile,
795 client_certfile, client_protocol=None, indata="FOO\n",
796 ciphers=None, chatty=True, connectionchatty=False,
797 wrap_accepting_socket=False):
798 """
799 Launch a server, connect a client to it and try various reads
800 and writes.
801 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000802 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000803 certreqs=certreqs,
804 ssl_version=protocol,
805 cacerts=cacertsfile,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000806 ciphers=ciphers,
Bill Janssen98d19da2007-09-10 21:51:02 +0000807 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000808 connectionchatty=connectionchatty,
809 wrap_accepting_socket=wrap_accepting_socket)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100810 with server:
811 # try to connect
812 if client_protocol is None:
813 client_protocol = protocol
Antoine Pitroudb187842010-04-27 10:32:58 +0000814 s = ssl.wrap_socket(socket.socket(),
815 certfile=client_certfile,
816 ca_certs=cacertsfile,
817 ciphers=ciphers,
818 cert_reqs=certreqs,
819 ssl_version=client_protocol)
820 s.connect((HOST, server.port))
821 for arg in [indata, bytearray(indata), memoryview(indata)]:
Bill Janssen98d19da2007-09-10 21:51:02 +0000822 if connectionchatty:
823 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +0000824 sys.stdout.write(
825 " client: sending %s...\n" % (repr(arg)))
826 s.write(arg)
827 outdata = s.read()
828 if connectionchatty:
829 if test_support.verbose:
830 sys.stdout.write(" client: read %s\n" % repr(outdata))
831 if outdata != indata.lower():
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000832 raise AssertionError(
Antoine Pitroudb187842010-04-27 10:32:58 +0000833 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
834 % (outdata[:min(len(outdata),20)], len(outdata),
835 indata[:min(len(indata),20)].lower(), len(indata)))
836 s.write("over\n")
837 if connectionchatty:
838 if test_support.verbose:
839 sys.stdout.write(" client: closing connection.\n")
840 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000841
Antoine Pitrou3945c862010-04-28 21:11:01 +0000842 def try_protocol_combo(server_protocol,
843 client_protocol,
844 expect_success,
845 certsreqs=None):
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000846 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000847 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +0000848 certtype = {
849 ssl.CERT_NONE: "CERT_NONE",
850 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
851 ssl.CERT_REQUIRED: "CERT_REQUIRED",
852 }[certsreqs]
Bill Janssen98d19da2007-09-10 21:51:02 +0000853 if test_support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000854 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +0000855 sys.stdout.write(formatstr %
856 (ssl.get_protocol_name(client_protocol),
857 ssl.get_protocol_name(server_protocol),
858 certtype))
859 try:
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000860 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
861 # will send an SSLv3 hello (rather than SSLv2) starting from
862 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou3945c862010-04-28 21:11:01 +0000863 server_params_test(CERTFILE, server_protocol, certsreqs,
864 CERTFILE, CERTFILE, client_protocol,
865 ciphers="ALL", chatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +0000866 # Protocol mismatch can result in either an SSLError, or a
867 # "Connection reset by peer" error.
868 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000869 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +0000870 raise
Antoine Pitroudb187842010-04-27 10:32:58 +0000871 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000872 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +0000873 raise
Bill Janssen98d19da2007-09-10 21:51:02 +0000874 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000875 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000876 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +0000877 "Client protocol %s succeeded with server protocol %s!"
878 % (ssl.get_protocol_name(client_protocol),
879 ssl.get_protocol_name(server_protocol)))
880
881
Bill Janssen934b16d2008-06-28 22:19:33 +0000882 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000883
Antoine Pitrou3945c862010-04-28 21:11:01 +0000884 def test_rude_shutdown(self):
885 """A brutal shutdown of an SSL server should raise an IOError
886 in the client when attempting handshake.
887 """
Bill Janssen98d19da2007-09-10 21:51:02 +0000888 listener_ready = threading.Event()
889 listener_gone = threading.Event()
890
Antoine Pitrou150acda2010-04-27 08:40:51 +0000891 s = socket.socket()
892 port = test_support.bind_port(s, HOST)
893
894 # `listener` runs in a thread. It sits in an accept() until
895 # the main thread connects. Then it rudely closes the socket,
896 # and sets Event `listener_gone` to let the main thread know
897 # the socket is gone.
Bill Janssen98d19da2007-09-10 21:51:02 +0000898 def listener():
Bill Janssen98d19da2007-09-10 21:51:02 +0000899 s.listen(5)
900 listener_ready.set()
901 s.accept()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000902 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000903 listener_gone.set()
904
905 def connector():
906 listener_ready.wait()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000907 c = socket.socket()
908 c.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000909 listener_gone.wait()
910 try:
Antoine Pitrou150acda2010-04-27 08:40:51 +0000911 ssl_sock = ssl.wrap_socket(c)
Bill Janssen934b16d2008-06-28 22:19:33 +0000912 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000913 pass
914 else:
Antoine Pitroudb187842010-04-27 10:32:58 +0000915 self.fail('connecting to closed SSL socket should have failed')
Bill Janssen98d19da2007-09-10 21:51:02 +0000916
917 t = threading.Thread(target=listener)
918 t.start()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000919 try:
920 connector()
921 finally:
922 t.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000923
Antoine Pitroud75efd92010-08-04 17:38:33 +0000924 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000925 def test_echo(self):
926 """Basic test of an SSL client connecting to a server"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000927 if test_support.verbose:
928 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000929 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
930 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
931 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000932
Antoine Pitrou3945c862010-04-28 21:11:01 +0000933 def test_getpeercert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000934 if test_support.verbose:
935 sys.stdout.write("\n")
936 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000937 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000938 certreqs=ssl.CERT_NONE,
939 ssl_version=ssl.PROTOCOL_SSLv23,
940 cacerts=CERTFILE,
941 chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100942 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +0000943 s = ssl.wrap_socket(socket.socket(),
944 certfile=CERTFILE,
945 ca_certs=CERTFILE,
946 cert_reqs=ssl.CERT_REQUIRED,
947 ssl_version=ssl.PROTOCOL_SSLv23)
948 s.connect((HOST, server.port))
949 cert = s.getpeercert()
950 self.assertTrue(cert, "Can't get peer certificate.")
951 cipher = s.cipher()
952 if test_support.verbose:
953 sys.stdout.write(pprint.pformat(cert) + '\n')
954 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
955 if 'subject' not in cert:
956 self.fail("No subject field in certificate: %s." %
957 pprint.pformat(cert))
958 if ((('organizationName', 'Python Software Foundation'),)
959 not in cert['subject']):
960 self.fail(
961 "Missing or invalid 'organizationName' field in certificate subject; "
962 "should be 'Python Software Foundation'.")
963 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000964
Antoine Pitrou3945c862010-04-28 21:11:01 +0000965 def test_empty_cert(self):
966 """Connecting with an empty cert file"""
967 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
968 "nullcert.pem"))
969 def test_malformed_cert(self):
970 """Connecting with a badly formatted certificate (syntax error)"""
971 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
972 "badcert.pem"))
973 def test_nonexisting_cert(self):
974 """Connecting with a non-existing cert file"""
975 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
976 "wrongcert.pem"))
977 def test_malformed_key(self):
978 """Connecting with a badly formatted key (syntax error)"""
979 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
980 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000981
Antoine Pitroud75efd92010-08-04 17:38:33 +0000982 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000983 def test_protocol_sslv2(self):
984 """Connecting to an SSLv2 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000985 if test_support.verbose:
986 sys.stdout.write("\n")
Antoine Pitrou6361ea22011-10-30 21:31:34 +0100987 if not hasattr(ssl, 'PROTOCOL_SSLv2'):
988 self.skipTest("PROTOCOL_SSLv2 needed")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000989 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
990 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
991 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
992 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
993 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
994 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000995
Antoine Pitroud75efd92010-08-04 17:38:33 +0000996 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000997 def test_protocol_sslv23(self):
998 """Connecting to an SSLv23 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000999 if test_support.verbose:
1000 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001001 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1002 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1003 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Bill Janssen98d19da2007-09-10 21:51:02 +00001004
Antoine Pitrou3945c862010-04-28 21:11:01 +00001005 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1006 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1007 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +00001008
Antoine Pitrou3945c862010-04-28 21:11:01 +00001009 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1010 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1011 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00001012
Antoine Pitroud75efd92010-08-04 17:38:33 +00001013 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001014 def test_protocol_sslv3(self):
1015 """Connecting to an SSLv3 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001016 if test_support.verbose:
1017 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001018 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1019 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1020 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001021 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1022 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001023 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001024
Antoine Pitroud75efd92010-08-04 17:38:33 +00001025 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001026 def test_protocol_tlsv1(self):
1027 """Connecting to a TLSv1 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001028 if test_support.verbose:
1029 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001030 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1031 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1032 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001033 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1034 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001035 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001036
Antoine Pitrou3945c862010-04-28 21:11:01 +00001037 def test_starttls(self):
1038 """Switching from clear text to encrypted and back again."""
Bill Janssen39295c22008-08-12 16:31:21 +00001039 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +00001040
Trent Nelsone41b0062008-04-08 23:47:30 +00001041 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00001042 ssl_version=ssl.PROTOCOL_TLSv1,
1043 starttls_server=True,
1044 chatty=True,
1045 connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +00001046 wrapped = False
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001047 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001048 s = socket.socket()
1049 s.setblocking(1)
1050 s.connect((HOST, server.port))
1051 if test_support.verbose:
1052 sys.stdout.write("\n")
1053 for indata in msgs:
Bill Janssen98d19da2007-09-10 21:51:02 +00001054 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00001055 sys.stdout.write(
1056 " client: sending %s...\n" % repr(indata))
1057 if wrapped:
1058 conn.write(indata)
1059 outdata = conn.read()
1060 else:
1061 s.send(indata)
1062 outdata = s.recv(1024)
1063 if (indata == "STARTTLS" and
1064 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001065 # STARTTLS ok, switch to secure mode
Bill Janssen98d19da2007-09-10 21:51:02 +00001066 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00001067 sys.stdout.write(
Antoine Pitroudb187842010-04-27 10:32:58 +00001068 " client: read %s from server, starting TLS...\n"
1069 % repr(outdata))
1070 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1071 wrapped = True
1072 elif (indata == "ENDTLS" and
1073 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001074 # ENDTLS ok, switch back to clear text
Antoine Pitroudb187842010-04-27 10:32:58 +00001075 if test_support.verbose:
1076 sys.stdout.write(
1077 " client: read %s from server, ending TLS...\n"
1078 % repr(outdata))
1079 s = conn.unwrap()
1080 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00001081 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001082 if test_support.verbose:
1083 sys.stdout.write(
1084 " client: read %s from server\n" % repr(outdata))
1085 if test_support.verbose:
1086 sys.stdout.write(" client: closing connection.\n")
1087 if wrapped:
1088 conn.write("over\n")
1089 else:
1090 s.send("over\n")
1091 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001092
Antoine Pitrou3945c862010-04-28 21:11:01 +00001093 def test_socketserver(self):
1094 """Using a SocketServer to create and manage SSL connections."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001095 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +00001096 flag = threading.Event()
1097 server.start(flag)
1098 # wait for it to start
1099 flag.wait()
1100 # try to connect
1101 try:
1102 if test_support.verbose:
1103 sys.stdout.write('\n')
Antoine Pitrou3945c862010-04-28 21:11:01 +00001104 with open(CERTFILE, 'rb') as f:
1105 d1 = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +00001106 d2 = ''
1107 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +00001108 url = 'https://127.0.0.1:%d/%s' % (
1109 server.port, os.path.split(CERTFILE)[1])
Florent Xicluna07627882010-03-21 01:14:24 +00001110 with test_support.check_py3k_warnings():
1111 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +00001112 dlen = f.info().getheader("content-length")
1113 if dlen and (int(dlen) > 0):
1114 d2 = f.read(int(dlen))
1115 if test_support.verbose:
1116 sys.stdout.write(
1117 " client: read %d bytes from remote server '%s'\n"
1118 % (len(d2), server))
1119 f.close()
Antoine Pitroudb187842010-04-27 10:32:58 +00001120 self.assertEqual(d1, d2)
Bill Janssen296a59d2007-09-16 22:06:00 +00001121 finally:
1122 server.stop()
1123 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001124
Antoine Pitrou3945c862010-04-28 21:11:01 +00001125 def test_wrapped_accept(self):
1126 """Check the accept() method on SSL sockets."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001127 if test_support.verbose:
1128 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001129 server_params_test(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1130 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1131 chatty=True, connectionchatty=True,
1132 wrap_accepting_socket=True)
Bill Janssen934b16d2008-06-28 22:19:33 +00001133
Antoine Pitrou3945c862010-04-28 21:11:01 +00001134 def test_asyncore_server(self):
1135 """Check the example asyncore integration."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001136 indata = "TEST MESSAGE of mixed case\n"
1137
1138 if test_support.verbose:
1139 sys.stdout.write("\n")
1140 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001141 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001142 s = ssl.wrap_socket(socket.socket())
1143 s.connect(('127.0.0.1', server.port))
1144 if test_support.verbose:
1145 sys.stdout.write(
1146 " client: sending %s...\n" % (repr(indata)))
1147 s.write(indata)
1148 outdata = s.read()
1149 if test_support.verbose:
1150 sys.stdout.write(" client: read %s\n" % repr(outdata))
1151 if outdata != indata.lower():
1152 self.fail(
1153 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1154 % (outdata[:min(len(outdata),20)], len(outdata),
1155 indata[:min(len(indata),20)].lower(), len(indata)))
1156 s.write("over\n")
1157 if test_support.verbose:
1158 sys.stdout.write(" client: closing connection.\n")
1159 s.close()
Bill Janssen934b16d2008-06-28 22:19:33 +00001160
Antoine Pitrou3945c862010-04-28 21:11:01 +00001161 def test_recv_send(self):
1162 """Test recv(), send() and friends."""
Bill Janssen61c001a2008-09-08 16:37:24 +00001163 if test_support.verbose:
1164 sys.stdout.write("\n")
1165
1166 server = ThreadedEchoServer(CERTFILE,
1167 certreqs=ssl.CERT_NONE,
1168 ssl_version=ssl.PROTOCOL_TLSv1,
1169 cacerts=CERTFILE,
1170 chatty=True,
1171 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001172 with server:
1173 s = ssl.wrap_socket(socket.socket(),
1174 server_side=False,
1175 certfile=CERTFILE,
1176 ca_certs=CERTFILE,
1177 cert_reqs=ssl.CERT_NONE,
1178 ssl_version=ssl.PROTOCOL_TLSv1)
1179 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00001180 # helper methods for standardising recv* method signatures
1181 def _recv_into():
1182 b = bytearray("\0"*100)
1183 count = s.recv_into(b)
1184 return b[:count]
1185
1186 def _recvfrom_into():
1187 b = bytearray("\0"*100)
1188 count, addr = s.recvfrom_into(b)
1189 return b[:count]
1190
1191 # (name, method, whether to expect success, *args)
1192 send_methods = [
1193 ('send', s.send, True, []),
1194 ('sendto', s.sendto, False, ["some.address"]),
1195 ('sendall', s.sendall, True, []),
1196 ]
1197 recv_methods = [
1198 ('recv', s.recv, True, []),
1199 ('recvfrom', s.recvfrom, False, ["some.address"]),
1200 ('recv_into', _recv_into, True, []),
1201 ('recvfrom_into', _recvfrom_into, False, []),
1202 ]
1203 data_prefix = u"PREFIX_"
1204
1205 for meth_name, send_meth, expect_success, args in send_methods:
1206 indata = data_prefix + meth_name
1207 try:
1208 send_meth(indata.encode('ASCII', 'strict'), *args)
1209 outdata = s.read()
1210 outdata = outdata.decode('ASCII', 'strict')
1211 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001212 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001213 "While sending with <<%s>> bad data "
1214 "<<%r>> (%d) received; "
1215 "expected <<%r>> (%d)\n" % (
1216 meth_name, outdata[:20], len(outdata),
1217 indata[:20], len(indata)
1218 )
1219 )
1220 except ValueError as e:
1221 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001222 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001223 "Failed to send with method <<%s>>; "
1224 "expected to succeed.\n" % (meth_name,)
1225 )
1226 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001227 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001228 "Method <<%s>> failed with unexpected "
1229 "exception message: %s\n" % (
1230 meth_name, e
1231 )
1232 )
1233
1234 for meth_name, recv_meth, expect_success, args in recv_methods:
1235 indata = data_prefix + meth_name
1236 try:
1237 s.send(indata.encode('ASCII', 'strict'))
1238 outdata = recv_meth(*args)
1239 outdata = outdata.decode('ASCII', 'strict')
1240 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001241 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001242 "While receiving with <<%s>> bad data "
1243 "<<%r>> (%d) received; "
1244 "expected <<%r>> (%d)\n" % (
1245 meth_name, outdata[:20], len(outdata),
1246 indata[:20], len(indata)
1247 )
1248 )
1249 except ValueError as e:
1250 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001251 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001252 "Failed to receive with method <<%s>>; "
1253 "expected to succeed.\n" % (meth_name,)
1254 )
1255 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001256 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001257 "Method <<%s>> failed with unexpected "
1258 "exception message: %s\n" % (
1259 meth_name, e
1260 )
1261 )
1262 # consume data
1263 s.read()
1264
1265 s.write("over\n".encode("ASCII", "strict"))
1266 s.close()
Bill Janssen61c001a2008-09-08 16:37:24 +00001267
Antoine Pitroufc69af12010-04-24 20:04:58 +00001268 def test_handshake_timeout(self):
1269 # Issue #5103: SSL handshake must respect the socket timeout
1270 server = socket.socket(socket.AF_INET)
1271 host = "127.0.0.1"
1272 port = test_support.bind_port(server)
1273 started = threading.Event()
1274 finish = False
1275
1276 def serve():
1277 server.listen(5)
1278 started.set()
1279 conns = []
1280 while not finish:
1281 r, w, e = select.select([server], [], [], 0.1)
1282 if server in r:
1283 # Let the socket hang around rather than having
1284 # it closed by garbage collection.
1285 conns.append(server.accept()[0])
1286
1287 t = threading.Thread(target=serve)
1288 t.start()
1289 started.wait()
1290
1291 try:
1292 try:
1293 c = socket.socket(socket.AF_INET)
1294 c.settimeout(0.2)
1295 c.connect((host, port))
1296 # Will attempt handshake and time out
1297 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1298 ssl.wrap_socket, c)
1299 finally:
1300 c.close()
1301 try:
1302 c = socket.socket(socket.AF_INET)
1303 c.settimeout(0.2)
1304 c = ssl.wrap_socket(c)
1305 # Will attempt handshake and time out
1306 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1307 c.connect, (host, port))
1308 finally:
1309 c.close()
1310 finally:
1311 finish = True
1312 t.join()
1313 server.close()
1314
Antoine Pitroud76088d2012-01-03 22:46:48 +01001315 def test_default_ciphers(self):
1316 with ThreadedEchoServer(CERTFILE,
1317 ssl_version=ssl.PROTOCOL_SSLv23,
1318 chatty=False) as server:
1319 sock = socket.socket()
1320 try:
1321 # Force a set of weak ciphers on our client socket
1322 try:
1323 s = ssl.wrap_socket(sock,
1324 ssl_version=ssl.PROTOCOL_SSLv23,
1325 ciphers="DES")
1326 except ssl.SSLError:
1327 self.skipTest("no DES cipher available")
1328 with self.assertRaises((OSError, ssl.SSLError)):
1329 s.connect((HOST, server.port))
1330 finally:
1331 sock.close()
1332 self.assertIn("no shared cipher", str(server.conn_errors[0]))
1333
Bill Janssen61c001a2008-09-08 16:37:24 +00001334
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001335def test_main(verbose=False):
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001336 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, NOKIACERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001337 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001338 "keycert.pem")
1339 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1340 os.path.dirname(__file__) or os.curdir,
1341 "https_svn_python_org_root.pem")
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001342 NOKIACERT = os.path.join(os.path.dirname(__file__) or os.curdir,
1343 "nokia.pem")
Bill Janssen296a59d2007-09-16 22:06:00 +00001344
1345 if (not os.path.exists(CERTFILE) or
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001346 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT) or
1347 not os.path.exists(NOKIACERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001348 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001349
Antoine Pitroude30f702010-09-14 12:54:08 +00001350 tests = [BasicTests, BasicSocketTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001351
Bill Janssen296a59d2007-09-16 22:06:00 +00001352 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001353 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001354
Bill Janssen98d19da2007-09-10 21:51:02 +00001355 if _have_threads:
1356 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001357 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001358 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001359
Antoine Pitrou3945c862010-04-28 21:11:01 +00001360 try:
1361 test_support.run_unittest(*tests)
1362 finally:
1363 if _have_threads:
1364 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001365
1366if __name__ == "__main__":
1367 test_main()