blob: 97552e8fdd6e94f6dbca4b26b497a9c91561134a [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()
Antoine Pitrou7a556842012-01-27 17:33:01 +0100565 handler.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000566 except socket.timeout:
567 pass
568 except KeyboardInterrupt:
569 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +0000570 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000571
Antoine Pitrou3945c862010-04-28 21:11:01 +0000572 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000573 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000574
Bill Janssen934b16d2008-06-28 22:19:33 +0000575 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000576
Antoine Pitrou3945c862010-04-28 21:11:01 +0000577 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +0000578
Antoine Pitrou3945c862010-04-28 21:11:01 +0000579 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +0000580
581 def __init__(self, conn, certfile):
582 asyncore.dispatcher_with_send.__init__(self, conn)
583 self.socket = ssl.wrap_socket(conn, server_side=True,
584 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +0000585 do_handshake_on_connect=False)
586 self._ssl_accepting = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000587
588 def readable(self):
589 if isinstance(self.socket, ssl.SSLSocket):
590 while self.socket.pending() > 0:
591 self.handle_read_event()
592 return True
593
Antoine Pitroufc69af12010-04-24 20:04:58 +0000594 def _do_ssl_handshake(self):
595 try:
596 self.socket.do_handshake()
597 except ssl.SSLError, err:
598 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
599 ssl.SSL_ERROR_WANT_WRITE):
600 return
601 elif err.args[0] == ssl.SSL_ERROR_EOF:
602 return self.handle_close()
603 raise
604 except socket.error, err:
605 if err.args[0] == errno.ECONNABORTED:
606 return self.handle_close()
607 else:
608 self._ssl_accepting = False
609
Bill Janssen934b16d2008-06-28 22:19:33 +0000610 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +0000611 if self._ssl_accepting:
612 self._do_ssl_handshake()
613 else:
614 data = self.recv(1024)
Antoine Pitroudb187842010-04-27 10:32:58 +0000615 if data and data.strip() != 'over':
616 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +0000617
618 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000619 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000620 if test_support.verbose:
621 sys.stdout.write(" server: closed connection %s\n" % self.socket)
622
623 def handle_error(self):
624 raise
625
626 def __init__(self, certfile):
627 self.certfile = certfile
628 asyncore.dispatcher.__init__(self)
629 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
630 self.port = test_support.bind_port(self.socket)
631 self.listen(5)
632
633 def handle_accept(self):
634 sock_obj, addr = self.accept()
635 if test_support.verbose:
636 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
637 self.ConnectionHandler(sock_obj, self.certfile)
638
639 def handle_error(self):
640 raise
641
642 def __init__(self, certfile):
643 self.flag = None
644 self.active = False
645 self.server = self.EchoServer(certfile)
646 self.port = self.server.port
647 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000648 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000649
650 def __str__(self):
651 return "<%s %s>" % (self.__class__.__name__, self.server)
652
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100653 def __enter__(self):
654 self.start(threading.Event())
655 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +0100656 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100657
658 def __exit__(self, *args):
659 if test_support.verbose:
660 sys.stdout.write(" cleanup: stopping server.\n")
661 self.stop()
662 if test_support.verbose:
663 sys.stdout.write(" cleanup: joining server thread.\n")
664 self.join()
665 if test_support.verbose:
666 sys.stdout.write(" cleanup: successfully joined.\n")
667
Antoine Pitrou3945c862010-04-28 21:11:01 +0000668 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000669 self.flag = flag
670 threading.Thread.start(self)
671
Antoine Pitrou3945c862010-04-28 21:11:01 +0000672 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000673 self.active = True
674 if self.flag:
675 self.flag.set()
676 while self.active:
Antoine Pitroudb187842010-04-27 10:32:58 +0000677 asyncore.loop(0.05)
Bill Janssen934b16d2008-06-28 22:19:33 +0000678
Antoine Pitrou3945c862010-04-28 21:11:01 +0000679 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000680 self.active = False
681 self.server.close()
682
683 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000684
685 class HTTPSServer(HTTPServer):
686
687 def __init__(self, server_address, RequestHandlerClass, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000688 HTTPServer.__init__(self, server_address, RequestHandlerClass)
689 # we assume the certfile contains both private key and certificate
690 self.certfile = certfile
Bill Janssen296a59d2007-09-16 22:06:00 +0000691 self.allow_reuse_address = True
692
Bill Janssen934b16d2008-06-28 22:19:33 +0000693 def __str__(self):
694 return ('<%s %s:%s>' %
695 (self.__class__.__name__,
696 self.server_name,
697 self.server_port))
698
Antoine Pitrou3945c862010-04-28 21:11:01 +0000699 def get_request(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000700 # override this to wrap socket with SSL
701 sock, addr = self.socket.accept()
702 sslconn = ssl.wrap_socket(sock, server_side=True,
703 certfile=self.certfile)
704 return sslconn, addr
705
Bill Janssen296a59d2007-09-16 22:06:00 +0000706 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Bill Janssen296a59d2007-09-16 22:06:00 +0000707 # need to override translate_path to get a known root,
708 # instead of using os.curdir, since the test could be
709 # run from anywhere
710
711 server_version = "TestHTTPS/1.0"
712
713 root = None
714
715 def translate_path(self, path):
716 """Translate a /-separated PATH to the local filename syntax.
717
718 Components that mean special things to the local file system
719 (e.g. drive or directory names) are ignored. (XXX They should
720 probably be diagnosed.)
721
722 """
723 # abandon query parameters
724 path = urlparse.urlparse(path)[2]
725 path = os.path.normpath(urllib.unquote(path))
726 words = path.split('/')
727 words = filter(None, words)
728 path = self.root
729 for word in words:
730 drive, word = os.path.splitdrive(word)
731 head, word = os.path.split(word)
732 if word in self.root: continue
733 path = os.path.join(path, word)
734 return path
735
736 def log_message(self, format, *args):
737
738 # we override this to suppress logging unless "verbose"
739
740 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000741 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
742 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000743 self.server.server_port,
744 self.request.cipher(),
745 self.log_date_time_string(),
746 format%args))
747
748
Trent Nelsone41b0062008-04-08 23:47:30 +0000749 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000750 self.flag = None
Bill Janssen296a59d2007-09-16 22:06:00 +0000751 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
752 self.server = self.HTTPSServer(
Antoine Pitrou150acda2010-04-27 08:40:51 +0000753 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
754 self.port = self.server.server_port
Bill Janssen296a59d2007-09-16 22:06:00 +0000755 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000756 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000757
758 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000759 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000760
Antoine Pitrou3945c862010-04-28 21:11:01 +0000761 def start(self, flag=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000762 self.flag = flag
763 threading.Thread.start(self)
764
Antoine Pitrou3945c862010-04-28 21:11:01 +0000765 def run(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000766 if self.flag:
767 self.flag.set()
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000768 self.server.serve_forever(0.05)
Bill Janssen296a59d2007-09-16 22:06:00 +0000769
Antoine Pitrou3945c862010-04-28 21:11:01 +0000770 def stop(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000771 self.server.shutdown()
Bill Janssen296a59d2007-09-16 22:06:00 +0000772
773
Antoine Pitrou3945c862010-04-28 21:11:01 +0000774 def bad_cert_test(certfile):
775 """
776 Launch a server with CERT_REQUIRED, and check that trying to
777 connect to it with the given client certificate fails.
778 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000779 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000780 certreqs=ssl.CERT_REQUIRED,
781 cacerts=CERTFILE, chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100782 with server:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000783 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000784 s = ssl.wrap_socket(socket.socket(),
785 certfile=certfile,
786 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000787 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000788 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000789 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000790 sys.stdout.write("\nSSLError is %s\n" % x[1])
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000791 except socket.error, x:
792 if test_support.verbose:
793 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000794 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000795 raise AssertionError("Use of invalid cert should have failed!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000796
Antoine Pitrou3945c862010-04-28 21:11:01 +0000797 def server_params_test(certfile, protocol, certreqs, cacertsfile,
798 client_certfile, client_protocol=None, indata="FOO\n",
799 ciphers=None, chatty=True, connectionchatty=False,
800 wrap_accepting_socket=False):
801 """
802 Launch a server, connect a client to it and try various reads
803 and writes.
804 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000805 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000806 certreqs=certreqs,
807 ssl_version=protocol,
808 cacerts=cacertsfile,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000809 ciphers=ciphers,
Bill Janssen98d19da2007-09-10 21:51:02 +0000810 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000811 connectionchatty=connectionchatty,
812 wrap_accepting_socket=wrap_accepting_socket)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100813 with server:
814 # try to connect
815 if client_protocol is None:
816 client_protocol = protocol
Antoine Pitroudb187842010-04-27 10:32:58 +0000817 s = ssl.wrap_socket(socket.socket(),
818 certfile=client_certfile,
819 ca_certs=cacertsfile,
820 ciphers=ciphers,
821 cert_reqs=certreqs,
822 ssl_version=client_protocol)
823 s.connect((HOST, server.port))
824 for arg in [indata, bytearray(indata), memoryview(indata)]:
Bill Janssen98d19da2007-09-10 21:51:02 +0000825 if connectionchatty:
826 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +0000827 sys.stdout.write(
828 " client: sending %s...\n" % (repr(arg)))
829 s.write(arg)
830 outdata = s.read()
831 if connectionchatty:
832 if test_support.verbose:
833 sys.stdout.write(" client: read %s\n" % repr(outdata))
834 if outdata != indata.lower():
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000835 raise AssertionError(
Antoine Pitroudb187842010-04-27 10:32:58 +0000836 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
837 % (outdata[:min(len(outdata),20)], len(outdata),
838 indata[:min(len(indata),20)].lower(), len(indata)))
839 s.write("over\n")
840 if connectionchatty:
841 if test_support.verbose:
842 sys.stdout.write(" client: closing connection.\n")
843 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000844
Antoine Pitrou3945c862010-04-28 21:11:01 +0000845 def try_protocol_combo(server_protocol,
846 client_protocol,
847 expect_success,
848 certsreqs=None):
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000849 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000850 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +0000851 certtype = {
852 ssl.CERT_NONE: "CERT_NONE",
853 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
854 ssl.CERT_REQUIRED: "CERT_REQUIRED",
855 }[certsreqs]
Bill Janssen98d19da2007-09-10 21:51:02 +0000856 if test_support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000857 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +0000858 sys.stdout.write(formatstr %
859 (ssl.get_protocol_name(client_protocol),
860 ssl.get_protocol_name(server_protocol),
861 certtype))
862 try:
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000863 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
864 # will send an SSLv3 hello (rather than SSLv2) starting from
865 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou3945c862010-04-28 21:11:01 +0000866 server_params_test(CERTFILE, server_protocol, certsreqs,
867 CERTFILE, CERTFILE, client_protocol,
868 ciphers="ALL", chatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +0000869 # Protocol mismatch can result in either an SSLError, or a
870 # "Connection reset by peer" error.
871 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000872 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +0000873 raise
Antoine Pitroudb187842010-04-27 10:32:58 +0000874 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000875 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +0000876 raise
Bill Janssen98d19da2007-09-10 21:51:02 +0000877 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000878 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000879 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +0000880 "Client protocol %s succeeded with server protocol %s!"
881 % (ssl.get_protocol_name(client_protocol),
882 ssl.get_protocol_name(server_protocol)))
883
884
Bill Janssen934b16d2008-06-28 22:19:33 +0000885 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000886
Antoine Pitrou3945c862010-04-28 21:11:01 +0000887 def test_rude_shutdown(self):
888 """A brutal shutdown of an SSL server should raise an IOError
889 in the client when attempting handshake.
890 """
Bill Janssen98d19da2007-09-10 21:51:02 +0000891 listener_ready = threading.Event()
892 listener_gone = threading.Event()
893
Antoine Pitrou150acda2010-04-27 08:40:51 +0000894 s = socket.socket()
895 port = test_support.bind_port(s, HOST)
896
897 # `listener` runs in a thread. It sits in an accept() until
898 # the main thread connects. Then it rudely closes the socket,
899 # and sets Event `listener_gone` to let the main thread know
900 # the socket is gone.
Bill Janssen98d19da2007-09-10 21:51:02 +0000901 def listener():
Bill Janssen98d19da2007-09-10 21:51:02 +0000902 s.listen(5)
903 listener_ready.set()
904 s.accept()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000905 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000906 listener_gone.set()
907
908 def connector():
909 listener_ready.wait()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000910 c = socket.socket()
911 c.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000912 listener_gone.wait()
913 try:
Antoine Pitrou150acda2010-04-27 08:40:51 +0000914 ssl_sock = ssl.wrap_socket(c)
Bill Janssen934b16d2008-06-28 22:19:33 +0000915 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000916 pass
917 else:
Antoine Pitroudb187842010-04-27 10:32:58 +0000918 self.fail('connecting to closed SSL socket should have failed')
Bill Janssen98d19da2007-09-10 21:51:02 +0000919
920 t = threading.Thread(target=listener)
921 t.start()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000922 try:
923 connector()
924 finally:
925 t.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000926
Antoine Pitroud75efd92010-08-04 17:38:33 +0000927 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000928 def test_echo(self):
929 """Basic test of an SSL client connecting to a server"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000930 if test_support.verbose:
931 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000932 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
933 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
934 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000935
Antoine Pitrou3945c862010-04-28 21:11:01 +0000936 def test_getpeercert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000937 if test_support.verbose:
938 sys.stdout.write("\n")
939 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000940 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000941 certreqs=ssl.CERT_NONE,
942 ssl_version=ssl.PROTOCOL_SSLv23,
943 cacerts=CERTFILE,
944 chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100945 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +0000946 s = ssl.wrap_socket(socket.socket(),
947 certfile=CERTFILE,
948 ca_certs=CERTFILE,
949 cert_reqs=ssl.CERT_REQUIRED,
950 ssl_version=ssl.PROTOCOL_SSLv23)
951 s.connect((HOST, server.port))
952 cert = s.getpeercert()
953 self.assertTrue(cert, "Can't get peer certificate.")
954 cipher = s.cipher()
955 if test_support.verbose:
956 sys.stdout.write(pprint.pformat(cert) + '\n')
957 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
958 if 'subject' not in cert:
959 self.fail("No subject field in certificate: %s." %
960 pprint.pformat(cert))
961 if ((('organizationName', 'Python Software Foundation'),)
962 not in cert['subject']):
963 self.fail(
964 "Missing or invalid 'organizationName' field in certificate subject; "
965 "should be 'Python Software Foundation'.")
966 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000967
Antoine Pitrou3945c862010-04-28 21:11:01 +0000968 def test_empty_cert(self):
969 """Connecting with an empty cert file"""
970 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
971 "nullcert.pem"))
972 def test_malformed_cert(self):
973 """Connecting with a badly formatted certificate (syntax error)"""
974 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
975 "badcert.pem"))
976 def test_nonexisting_cert(self):
977 """Connecting with a non-existing cert file"""
978 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
979 "wrongcert.pem"))
980 def test_malformed_key(self):
981 """Connecting with a badly formatted key (syntax error)"""
982 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
983 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000984
Antoine Pitroud75efd92010-08-04 17:38:33 +0000985 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000986 def test_protocol_sslv2(self):
987 """Connecting to an SSLv2 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000988 if test_support.verbose:
989 sys.stdout.write("\n")
Antoine Pitrou6361ea22011-10-30 21:31:34 +0100990 if not hasattr(ssl, 'PROTOCOL_SSLv2'):
991 self.skipTest("PROTOCOL_SSLv2 needed")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000992 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
993 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
994 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
995 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
996 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
997 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000998
Antoine Pitroud75efd92010-08-04 17:38:33 +0000999 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001000 def test_protocol_sslv23(self):
1001 """Connecting to an SSLv23 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001002 if test_support.verbose:
1003 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001004 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1005 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1006 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Bill Janssen98d19da2007-09-10 21:51:02 +00001007
Antoine Pitrou3945c862010-04-28 21:11:01 +00001008 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1009 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1010 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +00001011
Antoine Pitrou3945c862010-04-28 21:11:01 +00001012 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1013 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1014 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00001015
Antoine Pitroud75efd92010-08-04 17:38:33 +00001016 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001017 def test_protocol_sslv3(self):
1018 """Connecting to an SSLv3 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001019 if test_support.verbose:
1020 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001021 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1022 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1023 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001024 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1025 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001026 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001027
Antoine Pitroud75efd92010-08-04 17:38:33 +00001028 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001029 def test_protocol_tlsv1(self):
1030 """Connecting to a TLSv1 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001031 if test_support.verbose:
1032 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001033 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1034 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1035 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001036 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1037 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001038 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001039
Antoine Pitrou3945c862010-04-28 21:11:01 +00001040 def test_starttls(self):
1041 """Switching from clear text to encrypted and back again."""
Bill Janssen39295c22008-08-12 16:31:21 +00001042 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +00001043
Trent Nelsone41b0062008-04-08 23:47:30 +00001044 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00001045 ssl_version=ssl.PROTOCOL_TLSv1,
1046 starttls_server=True,
1047 chatty=True,
1048 connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +00001049 wrapped = False
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001050 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001051 s = socket.socket()
1052 s.setblocking(1)
1053 s.connect((HOST, server.port))
1054 if test_support.verbose:
1055 sys.stdout.write("\n")
1056 for indata in msgs:
Bill Janssen98d19da2007-09-10 21:51:02 +00001057 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00001058 sys.stdout.write(
1059 " client: sending %s...\n" % repr(indata))
1060 if wrapped:
1061 conn.write(indata)
1062 outdata = conn.read()
1063 else:
1064 s.send(indata)
1065 outdata = s.recv(1024)
1066 if (indata == "STARTTLS" and
1067 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001068 # STARTTLS ok, switch to secure mode
Bill Janssen98d19da2007-09-10 21:51:02 +00001069 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00001070 sys.stdout.write(
Antoine Pitroudb187842010-04-27 10:32:58 +00001071 " client: read %s from server, starting TLS...\n"
1072 % repr(outdata))
1073 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1074 wrapped = True
1075 elif (indata == "ENDTLS" and
1076 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001077 # ENDTLS ok, switch back to clear text
Antoine Pitroudb187842010-04-27 10:32:58 +00001078 if test_support.verbose:
1079 sys.stdout.write(
1080 " client: read %s from server, ending TLS...\n"
1081 % repr(outdata))
1082 s = conn.unwrap()
1083 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00001084 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001085 if test_support.verbose:
1086 sys.stdout.write(
1087 " client: read %s from server\n" % repr(outdata))
1088 if test_support.verbose:
1089 sys.stdout.write(" client: closing connection.\n")
1090 if wrapped:
1091 conn.write("over\n")
1092 else:
1093 s.send("over\n")
1094 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001095
Antoine Pitrou3945c862010-04-28 21:11:01 +00001096 def test_socketserver(self):
1097 """Using a SocketServer to create and manage SSL connections."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001098 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +00001099 flag = threading.Event()
1100 server.start(flag)
1101 # wait for it to start
1102 flag.wait()
1103 # try to connect
1104 try:
1105 if test_support.verbose:
1106 sys.stdout.write('\n')
Antoine Pitrou3945c862010-04-28 21:11:01 +00001107 with open(CERTFILE, 'rb') as f:
1108 d1 = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +00001109 d2 = ''
1110 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +00001111 url = 'https://127.0.0.1:%d/%s' % (
1112 server.port, os.path.split(CERTFILE)[1])
Florent Xicluna07627882010-03-21 01:14:24 +00001113 with test_support.check_py3k_warnings():
1114 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +00001115 dlen = f.info().getheader("content-length")
1116 if dlen and (int(dlen) > 0):
1117 d2 = f.read(int(dlen))
1118 if test_support.verbose:
1119 sys.stdout.write(
1120 " client: read %d bytes from remote server '%s'\n"
1121 % (len(d2), server))
1122 f.close()
Antoine Pitroudb187842010-04-27 10:32:58 +00001123 self.assertEqual(d1, d2)
Bill Janssen296a59d2007-09-16 22:06:00 +00001124 finally:
1125 server.stop()
1126 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001127
Antoine Pitrou3945c862010-04-28 21:11:01 +00001128 def test_wrapped_accept(self):
1129 """Check the accept() method on SSL sockets."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001130 if test_support.verbose:
1131 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001132 server_params_test(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1133 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1134 chatty=True, connectionchatty=True,
1135 wrap_accepting_socket=True)
Bill Janssen934b16d2008-06-28 22:19:33 +00001136
Antoine Pitrou3945c862010-04-28 21:11:01 +00001137 def test_asyncore_server(self):
1138 """Check the example asyncore integration."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001139 indata = "TEST MESSAGE of mixed case\n"
1140
1141 if test_support.verbose:
1142 sys.stdout.write("\n")
1143 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001144 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001145 s = ssl.wrap_socket(socket.socket())
1146 s.connect(('127.0.0.1', server.port))
1147 if test_support.verbose:
1148 sys.stdout.write(
1149 " client: sending %s...\n" % (repr(indata)))
1150 s.write(indata)
1151 outdata = s.read()
1152 if test_support.verbose:
1153 sys.stdout.write(" client: read %s\n" % repr(outdata))
1154 if outdata != indata.lower():
1155 self.fail(
1156 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1157 % (outdata[:min(len(outdata),20)], len(outdata),
1158 indata[:min(len(indata),20)].lower(), len(indata)))
1159 s.write("over\n")
1160 if test_support.verbose:
1161 sys.stdout.write(" client: closing connection.\n")
1162 s.close()
Bill Janssen934b16d2008-06-28 22:19:33 +00001163
Antoine Pitrou3945c862010-04-28 21:11:01 +00001164 def test_recv_send(self):
1165 """Test recv(), send() and friends."""
Bill Janssen61c001a2008-09-08 16:37:24 +00001166 if test_support.verbose:
1167 sys.stdout.write("\n")
1168
1169 server = ThreadedEchoServer(CERTFILE,
1170 certreqs=ssl.CERT_NONE,
1171 ssl_version=ssl.PROTOCOL_TLSv1,
1172 cacerts=CERTFILE,
1173 chatty=True,
1174 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001175 with server:
1176 s = ssl.wrap_socket(socket.socket(),
1177 server_side=False,
1178 certfile=CERTFILE,
1179 ca_certs=CERTFILE,
1180 cert_reqs=ssl.CERT_NONE,
1181 ssl_version=ssl.PROTOCOL_TLSv1)
1182 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00001183 # helper methods for standardising recv* method signatures
1184 def _recv_into():
1185 b = bytearray("\0"*100)
1186 count = s.recv_into(b)
1187 return b[:count]
1188
1189 def _recvfrom_into():
1190 b = bytearray("\0"*100)
1191 count, addr = s.recvfrom_into(b)
1192 return b[:count]
1193
1194 # (name, method, whether to expect success, *args)
1195 send_methods = [
1196 ('send', s.send, True, []),
1197 ('sendto', s.sendto, False, ["some.address"]),
1198 ('sendall', s.sendall, True, []),
1199 ]
1200 recv_methods = [
1201 ('recv', s.recv, True, []),
1202 ('recvfrom', s.recvfrom, False, ["some.address"]),
1203 ('recv_into', _recv_into, True, []),
1204 ('recvfrom_into', _recvfrom_into, False, []),
1205 ]
1206 data_prefix = u"PREFIX_"
1207
1208 for meth_name, send_meth, expect_success, args in send_methods:
1209 indata = data_prefix + meth_name
1210 try:
1211 send_meth(indata.encode('ASCII', 'strict'), *args)
1212 outdata = s.read()
1213 outdata = outdata.decode('ASCII', 'strict')
1214 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001215 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001216 "While sending with <<%s>> bad data "
1217 "<<%r>> (%d) received; "
1218 "expected <<%r>> (%d)\n" % (
1219 meth_name, outdata[:20], len(outdata),
1220 indata[:20], len(indata)
1221 )
1222 )
1223 except ValueError as e:
1224 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001225 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001226 "Failed to send with method <<%s>>; "
1227 "expected to succeed.\n" % (meth_name,)
1228 )
1229 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001230 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001231 "Method <<%s>> failed with unexpected "
1232 "exception message: %s\n" % (
1233 meth_name, e
1234 )
1235 )
1236
1237 for meth_name, recv_meth, expect_success, args in recv_methods:
1238 indata = data_prefix + meth_name
1239 try:
1240 s.send(indata.encode('ASCII', 'strict'))
1241 outdata = recv_meth(*args)
1242 outdata = outdata.decode('ASCII', 'strict')
1243 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001244 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001245 "While receiving with <<%s>> bad data "
1246 "<<%r>> (%d) received; "
1247 "expected <<%r>> (%d)\n" % (
1248 meth_name, outdata[:20], len(outdata),
1249 indata[:20], len(indata)
1250 )
1251 )
1252 except ValueError as e:
1253 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001254 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001255 "Failed to receive with method <<%s>>; "
1256 "expected to succeed.\n" % (meth_name,)
1257 )
1258 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001259 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001260 "Method <<%s>> failed with unexpected "
1261 "exception message: %s\n" % (
1262 meth_name, e
1263 )
1264 )
1265 # consume data
1266 s.read()
1267
1268 s.write("over\n".encode("ASCII", "strict"))
1269 s.close()
Bill Janssen61c001a2008-09-08 16:37:24 +00001270
Antoine Pitroufc69af12010-04-24 20:04:58 +00001271 def test_handshake_timeout(self):
1272 # Issue #5103: SSL handshake must respect the socket timeout
1273 server = socket.socket(socket.AF_INET)
1274 host = "127.0.0.1"
1275 port = test_support.bind_port(server)
1276 started = threading.Event()
1277 finish = False
1278
1279 def serve():
1280 server.listen(5)
1281 started.set()
1282 conns = []
1283 while not finish:
1284 r, w, e = select.select([server], [], [], 0.1)
1285 if server in r:
1286 # Let the socket hang around rather than having
1287 # it closed by garbage collection.
1288 conns.append(server.accept()[0])
1289
1290 t = threading.Thread(target=serve)
1291 t.start()
1292 started.wait()
1293
1294 try:
1295 try:
1296 c = socket.socket(socket.AF_INET)
1297 c.settimeout(0.2)
1298 c.connect((host, port))
1299 # Will attempt handshake and time out
1300 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1301 ssl.wrap_socket, c)
1302 finally:
1303 c.close()
1304 try:
1305 c = socket.socket(socket.AF_INET)
1306 c.settimeout(0.2)
1307 c = ssl.wrap_socket(c)
1308 # Will attempt handshake and time out
1309 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1310 c.connect, (host, port))
1311 finally:
1312 c.close()
1313 finally:
1314 finish = True
1315 t.join()
1316 server.close()
1317
Antoine Pitroud76088d2012-01-03 22:46:48 +01001318 def test_default_ciphers(self):
1319 with ThreadedEchoServer(CERTFILE,
1320 ssl_version=ssl.PROTOCOL_SSLv23,
1321 chatty=False) as server:
1322 sock = socket.socket()
1323 try:
1324 # Force a set of weak ciphers on our client socket
1325 try:
1326 s = ssl.wrap_socket(sock,
1327 ssl_version=ssl.PROTOCOL_SSLv23,
1328 ciphers="DES")
1329 except ssl.SSLError:
1330 self.skipTest("no DES cipher available")
1331 with self.assertRaises((OSError, ssl.SSLError)):
1332 s.connect((HOST, server.port))
1333 finally:
1334 sock.close()
1335 self.assertIn("no shared cipher", str(server.conn_errors[0]))
1336
Bill Janssen61c001a2008-09-08 16:37:24 +00001337
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001338def test_main(verbose=False):
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001339 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, NOKIACERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001340 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001341 "keycert.pem")
1342 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1343 os.path.dirname(__file__) or os.curdir,
1344 "https_svn_python_org_root.pem")
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001345 NOKIACERT = os.path.join(os.path.dirname(__file__) or os.curdir,
1346 "nokia.pem")
Bill Janssen296a59d2007-09-16 22:06:00 +00001347
1348 if (not os.path.exists(CERTFILE) or
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001349 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT) or
1350 not os.path.exists(NOKIACERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001351 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001352
Antoine Pitroude30f702010-09-14 12:54:08 +00001353 tests = [BasicTests, BasicSocketTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001354
Bill Janssen296a59d2007-09-16 22:06:00 +00001355 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001356 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001357
Bill Janssen98d19da2007-09-10 21:51:02 +00001358 if _have_threads:
1359 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001360 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001361 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001362
Antoine Pitrou3945c862010-04-28 21:11:01 +00001363 try:
1364 test_support.run_unittest(*tests)
1365 finally:
1366 if _have_threads:
1367 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001368
1369if __name__ == "__main__":
1370 test_main()