blob: 921205d854cd04aecfda6f9cffdeb19be1ea1e83 [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):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000445 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000446 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
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000499 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
500
501 # need to override translate_path to get a known root,
502 # instead of using os.curdir, since the test could be
503 # run from anywhere
504
505 server_version = "TestHTTPS/1.0"
506
507 root = None
508
509 def translate_path(self, path):
510 """Translate a /-separated PATH to the local filename syntax.
511
512 Components that mean special things to the local file system
513 (e.g. drive or directory names) are ignored. (XXX They should
514 probably be diagnosed.)
515
516 """
517 # abandon query parameters
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000518 path = urllib.parse.urlparse(path)[2]
519 path = os.path.normpath(urllib.parse.unquote(path))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000520 words = path.split('/')
521 words = filter(None, words)
522 path = self.root
523 for word in words:
524 drive, word = os.path.splitdrive(word)
525 head, word = os.path.split(word)
526 if word in self.root: continue
527 path = os.path.join(path, word)
528 return path
529
530 def log_message(self, format, *args):
531
532 # we override this to suppress logging unless "verbose"
533
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000534 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000535 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
536 (self.server.server_address,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000537 self.server.server_port,
538 self.request.cipher(),
539 self.log_date_time_string(),
540 format%args))
Thomas Woutersed03b412007-08-28 21:37:11 +0000541
542
Trent Nelson78520002008-04-10 20:54:35 +0000543 def __init__(self, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000544 self.flag = None
545 self.active = False
546 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
547 self.server = self.HTTPSServer(
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000548 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
549 self.port = self.server.server_port
Thomas Woutersed03b412007-08-28 21:37:11 +0000550 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000551 self.daemon = True
Thomas Woutersed03b412007-08-28 21:37:11 +0000552
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000553 def __str__(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000554 return "<%s %s>" % (self.__class__.__name__, self.server)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000555
556 def start (self, flag=None):
557 self.flag = flag
558 threading.Thread.start(self)
559
Thomas Woutersed03b412007-08-28 21:37:11 +0000560 def run (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000561 self.active = True
562 if self.flag:
563 self.flag.set()
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000564 self.server.serve_forever(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000565 self.active = False
566
567 def stop (self):
568 self.active = False
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000569 self.server.shutdown()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000570
571
Bill Janssen54cc54c2007-12-14 22:08:56 +0000572 class AsyncoreEchoServer(threading.Thread):
573
574 # this one's based on asyncore.dispatcher
575
576 class EchoServer (asyncore.dispatcher):
577
578 class ConnectionHandler (asyncore.dispatcher_with_send):
579
580 def __init__(self, conn, certfile):
581 self.socket = ssl.wrap_socket(conn, server_side=True,
582 certfile=certfile,
583 do_handshake_on_connect=False)
584 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000585 self._ssl_accepting = True
586 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000587
588 def readable(self):
589 if isinstance(self.socket, ssl.SSLSocket):
590 while self.socket.pending() > 0:
591 self.handle_read_event()
592 return True
593
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000594 def _do_ssl_handshake(self):
595 try:
596 self.socket.do_handshake()
597 except ssl.SSLError as err:
598 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
599 ssl.SSL_ERROR_WANT_WRITE):
600 return
601 elif err.args[0] == ssl.SSL_ERROR_EOF:
602 return self.handle_close()
603 raise
604 except socket.error as err:
605 if err.args[0] == errno.ECONNABORTED:
606 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000607 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000608 self._ssl_accepting = False
609
610 def handle_read(self):
611 if self._ssl_accepting:
612 self._do_ssl_handshake()
613 else:
614 data = self.recv(1024)
615 if support.verbose:
616 sys.stdout.write(" server: read %s from client\n" % repr(data))
617 if not data:
618 self.close()
619 else:
620 self.send(str(data, 'ASCII', 'strict').lower().encode('ASCII', 'strict'))
Bill Janssen54cc54c2007-12-14 22:08:56 +0000621
622 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000623 self.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000624 if test_support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000625 sys.stdout.write(" server: closed connection %s\n" % self.socket)
626
627 def handle_error(self):
628 raise
629
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000630 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000631 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000632 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
633 self.port = support.bind_port(sock, '')
634 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000635 self.listen(5)
636
637 def handle_accept(self):
638 sock_obj, addr = self.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000639 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000640 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
641 self.ConnectionHandler(sock_obj, self.certfile)
642
643 def handle_error(self):
644 raise
645
Trent Nelson78520002008-04-10 20:54:35 +0000646 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000647 self.flag = None
648 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000649 self.server = self.EchoServer(certfile)
650 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000651 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000652 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000653
654 def __str__(self):
655 return "<%s %s>" % (self.__class__.__name__, self.server)
656
657 def start (self, flag=None):
658 self.flag = flag
659 threading.Thread.start(self)
660
661 def run (self):
662 self.active = True
663 if self.flag:
664 self.flag.set()
665 while self.active:
666 try:
667 asyncore.loop(1)
668 except:
669 pass
670
671 def stop (self):
672 self.active = False
673 self.server.close()
674
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000675 def badCertTest (certfile):
Trent Nelson78520002008-04-10 20:54:35 +0000676 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000677 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000678 cacerts=CERTFILE, chatty=False,
679 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000680 flag = threading.Event()
681 server.start(flag)
682 # wait for it to start
683 flag.wait()
684 # try to connect
685 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000686 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000687 s = ssl.wrap_socket(socket.socket(),
688 certfile=certfile,
689 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelson78520002008-04-10 20:54:35 +0000690 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000691 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000692 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000693 sys.stdout.write("\nSSLError is %s\n" % x)
Bill Janssenddc56692008-07-17 18:17:20 +0000694 except socket.error as x:
695 if support.verbose:
696 sys.stdout.write("\nsocket.error is %s\n" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000697 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000698 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000699 "Use of invalid cert should have failed!")
700 finally:
701 server.stop()
702 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000703
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000704 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
Bill Janssen6e027db2007-11-15 22:23:56 +0000705 client_certfile, client_protocol=None,
706 indata="FOO\n",
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000707 ciphers=None, chatty=False, connectionchatty=False):
Thomas Woutersed03b412007-08-28 21:37:11 +0000708
Trent Nelson78520002008-04-10 20:54:35 +0000709 server = ThreadedEchoServer(certfile,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000710 certreqs=certreqs,
711 ssl_version=protocol,
712 cacerts=cacertsfile,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000713 ciphers=ciphers,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000714 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000715 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000716 flag = threading.Event()
717 server.start(flag)
718 # wait for it to start
719 flag.wait()
720 # try to connect
721 if client_protocol is None:
722 client_protocol = protocol
723 try:
Bill Janssen6e027db2007-11-15 22:23:56 +0000724 s = ssl.wrap_socket(socket.socket(),
Trent Nelson6b240cd2008-04-10 20:12:06 +0000725 server_side=False,
Bill Janssen6e027db2007-11-15 22:23:56 +0000726 certfile=client_certfile,
727 ca_certs=cacertsfile,
728 cert_reqs=certreqs,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000729 ciphers=ciphers,
Bill Janssen6e027db2007-11-15 22:23:56 +0000730 ssl_version=client_protocol)
Trent Nelson78520002008-04-10 20:54:35 +0000731 s.connect((HOST, server.port))
Bill Janssen6e027db2007-11-15 22:23:56 +0000732 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000733 raise support.TestFailed("Unexpected SSL error: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000734 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000735 raise support.TestFailed("Unexpected exception: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000736 else:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000737 bindata = indata.encode('ASCII', 'strict')
738 for arg in [bindata, bytearray(bindata), memoryview(bindata)]:
739 if connectionchatty:
740 if support.verbose:
741 sys.stdout.write(
742 " client: sending %s...\n" % (repr(indata)))
743 s.write(arg)
744 outdata = s.read()
745 if connectionchatty:
746 if support.verbose:
747 sys.stdout.write(" client: read %s\n" % repr(outdata))
748 outdata = str(outdata, 'ASCII', 'strict')
749 if outdata != indata.lower():
750 raise support.TestFailed(
751 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
752 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
753 repr(indata[:min(len(indata),20)].lower()), len(indata)))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000754 s.write("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +0000755 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000756 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000757 sys.stdout.write(" client: closing connection.\n")
758 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000759 finally:
760 server.stop()
761 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000762
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000763 def tryProtocolCombo (server_protocol,
764 client_protocol,
765 expectedToWork,
766 certsreqs=None):
Thomas Woutersed03b412007-08-28 21:37:11 +0000767
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000768 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000769 certsreqs = ssl.CERT_NONE
Thomas Woutersed03b412007-08-28 21:37:11 +0000770
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000771 if certsreqs == ssl.CERT_NONE:
772 certtype = "CERT_NONE"
773 elif certsreqs == ssl.CERT_OPTIONAL:
774 certtype = "CERT_OPTIONAL"
775 elif certsreqs == ssl.CERT_REQUIRED:
776 certtype = "CERT_REQUIRED"
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000777 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000778 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
779 sys.stdout.write(formatstr %
780 (ssl.get_protocol_name(client_protocol),
781 ssl.get_protocol_name(server_protocol),
782 certtype))
783 try:
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000784 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
785 # will send an SSLv3 hello (rather than SSLv2) starting from
786 # OpenSSL 1.0.0 (see issue #8322).
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000787 serverParamsTest(CERTFILE, server_protocol, certsreqs,
Bill Janssen6e027db2007-11-15 22:23:56 +0000788 CERTFILE, CERTFILE, client_protocol,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000789 ciphers="ALL",
Bill Janssen6e027db2007-11-15 22:23:56 +0000790 chatty=False, connectionchatty=False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000791 except support.TestFailed:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000792 if expectedToWork:
793 raise
794 else:
795 if not expectedToWork:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000796 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000797 "Client protocol %s succeeded with server protocol %s!"
798 % (ssl.get_protocol_name(client_protocol),
799 ssl.get_protocol_name(server_protocol)))
800
801
Bill Janssen6e027db2007-11-15 22:23:56 +0000802 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000803
Trent Nelson6b240cd2008-04-10 20:12:06 +0000804 def testEcho (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000805
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000806 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000807 sys.stdout.write("\n")
808 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
809 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
810 chatty=True, connectionchatty=True)
811
812 def testReadCert(self):
813
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000814 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000815 sys.stdout.write("\n")
816 s2 = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000817 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000818 certreqs=ssl.CERT_NONE,
819 ssl_version=ssl.PROTOCOL_SSLv23,
820 cacerts=CERTFILE,
821 chatty=False)
822 flag = threading.Event()
823 server.start(flag)
824 # wait for it to start
825 flag.wait()
826 # try to connect
827 try:
828 try:
829 s = ssl.wrap_socket(socket.socket(),
830 certfile=CERTFILE,
831 ca_certs=CERTFILE,
832 cert_reqs=ssl.CERT_REQUIRED,
833 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelson78520002008-04-10 20:54:35 +0000834 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000835 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000836 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000837 "Unexpected SSL error: " + str(x))
838 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000839 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000840 "Unexpected exception: " + str(x))
841 else:
842 if not s:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000843 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000844 "Can't SSL-handshake with test server")
845 cert = s.getpeercert()
846 if not cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000847 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000848 "Can't get peer certificate.")
849 cipher = s.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000850 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000851 sys.stdout.write(pprint.pformat(cert) + '\n')
852 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
Bill Janssen6e027db2007-11-15 22:23:56 +0000853 if 'subject' not in cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000854 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000855 "No subject field in certificate: %s." %
856 pprint.pformat(cert))
857 if ((('organizationName', 'Python Software Foundation'),)
858 not in cert['subject']):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000859 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000860 "Missing or invalid 'organizationName' field in certificate subject; "
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000861 "should be 'Python Software Foundation'.")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000862 s.close()
863 finally:
864 server.stop()
865 server.join()
866
867 def testNULLcert(self):
868 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
869 "nullcert.pem"))
870 def testMalformedCert(self):
871 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
872 "badcert.pem"))
Bill Janssen58afe4c2008-09-08 16:45:19 +0000873 def testWrongCert(self):
874 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
875 "wrongcert.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000876 def testMalformedKey(self):
877 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
878 "badkey.pem"))
879
Trent Nelson6b240cd2008-04-10 20:12:06 +0000880 def testRudeShutdown(self):
881
882 listener_ready = threading.Event()
883 listener_gone = threading.Event()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000884 s = socket.socket()
885 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000886
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000887 # `listener` runs in a thread. It sits in an accept() until
888 # the main thread connects. Then it rudely closes the socket,
889 # and sets Event `listener_gone` to let the main thread know
890 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +0000891 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +0000892 s.listen(5)
893 listener_ready.set()
894 s.accept()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000895 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000896 listener_gone.set()
897
898 def connector():
899 listener_ready.wait()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000900 c = socket.socket()
901 c.connect((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000902 listener_gone.wait()
903 try:
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000904 ssl_sock = ssl.wrap_socket(c)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000905 except IOError:
906 pass
907 else:
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000908 raise test_support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +0000909 'connecting to closed SSL socket should have failed')
910
911 t = threading.Thread(target=listener)
912 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000913 try:
914 connector()
915 finally:
916 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000917
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000918 def testProtocolSSL2(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000919 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000920 sys.stdout.write("\n")
921 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
922 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
923 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
924 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
925 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
926 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
927
928 def testProtocolSSL23(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000929 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000930 sys.stdout.write("\n")
931 try:
932 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000933 except support.TestFailed as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000934 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000935 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000936 sys.stdout.write(
937 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
938 % str(x))
939 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
940 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
941 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
942
943 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
944 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
945 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
946
947 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
948 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
949 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
950
951 def testProtocolSSL3(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000952 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000953 sys.stdout.write("\n")
954 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
955 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
956 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
957 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
958 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
959 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
960
961 def testProtocolTLS1(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_TLSv1, ssl.PROTOCOL_TLSv1, True)
965 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
966 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
967 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
968 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
969 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
970
971 def testSTARTTLS (self):
972
Bill Janssen40a0f662008-08-12 16:56:25 +0000973 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000974
Trent Nelson78520002008-04-10 20:54:35 +0000975 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000976 ssl_version=ssl.PROTOCOL_TLSv1,
977 starttls_server=True,
978 chatty=True,
979 connectionchatty=True)
980 flag = threading.Event()
981 server.start(flag)
982 # wait for it to start
983 flag.wait()
984 # try to connect
985 wrapped = False
986 try:
987 try:
988 s = socket.socket()
989 s.setblocking(1)
Trent Nelson78520002008-04-10 20:54:35 +0000990 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000991 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000992 raise support.TestFailed("Unexpected exception: " + str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000993 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000994 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000995 sys.stdout.write("\n")
996 for indata in msgs:
Bill Janssen6e027db2007-11-15 22:23:56 +0000997 msg = indata.encode('ASCII', 'replace')
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000998 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000999 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +00001000 " client: sending %s...\n" % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001001 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +00001002 conn.write(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001003 outdata = conn.read()
1004 else:
Bill Janssen6e027db2007-11-15 22:23:56 +00001005 s.send(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001006 outdata = s.recv(1024)
1007 if (indata == "STARTTLS" and
Bill Janssen6e027db2007-11-15 22:23:56 +00001008 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001009 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001010 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001011 sys.stdout.write(
1012 " client: read %s from server, starting TLS...\n"
Bill Janssen6e027db2007-11-15 22:23:56 +00001013 % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001014 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001015 wrapped = True
Bill Janssen40a0f662008-08-12 16:56:25 +00001016 elif (indata == "ENDTLS" and
1017 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
1018 if support.verbose:
1019 msg = str(outdata, 'ASCII', 'replace')
1020 sys.stdout.write(
1021 " client: read %s from server, ending TLS...\n"
1022 % repr(msg))
1023 s = conn.unwrap()
1024 wrapped = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001025 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001026 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001027 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001028 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +00001029 " client: read %s from server\n" % repr(msg))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001030 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001031 sys.stdout.write(" client: closing connection.\n")
1032 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +00001033 conn.write("over\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001034 else:
Bill Janssen40a0f662008-08-12 16:56:25 +00001035 s.send("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +00001036 if wrapped:
1037 conn.close()
1038 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001039 s.close()
1040 finally:
1041 server.stop()
1042 server.join()
1043
Bill Janssen54cc54c2007-12-14 22:08:56 +00001044 def testSocketServer(self):
Bill Janssen6e027db2007-11-15 22:23:56 +00001045
Trent Nelson78520002008-04-10 20:54:35 +00001046 server = OurHTTPSServer(CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001047 flag = threading.Event()
1048 server.start(flag)
1049 # wait for it to start
1050 flag.wait()
1051 # try to connect
1052 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001053 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001054 sys.stdout.write('\n')
1055 d1 = open(CERTFILE, 'rb').read()
1056 d2 = ''
1057 # now fetch the same data from the HTTPS server
Trent Nelson78520002008-04-10 20:54:35 +00001058 url = 'https://%s:%d/%s' % (
1059 HOST, server.port, os.path.split(CERTFILE)[1])
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001060 f = urllib.request.urlopen(url)
Barry Warsaw820c1202008-06-12 04:06:45 +00001061 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001062 if dlen and (int(dlen) > 0):
1063 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001064 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001065 sys.stdout.write(
1066 " client: read %d bytes from remote server '%s'\n"
1067 % (len(d2), server))
1068 f.close()
1069 except:
1070 msg = ''.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001071 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001072 sys.stdout.write('\n' + msg)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001073 raise support.TestFailed(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001074 else:
1075 if not (d1 == d2):
Bill Janssen6e027db2007-11-15 22:23:56 +00001076 print("d1 is", len(d1), repr(d1))
1077 print("d2 is", len(d2), repr(d2))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001078 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001079 "Couldn't fetch data from HTTPS server")
1080 finally:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001081 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001082 sys.stdout.write('stopping server\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001083 server.stop()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001084 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001085 sys.stdout.write('joining thread\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001086 server.join()
1087
Trent Nelson6b240cd2008-04-10 20:12:06 +00001088 def testAsyncoreServer(self):
1089
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001090 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001091 sys.stdout.write("\n")
1092
1093 indata="FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001094 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001095 flag = threading.Event()
1096 server.start(flag)
1097 # wait for it to start
1098 flag.wait()
1099 # try to connect
1100 try:
1101 s = ssl.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001102 s.connect((HOST, server.port))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001103 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001104 raise support.TestFailed("Unexpected SSL error: " + str(x))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001105 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001106 raise support.TestFailed("Unexpected exception: " + str(x))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001107 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001108 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001109 sys.stdout.write(
1110 " client: sending %s...\n" % (repr(indata)))
1111 s.sendall(indata.encode('ASCII', 'strict'))
1112 outdata = s.recv()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001113 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001114 sys.stdout.write(" client: read %s\n" % repr(outdata))
1115 outdata = str(outdata, 'ASCII', 'strict')
1116 if outdata != indata.lower():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001117 raise support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +00001118 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1119 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
1120 repr(indata[:min(len(indata),20)].lower()), len(indata)))
1121 s.write("over\n".encode("ASCII", "strict"))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001122 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001123 sys.stdout.write(" client: closing connection.\n")
1124 s.close()
1125 finally:
1126 server.stop()
1127 server.join()
1128
Bill Janssen58afe4c2008-09-08 16:45:19 +00001129 def testAllRecvAndSendMethods(self):
1130
1131 if support.verbose:
1132 sys.stdout.write("\n")
1133
1134 server = ThreadedEchoServer(CERTFILE,
1135 certreqs=ssl.CERT_NONE,
1136 ssl_version=ssl.PROTOCOL_TLSv1,
1137 cacerts=CERTFILE,
1138 chatty=True,
1139 connectionchatty=False)
1140 flag = threading.Event()
1141 server.start(flag)
1142 # wait for it to start
1143 flag.wait()
1144 # try to connect
1145 try:
1146 s = ssl.wrap_socket(socket.socket(),
1147 server_side=False,
1148 certfile=CERTFILE,
1149 ca_certs=CERTFILE,
1150 cert_reqs=ssl.CERT_NONE,
1151 ssl_version=ssl.PROTOCOL_TLSv1)
1152 s.connect((HOST, server.port))
1153 except ssl.SSLError as x:
Georg Brandl89fad142010-03-14 10:23:39 +00001154 self.fail("Unexpected SSL error: " + str(x))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001155 except Exception as x:
Georg Brandl89fad142010-03-14 10:23:39 +00001156 self.fail("Unexpected exception: " + str(x))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001157 else:
1158 # helper methods for standardising recv* method signatures
1159 def _recv_into():
1160 b = bytearray(b"\0"*100)
1161 count = s.recv_into(b)
1162 return b[:count]
1163
1164 def _recvfrom_into():
1165 b = bytearray(b"\0"*100)
1166 count, addr = s.recvfrom_into(b)
1167 return b[:count]
1168
1169 # (name, method, whether to expect success, *args)
1170 send_methods = [
1171 ('send', s.send, True, []),
1172 ('sendto', s.sendto, False, ["some.address"]),
1173 ('sendall', s.sendall, True, []),
1174 ]
1175 recv_methods = [
1176 ('recv', s.recv, True, []),
1177 ('recvfrom', s.recvfrom, False, ["some.address"]),
1178 ('recv_into', _recv_into, True, []),
1179 ('recvfrom_into', _recvfrom_into, False, []),
1180 ]
1181 data_prefix = "PREFIX_"
1182
1183 for meth_name, send_meth, expect_success, args in send_methods:
1184 indata = data_prefix + meth_name
1185 try:
1186 send_meth(indata.encode('ASCII', 'strict'), *args)
1187 outdata = s.read()
1188 outdata = str(outdata, 'ASCII', 'strict')
1189 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001190 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001191 "While sending with <<{name:s}>> bad data "
1192 "<<{outdata:s}>> ({nout:d}) received; "
1193 "expected <<{indata:s}>> ({nin:d})\n".format(
1194 name=meth_name, outdata=repr(outdata[:20]),
1195 nout=len(outdata),
1196 indata=repr(indata[:20]), nin=len(indata)
1197 )
1198 )
1199 except ValueError as e:
1200 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001201 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001202 "Failed to send with method <<{name:s}>>; "
1203 "expected to succeed.\n".format(name=meth_name)
1204 )
1205 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001206 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001207 "Method <<{name:s}>> failed with unexpected "
1208 "exception message: {exp:s}\n".format(
1209 name=meth_name, exp=e
1210 )
1211 )
1212
1213 for meth_name, recv_meth, expect_success, args in recv_methods:
1214 indata = data_prefix + meth_name
1215 try:
1216 s.send(indata.encode('ASCII', 'strict'))
1217 outdata = recv_meth(*args)
1218 outdata = str(outdata, 'ASCII', 'strict')
1219 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001220 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001221 "While receiving with <<{name:s}>> bad data "
1222 "<<{outdata:s}>> ({nout:d}) received; "
1223 "expected <<{indata:s}>> ({nin:d})\n".format(
1224 name=meth_name, outdata=repr(outdata[:20]),
1225 nout=len(outdata),
1226 indata=repr(indata[:20]), nin=len(indata)
1227 )
1228 )
1229 except ValueError as e:
1230 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001231 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001232 "Failed to receive with method <<{name:s}>>; "
1233 "expected to succeed.\n".format(name=meth_name)
1234 )
1235 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001236 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001237 "Method <<{name:s}>> failed with unexpected "
1238 "exception message: {exp:s}\n".format(
1239 name=meth_name, exp=e
1240 )
1241 )
1242 # consume data
1243 s.read()
1244
1245 s.write("over\n".encode("ASCII", "strict"))
1246 s.close()
1247 finally:
1248 server.stop()
1249 server.join()
1250
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001251 def test_handshake_timeout(self):
1252 # Issue #5103: SSL handshake must respect the socket timeout
1253 server = socket.socket(socket.AF_INET)
1254 host = "127.0.0.1"
1255 port = support.bind_port(server)
1256 started = threading.Event()
1257 finish = False
1258
1259 def serve():
1260 server.listen(5)
1261 started.set()
1262 conns = []
1263 while not finish:
1264 r, w, e = select.select([server], [], [], 0.1)
1265 if server in r:
1266 # Let the socket hang around rather than having
1267 # it closed by garbage collection.
1268 conns.append(server.accept()[0])
1269
1270 t = threading.Thread(target=serve)
1271 t.start()
1272 started.wait()
1273
1274 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001275 try:
1276 c = socket.socket(socket.AF_INET)
1277 c.settimeout(0.2)
1278 c.connect((host, port))
1279 # Will attempt handshake and time out
1280 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1281 ssl.wrap_socket, c)
1282 finally:
1283 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001284 try:
1285 c = socket.socket(socket.AF_INET)
1286 c = ssl.wrap_socket(c)
1287 c.settimeout(0.2)
1288 # Will attempt handshake and time out
1289 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1290 c.connect, (host, port))
1291 finally:
1292 c.close()
1293 finally:
1294 finish = True
1295 t.join()
1296 server.close()
1297
Bill Janssen58afe4c2008-09-08 16:45:19 +00001298
Thomas Woutersed03b412007-08-28 21:37:11 +00001299def test_main(verbose=False):
1300 if skip_expected:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001301 raise unittest.SkipTest("No SSL support")
Thomas Woutersed03b412007-08-28 21:37:11 +00001302
Trent Nelson78520002008-04-10 20:54:35 +00001303 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Thomas Woutersed03b412007-08-28 21:37:11 +00001304 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
1305 "keycert.pem")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001306 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1307 os.path.dirname(__file__) or os.curdir,
1308 "https_svn_python_org_root.pem")
1309
1310 if (not os.path.exists(CERTFILE) or
1311 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001312 raise support.TestFailed("Can't read certificate files!")
Bill Janssen6e027db2007-11-15 22:23:56 +00001313
Thomas Woutersed03b412007-08-28 21:37:11 +00001314 tests = [BasicTests]
1315
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001316 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001317 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001318
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001319 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001320 thread_info = support.threading_setup()
1321 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001322 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001323
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001324 support.run_unittest(*tests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001325
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001326 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001327 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001328
1329if __name__ == "__main__":
1330 test_main()