blob: 113b30883bcb07515d5e2a101798f55c77b1af25 [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]
590 self.server = self.HTTPSServer(
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000591 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
592 self.port = self.server.server_port
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
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000673 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000674 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000675 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
676 self.port = support.bind_port(sock, '')
677 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000678 self.listen(5)
679
680 def handle_accept(self):
681 sock_obj, addr = self.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000682 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000683 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
684 self.ConnectionHandler(sock_obj, self.certfile)
685
686 def handle_error(self):
687 raise
688
Trent Nelson78520002008-04-10 20:54:35 +0000689 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000690 self.flag = None
691 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000692 self.server = self.EchoServer(certfile)
693 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000694 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000695 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000696
697 def __str__(self):
698 return "<%s %s>" % (self.__class__.__name__, self.server)
699
700 def start (self, flag=None):
701 self.flag = flag
702 threading.Thread.start(self)
703
704 def run (self):
705 self.active = True
706 if self.flag:
707 self.flag.set()
708 while self.active:
709 try:
710 asyncore.loop(1)
711 except:
712 pass
713
714 def stop (self):
715 self.active = False
716 self.server.close()
717
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000718 def badCertTest (certfile):
Trent Nelson78520002008-04-10 20:54:35 +0000719 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000720 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000721 cacerts=CERTFILE, chatty=False,
722 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000723 flag = threading.Event()
724 server.start(flag)
725 # wait for it to start
726 flag.wait()
727 # try to connect
728 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000729 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000730 s = ssl.wrap_socket(socket.socket(),
731 certfile=certfile,
732 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelson78520002008-04-10 20:54:35 +0000733 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000734 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000735 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000736 sys.stdout.write("\nSSLError is %s\n" % x)
Bill Janssenddc56692008-07-17 18:17:20 +0000737 except socket.error as x:
738 if support.verbose:
739 sys.stdout.write("\nsocket.error is %s\n" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000740 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000741 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000742 "Use of invalid cert should have failed!")
743 finally:
744 server.stop()
745 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000746
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000747 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
Bill Janssen6e027db2007-11-15 22:23:56 +0000748 client_certfile, client_protocol=None,
749 indata="FOO\n",
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000750 ciphers=None, chatty=False, connectionchatty=False):
Thomas Woutersed03b412007-08-28 21:37:11 +0000751
Trent Nelson78520002008-04-10 20:54:35 +0000752 server = ThreadedEchoServer(certfile,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000753 certreqs=certreqs,
754 ssl_version=protocol,
755 cacerts=cacertsfile,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000756 ciphers=ciphers,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000757 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000758 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000759 flag = threading.Event()
760 server.start(flag)
761 # wait for it to start
762 flag.wait()
763 # try to connect
764 if client_protocol is None:
765 client_protocol = protocol
766 try:
Bill Janssen6e027db2007-11-15 22:23:56 +0000767 s = ssl.wrap_socket(socket.socket(),
Trent Nelson6b240cd2008-04-10 20:12:06 +0000768 server_side=False,
Bill Janssen6e027db2007-11-15 22:23:56 +0000769 certfile=client_certfile,
770 ca_certs=cacertsfile,
771 cert_reqs=certreqs,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000772 ciphers=ciphers,
Bill Janssen6e027db2007-11-15 22:23:56 +0000773 ssl_version=client_protocol)
Trent Nelson78520002008-04-10 20:54:35 +0000774 s.connect((HOST, server.port))
Bill Janssen6e027db2007-11-15 22:23:56 +0000775 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000776 raise support.TestFailed("Unexpected SSL error: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000777 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000778 raise support.TestFailed("Unexpected exception: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000779 else:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000780 bindata = indata.encode('ASCII', 'strict')
781 for arg in [bindata, bytearray(bindata), memoryview(bindata)]:
782 if connectionchatty:
783 if support.verbose:
784 sys.stdout.write(
785 " client: sending %s...\n" % (repr(indata)))
786 s.write(arg)
787 outdata = s.read()
788 if connectionchatty:
789 if support.verbose:
790 sys.stdout.write(" client: read %s\n" % repr(outdata))
791 outdata = str(outdata, 'ASCII', 'strict')
792 if outdata != indata.lower():
793 raise support.TestFailed(
794 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
795 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
796 repr(indata[:min(len(indata),20)].lower()), len(indata)))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000797 s.write("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +0000798 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000799 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000800 sys.stdout.write(" client: closing connection.\n")
801 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000802 finally:
803 server.stop()
804 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000805
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000806 def tryProtocolCombo (server_protocol,
807 client_protocol,
808 expectedToWork,
809 certsreqs=None):
Thomas Woutersed03b412007-08-28 21:37:11 +0000810
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000811 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000812 certsreqs = ssl.CERT_NONE
Thomas Woutersed03b412007-08-28 21:37:11 +0000813
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000814 if certsreqs == ssl.CERT_NONE:
815 certtype = "CERT_NONE"
816 elif certsreqs == ssl.CERT_OPTIONAL:
817 certtype = "CERT_OPTIONAL"
818 elif certsreqs == ssl.CERT_REQUIRED:
819 certtype = "CERT_REQUIRED"
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000820 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000821 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
822 sys.stdout.write(formatstr %
823 (ssl.get_protocol_name(client_protocol),
824 ssl.get_protocol_name(server_protocol),
825 certtype))
826 try:
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000827 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
828 # will send an SSLv3 hello (rather than SSLv2) starting from
829 # OpenSSL 1.0.0 (see issue #8322).
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000830 serverParamsTest(CERTFILE, server_protocol, certsreqs,
Bill Janssen6e027db2007-11-15 22:23:56 +0000831 CERTFILE, CERTFILE, client_protocol,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000832 ciphers="ALL",
Bill Janssen6e027db2007-11-15 22:23:56 +0000833 chatty=False, connectionchatty=False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000834 except support.TestFailed:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000835 if expectedToWork:
836 raise
837 else:
838 if not expectedToWork:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000839 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000840 "Client protocol %s succeeded with server protocol %s!"
841 % (ssl.get_protocol_name(client_protocol),
842 ssl.get_protocol_name(server_protocol)))
843
844
Bill Janssen6e027db2007-11-15 22:23:56 +0000845 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000846
Trent Nelson6b240cd2008-04-10 20:12:06 +0000847 def testEcho (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000848
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000849 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000850 sys.stdout.write("\n")
851 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
852 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
853 chatty=True, connectionchatty=True)
854
855 def testReadCert(self):
856
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000857 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000858 sys.stdout.write("\n")
859 s2 = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000860 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000861 certreqs=ssl.CERT_NONE,
862 ssl_version=ssl.PROTOCOL_SSLv23,
863 cacerts=CERTFILE,
864 chatty=False)
865 flag = threading.Event()
866 server.start(flag)
867 # wait for it to start
868 flag.wait()
869 # try to connect
870 try:
871 try:
872 s = ssl.wrap_socket(socket.socket(),
873 certfile=CERTFILE,
874 ca_certs=CERTFILE,
875 cert_reqs=ssl.CERT_REQUIRED,
876 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelson78520002008-04-10 20:54:35 +0000877 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000878 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000879 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000880 "Unexpected SSL error: " + str(x))
881 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000882 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000883 "Unexpected exception: " + str(x))
884 else:
885 if not s:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000886 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000887 "Can't SSL-handshake with test server")
888 cert = s.getpeercert()
889 if not cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000890 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000891 "Can't get peer certificate.")
892 cipher = s.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000893 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000894 sys.stdout.write(pprint.pformat(cert) + '\n')
895 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
Bill Janssen6e027db2007-11-15 22:23:56 +0000896 if 'subject' not in cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000897 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000898 "No subject field in certificate: %s." %
899 pprint.pformat(cert))
900 if ((('organizationName', 'Python Software Foundation'),)
901 not in cert['subject']):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000902 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000903 "Missing or invalid 'organizationName' field in certificate subject; "
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000904 "should be 'Python Software Foundation'.")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000905 s.close()
906 finally:
907 server.stop()
908 server.join()
909
910 def testNULLcert(self):
911 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
912 "nullcert.pem"))
913 def testMalformedCert(self):
914 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
915 "badcert.pem"))
Bill Janssen58afe4c2008-09-08 16:45:19 +0000916 def testWrongCert(self):
917 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
918 "wrongcert.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000919 def testMalformedKey(self):
920 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
921 "badkey.pem"))
922
Trent Nelson6b240cd2008-04-10 20:12:06 +0000923 def testRudeShutdown(self):
924
925 listener_ready = threading.Event()
926 listener_gone = threading.Event()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000927 s = socket.socket()
928 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000929
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000930 # `listener` runs in a thread. It sits in an accept() until
931 # the main thread connects. Then it rudely closes the socket,
932 # and sets Event `listener_gone` to let the main thread know
933 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +0000934 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +0000935 s.listen(5)
936 listener_ready.set()
937 s.accept()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000938 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000939 listener_gone.set()
940
941 def connector():
942 listener_ready.wait()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000943 c = socket.socket()
944 c.connect((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000945 listener_gone.wait()
946 try:
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000947 ssl_sock = ssl.wrap_socket(c)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000948 except IOError:
949 pass
950 else:
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000951 raise test_support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +0000952 'connecting to closed SSL socket should have failed')
953
954 t = threading.Thread(target=listener)
955 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000956 try:
957 connector()
958 finally:
959 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000960
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()