blob: e643f7493a17ee5b72ba216a1283c99e7dd3fb9e [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 Pitrouc642f672012-05-04 16:33:30 +0200358 self.skipTest("remote host needs SNI, only available on Python 3.2+")
359 # NOTE: https://sha2.hboeck.de is another possible test host
Antoine Pitroud43245a2011-01-08 10:32:51 +0000360 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000361 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitroud43245a2011-01-08 10:32:51 +0000362 with test_support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrouc818ed42010-09-07 21:40:25 +0000363 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
364 cert_reqs=ssl.CERT_REQUIRED,
365 ca_certs=sha256_cert,)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000366 try:
367 s.connect(remote)
368 if test_support.verbose:
369 sys.stdout.write("\nCipher with %r is %r\n" %
370 (remote, s.cipher()))
371 sys.stdout.write("Certificate is:\n%s\n" %
372 pprint.pformat(s.getpeercert()))
373 finally:
374 s.close()
375
Bill Janssen296a59d2007-09-16 22:06:00 +0000376
Bill Janssen98d19da2007-09-10 21:51:02 +0000377try:
378 import threading
379except ImportError:
380 _have_threads = False
381else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000382 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000383
Bill Janssen98d19da2007-09-10 21:51:02 +0000384 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000385
Bill Janssen98d19da2007-09-10 21:51:02 +0000386 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000387
Bill Janssen98d19da2007-09-10 21:51:02 +0000388 """A mildly complicated class, because we want it to work both
389 with and without the SSL wrapper around the socket connection, so
390 that we can test the STARTTLS functionality."""
391
392 def __init__(self, server, connsock):
393 self.server = server
394 self.running = False
395 self.sock = connsock
396 self.sock.setblocking(1)
397 self.sslconn = None
398 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000399 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000400
Bill Janssen934b16d2008-06-28 22:19:33 +0000401 def show_conn_details(self):
402 if self.server.certreqs == ssl.CERT_REQUIRED:
403 cert = self.sslconn.getpeercert()
404 if test_support.verbose and self.server.chatty:
405 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
406 cert_binary = self.sslconn.getpeercert(True)
407 if test_support.verbose and self.server.chatty:
408 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
409 cipher = self.sslconn.cipher()
410 if test_support.verbose and self.server.chatty:
411 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
412
Antoine Pitrou3945c862010-04-28 21:11:01 +0000413 def wrap_conn(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000414 try:
415 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
416 certfile=self.server.certificate,
417 ssl_version=self.server.protocol,
418 ca_certs=self.server.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000419 cert_reqs=self.server.certreqs,
420 ciphers=self.server.ciphers)
Antoine Pitroud76088d2012-01-03 22:46:48 +0100421 except ssl.SSLError as e:
Antoine Pitroudb187842010-04-27 10:32:58 +0000422 # XXX Various errors can have happened here, for example
423 # a mismatching protocol version, an invalid certificate,
424 # or a low-level bug. This should be made more discriminating.
Antoine Pitroud76088d2012-01-03 22:46:48 +0100425 self.server.conn_errors.append(e)
Bill Janssen98d19da2007-09-10 21:51:02 +0000426 if self.server.chatty:
427 handle_error("\n server: bad connection attempt from " +
428 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000429 self.close()
Antoine Pitroudb187842010-04-27 10:32:58 +0000430 self.running = False
431 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000432 return False
Bill Janssen98d19da2007-09-10 21:51:02 +0000433 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000434 return True
435
436 def read(self):
437 if self.sslconn:
438 return self.sslconn.read()
439 else:
440 return self.sock.recv(1024)
441
442 def write(self, bytes):
443 if self.sslconn:
444 return self.sslconn.write(bytes)
445 else:
446 return self.sock.send(bytes)
447
448 def close(self):
449 if self.sslconn:
450 self.sslconn.close()
451 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000452 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000453
Antoine Pitrou3945c862010-04-28 21:11:01 +0000454 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000455 self.running = True
456 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000457 if isinstance(self.sock, ssl.SSLSocket):
458 self.sslconn = self.sock
459 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000460 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000461 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000462 while self.running:
463 try:
464 msg = self.read()
465 if not msg:
466 # eof, so quit this handler
467 self.running = False
468 self.close()
469 elif msg.strip() == 'over':
470 if test_support.verbose and self.server.connectionchatty:
471 sys.stdout.write(" server: client closed connection\n")
472 self.close()
473 return
474 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
475 if test_support.verbose and self.server.connectionchatty:
476 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
477 self.write("OK\n")
478 if not self.wrap_conn():
479 return
Bill Janssen39295c22008-08-12 16:31:21 +0000480 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
481 if test_support.verbose and self.server.connectionchatty:
482 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
483 self.write("OK\n")
484 self.sslconn.unwrap()
485 self.sslconn = None
486 if test_support.verbose and self.server.connectionchatty:
487 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000488 else:
489 if (test_support.verbose and
490 self.server.connectionchatty):
491 ctype = (self.sslconn and "encrypted") or "unencrypted"
492 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
493 % (repr(msg), ctype, repr(msg.lower()), ctype))
494 self.write(msg.lower())
495 except ssl.SSLError:
496 if self.server.chatty:
497 handle_error("Test server failure:\n")
498 self.close()
499 self.running = False
500 # normally, we'd just stop here, but for the test
501 # harness, we want to stop the server
502 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000503
Trent Nelsone41b0062008-04-08 23:47:30 +0000504 def __init__(self, certificate, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +0000505 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000506 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000507 wrap_accepting_socket=False, ciphers=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000508
Bill Janssen98d19da2007-09-10 21:51:02 +0000509 if ssl_version is None:
510 ssl_version = ssl.PROTOCOL_TLSv1
511 if certreqs is None:
512 certreqs = ssl.CERT_NONE
513 self.certificate = certificate
514 self.protocol = ssl_version
515 self.certreqs = certreqs
516 self.cacerts = cacerts
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000517 self.ciphers = ciphers
Bill Janssen98d19da2007-09-10 21:51:02 +0000518 self.chatty = chatty
519 self.connectionchatty = connectionchatty
520 self.starttls_server = starttls_server
521 self.sock = socket.socket()
522 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000523 if wrap_accepting_socket:
524 self.sock = ssl.wrap_socket(self.sock, server_side=True,
525 certfile=self.certificate,
526 cert_reqs = self.certreqs,
527 ca_certs = self.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000528 ssl_version = self.protocol,
529 ciphers = self.ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000530 if test_support.verbose and self.chatty:
531 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
532 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000533 self.active = False
Antoine Pitroud76088d2012-01-03 22:46:48 +0100534 self.conn_errors = []
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000535 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000536 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000537
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100538 def __enter__(self):
539 self.start(threading.Event())
540 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +0100541 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100542
543 def __exit__(self, *args):
544 self.stop()
545 self.join()
546
Antoine Pitrou3945c862010-04-28 21:11:01 +0000547 def start(self, flag=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000548 self.flag = flag
549 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000550
Antoine Pitrou3945c862010-04-28 21:11:01 +0000551 def run(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000552 self.sock.settimeout(0.05)
Bill Janssen98d19da2007-09-10 21:51:02 +0000553 self.sock.listen(5)
554 self.active = True
555 if self.flag:
556 # signal an event
557 self.flag.set()
558 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000559 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000560 newconn, connaddr = self.sock.accept()
561 if test_support.verbose and self.chatty:
562 sys.stdout.write(' server: new connection from '
563 + str(connaddr) + '\n')
564 handler = self.ConnectionHandler(self, newconn)
565 handler.start()
Antoine Pitrou7a556842012-01-27 17:33:01 +0100566 handler.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000567 except socket.timeout:
568 pass
569 except KeyboardInterrupt:
570 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +0000571 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000572
Antoine Pitrou3945c862010-04-28 21:11:01 +0000573 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000574 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000575
Bill Janssen934b16d2008-06-28 22:19:33 +0000576 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000577
Antoine Pitrou3945c862010-04-28 21:11:01 +0000578 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +0000579
Antoine Pitrou3945c862010-04-28 21:11:01 +0000580 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +0000581
582 def __init__(self, conn, certfile):
583 asyncore.dispatcher_with_send.__init__(self, conn)
584 self.socket = ssl.wrap_socket(conn, server_side=True,
585 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +0000586 do_handshake_on_connect=False)
587 self._ssl_accepting = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000588
589 def readable(self):
590 if isinstance(self.socket, ssl.SSLSocket):
591 while self.socket.pending() > 0:
592 self.handle_read_event()
593 return True
594
Antoine Pitroufc69af12010-04-24 20:04:58 +0000595 def _do_ssl_handshake(self):
596 try:
597 self.socket.do_handshake()
598 except ssl.SSLError, err:
599 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
600 ssl.SSL_ERROR_WANT_WRITE):
601 return
602 elif err.args[0] == ssl.SSL_ERROR_EOF:
603 return self.handle_close()
604 raise
605 except socket.error, err:
606 if err.args[0] == errno.ECONNABORTED:
607 return self.handle_close()
608 else:
609 self._ssl_accepting = False
610
Bill Janssen934b16d2008-06-28 22:19:33 +0000611 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +0000612 if self._ssl_accepting:
613 self._do_ssl_handshake()
614 else:
615 data = self.recv(1024)
Antoine Pitroudb187842010-04-27 10:32:58 +0000616 if data and data.strip() != 'over':
617 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +0000618
619 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000620 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000621 if test_support.verbose:
622 sys.stdout.write(" server: closed connection %s\n" % self.socket)
623
624 def handle_error(self):
625 raise
626
627 def __init__(self, certfile):
628 self.certfile = certfile
629 asyncore.dispatcher.__init__(self)
630 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
631 self.port = test_support.bind_port(self.socket)
632 self.listen(5)
633
634 def handle_accept(self):
635 sock_obj, addr = self.accept()
636 if test_support.verbose:
637 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
638 self.ConnectionHandler(sock_obj, self.certfile)
639
640 def handle_error(self):
641 raise
642
643 def __init__(self, certfile):
644 self.flag = None
645 self.active = False
646 self.server = self.EchoServer(certfile)
647 self.port = self.server.port
648 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000649 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000650
651 def __str__(self):
652 return "<%s %s>" % (self.__class__.__name__, self.server)
653
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100654 def __enter__(self):
655 self.start(threading.Event())
656 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +0100657 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100658
659 def __exit__(self, *args):
660 if test_support.verbose:
661 sys.stdout.write(" cleanup: stopping server.\n")
662 self.stop()
663 if test_support.verbose:
664 sys.stdout.write(" cleanup: joining server thread.\n")
665 self.join()
666 if test_support.verbose:
667 sys.stdout.write(" cleanup: successfully joined.\n")
668
Antoine Pitrou3945c862010-04-28 21:11:01 +0000669 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000670 self.flag = flag
671 threading.Thread.start(self)
672
Antoine Pitrou3945c862010-04-28 21:11:01 +0000673 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000674 self.active = True
675 if self.flag:
676 self.flag.set()
677 while self.active:
Antoine Pitroudb187842010-04-27 10:32:58 +0000678 asyncore.loop(0.05)
Bill Janssen934b16d2008-06-28 22:19:33 +0000679
Antoine Pitrou3945c862010-04-28 21:11:01 +0000680 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000681 self.active = False
682 self.server.close()
683
684 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000685
686 class HTTPSServer(HTTPServer):
687
688 def __init__(self, server_address, RequestHandlerClass, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000689 HTTPServer.__init__(self, server_address, RequestHandlerClass)
690 # we assume the certfile contains both private key and certificate
691 self.certfile = certfile
Bill Janssen296a59d2007-09-16 22:06:00 +0000692 self.allow_reuse_address = True
693
Bill Janssen934b16d2008-06-28 22:19:33 +0000694 def __str__(self):
695 return ('<%s %s:%s>' %
696 (self.__class__.__name__,
697 self.server_name,
698 self.server_port))
699
Antoine Pitrou3945c862010-04-28 21:11:01 +0000700 def get_request(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000701 # override this to wrap socket with SSL
702 sock, addr = self.socket.accept()
703 sslconn = ssl.wrap_socket(sock, server_side=True,
704 certfile=self.certfile)
705 return sslconn, addr
706
Bill Janssen296a59d2007-09-16 22:06:00 +0000707 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Bill Janssen296a59d2007-09-16 22:06:00 +0000708 # need to override translate_path to get a known root,
709 # instead of using os.curdir, since the test could be
710 # run from anywhere
711
712 server_version = "TestHTTPS/1.0"
713
714 root = None
715
716 def translate_path(self, path):
717 """Translate a /-separated PATH to the local filename syntax.
718
719 Components that mean special things to the local file system
720 (e.g. drive or directory names) are ignored. (XXX They should
721 probably be diagnosed.)
722
723 """
724 # abandon query parameters
725 path = urlparse.urlparse(path)[2]
726 path = os.path.normpath(urllib.unquote(path))
727 words = path.split('/')
728 words = filter(None, words)
729 path = self.root
730 for word in words:
731 drive, word = os.path.splitdrive(word)
732 head, word = os.path.split(word)
733 if word in self.root: continue
734 path = os.path.join(path, word)
735 return path
736
737 def log_message(self, format, *args):
738
739 # we override this to suppress logging unless "verbose"
740
741 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000742 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
743 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000744 self.server.server_port,
745 self.request.cipher(),
746 self.log_date_time_string(),
747 format%args))
748
749
Trent Nelsone41b0062008-04-08 23:47:30 +0000750 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000751 self.flag = None
Bill Janssen296a59d2007-09-16 22:06:00 +0000752 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
753 self.server = self.HTTPSServer(
Antoine Pitrou150acda2010-04-27 08:40:51 +0000754 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
755 self.port = self.server.server_port
Bill Janssen296a59d2007-09-16 22:06:00 +0000756 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000757 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000758
759 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000760 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000761
Antoine Pitrou3945c862010-04-28 21:11:01 +0000762 def start(self, flag=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000763 self.flag = flag
764 threading.Thread.start(self)
765
Antoine Pitrou3945c862010-04-28 21:11:01 +0000766 def run(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000767 if self.flag:
768 self.flag.set()
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000769 self.server.serve_forever(0.05)
Bill Janssen296a59d2007-09-16 22:06:00 +0000770
Antoine Pitrou3945c862010-04-28 21:11:01 +0000771 def stop(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000772 self.server.shutdown()
Bill Janssen296a59d2007-09-16 22:06:00 +0000773
774
Antoine Pitrou3945c862010-04-28 21:11:01 +0000775 def bad_cert_test(certfile):
776 """
777 Launch a server with CERT_REQUIRED, and check that trying to
778 connect to it with the given client certificate fails.
779 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000780 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000781 certreqs=ssl.CERT_REQUIRED,
782 cacerts=CERTFILE, chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100783 with server:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000784 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000785 s = ssl.wrap_socket(socket.socket(),
786 certfile=certfile,
787 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000788 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000789 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000790 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000791 sys.stdout.write("\nSSLError is %s\n" % x[1])
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000792 except socket.error, x:
793 if test_support.verbose:
794 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000795 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000796 raise AssertionError("Use of invalid cert should have failed!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000797
Antoine Pitrou3945c862010-04-28 21:11:01 +0000798 def server_params_test(certfile, protocol, certreqs, cacertsfile,
799 client_certfile, client_protocol=None, indata="FOO\n",
800 ciphers=None, chatty=True, connectionchatty=False,
801 wrap_accepting_socket=False):
802 """
803 Launch a server, connect a client to it and try various reads
804 and writes.
805 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000806 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000807 certreqs=certreqs,
808 ssl_version=protocol,
809 cacerts=cacertsfile,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000810 ciphers=ciphers,
Bill Janssen98d19da2007-09-10 21:51:02 +0000811 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000812 connectionchatty=connectionchatty,
813 wrap_accepting_socket=wrap_accepting_socket)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100814 with server:
815 # try to connect
816 if client_protocol is None:
817 client_protocol = protocol
Antoine Pitroudb187842010-04-27 10:32:58 +0000818 s = ssl.wrap_socket(socket.socket(),
819 certfile=client_certfile,
820 ca_certs=cacertsfile,
821 ciphers=ciphers,
822 cert_reqs=certreqs,
823 ssl_version=client_protocol)
824 s.connect((HOST, server.port))
825 for arg in [indata, bytearray(indata), memoryview(indata)]:
Bill Janssen98d19da2007-09-10 21:51:02 +0000826 if connectionchatty:
827 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +0000828 sys.stdout.write(
829 " client: sending %s...\n" % (repr(arg)))
830 s.write(arg)
831 outdata = s.read()
832 if connectionchatty:
833 if test_support.verbose:
834 sys.stdout.write(" client: read %s\n" % repr(outdata))
835 if outdata != indata.lower():
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000836 raise AssertionError(
Antoine Pitroudb187842010-04-27 10:32:58 +0000837 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
838 % (outdata[:min(len(outdata),20)], len(outdata),
839 indata[:min(len(indata),20)].lower(), len(indata)))
840 s.write("over\n")
841 if connectionchatty:
842 if test_support.verbose:
843 sys.stdout.write(" client: closing connection.\n")
844 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000845
Antoine Pitrou3945c862010-04-28 21:11:01 +0000846 def try_protocol_combo(server_protocol,
847 client_protocol,
848 expect_success,
849 certsreqs=None):
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000850 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000851 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +0000852 certtype = {
853 ssl.CERT_NONE: "CERT_NONE",
854 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
855 ssl.CERT_REQUIRED: "CERT_REQUIRED",
856 }[certsreqs]
Bill Janssen98d19da2007-09-10 21:51:02 +0000857 if test_support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000858 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +0000859 sys.stdout.write(formatstr %
860 (ssl.get_protocol_name(client_protocol),
861 ssl.get_protocol_name(server_protocol),
862 certtype))
863 try:
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000864 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
865 # will send an SSLv3 hello (rather than SSLv2) starting from
866 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou3945c862010-04-28 21:11:01 +0000867 server_params_test(CERTFILE, server_protocol, certsreqs,
868 CERTFILE, CERTFILE, client_protocol,
869 ciphers="ALL", chatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +0000870 # Protocol mismatch can result in either an SSLError, or a
871 # "Connection reset by peer" error.
872 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000873 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +0000874 raise
Antoine Pitroudb187842010-04-27 10:32:58 +0000875 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000876 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +0000877 raise
Bill Janssen98d19da2007-09-10 21:51:02 +0000878 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000879 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000880 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +0000881 "Client protocol %s succeeded with server protocol %s!"
882 % (ssl.get_protocol_name(client_protocol),
883 ssl.get_protocol_name(server_protocol)))
884
885
Bill Janssen934b16d2008-06-28 22:19:33 +0000886 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000887
Antoine Pitrou3945c862010-04-28 21:11:01 +0000888 def test_rude_shutdown(self):
889 """A brutal shutdown of an SSL server should raise an IOError
890 in the client when attempting handshake.
891 """
Bill Janssen98d19da2007-09-10 21:51:02 +0000892 listener_ready = threading.Event()
893 listener_gone = threading.Event()
894
Antoine Pitrou150acda2010-04-27 08:40:51 +0000895 s = socket.socket()
896 port = test_support.bind_port(s, HOST)
897
898 # `listener` runs in a thread. It sits in an accept() until
899 # the main thread connects. Then it rudely closes the socket,
900 # and sets Event `listener_gone` to let the main thread know
901 # the socket is gone.
Bill Janssen98d19da2007-09-10 21:51:02 +0000902 def listener():
Bill Janssen98d19da2007-09-10 21:51:02 +0000903 s.listen(5)
904 listener_ready.set()
905 s.accept()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000906 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000907 listener_gone.set()
908
909 def connector():
910 listener_ready.wait()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000911 c = socket.socket()
912 c.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000913 listener_gone.wait()
914 try:
Antoine Pitrou150acda2010-04-27 08:40:51 +0000915 ssl_sock = ssl.wrap_socket(c)
Bill Janssen934b16d2008-06-28 22:19:33 +0000916 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000917 pass
918 else:
Antoine Pitroudb187842010-04-27 10:32:58 +0000919 self.fail('connecting to closed SSL socket should have failed')
Bill Janssen98d19da2007-09-10 21:51:02 +0000920
921 t = threading.Thread(target=listener)
922 t.start()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000923 try:
924 connector()
925 finally:
926 t.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000927
Antoine Pitroud75efd92010-08-04 17:38:33 +0000928 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000929 def test_echo(self):
930 """Basic test of an SSL client connecting to a server"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000931 if test_support.verbose:
932 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000933 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
934 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
935 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000936
Antoine Pitrou3945c862010-04-28 21:11:01 +0000937 def test_getpeercert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000938 if test_support.verbose:
939 sys.stdout.write("\n")
940 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000941 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000942 certreqs=ssl.CERT_NONE,
943 ssl_version=ssl.PROTOCOL_SSLv23,
944 cacerts=CERTFILE,
945 chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100946 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +0000947 s = ssl.wrap_socket(socket.socket(),
948 certfile=CERTFILE,
949 ca_certs=CERTFILE,
950 cert_reqs=ssl.CERT_REQUIRED,
951 ssl_version=ssl.PROTOCOL_SSLv23)
952 s.connect((HOST, server.port))
953 cert = s.getpeercert()
954 self.assertTrue(cert, "Can't get peer certificate.")
955 cipher = s.cipher()
956 if test_support.verbose:
957 sys.stdout.write(pprint.pformat(cert) + '\n')
958 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
959 if 'subject' not in cert:
960 self.fail("No subject field in certificate: %s." %
961 pprint.pformat(cert))
962 if ((('organizationName', 'Python Software Foundation'),)
963 not in cert['subject']):
964 self.fail(
965 "Missing or invalid 'organizationName' field in certificate subject; "
966 "should be 'Python Software Foundation'.")
967 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000968
Antoine Pitrou3945c862010-04-28 21:11:01 +0000969 def test_empty_cert(self):
970 """Connecting with an empty cert file"""
971 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
972 "nullcert.pem"))
973 def test_malformed_cert(self):
974 """Connecting with a badly formatted certificate (syntax error)"""
975 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
976 "badcert.pem"))
977 def test_nonexisting_cert(self):
978 """Connecting with a non-existing cert file"""
979 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
980 "wrongcert.pem"))
981 def test_malformed_key(self):
982 """Connecting with a badly formatted key (syntax error)"""
983 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
984 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000985
Antoine Pitroud75efd92010-08-04 17:38:33 +0000986 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000987 def test_protocol_sslv2(self):
988 """Connecting to an SSLv2 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000989 if test_support.verbose:
990 sys.stdout.write("\n")
Antoine Pitrou6361ea22011-10-30 21:31:34 +0100991 if not hasattr(ssl, 'PROTOCOL_SSLv2'):
992 self.skipTest("PROTOCOL_SSLv2 needed")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000993 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
994 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
995 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
996 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
997 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
998 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000999
Antoine Pitroud75efd92010-08-04 17:38:33 +00001000 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001001 def test_protocol_sslv23(self):
1002 """Connecting to an SSLv23 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001003 if test_support.verbose:
1004 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001005 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1006 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1007 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
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_OPTIONAL)
1010 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1011 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +00001012
Antoine Pitrou3945c862010-04-28 21:11:01 +00001013 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1014 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1015 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00001016
Antoine Pitroud75efd92010-08-04 17:38:33 +00001017 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001018 def test_protocol_sslv3(self):
1019 """Connecting to an SSLv3 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001020 if test_support.verbose:
1021 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001022 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1023 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1024 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001025 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1026 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001027 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001028
Antoine Pitroud75efd92010-08-04 17:38:33 +00001029 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001030 def test_protocol_tlsv1(self):
1031 """Connecting to a TLSv1 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001032 if test_support.verbose:
1033 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001034 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1035 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1036 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001037 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1038 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001039 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001040
Antoine Pitrou3945c862010-04-28 21:11:01 +00001041 def test_starttls(self):
1042 """Switching from clear text to encrypted and back again."""
Bill Janssen39295c22008-08-12 16:31:21 +00001043 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +00001044
Trent Nelsone41b0062008-04-08 23:47:30 +00001045 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00001046 ssl_version=ssl.PROTOCOL_TLSv1,
1047 starttls_server=True,
1048 chatty=True,
1049 connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +00001050 wrapped = False
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001051 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001052 s = socket.socket()
1053 s.setblocking(1)
1054 s.connect((HOST, server.port))
1055 if test_support.verbose:
1056 sys.stdout.write("\n")
1057 for indata in msgs:
Bill Janssen98d19da2007-09-10 21:51:02 +00001058 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00001059 sys.stdout.write(
1060 " client: sending %s...\n" % repr(indata))
1061 if wrapped:
1062 conn.write(indata)
1063 outdata = conn.read()
1064 else:
1065 s.send(indata)
1066 outdata = s.recv(1024)
1067 if (indata == "STARTTLS" and
1068 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001069 # STARTTLS ok, switch to secure mode
Bill Janssen98d19da2007-09-10 21:51:02 +00001070 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00001071 sys.stdout.write(
Antoine Pitroudb187842010-04-27 10:32:58 +00001072 " client: read %s from server, starting TLS...\n"
1073 % repr(outdata))
1074 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1075 wrapped = True
1076 elif (indata == "ENDTLS" and
1077 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001078 # ENDTLS ok, switch back to clear text
Antoine Pitroudb187842010-04-27 10:32:58 +00001079 if test_support.verbose:
1080 sys.stdout.write(
1081 " client: read %s from server, ending TLS...\n"
1082 % repr(outdata))
1083 s = conn.unwrap()
1084 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00001085 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001086 if test_support.verbose:
1087 sys.stdout.write(
1088 " client: read %s from server\n" % repr(outdata))
1089 if test_support.verbose:
1090 sys.stdout.write(" client: closing connection.\n")
1091 if wrapped:
1092 conn.write("over\n")
1093 else:
1094 s.send("over\n")
1095 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001096
Antoine Pitrou3945c862010-04-28 21:11:01 +00001097 def test_socketserver(self):
1098 """Using a SocketServer to create and manage SSL connections."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001099 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +00001100 flag = threading.Event()
1101 server.start(flag)
1102 # wait for it to start
1103 flag.wait()
1104 # try to connect
1105 try:
1106 if test_support.verbose:
1107 sys.stdout.write('\n')
Antoine Pitrou3945c862010-04-28 21:11:01 +00001108 with open(CERTFILE, 'rb') as f:
1109 d1 = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +00001110 d2 = ''
1111 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +00001112 url = 'https://127.0.0.1:%d/%s' % (
1113 server.port, os.path.split(CERTFILE)[1])
Florent Xicluna07627882010-03-21 01:14:24 +00001114 with test_support.check_py3k_warnings():
1115 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +00001116 dlen = f.info().getheader("content-length")
1117 if dlen and (int(dlen) > 0):
1118 d2 = f.read(int(dlen))
1119 if test_support.verbose:
1120 sys.stdout.write(
1121 " client: read %d bytes from remote server '%s'\n"
1122 % (len(d2), server))
1123 f.close()
Antoine Pitroudb187842010-04-27 10:32:58 +00001124 self.assertEqual(d1, d2)
Bill Janssen296a59d2007-09-16 22:06:00 +00001125 finally:
1126 server.stop()
1127 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001128
Antoine Pitrou3945c862010-04-28 21:11:01 +00001129 def test_wrapped_accept(self):
1130 """Check the accept() method on SSL sockets."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001131 if test_support.verbose:
1132 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001133 server_params_test(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1134 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1135 chatty=True, connectionchatty=True,
1136 wrap_accepting_socket=True)
Bill Janssen934b16d2008-06-28 22:19:33 +00001137
Antoine Pitrou3945c862010-04-28 21:11:01 +00001138 def test_asyncore_server(self):
1139 """Check the example asyncore integration."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001140 indata = "TEST MESSAGE of mixed case\n"
1141
1142 if test_support.verbose:
1143 sys.stdout.write("\n")
1144 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001145 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001146 s = ssl.wrap_socket(socket.socket())
1147 s.connect(('127.0.0.1', server.port))
1148 if test_support.verbose:
1149 sys.stdout.write(
1150 " client: sending %s...\n" % (repr(indata)))
1151 s.write(indata)
1152 outdata = s.read()
1153 if test_support.verbose:
1154 sys.stdout.write(" client: read %s\n" % repr(outdata))
1155 if outdata != indata.lower():
1156 self.fail(
1157 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1158 % (outdata[:min(len(outdata),20)], len(outdata),
1159 indata[:min(len(indata),20)].lower(), len(indata)))
1160 s.write("over\n")
1161 if test_support.verbose:
1162 sys.stdout.write(" client: closing connection.\n")
1163 s.close()
Bill Janssen934b16d2008-06-28 22:19:33 +00001164
Antoine Pitrou3945c862010-04-28 21:11:01 +00001165 def test_recv_send(self):
1166 """Test recv(), send() and friends."""
Bill Janssen61c001a2008-09-08 16:37:24 +00001167 if test_support.verbose:
1168 sys.stdout.write("\n")
1169
1170 server = ThreadedEchoServer(CERTFILE,
1171 certreqs=ssl.CERT_NONE,
1172 ssl_version=ssl.PROTOCOL_TLSv1,
1173 cacerts=CERTFILE,
1174 chatty=True,
1175 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001176 with server:
1177 s = ssl.wrap_socket(socket.socket(),
1178 server_side=False,
1179 certfile=CERTFILE,
1180 ca_certs=CERTFILE,
1181 cert_reqs=ssl.CERT_NONE,
1182 ssl_version=ssl.PROTOCOL_TLSv1)
1183 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00001184 # helper methods for standardising recv* method signatures
1185 def _recv_into():
1186 b = bytearray("\0"*100)
1187 count = s.recv_into(b)
1188 return b[:count]
1189
1190 def _recvfrom_into():
1191 b = bytearray("\0"*100)
1192 count, addr = s.recvfrom_into(b)
1193 return b[:count]
1194
1195 # (name, method, whether to expect success, *args)
1196 send_methods = [
1197 ('send', s.send, True, []),
1198 ('sendto', s.sendto, False, ["some.address"]),
1199 ('sendall', s.sendall, True, []),
1200 ]
1201 recv_methods = [
1202 ('recv', s.recv, True, []),
1203 ('recvfrom', s.recvfrom, False, ["some.address"]),
1204 ('recv_into', _recv_into, True, []),
1205 ('recvfrom_into', _recvfrom_into, False, []),
1206 ]
1207 data_prefix = u"PREFIX_"
1208
1209 for meth_name, send_meth, expect_success, args in send_methods:
1210 indata = data_prefix + meth_name
1211 try:
1212 send_meth(indata.encode('ASCII', 'strict'), *args)
1213 outdata = s.read()
1214 outdata = outdata.decode('ASCII', 'strict')
1215 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001216 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001217 "While sending with <<%s>> bad data "
1218 "<<%r>> (%d) received; "
1219 "expected <<%r>> (%d)\n" % (
1220 meth_name, outdata[:20], len(outdata),
1221 indata[:20], len(indata)
1222 )
1223 )
1224 except ValueError as e:
1225 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001226 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001227 "Failed to send with method <<%s>>; "
1228 "expected to succeed.\n" % (meth_name,)
1229 )
1230 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001231 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001232 "Method <<%s>> failed with unexpected "
1233 "exception message: %s\n" % (
1234 meth_name, e
1235 )
1236 )
1237
1238 for meth_name, recv_meth, expect_success, args in recv_methods:
1239 indata = data_prefix + meth_name
1240 try:
1241 s.send(indata.encode('ASCII', 'strict'))
1242 outdata = recv_meth(*args)
1243 outdata = outdata.decode('ASCII', 'strict')
1244 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001245 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001246 "While receiving with <<%s>> bad data "
1247 "<<%r>> (%d) received; "
1248 "expected <<%r>> (%d)\n" % (
1249 meth_name, outdata[:20], len(outdata),
1250 indata[:20], len(indata)
1251 )
1252 )
1253 except ValueError as e:
1254 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001255 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001256 "Failed to receive with method <<%s>>; "
1257 "expected to succeed.\n" % (meth_name,)
1258 )
1259 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001260 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001261 "Method <<%s>> failed with unexpected "
1262 "exception message: %s\n" % (
1263 meth_name, e
1264 )
1265 )
1266 # consume data
1267 s.read()
1268
1269 s.write("over\n".encode("ASCII", "strict"))
1270 s.close()
Bill Janssen61c001a2008-09-08 16:37:24 +00001271
Antoine Pitroufc69af12010-04-24 20:04:58 +00001272 def test_handshake_timeout(self):
1273 # Issue #5103: SSL handshake must respect the socket timeout
1274 server = socket.socket(socket.AF_INET)
1275 host = "127.0.0.1"
1276 port = test_support.bind_port(server)
1277 started = threading.Event()
1278 finish = False
1279
1280 def serve():
1281 server.listen(5)
1282 started.set()
1283 conns = []
1284 while not finish:
1285 r, w, e = select.select([server], [], [], 0.1)
1286 if server in r:
1287 # Let the socket hang around rather than having
1288 # it closed by garbage collection.
1289 conns.append(server.accept()[0])
1290
1291 t = threading.Thread(target=serve)
1292 t.start()
1293 started.wait()
1294
1295 try:
1296 try:
1297 c = socket.socket(socket.AF_INET)
1298 c.settimeout(0.2)
1299 c.connect((host, port))
1300 # Will attempt handshake and time out
1301 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1302 ssl.wrap_socket, c)
1303 finally:
1304 c.close()
1305 try:
1306 c = socket.socket(socket.AF_INET)
1307 c.settimeout(0.2)
1308 c = ssl.wrap_socket(c)
1309 # Will attempt handshake and time out
1310 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1311 c.connect, (host, port))
1312 finally:
1313 c.close()
1314 finally:
1315 finish = True
1316 t.join()
1317 server.close()
1318
Antoine Pitroud76088d2012-01-03 22:46:48 +01001319 def test_default_ciphers(self):
1320 with ThreadedEchoServer(CERTFILE,
1321 ssl_version=ssl.PROTOCOL_SSLv23,
1322 chatty=False) as server:
1323 sock = socket.socket()
1324 try:
1325 # Force a set of weak ciphers on our client socket
1326 try:
1327 s = ssl.wrap_socket(sock,
1328 ssl_version=ssl.PROTOCOL_SSLv23,
1329 ciphers="DES")
1330 except ssl.SSLError:
1331 self.skipTest("no DES cipher available")
1332 with self.assertRaises((OSError, ssl.SSLError)):
1333 s.connect((HOST, server.port))
1334 finally:
1335 sock.close()
1336 self.assertIn("no shared cipher", str(server.conn_errors[0]))
1337
Bill Janssen61c001a2008-09-08 16:37:24 +00001338
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001339def test_main(verbose=False):
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001340 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, NOKIACERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001341 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001342 "keycert.pem")
1343 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1344 os.path.dirname(__file__) or os.curdir,
1345 "https_svn_python_org_root.pem")
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001346 NOKIACERT = os.path.join(os.path.dirname(__file__) or os.curdir,
1347 "nokia.pem")
Bill Janssen296a59d2007-09-16 22:06:00 +00001348
1349 if (not os.path.exists(CERTFILE) or
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001350 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT) or
1351 not os.path.exists(NOKIACERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001352 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001353
Antoine Pitroude30f702010-09-14 12:54:08 +00001354 tests = [BasicTests, BasicSocketTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001355
Bill Janssen296a59d2007-09-16 22:06:00 +00001356 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001357 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001358
Bill Janssen98d19da2007-09-10 21:51:02 +00001359 if _have_threads:
1360 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001361 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001362 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001363
Antoine Pitrou3945c862010-04-28 21:11:01 +00001364 try:
1365 test_support.run_unittest(*tests)
1366 finally:
1367 if _have_threads:
1368 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001369
1370if __name__ == "__main__":
1371 test_main()