blob: 3c03b59d5a5e6e3db53b1d41c26a921320c3d3d5 [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Thomas Woutersed03b412007-08-28 21:37:11 +00006import socket
Bill Janssen6e027db2007-11-15 22:23:56 +00007import select
Thomas Woutersed03b412007-08-28 21:37:11 +00008import time
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +00009import gc
Thomas Woutersed03b412007-08-28 21:37:11 +000010import os
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000011import errno
Thomas Woutersed03b412007-08-28 21:37:11 +000012import pprint
Jeremy Hylton1afc1692008-06-18 20:49:58 +000013import urllib.parse, urllib.request
Thomas Woutersed03b412007-08-28 21:37:11 +000014import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000015import asyncore
Antoine Pitrou9d543662010-04-23 23:10:32 +000016import weakref
Thomas Woutersed03b412007-08-28 21:37:11 +000017
Georg Brandl24420152008-05-26 16:32:26 +000018from http.server import HTTPServer, SimpleHTTPRequestHandler
Thomas Wouters1b7f8912007-09-19 03:06:30 +000019
Thomas Woutersed03b412007-08-28 21:37:11 +000020# Optionally test SSL support, if we have it in the tested platform
21skip_expected = False
22try:
23 import ssl
24except ImportError:
25 skip_expected = True
26
Benjamin Petersonee8712c2008-05-20 21:35:26 +000027HOST = support.HOST
Thomas Woutersed03b412007-08-28 21:37:11 +000028CERTFILE = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +000029SVN_PYTHON_ORG_ROOT_CERT = None
Thomas Woutersed03b412007-08-28 21:37:11 +000030
Thomas Woutersed03b412007-08-28 21:37:11 +000031def handle_error(prefix):
32 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000033 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000034 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000035
36
37class BasicTests(unittest.TestCase):
38
Georg Brandlfceab5a2008-01-19 20:08:23 +000039 def testSSLconnect(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000040 if not support.is_resource_enabled('network'):
Georg Brandlfceab5a2008-01-19 20:08:23 +000041 return
42 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
43 cert_reqs=ssl.CERT_NONE)
44 s.connect(("svn.python.org", 443))
45 c = s.getpeercert()
46 if c:
Benjamin Petersonee8712c2008-05-20 21:35:26 +000047 raise support.TestFailed("Peer cert %s shouldn't be here!")
Georg Brandlfceab5a2008-01-19 20:08:23 +000048 s.close()
49
50 # this should fail because we have no verification certs
51 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
52 cert_reqs=ssl.CERT_REQUIRED)
53 try:
54 s.connect(("svn.python.org", 443))
55 except ssl.SSLError:
56 pass
57 finally:
58 s.close()
59
Thomas Wouters1b7f8912007-09-19 03:06:30 +000060 def testCrucialConstants(self):
61 ssl.PROTOCOL_SSLv2
62 ssl.PROTOCOL_SSLv23
63 ssl.PROTOCOL_SSLv3
64 ssl.PROTOCOL_TLSv1
65 ssl.CERT_NONE
66 ssl.CERT_OPTIONAL
67 ssl.CERT_REQUIRED
Thomas Woutersed03b412007-08-28 21:37:11 +000068
Thomas Wouters1b7f8912007-09-19 03:06:30 +000069 def testRAND(self):
70 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +000071 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000072 sys.stdout.write("\n RAND_status is %d (%s)\n"
73 % (v, (v and "sufficient randomness") or
74 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +000075 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000076 ssl.RAND_egd(1)
77 except TypeError:
78 pass
Thomas Woutersed03b412007-08-28 21:37:11 +000079 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000080 print("didn't raise TypeError")
81 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +000082
Thomas Wouters1b7f8912007-09-19 03:06:30 +000083 def testParseCert(self):
84 # note that this uses an 'unofficial' function in _ssl.c,
85 # provided solely for this test, to exercise the certificate
86 # parsing code
87 p = ssl._ssl._test_decode_cert(CERTFILE, False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000088 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000089 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +000090
Thomas Wouters1b7f8912007-09-19 03:06:30 +000091 def testDERtoPEM(self):
92
93 pem = open(SVN_PYTHON_ORG_ROOT_CERT, 'r').read()
94 d1 = ssl.PEM_cert_to_DER_cert(pem)
95 p2 = ssl.DER_cert_to_PEM_cert(d1)
96 d2 = ssl.PEM_cert_to_DER_cert(p2)
97 if (d1 != d2):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000098 raise support.TestFailed("PEM-to-DER or DER-to-PEM translation failed")
Thomas Wouters1b7f8912007-09-19 03:06:30 +000099
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000100 def test_openssl_version(self):
101 n = ssl.OPENSSL_VERSION_NUMBER
102 t = ssl.OPENSSL_VERSION_INFO
103 s = ssl.OPENSSL_VERSION
104 self.assertIsInstance(n, int)
105 self.assertIsInstance(t, tuple)
106 self.assertIsInstance(s, str)
107 # Some sanity checks follow
108 # >= 0.9
109 self.assertGreaterEqual(n, 0x900000)
110 # < 2.0
111 self.assertLess(n, 0x20000000)
112 major, minor, fix, patch, status = t
113 self.assertGreaterEqual(major, 0)
114 self.assertLess(major, 2)
115 self.assertGreaterEqual(minor, 0)
116 self.assertLess(minor, 256)
117 self.assertGreaterEqual(fix, 0)
118 self.assertLess(fix, 256)
119 self.assertGreaterEqual(patch, 0)
120 self.assertLessEqual(patch, 26)
121 self.assertGreaterEqual(status, 0)
122 self.assertLessEqual(status, 15)
123 # Version string as returned by OpenSSL, the format might change
124 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
125 (s, t))
126
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000127 def test_ciphers(self):
128 if not support.is_resource_enabled('network'):
129 return
130 remote = ("svn.python.org", 443)
131 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
132 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
133 s.connect(remote)
134 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
135 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
136 s.connect(remote)
137 # Error checking occurs when connecting, because the SSL context
138 # isn't created before.
139 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
140 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
141 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
142 s.connect(remote)
143
Antoine Pitrou9d543662010-04-23 23:10:32 +0000144 @support.cpython_only
145 def test_refcycle(self):
146 # Issue #7943: an SSL object doesn't create reference cycles with
147 # itself.
148 s = socket.socket(socket.AF_INET)
149 ss = ssl.wrap_socket(s)
150 wr = weakref.ref(ss)
151 del ss
152 self.assertEqual(wr(), None)
153
Antoine Pitrou40f08742010-04-24 22:04:40 +0000154 def test_timeout(self):
155 # Issue #8524: when creating an SSL socket, the timeout of the
156 # original socket should be retained.
157 for timeout in (None, 0.0, 5.0):
158 s = socket.socket(socket.AF_INET)
159 s.settimeout(timeout)
160 ss = ssl.wrap_socket(s)
161 self.assertEqual(timeout, ss.gettimeout())
162
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000163
Bill Janssen6e027db2007-11-15 22:23:56 +0000164class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000165
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000166 def testConnect(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000167 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
168 cert_reqs=ssl.CERT_NONE)
169 s.connect(("svn.python.org", 443))
170 c = s.getpeercert()
171 if c:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000172 raise support.TestFailed("Peer cert %s shouldn't be here!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000173 s.close()
174
175 # this should fail because we have no verification certs
176 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
177 cert_reqs=ssl.CERT_REQUIRED)
Thomas Woutersed03b412007-08-28 21:37:11 +0000178 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000179 s.connect(("svn.python.org", 443))
180 except ssl.SSLError:
181 pass
182 finally:
183 s.close()
184
185 # this should succeed because we specify the root cert
186 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
187 cert_reqs=ssl.CERT_REQUIRED,
188 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
189 try:
190 s.connect(("svn.python.org", 443))
191 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000192 raise support.TestFailed("Unexpected exception %s" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000193 finally:
194 s.close()
195
Antoine Pitroue3220242010-04-24 11:13:53 +0000196 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
197 def test_makefile_close(self):
198 # Issue #5238: creating a file-like object with makefile() shouldn't
199 # delay closing the underlying "real socket" (here tested with its
200 # file descriptor, hence skipping the test under Windows).
201 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
202 ss.connect(("svn.python.org", 443))
203 fd = ss.fileno()
204 f = ss.makefile()
205 f.close()
206 # The fd is still open
207 os.read(fd, 0)
208 # Closing the SSL socket should close the fd too
209 ss.close()
210 gc.collect()
211 with self.assertRaises(OSError) as e:
212 os.read(fd, 0)
213 self.assertEqual(e.exception.errno, errno.EBADF)
214
Bill Janssen6e027db2007-11-15 22:23:56 +0000215 def testNonBlockingHandshake(self):
216 s = socket.socket(socket.AF_INET)
217 s.connect(("svn.python.org", 443))
218 s.setblocking(False)
219 s = ssl.wrap_socket(s,
220 cert_reqs=ssl.CERT_NONE,
221 do_handshake_on_connect=False)
222 count = 0
223 while True:
224 try:
225 count += 1
226 s.do_handshake()
227 break
228 except ssl.SSLError as err:
229 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
230 select.select([s], [], [])
231 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
232 select.select([], [s], [])
233 else:
234 raise
235 s.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000236 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000237 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000238
Bill Janssen54cc54c2007-12-14 22:08:56 +0000239 def testFetchServerCert(self):
240
241 pem = ssl.get_server_certificate(("svn.python.org", 443))
242 if not pem:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000243 raise support.TestFailed("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000244
245 return
246
247 try:
248 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
249 except ssl.SSLError as x:
250 #should fail
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000251 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000252 sys.stdout.write("%s\n" % x)
253 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000254 raise support.TestFailed("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000255
256 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
257 if not pem:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000258 raise support.TestFailed("No server certificate on svn.python.org:443!")
259 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000260 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
261
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000262 def test_algorithms(self):
263 # Issue #8484: all algorithms should be available when verifying a
264 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000265 # SHA256 was added in OpenSSL 0.9.8
266 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
267 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000268 # NOTE: https://sha256.tbs-internet.com is another possible test host
269 remote = ("sha2.hboeck.de", 443)
270 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
271 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
272 cert_reqs=ssl.CERT_REQUIRED,
273 ca_certs=sha256_cert,)
274 with support.transient_internet():
275 try:
276 s.connect(remote)
277 if support.verbose:
278 sys.stdout.write("\nCipher with %r is %r\n" %
279 (remote, s.cipher()))
280 sys.stdout.write("Certificate is:\n%s\n" %
281 pprint.pformat(s.getpeercert()))
282 finally:
283 s.close()
284
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000285
286try:
287 import threading
288except ImportError:
289 _have_threads = False
290else:
291
292 _have_threads = True
293
294 class ThreadedEchoServer(threading.Thread):
295
296 class ConnectionHandler(threading.Thread):
297
298 """A mildly complicated class, because we want it to work both
299 with and without the SSL wrapper around the socket connection, so
300 that we can test the STARTTLS functionality."""
301
Bill Janssen6e027db2007-11-15 22:23:56 +0000302 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000303 self.server = server
304 self.running = False
305 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000306 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000307 self.sock.setblocking(1)
308 self.sslconn = None
309 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000310 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000311
312 def wrap_conn (self):
313 try:
314 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
315 certfile=self.server.certificate,
316 ssl_version=self.server.protocol,
317 ca_certs=self.server.cacerts,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000318 cert_reqs=self.server.certreqs,
319 ciphers=self.server.ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000320 except:
321 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000322 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000323 if not self.server.expect_bad_connects:
324 # here, we want to stop the server, because this shouldn't
325 # happen in the context of our test case
326 self.running = False
327 # normally, we'd just stop here, but for the test
328 # harness, we want to stop the server
329 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000330 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000331 return False
332
333 else:
334 if self.server.certreqs == ssl.CERT_REQUIRED:
335 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000336 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000337 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
338 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000339 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000340 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
341 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000342 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000343 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
344 return True
345
346 def read(self):
347 if self.sslconn:
348 return self.sslconn.read()
349 else:
350 return self.sock.recv(1024)
351
352 def write(self, bytes):
353 if self.sslconn:
354 return self.sslconn.write(bytes)
355 else:
356 return self.sock.send(bytes)
357
358 def close(self):
359 if self.sslconn:
360 self.sslconn.close()
361 else:
362 self.sock.close()
363
364 def run (self):
365 self.running = True
366 if not self.server.starttls_server:
367 if not self.wrap_conn():
368 return
369 while self.running:
370 try:
371 msg = self.read()
Bill Janssen6e027db2007-11-15 22:23:56 +0000372 amsg = (msg and str(msg, 'ASCII', 'strict')) or ''
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000373 if not msg:
374 # eof, so quit this handler
375 self.running = False
376 self.close()
Bill Janssen6e027db2007-11-15 22:23:56 +0000377 elif amsg.strip() == 'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000378 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000379 sys.stdout.write(" server: client closed connection\n")
380 self.close()
381 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000382 elif (self.server.starttls_server and
383 amsg.strip() == 'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000384 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000385 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000386 self.write("OK\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000387 if not self.wrap_conn():
388 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000389 elif (self.server.starttls_server and self.sslconn
390 and amsg.strip() == 'ENDTLS'):
391 if support.verbose and self.server.connectionchatty:
392 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
393 self.write("OK\n".encode("ASCII", "strict"))
394 self.sock = self.sslconn.unwrap()
395 self.sslconn = None
396 if support.verbose and self.server.connectionchatty:
397 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000398 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000399 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000400 self.server.connectionchatty):
401 ctype = (self.sslconn and "encrypted") or "unencrypted"
402 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
403 % (repr(msg), ctype, repr(msg.lower()), ctype))
Bill Janssen6e027db2007-11-15 22:23:56 +0000404 self.write(amsg.lower().encode('ASCII', 'strict'))
405 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000406 if self.server.chatty:
407 handle_error("Test server failure:\n")
408 self.close()
409 self.running = False
410 # normally, we'd just stop here, but for the test
411 # harness, we want to stop the server
412 self.server.stop()
413 except:
414 handle_error('')
415
Trent Nelson78520002008-04-10 20:54:35 +0000416 def __init__(self, certificate, ssl_version=None,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000417 certreqs=None, cacerts=None, expect_bad_connects=False,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000418 chatty=True, connectionchatty=False, starttls_server=False,
419 ciphers=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000420 if ssl_version is None:
421 ssl_version = ssl.PROTOCOL_TLSv1
422 if certreqs is None:
423 certreqs = ssl.CERT_NONE
424 self.certificate = certificate
425 self.protocol = ssl_version
426 self.certreqs = certreqs
427 self.cacerts = cacerts
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000428 self.ciphers = ciphers
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000429 self.expect_bad_connects = expect_bad_connects
430 self.chatty = chatty
431 self.connectionchatty = connectionchatty
432 self.starttls_server = starttls_server
433 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000434 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000435 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000436 self.active = False
437 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000438 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000439
440 def start (self, flag=None):
441 self.flag = flag
442 threading.Thread.start(self)
443
444 def run (self):
445 self.sock.settimeout(0.5)
446 self.sock.listen(5)
447 self.active = True
448 if self.flag:
449 # signal an event
450 self.flag.set()
451 while self.active:
452 try:
453 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000454 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000455 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000456 + repr(connaddr) + '\n')
457 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000458 handler.start()
459 except socket.timeout:
460 pass
461 except KeyboardInterrupt:
462 self.stop()
463 except:
464 if self.chatty:
465 handle_error("Test server failure:\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000466 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000467
468 def stop (self):
469 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000470
Bill Janssen54cc54c2007-12-14 22:08:56 +0000471 class OurHTTPSServer(threading.Thread):
472
473 # This one's based on HTTPServer, which is based on SocketServer
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000474
475 class HTTPSServer(HTTPServer):
476
477 def __init__(self, server_address, RequestHandlerClass, certfile):
478
479 HTTPServer.__init__(self, server_address, RequestHandlerClass)
480 # we assume the certfile contains both private key and certificate
481 self.certfile = certfile
482 self.active = False
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000483 self.active_lock = threading.Lock()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000484 self.allow_reuse_address = True
485
Bill Janssen6e027db2007-11-15 22:23:56 +0000486 def __str__(self):
487 return ('<%s %s:%s>' %
488 (self.__class__.__name__,
489 self.server_name,
490 self.server_port))
491
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000492 def get_request (self):
493 # override this to wrap socket with SSL
494 sock, addr = self.socket.accept()
495 sslconn = ssl.wrap_socket(sock, server_side=True,
496 certfile=self.certfile)
497 return sslconn, addr
498
499 # The methods overridden below this are mainly so that we
500 # can run it in a thread and be able to stop it from another
501 # You probably wouldn't need them in other uses.
502
503 def server_activate(self):
504 # We want to run this in a thread for testing purposes,
505 # so we override this to set timeout, so that we get
506 # a chance to stop the server
507 self.socket.settimeout(0.5)
508 HTTPServer.server_activate(self)
509
510 def serve_forever(self):
511 # We want this to run in a thread, so we use a slightly
512 # modified version of "forever".
513 self.active = True
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000514 while 1:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000515 try:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000516 # We need to lock while handling the request.
517 # Another thread can close the socket after self.active
518 # has been checked and before the request is handled.
519 # This causes an exception when using the closed socket.
520 with self.active_lock:
521 if not self.active:
522 break
523 self.handle_request()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000524 except socket.timeout:
525 pass
526 except KeyboardInterrupt:
527 self.server_close()
528 return
529 except:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000530 sys.stdout.write(''.join(traceback.format_exception(*sys.exc_info())))
531 break
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000532 time.sleep(0.1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000533
534 def server_close(self):
535 # Again, we want this to run in a thread, so we need to override
536 # close to clear the "active" flag, so that serve_forever() will
537 # terminate.
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000538 with self.active_lock:
539 HTTPServer.server_close(self)
540 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000541
542 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
543
544 # need to override translate_path to get a known root,
545 # instead of using os.curdir, since the test could be
546 # run from anywhere
547
548 server_version = "TestHTTPS/1.0"
549
550 root = None
551
552 def translate_path(self, path):
553 """Translate a /-separated PATH to the local filename syntax.
554
555 Components that mean special things to the local file system
556 (e.g. drive or directory names) are ignored. (XXX They should
557 probably be diagnosed.)
558
559 """
560 # abandon query parameters
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000561 path = urllib.parse.urlparse(path)[2]
562 path = os.path.normpath(urllib.parse.unquote(path))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000563 words = path.split('/')
564 words = filter(None, words)
565 path = self.root
566 for word in words:
567 drive, word = os.path.splitdrive(word)
568 head, word = os.path.split(word)
569 if word in self.root: continue
570 path = os.path.join(path, word)
571 return path
572
573 def log_message(self, format, *args):
574
575 # we override this to suppress logging unless "verbose"
576
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000577 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000578 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
579 (self.server.server_address,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000580 self.server.server_port,
581 self.request.cipher(),
582 self.log_date_time_string(),
583 format%args))
Thomas Woutersed03b412007-08-28 21:37:11 +0000584
585
Trent Nelson78520002008-04-10 20:54:35 +0000586 def __init__(self, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000587 self.flag = None
588 self.active = False
589 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000590 self.port = support.find_unused_port()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000591 self.server = self.HTTPSServer(
Trent Nelson78520002008-04-10 20:54:35 +0000592 (HOST, self.port), self.RootedHTTPRequestHandler, certfile)
Thomas Woutersed03b412007-08-28 21:37:11 +0000593 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000594 self.daemon = True
Thomas Woutersed03b412007-08-28 21:37:11 +0000595
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000596 def __str__(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000597 return "<%s %s>" % (self.__class__.__name__, self.server)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000598
599 def start (self, flag=None):
600 self.flag = flag
601 threading.Thread.start(self)
602
Thomas Woutersed03b412007-08-28 21:37:11 +0000603 def run (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000604 self.active = True
605 if self.flag:
606 self.flag.set()
607 self.server.serve_forever()
608 self.active = False
609
610 def stop (self):
611 self.active = False
612 self.server.server_close()
613
614
Bill Janssen54cc54c2007-12-14 22:08:56 +0000615 class AsyncoreEchoServer(threading.Thread):
616
617 # this one's based on asyncore.dispatcher
618
619 class EchoServer (asyncore.dispatcher):
620
621 class ConnectionHandler (asyncore.dispatcher_with_send):
622
623 def __init__(self, conn, certfile):
624 self.socket = ssl.wrap_socket(conn, server_side=True,
625 certfile=certfile,
626 do_handshake_on_connect=False)
627 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000628 self._ssl_accepting = True
629 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000630
631 def readable(self):
632 if isinstance(self.socket, ssl.SSLSocket):
633 while self.socket.pending() > 0:
634 self.handle_read_event()
635 return True
636
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000637 def _do_ssl_handshake(self):
638 try:
639 self.socket.do_handshake()
640 except ssl.SSLError as err:
641 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
642 ssl.SSL_ERROR_WANT_WRITE):
643 return
644 elif err.args[0] == ssl.SSL_ERROR_EOF:
645 return self.handle_close()
646 raise
647 except socket.error as err:
648 if err.args[0] == errno.ECONNABORTED:
649 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000650 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000651 self._ssl_accepting = False
652
653 def handle_read(self):
654 if self._ssl_accepting:
655 self._do_ssl_handshake()
656 else:
657 data = self.recv(1024)
658 if support.verbose:
659 sys.stdout.write(" server: read %s from client\n" % repr(data))
660 if not data:
661 self.close()
662 else:
663 self.send(str(data, 'ASCII', 'strict').lower().encode('ASCII', 'strict'))
Bill Janssen54cc54c2007-12-14 22:08:56 +0000664
665 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000666 self.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000667 if test_support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000668 sys.stdout.write(" server: closed connection %s\n" % self.socket)
669
670 def handle_error(self):
671 raise
672
673 def __init__(self, port, certfile):
674 self.port = port
675 self.certfile = certfile
676 asyncore.dispatcher.__init__(self)
677 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
678 self.bind(('', port))
679 self.listen(5)
680
681 def handle_accept(self):
682 sock_obj, addr = self.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000683 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000684 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
685 self.ConnectionHandler(sock_obj, self.certfile)
686
687 def handle_error(self):
688 raise
689
Trent Nelson78520002008-04-10 20:54:35 +0000690 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000691 self.flag = None
692 self.active = False
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000693 self.port = support.find_unused_port()
Trent Nelson78520002008-04-10 20:54:35 +0000694 self.server = self.EchoServer(self.port, certfile)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000695 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000696 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000697
698 def __str__(self):
699 return "<%s %s>" % (self.__class__.__name__, self.server)
700
701 def start (self, flag=None):
702 self.flag = flag
703 threading.Thread.start(self)
704
705 def run (self):
706 self.active = True
707 if self.flag:
708 self.flag.set()
709 while self.active:
710 try:
711 asyncore.loop(1)
712 except:
713 pass
714
715 def stop (self):
716 self.active = False
717 self.server.close()
718
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000719 def badCertTest (certfile):
Trent Nelson78520002008-04-10 20:54:35 +0000720 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000721 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000722 cacerts=CERTFILE, chatty=False,
723 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000724 flag = threading.Event()
725 server.start(flag)
726 # wait for it to start
727 flag.wait()
728 # try to connect
729 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000730 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000731 s = ssl.wrap_socket(socket.socket(),
732 certfile=certfile,
733 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelson78520002008-04-10 20:54:35 +0000734 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000735 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000736 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000737 sys.stdout.write("\nSSLError is %s\n" % x)
Bill Janssenddc56692008-07-17 18:17:20 +0000738 except socket.error as x:
739 if support.verbose:
740 sys.stdout.write("\nsocket.error is %s\n" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000741 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000742 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000743 "Use of invalid cert should have failed!")
744 finally:
745 server.stop()
746 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000747
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000748 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
Bill Janssen6e027db2007-11-15 22:23:56 +0000749 client_certfile, client_protocol=None,
750 indata="FOO\n",
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000751 ciphers=None, chatty=False, connectionchatty=False):
Thomas Woutersed03b412007-08-28 21:37:11 +0000752
Trent Nelson78520002008-04-10 20:54:35 +0000753 server = ThreadedEchoServer(certfile,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000754 certreqs=certreqs,
755 ssl_version=protocol,
756 cacerts=cacertsfile,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000757 ciphers=ciphers,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000758 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000759 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000760 flag = threading.Event()
761 server.start(flag)
762 # wait for it to start
763 flag.wait()
764 # try to connect
765 if client_protocol is None:
766 client_protocol = protocol
767 try:
Bill Janssen6e027db2007-11-15 22:23:56 +0000768 s = ssl.wrap_socket(socket.socket(),
Trent Nelson6b240cd2008-04-10 20:12:06 +0000769 server_side=False,
Bill Janssen6e027db2007-11-15 22:23:56 +0000770 certfile=client_certfile,
771 ca_certs=cacertsfile,
772 cert_reqs=certreqs,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000773 ciphers=ciphers,
Bill Janssen6e027db2007-11-15 22:23:56 +0000774 ssl_version=client_protocol)
Trent Nelson78520002008-04-10 20:54:35 +0000775 s.connect((HOST, server.port))
Bill Janssen6e027db2007-11-15 22:23:56 +0000776 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000777 raise support.TestFailed("Unexpected SSL error: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000778 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000779 raise support.TestFailed("Unexpected exception: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000780 else:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000781 bindata = indata.encode('ASCII', 'strict')
782 for arg in [bindata, bytearray(bindata), memoryview(bindata)]:
783 if connectionchatty:
784 if support.verbose:
785 sys.stdout.write(
786 " client: sending %s...\n" % (repr(indata)))
787 s.write(arg)
788 outdata = s.read()
789 if connectionchatty:
790 if support.verbose:
791 sys.stdout.write(" client: read %s\n" % repr(outdata))
792 outdata = str(outdata, 'ASCII', 'strict')
793 if outdata != indata.lower():
794 raise support.TestFailed(
795 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
796 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
797 repr(indata[:min(len(indata),20)].lower()), len(indata)))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000798 s.write("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +0000799 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000800 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000801 sys.stdout.write(" client: closing connection.\n")
802 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000803 finally:
804 server.stop()
805 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000806
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000807 def tryProtocolCombo (server_protocol,
808 client_protocol,
809 expectedToWork,
810 certsreqs=None):
Thomas Woutersed03b412007-08-28 21:37:11 +0000811
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000812 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000813 certsreqs = ssl.CERT_NONE
Thomas Woutersed03b412007-08-28 21:37:11 +0000814
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000815 if certsreqs == ssl.CERT_NONE:
816 certtype = "CERT_NONE"
817 elif certsreqs == ssl.CERT_OPTIONAL:
818 certtype = "CERT_OPTIONAL"
819 elif certsreqs == ssl.CERT_REQUIRED:
820 certtype = "CERT_REQUIRED"
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000821 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000822 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
823 sys.stdout.write(formatstr %
824 (ssl.get_protocol_name(client_protocol),
825 ssl.get_protocol_name(server_protocol),
826 certtype))
827 try:
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000828 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
829 # will send an SSLv3 hello (rather than SSLv2) starting from
830 # OpenSSL 1.0.0 (see issue #8322).
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000831 serverParamsTest(CERTFILE, server_protocol, certsreqs,
Bill Janssen6e027db2007-11-15 22:23:56 +0000832 CERTFILE, CERTFILE, client_protocol,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000833 ciphers="ALL",
Bill Janssen6e027db2007-11-15 22:23:56 +0000834 chatty=False, connectionchatty=False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000835 except support.TestFailed:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000836 if expectedToWork:
837 raise
838 else:
839 if not expectedToWork:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000840 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000841 "Client protocol %s succeeded with server protocol %s!"
842 % (ssl.get_protocol_name(client_protocol),
843 ssl.get_protocol_name(server_protocol)))
844
845
Bill Janssen6e027db2007-11-15 22:23:56 +0000846 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000847
Trent Nelson6b240cd2008-04-10 20:12:06 +0000848 def testEcho (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000849
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000850 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000851 sys.stdout.write("\n")
852 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
853 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
854 chatty=True, connectionchatty=True)
855
856 def testReadCert(self):
857
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000858 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000859 sys.stdout.write("\n")
860 s2 = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000861 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000862 certreqs=ssl.CERT_NONE,
863 ssl_version=ssl.PROTOCOL_SSLv23,
864 cacerts=CERTFILE,
865 chatty=False)
866 flag = threading.Event()
867 server.start(flag)
868 # wait for it to start
869 flag.wait()
870 # try to connect
871 try:
872 try:
873 s = ssl.wrap_socket(socket.socket(),
874 certfile=CERTFILE,
875 ca_certs=CERTFILE,
876 cert_reqs=ssl.CERT_REQUIRED,
877 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelson78520002008-04-10 20:54:35 +0000878 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000879 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000880 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000881 "Unexpected SSL error: " + str(x))
882 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000883 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000884 "Unexpected exception: " + str(x))
885 else:
886 if not s:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000887 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000888 "Can't SSL-handshake with test server")
889 cert = s.getpeercert()
890 if not cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000891 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000892 "Can't get peer certificate.")
893 cipher = s.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000894 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000895 sys.stdout.write(pprint.pformat(cert) + '\n')
896 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
Bill Janssen6e027db2007-11-15 22:23:56 +0000897 if 'subject' not in cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000898 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000899 "No subject field in certificate: %s." %
900 pprint.pformat(cert))
901 if ((('organizationName', 'Python Software Foundation'),)
902 not in cert['subject']):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000903 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000904 "Missing or invalid 'organizationName' field in certificate subject; "
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000905 "should be 'Python Software Foundation'.")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000906 s.close()
907 finally:
908 server.stop()
909 server.join()
910
911 def testNULLcert(self):
912 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
913 "nullcert.pem"))
914 def testMalformedCert(self):
915 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
916 "badcert.pem"))
Bill Janssen58afe4c2008-09-08 16:45:19 +0000917 def testWrongCert(self):
918 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
919 "wrongcert.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000920 def testMalformedKey(self):
921 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
922 "badkey.pem"))
923
Trent Nelson6b240cd2008-04-10 20:12:06 +0000924 def testRudeShutdown(self):
925
926 listener_ready = threading.Event()
927 listener_gone = threading.Event()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000928 port = support.find_unused_port()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000929
930 # `listener` runs in a thread. It opens a socket listening on
931 # PORT, and sits in an accept() until the main thread connects.
932 # Then it rudely closes the socket, and sets Event `listener_gone`
933 # to let the main thread know the socket is gone.
934 def listener():
935 s = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000936 s.bind((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000937 s.listen(5)
938 listener_ready.set()
939 s.accept()
940 s = None # reclaim the socket object, which also closes it
941 listener_gone.set()
942
943 def connector():
944 listener_ready.wait()
945 s = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000946 s.connect((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000947 listener_gone.wait()
948 try:
949 ssl_sock = ssl.wrap_socket(s)
950 except IOError:
951 pass
952 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000953 raise support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +0000954 'connecting to closed SSL socket should have failed')
955
956 t = threading.Thread(target=listener)
957 t.start()
958 connector()
959 t.join()
960
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000961 def testProtocolSSL2(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000962 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000963 sys.stdout.write("\n")
964 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
965 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
966 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
967 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
968 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
969 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
970
971 def testProtocolSSL23(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000972 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000973 sys.stdout.write("\n")
974 try:
975 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000976 except support.TestFailed as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000977 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000978 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000979 sys.stdout.write(
980 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
981 % str(x))
982 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
983 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
984 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
985
986 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
987 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
988 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
989
990 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
991 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
992 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
993
994 def testProtocolSSL3(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000995 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000996 sys.stdout.write("\n")
997 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
998 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
999 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1000 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1001 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1002 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
1003
1004 def testProtocolTLS1(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001005 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001006 sys.stdout.write("\n")
1007 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1008 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1009 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1010 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1011 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1012 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
1013
1014 def testSTARTTLS (self):
1015
Bill Janssen40a0f662008-08-12 16:56:25 +00001016 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001017
Trent Nelson78520002008-04-10 20:54:35 +00001018 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001019 ssl_version=ssl.PROTOCOL_TLSv1,
1020 starttls_server=True,
1021 chatty=True,
1022 connectionchatty=True)
1023 flag = threading.Event()
1024 server.start(flag)
1025 # wait for it to start
1026 flag.wait()
1027 # try to connect
1028 wrapped = False
1029 try:
1030 try:
1031 s = socket.socket()
1032 s.setblocking(1)
Trent Nelson78520002008-04-10 20:54:35 +00001033 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001034 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001035 raise support.TestFailed("Unexpected exception: " + str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001036 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001037 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001038 sys.stdout.write("\n")
1039 for indata in msgs:
Bill Janssen6e027db2007-11-15 22:23:56 +00001040 msg = indata.encode('ASCII', 'replace')
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001041 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001042 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +00001043 " client: sending %s...\n" % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001044 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +00001045 conn.write(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001046 outdata = conn.read()
1047 else:
Bill Janssen6e027db2007-11-15 22:23:56 +00001048 s.send(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001049 outdata = s.recv(1024)
1050 if (indata == "STARTTLS" and
Bill Janssen6e027db2007-11-15 22:23:56 +00001051 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001052 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001053 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001054 sys.stdout.write(
1055 " client: read %s from server, starting TLS...\n"
Bill Janssen6e027db2007-11-15 22:23:56 +00001056 % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001057 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001058 wrapped = True
Bill Janssen40a0f662008-08-12 16:56:25 +00001059 elif (indata == "ENDTLS" and
1060 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
1061 if support.verbose:
1062 msg = str(outdata, 'ASCII', 'replace')
1063 sys.stdout.write(
1064 " client: read %s from server, ending TLS...\n"
1065 % repr(msg))
1066 s = conn.unwrap()
1067 wrapped = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001068 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001069 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001070 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001071 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +00001072 " client: read %s from server\n" % repr(msg))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001073 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001074 sys.stdout.write(" client: closing connection.\n")
1075 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +00001076 conn.write("over\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001077 else:
Bill Janssen40a0f662008-08-12 16:56:25 +00001078 s.send("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +00001079 if wrapped:
1080 conn.close()
1081 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001082 s.close()
1083 finally:
1084 server.stop()
1085 server.join()
1086
Bill Janssen54cc54c2007-12-14 22:08:56 +00001087 def testSocketServer(self):
Bill Janssen6e027db2007-11-15 22:23:56 +00001088
Trent Nelson78520002008-04-10 20:54:35 +00001089 server = OurHTTPSServer(CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001090 flag = threading.Event()
1091 server.start(flag)
1092 # wait for it to start
1093 flag.wait()
1094 # try to connect
1095 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001096 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001097 sys.stdout.write('\n')
1098 d1 = open(CERTFILE, 'rb').read()
1099 d2 = ''
1100 # now fetch the same data from the HTTPS server
Trent Nelson78520002008-04-10 20:54:35 +00001101 url = 'https://%s:%d/%s' % (
1102 HOST, server.port, os.path.split(CERTFILE)[1])
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001103 f = urllib.request.urlopen(url)
Barry Warsaw820c1202008-06-12 04:06:45 +00001104 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001105 if dlen and (int(dlen) > 0):
1106 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001107 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001108 sys.stdout.write(
1109 " client: read %d bytes from remote server '%s'\n"
1110 % (len(d2), server))
1111 f.close()
1112 except:
1113 msg = ''.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001114 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001115 sys.stdout.write('\n' + msg)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001116 raise support.TestFailed(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001117 else:
1118 if not (d1 == d2):
Bill Janssen6e027db2007-11-15 22:23:56 +00001119 print("d1 is", len(d1), repr(d1))
1120 print("d2 is", len(d2), repr(d2))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001121 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001122 "Couldn't fetch data from HTTPS server")
1123 finally:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001124 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001125 sys.stdout.write('stopping server\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001126 server.stop()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001127 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001128 sys.stdout.write('joining thread\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001129 server.join()
1130
Trent Nelson6b240cd2008-04-10 20:12:06 +00001131 def testAsyncoreServer(self):
1132
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001133 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001134 sys.stdout.write("\n")
1135
1136 indata="FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001137 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001138 flag = threading.Event()
1139 server.start(flag)
1140 # wait for it to start
1141 flag.wait()
1142 # try to connect
1143 try:
1144 s = ssl.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001145 s.connect((HOST, server.port))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001146 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001147 raise support.TestFailed("Unexpected SSL error: " + str(x))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001148 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001149 raise support.TestFailed("Unexpected exception: " + str(x))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001150 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001151 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001152 sys.stdout.write(
1153 " client: sending %s...\n" % (repr(indata)))
1154 s.sendall(indata.encode('ASCII', 'strict'))
1155 outdata = s.recv()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001156 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001157 sys.stdout.write(" client: read %s\n" % repr(outdata))
1158 outdata = str(outdata, 'ASCII', 'strict')
1159 if outdata != indata.lower():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001160 raise support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +00001161 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1162 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
1163 repr(indata[:min(len(indata),20)].lower()), len(indata)))
1164 s.write("over\n".encode("ASCII", "strict"))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001165 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001166 sys.stdout.write(" client: closing connection.\n")
1167 s.close()
1168 finally:
1169 server.stop()
1170 server.join()
1171
Bill Janssen58afe4c2008-09-08 16:45:19 +00001172 def testAllRecvAndSendMethods(self):
1173
1174 if support.verbose:
1175 sys.stdout.write("\n")
1176
1177 server = ThreadedEchoServer(CERTFILE,
1178 certreqs=ssl.CERT_NONE,
1179 ssl_version=ssl.PROTOCOL_TLSv1,
1180 cacerts=CERTFILE,
1181 chatty=True,
1182 connectionchatty=False)
1183 flag = threading.Event()
1184 server.start(flag)
1185 # wait for it to start
1186 flag.wait()
1187 # try to connect
1188 try:
1189 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))
1196 except ssl.SSLError as x:
Georg Brandl89fad142010-03-14 10:23:39 +00001197 self.fail("Unexpected SSL error: " + str(x))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001198 except Exception as x:
Georg Brandl89fad142010-03-14 10:23:39 +00001199 self.fail("Unexpected exception: " + str(x))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001200 else:
1201 # helper methods for standardising recv* method signatures
1202 def _recv_into():
1203 b = bytearray(b"\0"*100)
1204 count = s.recv_into(b)
1205 return b[:count]
1206
1207 def _recvfrom_into():
1208 b = bytearray(b"\0"*100)
1209 count, addr = s.recvfrom_into(b)
1210 return b[:count]
1211
1212 # (name, method, whether to expect success, *args)
1213 send_methods = [
1214 ('send', s.send, True, []),
1215 ('sendto', s.sendto, False, ["some.address"]),
1216 ('sendall', s.sendall, True, []),
1217 ]
1218 recv_methods = [
1219 ('recv', s.recv, True, []),
1220 ('recvfrom', s.recvfrom, False, ["some.address"]),
1221 ('recv_into', _recv_into, True, []),
1222 ('recvfrom_into', _recvfrom_into, False, []),
1223 ]
1224 data_prefix = "PREFIX_"
1225
1226 for meth_name, send_meth, expect_success, args in send_methods:
1227 indata = data_prefix + meth_name
1228 try:
1229 send_meth(indata.encode('ASCII', 'strict'), *args)
1230 outdata = s.read()
1231 outdata = str(outdata, 'ASCII', 'strict')
1232 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001233 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001234 "While sending with <<{name:s}>> bad data "
1235 "<<{outdata:s}>> ({nout:d}) received; "
1236 "expected <<{indata:s}>> ({nin:d})\n".format(
1237 name=meth_name, outdata=repr(outdata[:20]),
1238 nout=len(outdata),
1239 indata=repr(indata[:20]), nin=len(indata)
1240 )
1241 )
1242 except ValueError as e:
1243 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001244 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001245 "Failed to send with method <<{name:s}>>; "
1246 "expected to succeed.\n".format(name=meth_name)
1247 )
1248 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001249 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001250 "Method <<{name:s}>> failed with unexpected "
1251 "exception message: {exp:s}\n".format(
1252 name=meth_name, exp=e
1253 )
1254 )
1255
1256 for meth_name, recv_meth, expect_success, args in recv_methods:
1257 indata = data_prefix + meth_name
1258 try:
1259 s.send(indata.encode('ASCII', 'strict'))
1260 outdata = recv_meth(*args)
1261 outdata = str(outdata, 'ASCII', 'strict')
1262 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001263 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001264 "While receiving with <<{name:s}>> bad data "
1265 "<<{outdata:s}>> ({nout:d}) received; "
1266 "expected <<{indata:s}>> ({nin:d})\n".format(
1267 name=meth_name, outdata=repr(outdata[:20]),
1268 nout=len(outdata),
1269 indata=repr(indata[:20]), nin=len(indata)
1270 )
1271 )
1272 except ValueError as e:
1273 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001274 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001275 "Failed to receive with method <<{name:s}>>; "
1276 "expected to succeed.\n".format(name=meth_name)
1277 )
1278 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001279 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001280 "Method <<{name:s}>> failed with unexpected "
1281 "exception message: {exp:s}\n".format(
1282 name=meth_name, exp=e
1283 )
1284 )
1285 # consume data
1286 s.read()
1287
1288 s.write("over\n".encode("ASCII", "strict"))
1289 s.close()
1290 finally:
1291 server.stop()
1292 server.join()
1293
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001294 def test_handshake_timeout(self):
1295 # Issue #5103: SSL handshake must respect the socket timeout
1296 server = socket.socket(socket.AF_INET)
1297 host = "127.0.0.1"
1298 port = support.bind_port(server)
1299 started = threading.Event()
1300 finish = False
1301
1302 def serve():
1303 server.listen(5)
1304 started.set()
1305 conns = []
1306 while not finish:
1307 r, w, e = select.select([server], [], [], 0.1)
1308 if server in r:
1309 # Let the socket hang around rather than having
1310 # it closed by garbage collection.
1311 conns.append(server.accept()[0])
1312
1313 t = threading.Thread(target=serve)
1314 t.start()
1315 started.wait()
1316
1317 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001318 try:
1319 c = socket.socket(socket.AF_INET)
1320 c.settimeout(0.2)
1321 c.connect((host, port))
1322 # Will attempt handshake and time out
1323 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1324 ssl.wrap_socket, c)
1325 finally:
1326 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001327 try:
1328 c = socket.socket(socket.AF_INET)
1329 c = ssl.wrap_socket(c)
1330 c.settimeout(0.2)
1331 # Will attempt handshake and time out
1332 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1333 c.connect, (host, port))
1334 finally:
1335 c.close()
1336 finally:
1337 finish = True
1338 t.join()
1339 server.close()
1340
Bill Janssen58afe4c2008-09-08 16:45:19 +00001341
Thomas Woutersed03b412007-08-28 21:37:11 +00001342def test_main(verbose=False):
1343 if skip_expected:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001344 raise unittest.SkipTest("No SSL support")
Thomas Woutersed03b412007-08-28 21:37:11 +00001345
Trent Nelson78520002008-04-10 20:54:35 +00001346 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Thomas Woutersed03b412007-08-28 21:37:11 +00001347 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
1348 "keycert.pem")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001349 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1350 os.path.dirname(__file__) or os.curdir,
1351 "https_svn_python_org_root.pem")
1352
1353 if (not os.path.exists(CERTFILE) or
1354 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001355 raise support.TestFailed("Can't read certificate files!")
Bill Janssen6e027db2007-11-15 22:23:56 +00001356
Thomas Woutersed03b412007-08-28 21:37:11 +00001357 tests = [BasicTests]
1358
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001359 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001360 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001361
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001362 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001363 thread_info = support.threading_setup()
1364 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001365 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001366
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001367 support.run_unittest(*tests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001368
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001369 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001370 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001371
1372if __name__ == "__main__":
1373 test_main()