blob: be2f51acaf62621e719548198ab80b9dc77742f7 [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
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000023# Optionally test SSL support, if we have it in the tested platform
24skip_expected = False
25try:
26 import ssl
27except ImportError:
28 skip_expected = True
29
Trent Nelsone41b0062008-04-08 23:47:30 +000030HOST = test_support.HOST
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000031CERTFILE = None
Bill Janssen296a59d2007-09-16 22:06:00 +000032SVN_PYTHON_ORG_ROOT_CERT = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000033
Neal Norwitz3e533c22007-08-27 01:03:18 +000034def handle_error(prefix):
35 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Bill Janssen98d19da2007-09-10 21:51:02 +000036 if test_support.verbose:
37 sys.stdout.write(prefix + exc_format)
Neal Norwitz3e533c22007-08-27 01:03:18 +000038
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000039
40class BasicTests(unittest.TestCase):
41
Antoine Pitrou3945c862010-04-28 21:11:01 +000042 def test_sslwrap_simple(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000043 # A crude test for the legacy API
Bill Jansseneb257ac2008-09-29 18:56:38 +000044 try:
45 ssl.sslwrap_simple(socket.socket(socket.AF_INET))
46 except IOError, e:
47 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
48 pass
49 else:
50 raise
51 try:
52 ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
53 except IOError, e:
54 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
55 pass
56 else:
57 raise
Neal Norwitz3e533c22007-08-27 01:03:18 +000058
Antoine Pitroud75efd92010-08-04 17:38:33 +000059# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
60def skip_if_broken_ubuntu_ssl(func):
Victor Stinnerb1241f92011-05-10 01:52:03 +020061 if hasattr(ssl, 'PROTOCOL_SSLv2'):
62 # We need to access the lower-level wrapper in order to create an
63 # implicit SSL context without trying to connect or listen.
Antoine Pitroud75efd92010-08-04 17:38:33 +000064 try:
Victor Stinnerb1241f92011-05-10 01:52:03 +020065 import _ssl
66 except ImportError:
67 # The returned function won't get executed, just ignore the error
68 pass
69 @functools.wraps(func)
70 def f(*args, **kwargs):
71 try:
72 s = socket.socket(socket.AF_INET)
73 _ssl.sslwrap(s._sock, 0, None, None,
74 ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
75 except ssl.SSLError as e:
76 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
77 platform.linux_distribution() == ('debian', 'squeeze/sid', '')
78 and 'Invalid SSL protocol variant specified' in str(e)):
79 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
80 return func(*args, **kwargs)
81 return f
82 else:
83 return func
Antoine Pitroud75efd92010-08-04 17:38:33 +000084
85
86class BasicSocketTests(unittest.TestCase):
87
Antoine Pitrou3945c862010-04-28 21:11:01 +000088 def test_constants(self):
Victor Stinnerb1241f92011-05-10 01:52:03 +020089 #ssl.PROTOCOL_SSLv2
Bill Janssen98d19da2007-09-10 21:51:02 +000090 ssl.PROTOCOL_SSLv23
91 ssl.PROTOCOL_SSLv3
92 ssl.PROTOCOL_TLSv1
93 ssl.CERT_NONE
94 ssl.CERT_OPTIONAL
95 ssl.CERT_REQUIRED
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000096
Antoine Pitrou3945c862010-04-28 21:11:01 +000097 def test_random(self):
Bill Janssen98d19da2007-09-10 21:51:02 +000098 v = ssl.RAND_status()
99 if test_support.verbose:
100 sys.stdout.write("\n RAND_status is %d (%s)\n"
101 % (v, (v and "sufficient randomness") or
102 "insufficient randomness"))
Guido van Rossume4729332007-08-26 19:35:09 +0000103 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000104 ssl.RAND_egd(1)
105 except TypeError:
106 pass
Guido van Rossume4729332007-08-26 19:35:09 +0000107 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000108 print "didn't raise TypeError"
109 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000110
Antoine Pitrou3945c862010-04-28 21:11:01 +0000111 def test_parse_cert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000112 # note that this uses an 'unofficial' function in _ssl.c,
113 # provided solely for this test, to exercise the certificate
114 # parsing code
115 p = ssl._ssl._test_decode_cert(CERTFILE, False)
116 if test_support.verbose:
117 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000118
Antoine Pitrou3945c862010-04-28 21:11:01 +0000119 def test_DER_to_PEM(self):
120 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
121 pem = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000122 d1 = ssl.PEM_cert_to_DER_cert(pem)
123 p2 = ssl.DER_cert_to_PEM_cert(d1)
124 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitroudb187842010-04-27 10:32:58 +0000125 self.assertEqual(d1, d2)
Antoine Pitrou4c7bcf12010-04-27 22:03:37 +0000126 if not p2.startswith(ssl.PEM_HEADER + '\n'):
127 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
128 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
129 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Bill Janssen296a59d2007-09-16 22:06:00 +0000130
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000131 def test_openssl_version(self):
132 n = ssl.OPENSSL_VERSION_NUMBER
133 t = ssl.OPENSSL_VERSION_INFO
134 s = ssl.OPENSSL_VERSION
135 self.assertIsInstance(n, (int, long))
136 self.assertIsInstance(t, tuple)
137 self.assertIsInstance(s, str)
138 # Some sanity checks follow
139 # >= 0.9
140 self.assertGreaterEqual(n, 0x900000)
141 # < 2.0
142 self.assertLess(n, 0x20000000)
143 major, minor, fix, patch, status = t
144 self.assertGreaterEqual(major, 0)
145 self.assertLess(major, 2)
146 self.assertGreaterEqual(minor, 0)
147 self.assertLess(minor, 256)
148 self.assertGreaterEqual(fix, 0)
149 self.assertLess(fix, 256)
150 self.assertGreaterEqual(patch, 0)
151 self.assertLessEqual(patch, 26)
152 self.assertGreaterEqual(status, 0)
153 self.assertLessEqual(status, 15)
154 # Version string as returned by OpenSSL, the format might change
155 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
156 (s, t))
157
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000158 def test_ciphers(self):
159 if not test_support.is_resource_enabled('network'):
160 return
161 remote = ("svn.python.org", 443)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000162 with test_support.transient_internet(remote[0]):
163 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
164 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000165 s.connect(remote)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000166 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
167 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
168 s.connect(remote)
169 # Error checking occurs when connecting, because the SSL context
170 # isn't created before.
171 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
172 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
173 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
174 s.connect(remote)
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000175
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000176 @test_support.cpython_only
177 def test_refcycle(self):
178 # Issue #7943: an SSL object doesn't create reference cycles with
179 # itself.
180 s = socket.socket(socket.AF_INET)
181 ss = ssl.wrap_socket(s)
182 wr = weakref.ref(ss)
183 del ss
184 self.assertEqual(wr(), None)
185
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000186 def test_wrapped_unconnected(self):
187 # The _delegate_methods in socket.py are correctly delegated to by an
188 # unconnected SSLSocket, so they will raise a socket.error rather than
189 # something unexpected like TypeError.
190 s = socket.socket(socket.AF_INET)
191 ss = ssl.wrap_socket(s)
192 self.assertRaises(socket.error, ss.recv, 1)
193 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
194 self.assertRaises(socket.error, ss.recvfrom, 1)
195 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
196 self.assertRaises(socket.error, ss.send, b'x')
197 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
198
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000199
Bill Janssen934b16d2008-06-28 22:19:33 +0000200class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +0000201
Antoine Pitrou3945c862010-04-28 21:11:01 +0000202 def test_connect(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000203 with test_support.transient_internet("svn.python.org"):
204 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
205 cert_reqs=ssl.CERT_NONE)
Bill Janssen296a59d2007-09-16 22:06:00 +0000206 s.connect(("svn.python.org", 443))
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000207 c = s.getpeercert()
208 if c:
209 self.fail("Peer cert %s shouldn't be here!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000210 s.close()
211
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000212 # this should fail because we have no verification certs
213 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
214 cert_reqs=ssl.CERT_REQUIRED)
215 try:
216 s.connect(("svn.python.org", 443))
217 except ssl.SSLError:
218 pass
219 finally:
220 s.close()
221
222 # this should succeed because we specify the root cert
223 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
224 cert_reqs=ssl.CERT_REQUIRED,
225 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
226 try:
227 s.connect(("svn.python.org", 443))
228 finally:
229 s.close()
Bill Janssen296a59d2007-09-16 22:06:00 +0000230
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000231 def test_connect_ex(self):
232 # Issue #11326: check connect_ex() implementation
233 with test_support.transient_internet("svn.python.org"):
234 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
235 cert_reqs=ssl.CERT_REQUIRED,
236 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
237 try:
238 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
239 self.assertTrue(s.getpeercert())
240 finally:
241 s.close()
242
243 def test_non_blocking_connect_ex(self):
244 # Issue #11326: non-blocking connect_ex() should allow handshake
245 # to proceed after the socket gets ready.
246 with test_support.transient_internet("svn.python.org"):
247 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
248 cert_reqs=ssl.CERT_REQUIRED,
249 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
250 do_handshake_on_connect=False)
251 try:
252 s.setblocking(False)
253 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitrou8ef39072011-02-27 15:45:22 +0000254 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
255 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000256 # Wait for connect to finish
257 select.select([], [s], [], 5.0)
258 # Non-blocking handshake
259 while True:
260 try:
261 s.do_handshake()
262 break
263 except ssl.SSLError as err:
264 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
265 select.select([s], [], [], 5.0)
266 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
267 select.select([], [s], [], 5.0)
268 else:
269 raise
270 # SSL established
271 self.assertTrue(s.getpeercert())
272 finally:
273 s.close()
274
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000275 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
276 def test_makefile_close(self):
277 # Issue #5238: creating a file-like object with makefile() shouldn't
278 # delay closing the underlying "real socket" (here tested with its
279 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000280 with test_support.transient_internet("svn.python.org"):
281 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
282 ss.connect(("svn.python.org", 443))
283 fd = ss.fileno()
284 f = ss.makefile()
285 f.close()
286 # The fd is still open
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000287 os.read(fd, 0)
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000288 # Closing the SSL socket should close the fd too
289 ss.close()
290 gc.collect()
291 with self.assertRaises(OSError) as e:
292 os.read(fd, 0)
293 self.assertEqual(e.exception.errno, errno.EBADF)
Bill Janssen934b16d2008-06-28 22:19:33 +0000294
Antoine Pitrou3945c862010-04-28 21:11:01 +0000295 def test_non_blocking_handshake(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000296 with test_support.transient_internet("svn.python.org"):
297 s = socket.socket(socket.AF_INET)
298 s.connect(("svn.python.org", 443))
299 s.setblocking(False)
300 s = ssl.wrap_socket(s,
301 cert_reqs=ssl.CERT_NONE,
302 do_handshake_on_connect=False)
303 count = 0
304 while True:
305 try:
306 count += 1
307 s.do_handshake()
308 break
309 except ssl.SSLError, err:
310 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
311 select.select([s], [], [])
312 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
313 select.select([], [s], [])
314 else:
315 raise
316 s.close()
317 if test_support.verbose:
318 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Bill Janssen934b16d2008-06-28 22:19:33 +0000319
Antoine Pitrou3945c862010-04-28 21:11:01 +0000320 def test_get_server_certificate(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000321 with test_support.transient_internet("svn.python.org"):
322 pem = ssl.get_server_certificate(("svn.python.org", 443))
323 if not pem:
324 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000325
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000326 try:
327 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
328 except ssl.SSLError:
329 #should fail
330 pass
331 else:
332 self.fail("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000333
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000334 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
335 if not pem:
336 self.fail("No server certificate on svn.python.org:443!")
337 if test_support.verbose:
338 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000339
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000340 def test_algorithms(self):
341 # Issue #8484: all algorithms should be available when verifying a
342 # certificate.
Antoine Pitrou9aed6042010-04-22 18:00:41 +0000343 # SHA256 was added in OpenSSL 0.9.8
344 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
345 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000346 # NOTE: https://sha256.tbs-internet.com is another possible test host
Antoine Pitroud43245a2011-01-08 10:32:51 +0000347 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000348 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitroud43245a2011-01-08 10:32:51 +0000349 with test_support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrouc818ed42010-09-07 21:40:25 +0000350 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
351 cert_reqs=ssl.CERT_REQUIRED,
352 ca_certs=sha256_cert,)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000353 try:
354 s.connect(remote)
355 if test_support.verbose:
356 sys.stdout.write("\nCipher with %r is %r\n" %
357 (remote, s.cipher()))
358 sys.stdout.write("Certificate is:\n%s\n" %
359 pprint.pformat(s.getpeercert()))
360 finally:
361 s.close()
362
Bill Janssen296a59d2007-09-16 22:06:00 +0000363
Bill Janssen98d19da2007-09-10 21:51:02 +0000364try:
365 import threading
366except ImportError:
367 _have_threads = False
368else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000369 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000370
Bill Janssen98d19da2007-09-10 21:51:02 +0000371 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000372
Bill Janssen98d19da2007-09-10 21:51:02 +0000373 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000374
Bill Janssen98d19da2007-09-10 21:51:02 +0000375 """A mildly complicated class, because we want it to work both
376 with and without the SSL wrapper around the socket connection, so
377 that we can test the STARTTLS functionality."""
378
379 def __init__(self, server, connsock):
380 self.server = server
381 self.running = False
382 self.sock = connsock
383 self.sock.setblocking(1)
384 self.sslconn = None
385 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000386 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000387
Bill Janssen934b16d2008-06-28 22:19:33 +0000388 def show_conn_details(self):
389 if self.server.certreqs == ssl.CERT_REQUIRED:
390 cert = self.sslconn.getpeercert()
391 if test_support.verbose and self.server.chatty:
392 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
393 cert_binary = self.sslconn.getpeercert(True)
394 if test_support.verbose and self.server.chatty:
395 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
396 cipher = self.sslconn.cipher()
397 if test_support.verbose and self.server.chatty:
398 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
399
Antoine Pitrou3945c862010-04-28 21:11:01 +0000400 def wrap_conn(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000401 try:
402 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
403 certfile=self.server.certificate,
404 ssl_version=self.server.protocol,
405 ca_certs=self.server.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000406 cert_reqs=self.server.certreqs,
407 ciphers=self.server.ciphers)
Antoine Pitroudb187842010-04-27 10:32:58 +0000408 except ssl.SSLError:
409 # XXX Various errors can have happened here, for example
410 # a mismatching protocol version, an invalid certificate,
411 # or a low-level bug. This should be made more discriminating.
Bill Janssen98d19da2007-09-10 21:51:02 +0000412 if self.server.chatty:
413 handle_error("\n server: bad connection attempt from " +
414 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000415 self.close()
Antoine Pitroudb187842010-04-27 10:32:58 +0000416 self.running = False
417 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000418 return False
Bill Janssen98d19da2007-09-10 21:51:02 +0000419 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000420 return True
421
422 def read(self):
423 if self.sslconn:
424 return self.sslconn.read()
425 else:
426 return self.sock.recv(1024)
427
428 def write(self, bytes):
429 if self.sslconn:
430 return self.sslconn.write(bytes)
431 else:
432 return self.sock.send(bytes)
433
434 def close(self):
435 if self.sslconn:
436 self.sslconn.close()
437 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000438 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000439
Antoine Pitrou3945c862010-04-28 21:11:01 +0000440 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000441 self.running = True
442 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000443 if isinstance(self.sock, ssl.SSLSocket):
444 self.sslconn = self.sock
445 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000446 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000447 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000448 while self.running:
449 try:
450 msg = self.read()
451 if not msg:
452 # eof, so quit this handler
453 self.running = False
454 self.close()
455 elif msg.strip() == 'over':
456 if test_support.verbose and self.server.connectionchatty:
457 sys.stdout.write(" server: client closed connection\n")
458 self.close()
459 return
460 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
461 if test_support.verbose and self.server.connectionchatty:
462 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
463 self.write("OK\n")
464 if not self.wrap_conn():
465 return
Bill Janssen39295c22008-08-12 16:31:21 +0000466 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
467 if test_support.verbose and self.server.connectionchatty:
468 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
469 self.write("OK\n")
470 self.sslconn.unwrap()
471 self.sslconn = None
472 if test_support.verbose and self.server.connectionchatty:
473 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000474 else:
475 if (test_support.verbose and
476 self.server.connectionchatty):
477 ctype = (self.sslconn and "encrypted") or "unencrypted"
478 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
479 % (repr(msg), ctype, repr(msg.lower()), ctype))
480 self.write(msg.lower())
481 except ssl.SSLError:
482 if self.server.chatty:
483 handle_error("Test server failure:\n")
484 self.close()
485 self.running = False
486 # normally, we'd just stop here, but for the test
487 # harness, we want to stop the server
488 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000489
Trent Nelsone41b0062008-04-08 23:47:30 +0000490 def __init__(self, certificate, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +0000491 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000492 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000493 wrap_accepting_socket=False, ciphers=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000494
Bill Janssen98d19da2007-09-10 21:51:02 +0000495 if ssl_version is None:
496 ssl_version = ssl.PROTOCOL_TLSv1
497 if certreqs is None:
498 certreqs = ssl.CERT_NONE
499 self.certificate = certificate
500 self.protocol = ssl_version
501 self.certreqs = certreqs
502 self.cacerts = cacerts
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000503 self.ciphers = ciphers
Bill Janssen98d19da2007-09-10 21:51:02 +0000504 self.chatty = chatty
505 self.connectionchatty = connectionchatty
506 self.starttls_server = starttls_server
507 self.sock = socket.socket()
508 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000509 if wrap_accepting_socket:
510 self.sock = ssl.wrap_socket(self.sock, server_side=True,
511 certfile=self.certificate,
512 cert_reqs = self.certreqs,
513 ca_certs = self.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000514 ssl_version = self.protocol,
515 ciphers = self.ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000516 if test_support.verbose and self.chatty:
517 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
518 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000519 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000520 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000521 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000522
Antoine Pitrou3945c862010-04-28 21:11:01 +0000523 def start(self, flag=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000524 self.flag = flag
525 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000526
Antoine Pitrou3945c862010-04-28 21:11:01 +0000527 def run(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000528 self.sock.settimeout(0.05)
Bill Janssen98d19da2007-09-10 21:51:02 +0000529 self.sock.listen(5)
530 self.active = True
531 if self.flag:
532 # signal an event
533 self.flag.set()
534 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000535 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000536 newconn, connaddr = self.sock.accept()
537 if test_support.verbose and self.chatty:
538 sys.stdout.write(' server: new connection from '
539 + str(connaddr) + '\n')
540 handler = self.ConnectionHandler(self, newconn)
541 handler.start()
542 except socket.timeout:
543 pass
544 except KeyboardInterrupt:
545 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +0000546 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000547
Antoine Pitrou3945c862010-04-28 21:11:01 +0000548 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000549 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000550
Bill Janssen934b16d2008-06-28 22:19:33 +0000551 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000552
Antoine Pitrou3945c862010-04-28 21:11:01 +0000553 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +0000554
Antoine Pitrou3945c862010-04-28 21:11:01 +0000555 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +0000556
557 def __init__(self, conn, certfile):
558 asyncore.dispatcher_with_send.__init__(self, conn)
559 self.socket = ssl.wrap_socket(conn, server_side=True,
560 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +0000561 do_handshake_on_connect=False)
562 self._ssl_accepting = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000563
564 def readable(self):
565 if isinstance(self.socket, ssl.SSLSocket):
566 while self.socket.pending() > 0:
567 self.handle_read_event()
568 return True
569
Antoine Pitroufc69af12010-04-24 20:04:58 +0000570 def _do_ssl_handshake(self):
571 try:
572 self.socket.do_handshake()
573 except ssl.SSLError, err:
574 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
575 ssl.SSL_ERROR_WANT_WRITE):
576 return
577 elif err.args[0] == ssl.SSL_ERROR_EOF:
578 return self.handle_close()
579 raise
580 except socket.error, err:
581 if err.args[0] == errno.ECONNABORTED:
582 return self.handle_close()
583 else:
584 self._ssl_accepting = False
585
Bill Janssen934b16d2008-06-28 22:19:33 +0000586 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +0000587 if self._ssl_accepting:
588 self._do_ssl_handshake()
589 else:
590 data = self.recv(1024)
Antoine Pitroudb187842010-04-27 10:32:58 +0000591 if data and data.strip() != 'over':
592 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +0000593
594 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000595 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000596 if test_support.verbose:
597 sys.stdout.write(" server: closed connection %s\n" % self.socket)
598
599 def handle_error(self):
600 raise
601
602 def __init__(self, certfile):
603 self.certfile = certfile
604 asyncore.dispatcher.__init__(self)
605 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
606 self.port = test_support.bind_port(self.socket)
607 self.listen(5)
608
609 def handle_accept(self):
610 sock_obj, addr = self.accept()
611 if test_support.verbose:
612 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
613 self.ConnectionHandler(sock_obj, self.certfile)
614
615 def handle_error(self):
616 raise
617
618 def __init__(self, certfile):
619 self.flag = None
620 self.active = False
621 self.server = self.EchoServer(certfile)
622 self.port = self.server.port
623 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000624 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000625
626 def __str__(self):
627 return "<%s %s>" % (self.__class__.__name__, self.server)
628
Antoine Pitrou3945c862010-04-28 21:11:01 +0000629 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000630 self.flag = flag
631 threading.Thread.start(self)
632
Antoine Pitrou3945c862010-04-28 21:11:01 +0000633 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000634 self.active = True
635 if self.flag:
636 self.flag.set()
637 while self.active:
Antoine Pitroudb187842010-04-27 10:32:58 +0000638 asyncore.loop(0.05)
Bill Janssen934b16d2008-06-28 22:19:33 +0000639
Antoine Pitrou3945c862010-04-28 21:11:01 +0000640 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000641 self.active = False
642 self.server.close()
643
644 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000645
646 class HTTPSServer(HTTPServer):
647
648 def __init__(self, server_address, RequestHandlerClass, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000649 HTTPServer.__init__(self, server_address, RequestHandlerClass)
650 # we assume the certfile contains both private key and certificate
651 self.certfile = certfile
Bill Janssen296a59d2007-09-16 22:06:00 +0000652 self.allow_reuse_address = True
653
Bill Janssen934b16d2008-06-28 22:19:33 +0000654 def __str__(self):
655 return ('<%s %s:%s>' %
656 (self.__class__.__name__,
657 self.server_name,
658 self.server_port))
659
Antoine Pitrou3945c862010-04-28 21:11:01 +0000660 def get_request(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000661 # override this to wrap socket with SSL
662 sock, addr = self.socket.accept()
663 sslconn = ssl.wrap_socket(sock, server_side=True,
664 certfile=self.certfile)
665 return sslconn, addr
666
Bill Janssen296a59d2007-09-16 22:06:00 +0000667 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Bill Janssen296a59d2007-09-16 22:06:00 +0000668 # need to override translate_path to get a known root,
669 # instead of using os.curdir, since the test could be
670 # run from anywhere
671
672 server_version = "TestHTTPS/1.0"
673
674 root = None
675
676 def translate_path(self, path):
677 """Translate a /-separated PATH to the local filename syntax.
678
679 Components that mean special things to the local file system
680 (e.g. drive or directory names) are ignored. (XXX They should
681 probably be diagnosed.)
682
683 """
684 # abandon query parameters
685 path = urlparse.urlparse(path)[2]
686 path = os.path.normpath(urllib.unquote(path))
687 words = path.split('/')
688 words = filter(None, words)
689 path = self.root
690 for word in words:
691 drive, word = os.path.splitdrive(word)
692 head, word = os.path.split(word)
693 if word in self.root: continue
694 path = os.path.join(path, word)
695 return path
696
697 def log_message(self, format, *args):
698
699 # we override this to suppress logging unless "verbose"
700
701 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000702 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
703 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000704 self.server.server_port,
705 self.request.cipher(),
706 self.log_date_time_string(),
707 format%args))
708
709
Trent Nelsone41b0062008-04-08 23:47:30 +0000710 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000711 self.flag = None
Bill Janssen296a59d2007-09-16 22:06:00 +0000712 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
713 self.server = self.HTTPSServer(
Antoine Pitrou150acda2010-04-27 08:40:51 +0000714 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
715 self.port = self.server.server_port
Bill Janssen296a59d2007-09-16 22:06:00 +0000716 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000717 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000718
719 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000720 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000721
Antoine Pitrou3945c862010-04-28 21:11:01 +0000722 def start(self, flag=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000723 self.flag = flag
724 threading.Thread.start(self)
725
Antoine Pitrou3945c862010-04-28 21:11:01 +0000726 def run(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000727 if self.flag:
728 self.flag.set()
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000729 self.server.serve_forever(0.05)
Bill Janssen296a59d2007-09-16 22:06:00 +0000730
Antoine Pitrou3945c862010-04-28 21:11:01 +0000731 def stop(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000732 self.server.shutdown()
Bill Janssen296a59d2007-09-16 22:06:00 +0000733
734
Antoine Pitrou3945c862010-04-28 21:11:01 +0000735 def bad_cert_test(certfile):
736 """
737 Launch a server with CERT_REQUIRED, and check that trying to
738 connect to it with the given client certificate fails.
739 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000740 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000741 certreqs=ssl.CERT_REQUIRED,
742 cacerts=CERTFILE, chatty=False)
743 flag = threading.Event()
744 server.start(flag)
745 # wait for it to start
746 flag.wait()
747 # try to connect
748 try:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000749 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000750 s = ssl.wrap_socket(socket.socket(),
751 certfile=certfile,
752 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000753 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000754 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000755 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000756 sys.stdout.write("\nSSLError is %s\n" % x[1])
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000757 except socket.error, x:
758 if test_support.verbose:
759 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000760 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000761 raise AssertionError("Use of invalid cert should have failed!")
Bill Janssen98d19da2007-09-10 21:51:02 +0000762 finally:
763 server.stop()
764 server.join()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000765
Antoine Pitrou3945c862010-04-28 21:11:01 +0000766 def server_params_test(certfile, protocol, certreqs, cacertsfile,
767 client_certfile, client_protocol=None, indata="FOO\n",
768 ciphers=None, chatty=True, connectionchatty=False,
769 wrap_accepting_socket=False):
770 """
771 Launch a server, connect a client to it and try various reads
772 and writes.
773 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000774 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000775 certreqs=certreqs,
776 ssl_version=protocol,
777 cacerts=cacertsfile,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000778 ciphers=ciphers,
Bill Janssen98d19da2007-09-10 21:51:02 +0000779 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000780 connectionchatty=connectionchatty,
781 wrap_accepting_socket=wrap_accepting_socket)
Bill Janssen98d19da2007-09-10 21:51:02 +0000782 flag = threading.Event()
783 server.start(flag)
784 # wait for it to start
785 flag.wait()
786 # try to connect
787 if client_protocol is None:
788 client_protocol = protocol
789 try:
Antoine Pitroudb187842010-04-27 10:32:58 +0000790 s = ssl.wrap_socket(socket.socket(),
791 certfile=client_certfile,
792 ca_certs=cacertsfile,
793 ciphers=ciphers,
794 cert_reqs=certreqs,
795 ssl_version=client_protocol)
796 s.connect((HOST, server.port))
797 for arg in [indata, bytearray(indata), memoryview(indata)]:
Bill Janssen98d19da2007-09-10 21:51:02 +0000798 if connectionchatty:
799 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +0000800 sys.stdout.write(
801 " client: sending %s...\n" % (repr(arg)))
802 s.write(arg)
803 outdata = s.read()
804 if connectionchatty:
805 if test_support.verbose:
806 sys.stdout.write(" client: read %s\n" % repr(outdata))
807 if outdata != indata.lower():
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000808 raise AssertionError(
Antoine Pitroudb187842010-04-27 10:32:58 +0000809 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
810 % (outdata[:min(len(outdata),20)], len(outdata),
811 indata[:min(len(indata),20)].lower(), len(indata)))
812 s.write("over\n")
813 if connectionchatty:
814 if test_support.verbose:
815 sys.stdout.write(" client: closing connection.\n")
816 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000817 finally:
818 server.stop()
819 server.join()
820
Antoine Pitrou3945c862010-04-28 21:11:01 +0000821 def try_protocol_combo(server_protocol,
822 client_protocol,
823 expect_success,
824 certsreqs=None):
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000825 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000826 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +0000827 certtype = {
828 ssl.CERT_NONE: "CERT_NONE",
829 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
830 ssl.CERT_REQUIRED: "CERT_REQUIRED",
831 }[certsreqs]
Bill Janssen98d19da2007-09-10 21:51:02 +0000832 if test_support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000833 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +0000834 sys.stdout.write(formatstr %
835 (ssl.get_protocol_name(client_protocol),
836 ssl.get_protocol_name(server_protocol),
837 certtype))
838 try:
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000839 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
840 # will send an SSLv3 hello (rather than SSLv2) starting from
841 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou3945c862010-04-28 21:11:01 +0000842 server_params_test(CERTFILE, server_protocol, certsreqs,
843 CERTFILE, CERTFILE, client_protocol,
844 ciphers="ALL", chatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +0000845 # Protocol mismatch can result in either an SSLError, or a
846 # "Connection reset by peer" error.
847 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000848 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +0000849 raise
Antoine Pitroudb187842010-04-27 10:32:58 +0000850 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000851 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +0000852 raise
Bill Janssen98d19da2007-09-10 21:51:02 +0000853 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000854 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000855 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +0000856 "Client protocol %s succeeded with server protocol %s!"
857 % (ssl.get_protocol_name(client_protocol),
858 ssl.get_protocol_name(server_protocol)))
859
860
Bill Janssen934b16d2008-06-28 22:19:33 +0000861 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000862
Antoine Pitrou3945c862010-04-28 21:11:01 +0000863 def test_rude_shutdown(self):
864 """A brutal shutdown of an SSL server should raise an IOError
865 in the client when attempting handshake.
866 """
Bill Janssen98d19da2007-09-10 21:51:02 +0000867 listener_ready = threading.Event()
868 listener_gone = threading.Event()
869
Antoine Pitrou150acda2010-04-27 08:40:51 +0000870 s = socket.socket()
871 port = test_support.bind_port(s, HOST)
872
873 # `listener` runs in a thread. It sits in an accept() until
874 # the main thread connects. Then it rudely closes the socket,
875 # and sets Event `listener_gone` to let the main thread know
876 # the socket is gone.
Bill Janssen98d19da2007-09-10 21:51:02 +0000877 def listener():
Bill Janssen98d19da2007-09-10 21:51:02 +0000878 s.listen(5)
879 listener_ready.set()
880 s.accept()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000881 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000882 listener_gone.set()
883
884 def connector():
885 listener_ready.wait()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000886 c = socket.socket()
887 c.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000888 listener_gone.wait()
889 try:
Antoine Pitrou150acda2010-04-27 08:40:51 +0000890 ssl_sock = ssl.wrap_socket(c)
Bill Janssen934b16d2008-06-28 22:19:33 +0000891 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000892 pass
893 else:
Antoine Pitroudb187842010-04-27 10:32:58 +0000894 self.fail('connecting to closed SSL socket should have failed')
Bill Janssen98d19da2007-09-10 21:51:02 +0000895
896 t = threading.Thread(target=listener)
897 t.start()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000898 try:
899 connector()
900 finally:
901 t.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000902
Antoine Pitroud75efd92010-08-04 17:38:33 +0000903 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000904 def test_echo(self):
905 """Basic test of an SSL client connecting to a server"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000906 if test_support.verbose:
907 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000908 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
909 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
910 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000911
Antoine Pitrou3945c862010-04-28 21:11:01 +0000912 def test_getpeercert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000913 if test_support.verbose:
914 sys.stdout.write("\n")
915 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000916 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000917 certreqs=ssl.CERT_NONE,
918 ssl_version=ssl.PROTOCOL_SSLv23,
919 cacerts=CERTFILE,
920 chatty=False)
921 flag = threading.Event()
922 server.start(flag)
923 # wait for it to start
924 flag.wait()
925 # try to connect
926 try:
Antoine Pitroudb187842010-04-27 10:32:58 +0000927 s = ssl.wrap_socket(socket.socket(),
928 certfile=CERTFILE,
929 ca_certs=CERTFILE,
930 cert_reqs=ssl.CERT_REQUIRED,
931 ssl_version=ssl.PROTOCOL_SSLv23)
932 s.connect((HOST, server.port))
933 cert = s.getpeercert()
934 self.assertTrue(cert, "Can't get peer certificate.")
935 cipher = s.cipher()
936 if test_support.verbose:
937 sys.stdout.write(pprint.pformat(cert) + '\n')
938 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
939 if 'subject' not in cert:
940 self.fail("No subject field in certificate: %s." %
941 pprint.pformat(cert))
942 if ((('organizationName', 'Python Software Foundation'),)
943 not in cert['subject']):
944 self.fail(
945 "Missing or invalid 'organizationName' field in certificate subject; "
946 "should be 'Python Software Foundation'.")
947 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000948 finally:
949 server.stop()
950 server.join()
951
Antoine Pitrou3945c862010-04-28 21:11:01 +0000952 def test_empty_cert(self):
953 """Connecting with an empty cert file"""
954 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
955 "nullcert.pem"))
956 def test_malformed_cert(self):
957 """Connecting with a badly formatted certificate (syntax error)"""
958 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
959 "badcert.pem"))
960 def test_nonexisting_cert(self):
961 """Connecting with a non-existing cert file"""
962 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
963 "wrongcert.pem"))
964 def test_malformed_key(self):
965 """Connecting with a badly formatted key (syntax error)"""
966 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
967 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +0000968
Antoine Pitroud75efd92010-08-04 17:38:33 +0000969 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000970 def test_protocol_sslv2(self):
971 """Connecting to an SSLv2 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000972 if test_support.verbose:
973 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000974 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
975 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
976 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
977 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
978 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
979 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +0000980
Antoine Pitroud75efd92010-08-04 17:38:33 +0000981 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000982 def test_protocol_sslv23(self):
983 """Connecting to an SSLv23 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000984 if test_support.verbose:
985 sys.stdout.write("\n")
986 try:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000987 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000988 except (ssl.SSLError, socket.error), x:
Bill Janssen98d19da2007-09-10 21:51:02 +0000989 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
990 if test_support.verbose:
991 sys.stdout.write(
992 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
993 % str(x))
Antoine Pitrou3945c862010-04-28 21:11:01 +0000994 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
995 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
996 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000997
Antoine Pitrou3945c862010-04-28 21:11:01 +0000998 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
999 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1000 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +00001001
Antoine Pitrou3945c862010-04-28 21:11:01 +00001002 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1003 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1004 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00001005
Antoine Pitroud75efd92010-08-04 17:38:33 +00001006 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001007 def test_protocol_sslv3(self):
1008 """Connecting to an SSLv3 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001009 if test_support.verbose:
1010 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001011 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1012 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1013 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001014 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1015 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001016 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1017 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001018
Antoine Pitroud75efd92010-08-04 17:38:33 +00001019 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001020 def test_protocol_tlsv1(self):
1021 """Connecting to a TLSv1 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001022 if test_support.verbose:
1023 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001024 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1025 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1026 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001027 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1028 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001029 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1030 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001031
Antoine Pitrou3945c862010-04-28 21:11:01 +00001032 def test_starttls(self):
1033 """Switching from clear text to encrypted and back again."""
Bill Janssen39295c22008-08-12 16:31:21 +00001034 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +00001035
Trent Nelsone41b0062008-04-08 23:47:30 +00001036 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00001037 ssl_version=ssl.PROTOCOL_TLSv1,
1038 starttls_server=True,
1039 chatty=True,
1040 connectionchatty=True)
1041 flag = threading.Event()
1042 server.start(flag)
1043 # wait for it to start
1044 flag.wait()
1045 # try to connect
1046 wrapped = False
1047 try:
Antoine Pitroudb187842010-04-27 10:32:58 +00001048 s = socket.socket()
1049 s.setblocking(1)
1050 s.connect((HOST, server.port))
1051 if test_support.verbose:
1052 sys.stdout.write("\n")
1053 for indata in msgs:
Bill Janssen98d19da2007-09-10 21:51:02 +00001054 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00001055 sys.stdout.write(
1056 " client: sending %s...\n" % repr(indata))
1057 if wrapped:
1058 conn.write(indata)
1059 outdata = conn.read()
1060 else:
1061 s.send(indata)
1062 outdata = s.recv(1024)
1063 if (indata == "STARTTLS" and
1064 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001065 # STARTTLS ok, switch to secure mode
Bill Janssen98d19da2007-09-10 21:51:02 +00001066 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00001067 sys.stdout.write(
Antoine Pitroudb187842010-04-27 10:32:58 +00001068 " client: read %s from server, starting TLS...\n"
1069 % repr(outdata))
1070 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1071 wrapped = True
1072 elif (indata == "ENDTLS" and
1073 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001074 # ENDTLS ok, switch back to clear text
Antoine Pitroudb187842010-04-27 10:32:58 +00001075 if test_support.verbose:
1076 sys.stdout.write(
1077 " client: read %s from server, ending TLS...\n"
1078 % repr(outdata))
1079 s = conn.unwrap()
1080 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00001081 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001082 if test_support.verbose:
1083 sys.stdout.write(
1084 " client: read %s from server\n" % repr(outdata))
1085 if test_support.verbose:
1086 sys.stdout.write(" client: closing connection.\n")
1087 if wrapped:
1088 conn.write("over\n")
1089 else:
1090 s.send("over\n")
1091 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001092 finally:
1093 server.stop()
1094 server.join()
1095
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)
1144 flag = threading.Event()
1145 server.start(flag)
1146 # wait for it to start
1147 flag.wait()
1148 # try to connect
1149 try:
Antoine Pitroudb187842010-04-27 10:32:58 +00001150 s = ssl.wrap_socket(socket.socket())
1151 s.connect(('127.0.0.1', server.port))
1152 if test_support.verbose:
1153 sys.stdout.write(
1154 " client: sending %s...\n" % (repr(indata)))
1155 s.write(indata)
1156 outdata = s.read()
1157 if test_support.verbose:
1158 sys.stdout.write(" client: read %s\n" % repr(outdata))
1159 if outdata != indata.lower():
1160 self.fail(
1161 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1162 % (outdata[:min(len(outdata),20)], len(outdata),
1163 indata[:min(len(indata),20)].lower(), len(indata)))
1164 s.write("over\n")
1165 if test_support.verbose:
1166 sys.stdout.write(" client: closing connection.\n")
1167 s.close()
Bill Janssen934b16d2008-06-28 22:19:33 +00001168 finally:
1169 server.stop()
1170 # wait for server thread to end
1171 server.join()
1172
Antoine Pitrou3945c862010-04-28 21:11:01 +00001173 def test_recv_send(self):
1174 """Test recv(), send() and friends."""
Bill Janssen61c001a2008-09-08 16:37:24 +00001175 if test_support.verbose:
1176 sys.stdout.write("\n")
1177
1178 server = ThreadedEchoServer(CERTFILE,
1179 certreqs=ssl.CERT_NONE,
1180 ssl_version=ssl.PROTOCOL_TLSv1,
1181 cacerts=CERTFILE,
1182 chatty=True,
1183 connectionchatty=False)
1184 flag = threading.Event()
1185 server.start(flag)
1186 # wait for it to start
1187 flag.wait()
1188 # try to connect
Antoine Pitroudb187842010-04-27 10:32:58 +00001189 s = ssl.wrap_socket(socket.socket(),
1190 server_side=False,
1191 certfile=CERTFILE,
1192 ca_certs=CERTFILE,
1193 cert_reqs=ssl.CERT_NONE,
1194 ssl_version=ssl.PROTOCOL_TLSv1)
1195 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00001196 try:
Bill Janssen61c001a2008-09-08 16:37:24 +00001197 # helper methods for standardising recv* method signatures
1198 def _recv_into():
1199 b = bytearray("\0"*100)
1200 count = s.recv_into(b)
1201 return b[:count]
1202
1203 def _recvfrom_into():
1204 b = bytearray("\0"*100)
1205 count, addr = s.recvfrom_into(b)
1206 return b[:count]
1207
1208 # (name, method, whether to expect success, *args)
1209 send_methods = [
1210 ('send', s.send, True, []),
1211 ('sendto', s.sendto, False, ["some.address"]),
1212 ('sendall', s.sendall, True, []),
1213 ]
1214 recv_methods = [
1215 ('recv', s.recv, True, []),
1216 ('recvfrom', s.recvfrom, False, ["some.address"]),
1217 ('recv_into', _recv_into, True, []),
1218 ('recvfrom_into', _recvfrom_into, False, []),
1219 ]
1220 data_prefix = u"PREFIX_"
1221
1222 for meth_name, send_meth, expect_success, args in send_methods:
1223 indata = data_prefix + meth_name
1224 try:
1225 send_meth(indata.encode('ASCII', 'strict'), *args)
1226 outdata = s.read()
1227 outdata = outdata.decode('ASCII', 'strict')
1228 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001229 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001230 "While sending with <<%s>> bad data "
1231 "<<%r>> (%d) received; "
1232 "expected <<%r>> (%d)\n" % (
1233 meth_name, outdata[:20], len(outdata),
1234 indata[:20], len(indata)
1235 )
1236 )
1237 except ValueError as e:
1238 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001239 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001240 "Failed to send with method <<%s>>; "
1241 "expected to succeed.\n" % (meth_name,)
1242 )
1243 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001244 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001245 "Method <<%s>> failed with unexpected "
1246 "exception message: %s\n" % (
1247 meth_name, e
1248 )
1249 )
1250
1251 for meth_name, recv_meth, expect_success, args in recv_methods:
1252 indata = data_prefix + meth_name
1253 try:
1254 s.send(indata.encode('ASCII', 'strict'))
1255 outdata = recv_meth(*args)
1256 outdata = outdata.decode('ASCII', 'strict')
1257 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001258 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001259 "While receiving with <<%s>> bad data "
1260 "<<%r>> (%d) received; "
1261 "expected <<%r>> (%d)\n" % (
1262 meth_name, outdata[:20], len(outdata),
1263 indata[:20], len(indata)
1264 )
1265 )
1266 except ValueError as e:
1267 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001268 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001269 "Failed to receive with method <<%s>>; "
1270 "expected to succeed.\n" % (meth_name,)
1271 )
1272 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001273 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001274 "Method <<%s>> failed with unexpected "
1275 "exception message: %s\n" % (
1276 meth_name, e
1277 )
1278 )
1279 # consume data
1280 s.read()
1281
1282 s.write("over\n".encode("ASCII", "strict"))
1283 s.close()
1284 finally:
1285 server.stop()
1286 server.join()
1287
Antoine Pitroufc69af12010-04-24 20:04:58 +00001288 def test_handshake_timeout(self):
1289 # Issue #5103: SSL handshake must respect the socket timeout
1290 server = socket.socket(socket.AF_INET)
1291 host = "127.0.0.1"
1292 port = test_support.bind_port(server)
1293 started = threading.Event()
1294 finish = False
1295
1296 def serve():
1297 server.listen(5)
1298 started.set()
1299 conns = []
1300 while not finish:
1301 r, w, e = select.select([server], [], [], 0.1)
1302 if server in r:
1303 # Let the socket hang around rather than having
1304 # it closed by garbage collection.
1305 conns.append(server.accept()[0])
1306
1307 t = threading.Thread(target=serve)
1308 t.start()
1309 started.wait()
1310
1311 try:
1312 try:
1313 c = socket.socket(socket.AF_INET)
1314 c.settimeout(0.2)
1315 c.connect((host, port))
1316 # Will attempt handshake and time out
1317 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1318 ssl.wrap_socket, c)
1319 finally:
1320 c.close()
1321 try:
1322 c = socket.socket(socket.AF_INET)
1323 c.settimeout(0.2)
1324 c = ssl.wrap_socket(c)
1325 # Will attempt handshake and time out
1326 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1327 c.connect, (host, port))
1328 finally:
1329 c.close()
1330 finally:
1331 finish = True
1332 t.join()
1333 server.close()
1334
Bill Janssen61c001a2008-09-08 16:37:24 +00001335
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001336def test_main(verbose=False):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001337 if skip_expected:
Benjamin Peterson888a39b2009-03-26 20:48:25 +00001338 raise unittest.SkipTest("No SSL support")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001339
Trent Nelsone41b0062008-04-08 23:47:30 +00001340 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
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")
1346
1347 if (not os.path.exists(CERTFILE) or
1348 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001349 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001350
Antoine Pitroude30f702010-09-14 12:54:08 +00001351 tests = [BasicTests, BasicSocketTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001352
Bill Janssen296a59d2007-09-16 22:06:00 +00001353 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001354 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001355
Bill Janssen98d19da2007-09-10 21:51:02 +00001356 if _have_threads:
1357 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001358 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001359 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001360
Antoine Pitrou3945c862010-04-28 21:11:01 +00001361 try:
1362 test_support.run_unittest(*tests)
1363 finally:
1364 if _have_threads:
1365 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001366
1367if __name__ == "__main__":
1368 test_main()