blob: e64d1b22fa535e6482a7809617a8cb9ffc4081b8 [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 Pitroud76088d2012-01-03 22:46:48 +0100420 except ssl.SSLError as e:
Antoine Pitroudb187842010-04-27 10:32:58 +0000421 # 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.
Antoine Pitroud76088d2012-01-03 22:46:48 +0100424 self.server.conn_errors.append(e)
Bill Janssen98d19da2007-09-10 21:51:02 +0000425 if self.server.chatty:
426 handle_error("\n server: bad connection attempt from " +
427 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000428 self.close()
Antoine Pitroudb187842010-04-27 10:32:58 +0000429 self.running = False
430 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000431 return False
Bill Janssen98d19da2007-09-10 21:51:02 +0000432 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000433 return True
434
435 def read(self):
436 if self.sslconn:
437 return self.sslconn.read()
438 else:
439 return self.sock.recv(1024)
440
441 def write(self, bytes):
442 if self.sslconn:
443 return self.sslconn.write(bytes)
444 else:
445 return self.sock.send(bytes)
446
447 def close(self):
448 if self.sslconn:
449 self.sslconn.close()
450 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000451 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000452
Antoine Pitrou3945c862010-04-28 21:11:01 +0000453 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000454 self.running = True
455 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000456 if isinstance(self.sock, ssl.SSLSocket):
457 self.sslconn = self.sock
458 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000459 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000460 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000461 while self.running:
462 try:
463 msg = self.read()
464 if not msg:
465 # eof, so quit this handler
466 self.running = False
467 self.close()
468 elif msg.strip() == 'over':
469 if test_support.verbose and self.server.connectionchatty:
470 sys.stdout.write(" server: client closed connection\n")
471 self.close()
472 return
473 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
474 if test_support.verbose and self.server.connectionchatty:
475 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
476 self.write("OK\n")
477 if not self.wrap_conn():
478 return
Bill Janssen39295c22008-08-12 16:31:21 +0000479 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
480 if test_support.verbose and self.server.connectionchatty:
481 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
482 self.write("OK\n")
483 self.sslconn.unwrap()
484 self.sslconn = None
485 if test_support.verbose and self.server.connectionchatty:
486 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000487 else:
488 if (test_support.verbose and
489 self.server.connectionchatty):
490 ctype = (self.sslconn and "encrypted") or "unencrypted"
491 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
492 % (repr(msg), ctype, repr(msg.lower()), ctype))
493 self.write(msg.lower())
494 except ssl.SSLError:
495 if self.server.chatty:
496 handle_error("Test server failure:\n")
497 self.close()
498 self.running = False
499 # normally, we'd just stop here, but for the test
500 # harness, we want to stop the server
501 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000502
Trent Nelsone41b0062008-04-08 23:47:30 +0000503 def __init__(self, certificate, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +0000504 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000505 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000506 wrap_accepting_socket=False, ciphers=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000507
Bill Janssen98d19da2007-09-10 21:51:02 +0000508 if ssl_version is None:
509 ssl_version = ssl.PROTOCOL_TLSv1
510 if certreqs is None:
511 certreqs = ssl.CERT_NONE
512 self.certificate = certificate
513 self.protocol = ssl_version
514 self.certreqs = certreqs
515 self.cacerts = cacerts
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000516 self.ciphers = ciphers
Bill Janssen98d19da2007-09-10 21:51:02 +0000517 self.chatty = chatty
518 self.connectionchatty = connectionchatty
519 self.starttls_server = starttls_server
520 self.sock = socket.socket()
521 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000522 if wrap_accepting_socket:
523 self.sock = ssl.wrap_socket(self.sock, server_side=True,
524 certfile=self.certificate,
525 cert_reqs = self.certreqs,
526 ca_certs = self.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000527 ssl_version = self.protocol,
528 ciphers = self.ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000529 if test_support.verbose and self.chatty:
530 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
531 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000532 self.active = False
Antoine Pitroud76088d2012-01-03 22:46:48 +0100533 self.conn_errors = []
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000534 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000535 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000536
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100537 def __enter__(self):
538 self.start(threading.Event())
539 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +0100540 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100541
542 def __exit__(self, *args):
543 self.stop()
544 self.join()
545
Antoine Pitrou3945c862010-04-28 21:11:01 +0000546 def start(self, flag=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000547 self.flag = flag
548 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000549
Antoine Pitrou3945c862010-04-28 21:11:01 +0000550 def run(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000551 self.sock.settimeout(0.05)
Bill Janssen98d19da2007-09-10 21:51:02 +0000552 self.sock.listen(5)
553 self.active = True
554 if self.flag:
555 # signal an event
556 self.flag.set()
557 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000558 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000559 newconn, connaddr = self.sock.accept()
560 if test_support.verbose and self.chatty:
561 sys.stdout.write(' server: new connection from '
562 + str(connaddr) + '\n')
563 handler = self.ConnectionHandler(self, newconn)
564 handler.start()
565 except socket.timeout:
566 pass
567 except KeyboardInterrupt:
568 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +0000569 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000570
Antoine Pitrou3945c862010-04-28 21:11:01 +0000571 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000572 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000573
Bill Janssen934b16d2008-06-28 22:19:33 +0000574 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000575
Antoine Pitrou3945c862010-04-28 21:11:01 +0000576 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +0000577
Antoine Pitrou3945c862010-04-28 21:11:01 +0000578 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +0000579
580 def __init__(self, conn, certfile):
581 asyncore.dispatcher_with_send.__init__(self, conn)
582 self.socket = ssl.wrap_socket(conn, server_side=True,
583 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +0000584 do_handshake_on_connect=False)
585 self._ssl_accepting = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000586
587 def readable(self):
588 if isinstance(self.socket, ssl.SSLSocket):
589 while self.socket.pending() > 0:
590 self.handle_read_event()
591 return True
592
Antoine Pitroufc69af12010-04-24 20:04:58 +0000593 def _do_ssl_handshake(self):
594 try:
595 self.socket.do_handshake()
596 except ssl.SSLError, err:
597 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
598 ssl.SSL_ERROR_WANT_WRITE):
599 return
600 elif err.args[0] == ssl.SSL_ERROR_EOF:
601 return self.handle_close()
602 raise
603 except socket.error, err:
604 if err.args[0] == errno.ECONNABORTED:
605 return self.handle_close()
606 else:
607 self._ssl_accepting = False
608
Bill Janssen934b16d2008-06-28 22:19:33 +0000609 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +0000610 if self._ssl_accepting:
611 self._do_ssl_handshake()
612 else:
613 data = self.recv(1024)
Antoine Pitroudb187842010-04-27 10:32:58 +0000614 if data and data.strip() != 'over':
615 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +0000616
617 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000618 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000619 if test_support.verbose:
620 sys.stdout.write(" server: closed connection %s\n" % self.socket)
621
622 def handle_error(self):
623 raise
624
625 def __init__(self, certfile):
626 self.certfile = certfile
627 asyncore.dispatcher.__init__(self)
628 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
629 self.port = test_support.bind_port(self.socket)
630 self.listen(5)
631
632 def handle_accept(self):
633 sock_obj, addr = self.accept()
634 if test_support.verbose:
635 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
636 self.ConnectionHandler(sock_obj, self.certfile)
637
638 def handle_error(self):
639 raise
640
641 def __init__(self, certfile):
642 self.flag = None
643 self.active = False
644 self.server = self.EchoServer(certfile)
645 self.port = self.server.port
646 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000647 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000648
649 def __str__(self):
650 return "<%s %s>" % (self.__class__.__name__, self.server)
651
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100652 def __enter__(self):
653 self.start(threading.Event())
654 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +0100655 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100656
657 def __exit__(self, *args):
658 if test_support.verbose:
659 sys.stdout.write(" cleanup: stopping server.\n")
660 self.stop()
661 if test_support.verbose:
662 sys.stdout.write(" cleanup: joining server thread.\n")
663 self.join()
664 if test_support.verbose:
665 sys.stdout.write(" cleanup: successfully joined.\n")
666
Antoine Pitrou3945c862010-04-28 21:11:01 +0000667 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000668 self.flag = flag
669 threading.Thread.start(self)
670
Antoine Pitrou3945c862010-04-28 21:11:01 +0000671 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000672 self.active = True
673 if self.flag:
674 self.flag.set()
675 while self.active:
Antoine Pitroudb187842010-04-27 10:32:58 +0000676 asyncore.loop(0.05)
Bill Janssen934b16d2008-06-28 22:19:33 +0000677
Antoine Pitrou3945c862010-04-28 21:11:01 +0000678 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000679 self.active = False
680 self.server.close()
681
682 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000683
684 class HTTPSServer(HTTPServer):
685
686 def __init__(self, server_address, RequestHandlerClass, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000687 HTTPServer.__init__(self, server_address, RequestHandlerClass)
688 # we assume the certfile contains both private key and certificate
689 self.certfile = certfile
Bill Janssen296a59d2007-09-16 22:06:00 +0000690 self.allow_reuse_address = True
691
Bill Janssen934b16d2008-06-28 22:19:33 +0000692 def __str__(self):
693 return ('<%s %s:%s>' %
694 (self.__class__.__name__,
695 self.server_name,
696 self.server_port))
697
Antoine Pitrou3945c862010-04-28 21:11:01 +0000698 def get_request(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000699 # override this to wrap socket with SSL
700 sock, addr = self.socket.accept()
701 sslconn = ssl.wrap_socket(sock, server_side=True,
702 certfile=self.certfile)
703 return sslconn, addr
704
Bill Janssen296a59d2007-09-16 22:06:00 +0000705 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Bill Janssen296a59d2007-09-16 22:06:00 +0000706 # need to override translate_path to get a known root,
707 # instead of using os.curdir, since the test could be
708 # run from anywhere
709
710 server_version = "TestHTTPS/1.0"
711
712 root = None
713
714 def translate_path(self, path):
715 """Translate a /-separated PATH to the local filename syntax.
716
717 Components that mean special things to the local file system
718 (e.g. drive or directory names) are ignored. (XXX They should
719 probably be diagnosed.)
720
721 """
722 # abandon query parameters
723 path = urlparse.urlparse(path)[2]
724 path = os.path.normpath(urllib.unquote(path))
725 words = path.split('/')
726 words = filter(None, words)
727 path = self.root
728 for word in words:
729 drive, word = os.path.splitdrive(word)
730 head, word = os.path.split(word)
731 if word in self.root: continue
732 path = os.path.join(path, word)
733 return path
734
735 def log_message(self, format, *args):
736
737 # we override this to suppress logging unless "verbose"
738
739 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000740 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
741 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000742 self.server.server_port,
743 self.request.cipher(),
744 self.log_date_time_string(),
745 format%args))
746
747
Trent Nelsone41b0062008-04-08 23:47:30 +0000748 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000749 self.flag = None
Bill Janssen296a59d2007-09-16 22:06:00 +0000750 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
751 self.server = self.HTTPSServer(
Antoine Pitrou150acda2010-04-27 08:40:51 +0000752 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
753 self.port = self.server.server_port
Bill Janssen296a59d2007-09-16 22:06:00 +0000754 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000755 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000756
757 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000758 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000759
Antoine Pitrou3945c862010-04-28 21:11:01 +0000760 def start(self, flag=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000761 self.flag = flag
762 threading.Thread.start(self)
763
Antoine Pitrou3945c862010-04-28 21:11:01 +0000764 def run(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000765 if self.flag:
766 self.flag.set()
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000767 self.server.serve_forever(0.05)
Bill Janssen296a59d2007-09-16 22:06:00 +0000768
Antoine Pitrou3945c862010-04-28 21:11:01 +0000769 def stop(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000770 self.server.shutdown()
Bill Janssen296a59d2007-09-16 22:06:00 +0000771
772
Antoine Pitrou3945c862010-04-28 21:11:01 +0000773 def bad_cert_test(certfile):
774 """
775 Launch a server with CERT_REQUIRED, and check that trying to
776 connect to it with the given client certificate fails.
777 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000778 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000779 certreqs=ssl.CERT_REQUIRED,
780 cacerts=CERTFILE, chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100781 with server:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000782 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000783 s = ssl.wrap_socket(socket.socket(),
784 certfile=certfile,
785 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000786 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000787 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000788 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000789 sys.stdout.write("\nSSLError is %s\n" % x[1])
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000790 except socket.error, x:
791 if test_support.verbose:
792 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000793 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000794 raise AssertionError("Use of invalid cert should have failed!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000795
Antoine Pitrou3945c862010-04-28 21:11:01 +0000796 def server_params_test(certfile, protocol, certreqs, cacertsfile,
797 client_certfile, client_protocol=None, indata="FOO\n",
798 ciphers=None, chatty=True, connectionchatty=False,
799 wrap_accepting_socket=False):
800 """
801 Launch a server, connect a client to it and try various reads
802 and writes.
803 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000804 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000805 certreqs=certreqs,
806 ssl_version=protocol,
807 cacerts=cacertsfile,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000808 ciphers=ciphers,
Bill Janssen98d19da2007-09-10 21:51:02 +0000809 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000810 connectionchatty=connectionchatty,
811 wrap_accepting_socket=wrap_accepting_socket)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100812 with server:
813 # try to connect
814 if client_protocol is None:
815 client_protocol = protocol
Antoine Pitroudb187842010-04-27 10:32:58 +0000816 s = ssl.wrap_socket(socket.socket(),
817 certfile=client_certfile,
818 ca_certs=cacertsfile,
819 ciphers=ciphers,
820 cert_reqs=certreqs,
821 ssl_version=client_protocol)
822 s.connect((HOST, server.port))
823 for arg in [indata, bytearray(indata), memoryview(indata)]:
Bill Janssen98d19da2007-09-10 21:51:02 +0000824 if connectionchatty:
825 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +0000826 sys.stdout.write(
827 " client: sending %s...\n" % (repr(arg)))
828 s.write(arg)
829 outdata = s.read()
830 if connectionchatty:
831 if test_support.verbose:
832 sys.stdout.write(" client: read %s\n" % repr(outdata))
833 if outdata != indata.lower():
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000834 raise AssertionError(
Antoine Pitroudb187842010-04-27 10:32:58 +0000835 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
836 % (outdata[:min(len(outdata),20)], len(outdata),
837 indata[:min(len(indata),20)].lower(), len(indata)))
838 s.write("over\n")
839 if connectionchatty:
840 if test_support.verbose:
841 sys.stdout.write(" client: closing connection.\n")
842 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000843
Antoine Pitrou3945c862010-04-28 21:11:01 +0000844 def try_protocol_combo(server_protocol,
845 client_protocol,
846 expect_success,
847 certsreqs=None):
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000848 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000849 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +0000850 certtype = {
851 ssl.CERT_NONE: "CERT_NONE",
852 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
853 ssl.CERT_REQUIRED: "CERT_REQUIRED",
854 }[certsreqs]
Bill Janssen98d19da2007-09-10 21:51:02 +0000855 if test_support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000856 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +0000857 sys.stdout.write(formatstr %
858 (ssl.get_protocol_name(client_protocol),
859 ssl.get_protocol_name(server_protocol),
860 certtype))
861 try:
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000862 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
863 # will send an SSLv3 hello (rather than SSLv2) starting from
864 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou3945c862010-04-28 21:11:01 +0000865 server_params_test(CERTFILE, server_protocol, certsreqs,
866 CERTFILE, CERTFILE, client_protocol,
867 ciphers="ALL", chatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +0000868 # Protocol mismatch can result in either an SSLError, or a
869 # "Connection reset by peer" error.
870 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000871 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +0000872 raise
Antoine Pitroudb187842010-04-27 10:32:58 +0000873 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000874 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +0000875 raise
Bill Janssen98d19da2007-09-10 21:51:02 +0000876 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000877 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000878 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +0000879 "Client protocol %s succeeded with server protocol %s!"
880 % (ssl.get_protocol_name(client_protocol),
881 ssl.get_protocol_name(server_protocol)))
882
883
Bill Janssen934b16d2008-06-28 22:19:33 +0000884 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000885
Antoine Pitrou3945c862010-04-28 21:11:01 +0000886 def test_rude_shutdown(self):
887 """A brutal shutdown of an SSL server should raise an IOError
888 in the client when attempting handshake.
889 """
Bill Janssen98d19da2007-09-10 21:51:02 +0000890 listener_ready = threading.Event()
891 listener_gone = threading.Event()
892
Antoine Pitrou150acda2010-04-27 08:40:51 +0000893 s = socket.socket()
894 port = test_support.bind_port(s, HOST)
895
896 # `listener` runs in a thread. It sits in an accept() until
897 # the main thread connects. Then it rudely closes the socket,
898 # and sets Event `listener_gone` to let the main thread know
899 # the socket is gone.
Bill Janssen98d19da2007-09-10 21:51:02 +0000900 def listener():
Bill Janssen98d19da2007-09-10 21:51:02 +0000901 s.listen(5)
902 listener_ready.set()
903 s.accept()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000904 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000905 listener_gone.set()
906
907 def connector():
908 listener_ready.wait()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000909 c = socket.socket()
910 c.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000911 listener_gone.wait()
912 try:
Antoine Pitrou150acda2010-04-27 08:40:51 +0000913 ssl_sock = ssl.wrap_socket(c)
Bill Janssen934b16d2008-06-28 22:19:33 +0000914 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000915 pass
916 else:
Antoine Pitroudb187842010-04-27 10:32:58 +0000917 self.fail('connecting to closed SSL socket should have failed')
Bill Janssen98d19da2007-09-10 21:51:02 +0000918
919 t = threading.Thread(target=listener)
920 t.start()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000921 try:
922 connector()
923 finally:
924 t.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000925
Antoine Pitroud75efd92010-08-04 17:38:33 +0000926 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000927 def test_echo(self):
928 """Basic test of an SSL client connecting to a server"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000929 if test_support.verbose:
930 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000931 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
932 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
933 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000934
Antoine Pitrou3945c862010-04-28 21:11:01 +0000935 def test_getpeercert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000936 if test_support.verbose:
937 sys.stdout.write("\n")
938 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000939 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000940 certreqs=ssl.CERT_NONE,
941 ssl_version=ssl.PROTOCOL_SSLv23,
942 cacerts=CERTFILE,
943 chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100944 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +0000945 s = ssl.wrap_socket(socket.socket(),
946 certfile=CERTFILE,
947 ca_certs=CERTFILE,
948 cert_reqs=ssl.CERT_REQUIRED,
949 ssl_version=ssl.PROTOCOL_SSLv23)
950 s.connect((HOST, server.port))
951 cert = s.getpeercert()
952 self.assertTrue(cert, "Can't get peer certificate.")
953 cipher = s.cipher()
954 if test_support.verbose:
955 sys.stdout.write(pprint.pformat(cert) + '\n')
956 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
957 if 'subject' not in cert:
958 self.fail("No subject field in certificate: %s." %
959 pprint.pformat(cert))
960 if ((('organizationName', 'Python Software Foundation'),)
961 not in cert['subject']):
962 self.fail(
963 "Missing or invalid 'organizationName' field in certificate subject; "
964 "should be 'Python Software Foundation'.")
965 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000966
Antoine Pitrou3945c862010-04-28 21:11:01 +0000967 def test_empty_cert(self):
968 """Connecting with an empty cert file"""
969 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
970 "nullcert.pem"))
971 def test_malformed_cert(self):
972 """Connecting with a badly formatted certificate (syntax error)"""
973 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
974 "badcert.pem"))
975 def test_nonexisting_cert(self):
976 """Connecting with a non-existing cert file"""
977 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
978 "wrongcert.pem"))
979 def test_malformed_key(self):
980 """Connecting with a badly formatted key (syntax error)"""
981 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
982 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000983
Antoine Pitroud75efd92010-08-04 17:38:33 +0000984 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000985 def test_protocol_sslv2(self):
986 """Connecting to an SSLv2 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000987 if test_support.verbose:
988 sys.stdout.write("\n")
Antoine Pitrou6361ea22011-10-30 21:31:34 +0100989 if not hasattr(ssl, 'PROTOCOL_SSLv2'):
990 self.skipTest("PROTOCOL_SSLv2 needed")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000991 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
992 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
993 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
994 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
995 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
996 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000997
Antoine Pitroud75efd92010-08-04 17:38:33 +0000998 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000999 def test_protocol_sslv23(self):
1000 """Connecting to an SSLv23 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001001 if test_support.verbose:
1002 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001003 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1004 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1005 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
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_OPTIONAL)
1008 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1009 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +00001010
Antoine Pitrou3945c862010-04-28 21:11:01 +00001011 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1012 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1013 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00001014
Antoine Pitroud75efd92010-08-04 17:38:33 +00001015 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001016 def test_protocol_sslv3(self):
1017 """Connecting to an SSLv3 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001018 if test_support.verbose:
1019 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001020 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1021 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1022 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001023 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1024 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001025 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001026
Antoine Pitroud75efd92010-08-04 17:38:33 +00001027 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001028 def test_protocol_tlsv1(self):
1029 """Connecting to a TLSv1 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001030 if test_support.verbose:
1031 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001032 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1033 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1034 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001035 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1036 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001037 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001038
Antoine Pitrou3945c862010-04-28 21:11:01 +00001039 def test_starttls(self):
1040 """Switching from clear text to encrypted and back again."""
Bill Janssen39295c22008-08-12 16:31:21 +00001041 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +00001042
Trent Nelsone41b0062008-04-08 23:47:30 +00001043 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00001044 ssl_version=ssl.PROTOCOL_TLSv1,
1045 starttls_server=True,
1046 chatty=True,
1047 connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +00001048 wrapped = False
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001049 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001050 s = socket.socket()
1051 s.setblocking(1)
1052 s.connect((HOST, server.port))
1053 if test_support.verbose:
1054 sys.stdout.write("\n")
1055 for indata in msgs:
Bill Janssen98d19da2007-09-10 21:51:02 +00001056 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00001057 sys.stdout.write(
1058 " client: sending %s...\n" % repr(indata))
1059 if wrapped:
1060 conn.write(indata)
1061 outdata = conn.read()
1062 else:
1063 s.send(indata)
1064 outdata = s.recv(1024)
1065 if (indata == "STARTTLS" and
1066 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001067 # STARTTLS ok, switch to secure mode
Bill Janssen98d19da2007-09-10 21:51:02 +00001068 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00001069 sys.stdout.write(
Antoine Pitroudb187842010-04-27 10:32:58 +00001070 " client: read %s from server, starting TLS...\n"
1071 % repr(outdata))
1072 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1073 wrapped = True
1074 elif (indata == "ENDTLS" and
1075 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001076 # ENDTLS ok, switch back to clear text
Antoine Pitroudb187842010-04-27 10:32:58 +00001077 if test_support.verbose:
1078 sys.stdout.write(
1079 " client: read %s from server, ending TLS...\n"
1080 % repr(outdata))
1081 s = conn.unwrap()
1082 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00001083 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001084 if test_support.verbose:
1085 sys.stdout.write(
1086 " client: read %s from server\n" % repr(outdata))
1087 if test_support.verbose:
1088 sys.stdout.write(" client: closing connection.\n")
1089 if wrapped:
1090 conn.write("over\n")
1091 else:
1092 s.send("over\n")
1093 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001094
Antoine Pitrou3945c862010-04-28 21:11:01 +00001095 def test_socketserver(self):
1096 """Using a SocketServer to create and manage SSL connections."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001097 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +00001098 flag = threading.Event()
1099 server.start(flag)
1100 # wait for it to start
1101 flag.wait()
1102 # try to connect
1103 try:
1104 if test_support.verbose:
1105 sys.stdout.write('\n')
Antoine Pitrou3945c862010-04-28 21:11:01 +00001106 with open(CERTFILE, 'rb') as f:
1107 d1 = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +00001108 d2 = ''
1109 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +00001110 url = 'https://127.0.0.1:%d/%s' % (
1111 server.port, os.path.split(CERTFILE)[1])
Florent Xicluna07627882010-03-21 01:14:24 +00001112 with test_support.check_py3k_warnings():
1113 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +00001114 dlen = f.info().getheader("content-length")
1115 if dlen and (int(dlen) > 0):
1116 d2 = f.read(int(dlen))
1117 if test_support.verbose:
1118 sys.stdout.write(
1119 " client: read %d bytes from remote server '%s'\n"
1120 % (len(d2), server))
1121 f.close()
Antoine Pitroudb187842010-04-27 10:32:58 +00001122 self.assertEqual(d1, d2)
Bill Janssen296a59d2007-09-16 22:06:00 +00001123 finally:
1124 server.stop()
1125 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001126
Antoine Pitrou3945c862010-04-28 21:11:01 +00001127 def test_wrapped_accept(self):
1128 """Check the accept() method on SSL sockets."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001129 if test_support.verbose:
1130 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001131 server_params_test(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1132 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1133 chatty=True, connectionchatty=True,
1134 wrap_accepting_socket=True)
Bill Janssen934b16d2008-06-28 22:19:33 +00001135
Antoine Pitrou3945c862010-04-28 21:11:01 +00001136 def test_asyncore_server(self):
1137 """Check the example asyncore integration."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001138 indata = "TEST MESSAGE of mixed case\n"
1139
1140 if test_support.verbose:
1141 sys.stdout.write("\n")
1142 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001143 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001144 s = ssl.wrap_socket(socket.socket())
1145 s.connect(('127.0.0.1', server.port))
1146 if test_support.verbose:
1147 sys.stdout.write(
1148 " client: sending %s...\n" % (repr(indata)))
1149 s.write(indata)
1150 outdata = s.read()
1151 if test_support.verbose:
1152 sys.stdout.write(" client: read %s\n" % repr(outdata))
1153 if outdata != indata.lower():
1154 self.fail(
1155 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1156 % (outdata[:min(len(outdata),20)], len(outdata),
1157 indata[:min(len(indata),20)].lower(), len(indata)))
1158 s.write("over\n")
1159 if test_support.verbose:
1160 sys.stdout.write(" client: closing connection.\n")
1161 s.close()
Bill Janssen934b16d2008-06-28 22:19:33 +00001162
Antoine Pitrou3945c862010-04-28 21:11:01 +00001163 def test_recv_send(self):
1164 """Test recv(), send() and friends."""
Bill Janssen61c001a2008-09-08 16:37:24 +00001165 if test_support.verbose:
1166 sys.stdout.write("\n")
1167
1168 server = ThreadedEchoServer(CERTFILE,
1169 certreqs=ssl.CERT_NONE,
1170 ssl_version=ssl.PROTOCOL_TLSv1,
1171 cacerts=CERTFILE,
1172 chatty=True,
1173 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001174 with server:
1175 s = ssl.wrap_socket(socket.socket(),
1176 server_side=False,
1177 certfile=CERTFILE,
1178 ca_certs=CERTFILE,
1179 cert_reqs=ssl.CERT_NONE,
1180 ssl_version=ssl.PROTOCOL_TLSv1)
1181 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00001182 # helper methods for standardising recv* method signatures
1183 def _recv_into():
1184 b = bytearray("\0"*100)
1185 count = s.recv_into(b)
1186 return b[:count]
1187
1188 def _recvfrom_into():
1189 b = bytearray("\0"*100)
1190 count, addr = s.recvfrom_into(b)
1191 return b[:count]
1192
1193 # (name, method, whether to expect success, *args)
1194 send_methods = [
1195 ('send', s.send, True, []),
1196 ('sendto', s.sendto, False, ["some.address"]),
1197 ('sendall', s.sendall, True, []),
1198 ]
1199 recv_methods = [
1200 ('recv', s.recv, True, []),
1201 ('recvfrom', s.recvfrom, False, ["some.address"]),
1202 ('recv_into', _recv_into, True, []),
1203 ('recvfrom_into', _recvfrom_into, False, []),
1204 ]
1205 data_prefix = u"PREFIX_"
1206
1207 for meth_name, send_meth, expect_success, args in send_methods:
1208 indata = data_prefix + meth_name
1209 try:
1210 send_meth(indata.encode('ASCII', 'strict'), *args)
1211 outdata = s.read()
1212 outdata = outdata.decode('ASCII', 'strict')
1213 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001214 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001215 "While sending with <<%s>> bad data "
1216 "<<%r>> (%d) received; "
1217 "expected <<%r>> (%d)\n" % (
1218 meth_name, outdata[:20], len(outdata),
1219 indata[:20], len(indata)
1220 )
1221 )
1222 except ValueError as e:
1223 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001224 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001225 "Failed to send with method <<%s>>; "
1226 "expected to succeed.\n" % (meth_name,)
1227 )
1228 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001229 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001230 "Method <<%s>> failed with unexpected "
1231 "exception message: %s\n" % (
1232 meth_name, e
1233 )
1234 )
1235
1236 for meth_name, recv_meth, expect_success, args in recv_methods:
1237 indata = data_prefix + meth_name
1238 try:
1239 s.send(indata.encode('ASCII', 'strict'))
1240 outdata = recv_meth(*args)
1241 outdata = outdata.decode('ASCII', 'strict')
1242 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001243 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001244 "While receiving with <<%s>> bad data "
1245 "<<%r>> (%d) received; "
1246 "expected <<%r>> (%d)\n" % (
1247 meth_name, outdata[:20], len(outdata),
1248 indata[:20], len(indata)
1249 )
1250 )
1251 except ValueError as e:
1252 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001253 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001254 "Failed to receive with method <<%s>>; "
1255 "expected to succeed.\n" % (meth_name,)
1256 )
1257 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001258 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001259 "Method <<%s>> failed with unexpected "
1260 "exception message: %s\n" % (
1261 meth_name, e
1262 )
1263 )
1264 # consume data
1265 s.read()
1266
1267 s.write("over\n".encode("ASCII", "strict"))
1268 s.close()
Bill Janssen61c001a2008-09-08 16:37:24 +00001269
Antoine Pitroufc69af12010-04-24 20:04:58 +00001270 def test_handshake_timeout(self):
1271 # Issue #5103: SSL handshake must respect the socket timeout
1272 server = socket.socket(socket.AF_INET)
1273 host = "127.0.0.1"
1274 port = test_support.bind_port(server)
1275 started = threading.Event()
1276 finish = False
1277
1278 def serve():
1279 server.listen(5)
1280 started.set()
1281 conns = []
1282 while not finish:
1283 r, w, e = select.select([server], [], [], 0.1)
1284 if server in r:
1285 # Let the socket hang around rather than having
1286 # it closed by garbage collection.
1287 conns.append(server.accept()[0])
1288
1289 t = threading.Thread(target=serve)
1290 t.start()
1291 started.wait()
1292
1293 try:
1294 try:
1295 c = socket.socket(socket.AF_INET)
1296 c.settimeout(0.2)
1297 c.connect((host, port))
1298 # Will attempt handshake and time out
1299 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1300 ssl.wrap_socket, c)
1301 finally:
1302 c.close()
1303 try:
1304 c = socket.socket(socket.AF_INET)
1305 c.settimeout(0.2)
1306 c = ssl.wrap_socket(c)
1307 # Will attempt handshake and time out
1308 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1309 c.connect, (host, port))
1310 finally:
1311 c.close()
1312 finally:
1313 finish = True
1314 t.join()
1315 server.close()
1316
Antoine Pitroud76088d2012-01-03 22:46:48 +01001317 def test_default_ciphers(self):
1318 with ThreadedEchoServer(CERTFILE,
1319 ssl_version=ssl.PROTOCOL_SSLv23,
1320 chatty=False) as server:
1321 sock = socket.socket()
1322 try:
1323 # Force a set of weak ciphers on our client socket
1324 try:
1325 s = ssl.wrap_socket(sock,
1326 ssl_version=ssl.PROTOCOL_SSLv23,
1327 ciphers="DES")
1328 except ssl.SSLError:
1329 self.skipTest("no DES cipher available")
1330 with self.assertRaises((OSError, ssl.SSLError)):
1331 s.connect((HOST, server.port))
1332 finally:
1333 sock.close()
1334 self.assertIn("no shared cipher", str(server.conn_errors[0]))
1335
Bill Janssen61c001a2008-09-08 16:37:24 +00001336
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001337def test_main(verbose=False):
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001338 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, NOKIACERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001339 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001340 "keycert.pem")
1341 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1342 os.path.dirname(__file__) or os.curdir,
1343 "https_svn_python_org_root.pem")
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001344 NOKIACERT = os.path.join(os.path.dirname(__file__) or os.curdir,
1345 "nokia.pem")
Bill Janssen296a59d2007-09-16 22:06:00 +00001346
1347 if (not os.path.exists(CERTFILE) or
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001348 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT) or
1349 not os.path.exists(NOKIACERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001350 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001351
Antoine Pitroude30f702010-09-14 12:54:08 +00001352 tests = [BasicTests, BasicSocketTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001353
Bill Janssen296a59d2007-09-16 22:06:00 +00001354 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001355 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001356
Bill Janssen98d19da2007-09-10 21:51:02 +00001357 if _have_threads:
1358 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001359 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001360 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001361
Antoine Pitrou3945c862010-04-28 21:11:01 +00001362 try:
1363 test_support.run_unittest(*tests)
1364 finally:
1365 if _have_threads:
1366 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001367
1368if __name__ == "__main__":
1369 test_main()