blob: bd2aed578b5cbbf8b54ccf6bda07791159bdad61 [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 Pitrou04f6a322010-04-05 21:40:07 +0000154
Bill Janssen6e027db2007-11-15 22:23:56 +0000155class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000156
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000157 def testConnect(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000158 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
159 cert_reqs=ssl.CERT_NONE)
160 s.connect(("svn.python.org", 443))
161 c = s.getpeercert()
162 if c:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000163 raise support.TestFailed("Peer cert %s shouldn't be here!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000164 s.close()
165
166 # this should fail because we have no verification certs
167 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
168 cert_reqs=ssl.CERT_REQUIRED)
Thomas Woutersed03b412007-08-28 21:37:11 +0000169 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000170 s.connect(("svn.python.org", 443))
171 except ssl.SSLError:
172 pass
173 finally:
174 s.close()
175
176 # this should succeed because we specify the root cert
177 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
178 cert_reqs=ssl.CERT_REQUIRED,
179 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
180 try:
181 s.connect(("svn.python.org", 443))
182 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000183 raise support.TestFailed("Unexpected exception %s" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000184 finally:
185 s.close()
186
Antoine Pitroue3220242010-04-24 11:13:53 +0000187 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
188 def test_makefile_close(self):
189 # Issue #5238: creating a file-like object with makefile() shouldn't
190 # delay closing the underlying "real socket" (here tested with its
191 # file descriptor, hence skipping the test under Windows).
192 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
193 ss.connect(("svn.python.org", 443))
194 fd = ss.fileno()
195 f = ss.makefile()
196 f.close()
197 # The fd is still open
198 os.read(fd, 0)
199 # Closing the SSL socket should close the fd too
200 ss.close()
201 gc.collect()
202 with self.assertRaises(OSError) as e:
203 os.read(fd, 0)
204 self.assertEqual(e.exception.errno, errno.EBADF)
205
Bill Janssen6e027db2007-11-15 22:23:56 +0000206 def testNonBlockingHandshake(self):
207 s = socket.socket(socket.AF_INET)
208 s.connect(("svn.python.org", 443))
209 s.setblocking(False)
210 s = ssl.wrap_socket(s,
211 cert_reqs=ssl.CERT_NONE,
212 do_handshake_on_connect=False)
213 count = 0
214 while True:
215 try:
216 count += 1
217 s.do_handshake()
218 break
219 except ssl.SSLError as err:
220 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
221 select.select([s], [], [])
222 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
223 select.select([], [s], [])
224 else:
225 raise
226 s.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000227 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000228 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000229
Bill Janssen54cc54c2007-12-14 22:08:56 +0000230 def testFetchServerCert(self):
231
232 pem = ssl.get_server_certificate(("svn.python.org", 443))
233 if not pem:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000234 raise support.TestFailed("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000235
236 return
237
238 try:
239 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
240 except ssl.SSLError as x:
241 #should fail
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000242 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000243 sys.stdout.write("%s\n" % x)
244 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000245 raise support.TestFailed("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000246
247 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
248 if not pem:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000249 raise support.TestFailed("No server certificate on svn.python.org:443!")
250 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000251 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
252
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000253 def test_algorithms(self):
254 # Issue #8484: all algorithms should be available when verifying a
255 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000256 # SHA256 was added in OpenSSL 0.9.8
257 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
258 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000259 # NOTE: https://sha256.tbs-internet.com is another possible test host
260 remote = ("sha2.hboeck.de", 443)
261 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
262 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
263 cert_reqs=ssl.CERT_REQUIRED,
264 ca_certs=sha256_cert,)
265 with support.transient_internet():
266 try:
267 s.connect(remote)
268 if support.verbose:
269 sys.stdout.write("\nCipher with %r is %r\n" %
270 (remote, s.cipher()))
271 sys.stdout.write("Certificate is:\n%s\n" %
272 pprint.pformat(s.getpeercert()))
273 finally:
274 s.close()
275
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000276
277try:
278 import threading
279except ImportError:
280 _have_threads = False
281else:
282
283 _have_threads = True
284
285 class ThreadedEchoServer(threading.Thread):
286
287 class ConnectionHandler(threading.Thread):
288
289 """A mildly complicated class, because we want it to work both
290 with and without the SSL wrapper around the socket connection, so
291 that we can test the STARTTLS functionality."""
292
Bill Janssen6e027db2007-11-15 22:23:56 +0000293 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000294 self.server = server
295 self.running = False
296 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000297 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000298 self.sock.setblocking(1)
299 self.sslconn = None
300 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000301 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000302
303 def wrap_conn (self):
304 try:
305 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
306 certfile=self.server.certificate,
307 ssl_version=self.server.protocol,
308 ca_certs=self.server.cacerts,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000309 cert_reqs=self.server.certreqs,
310 ciphers=self.server.ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000311 except:
312 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000313 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000314 if not self.server.expect_bad_connects:
315 # here, we want to stop the server, because this shouldn't
316 # happen in the context of our test case
317 self.running = False
318 # normally, we'd just stop here, but for the test
319 # harness, we want to stop the server
320 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000321 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000322 return False
323
324 else:
325 if self.server.certreqs == ssl.CERT_REQUIRED:
326 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000327 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000328 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
329 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000330 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000331 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
332 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000333 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000334 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
335 return True
336
337 def read(self):
338 if self.sslconn:
339 return self.sslconn.read()
340 else:
341 return self.sock.recv(1024)
342
343 def write(self, bytes):
344 if self.sslconn:
345 return self.sslconn.write(bytes)
346 else:
347 return self.sock.send(bytes)
348
349 def close(self):
350 if self.sslconn:
351 self.sslconn.close()
352 else:
353 self.sock.close()
354
355 def run (self):
356 self.running = True
357 if not self.server.starttls_server:
358 if not self.wrap_conn():
359 return
360 while self.running:
361 try:
362 msg = self.read()
Bill Janssen6e027db2007-11-15 22:23:56 +0000363 amsg = (msg and str(msg, 'ASCII', 'strict')) or ''
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000364 if not msg:
365 # eof, so quit this handler
366 self.running = False
367 self.close()
Bill Janssen6e027db2007-11-15 22:23:56 +0000368 elif amsg.strip() == 'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000369 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000370 sys.stdout.write(" server: client closed connection\n")
371 self.close()
372 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000373 elif (self.server.starttls_server and
374 amsg.strip() == 'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000375 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000376 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000377 self.write("OK\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000378 if not self.wrap_conn():
379 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000380 elif (self.server.starttls_server and self.sslconn
381 and amsg.strip() == 'ENDTLS'):
382 if support.verbose and self.server.connectionchatty:
383 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
384 self.write("OK\n".encode("ASCII", "strict"))
385 self.sock = self.sslconn.unwrap()
386 self.sslconn = None
387 if support.verbose and self.server.connectionchatty:
388 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000389 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000390 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000391 self.server.connectionchatty):
392 ctype = (self.sslconn and "encrypted") or "unencrypted"
393 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
394 % (repr(msg), ctype, repr(msg.lower()), ctype))
Bill Janssen6e027db2007-11-15 22:23:56 +0000395 self.write(amsg.lower().encode('ASCII', 'strict'))
396 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000397 if self.server.chatty:
398 handle_error("Test server failure:\n")
399 self.close()
400 self.running = False
401 # normally, we'd just stop here, but for the test
402 # harness, we want to stop the server
403 self.server.stop()
404 except:
405 handle_error('')
406
Trent Nelson78520002008-04-10 20:54:35 +0000407 def __init__(self, certificate, ssl_version=None,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000408 certreqs=None, cacerts=None, expect_bad_connects=False,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000409 chatty=True, connectionchatty=False, starttls_server=False,
410 ciphers=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000411 if ssl_version is None:
412 ssl_version = ssl.PROTOCOL_TLSv1
413 if certreqs is None:
414 certreqs = ssl.CERT_NONE
415 self.certificate = certificate
416 self.protocol = ssl_version
417 self.certreqs = certreqs
418 self.cacerts = cacerts
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000419 self.ciphers = ciphers
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000420 self.expect_bad_connects = expect_bad_connects
421 self.chatty = chatty
422 self.connectionchatty = connectionchatty
423 self.starttls_server = starttls_server
424 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000425 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000426 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000427 self.active = False
428 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000429 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000430
431 def start (self, flag=None):
432 self.flag = flag
433 threading.Thread.start(self)
434
435 def run (self):
436 self.sock.settimeout(0.5)
437 self.sock.listen(5)
438 self.active = True
439 if self.flag:
440 # signal an event
441 self.flag.set()
442 while self.active:
443 try:
444 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000445 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000446 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000447 + repr(connaddr) + '\n')
448 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000449 handler.start()
450 except socket.timeout:
451 pass
452 except KeyboardInterrupt:
453 self.stop()
454 except:
455 if self.chatty:
456 handle_error("Test server failure:\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000457 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000458
459 def stop (self):
460 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000461
Bill Janssen54cc54c2007-12-14 22:08:56 +0000462 class OurHTTPSServer(threading.Thread):
463
464 # This one's based on HTTPServer, which is based on SocketServer
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000465
466 class HTTPSServer(HTTPServer):
467
468 def __init__(self, server_address, RequestHandlerClass, certfile):
469
470 HTTPServer.__init__(self, server_address, RequestHandlerClass)
471 # we assume the certfile contains both private key and certificate
472 self.certfile = certfile
473 self.active = False
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000474 self.active_lock = threading.Lock()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000475 self.allow_reuse_address = True
476
Bill Janssen6e027db2007-11-15 22:23:56 +0000477 def __str__(self):
478 return ('<%s %s:%s>' %
479 (self.__class__.__name__,
480 self.server_name,
481 self.server_port))
482
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000483 def get_request (self):
484 # override this to wrap socket with SSL
485 sock, addr = self.socket.accept()
486 sslconn = ssl.wrap_socket(sock, server_side=True,
487 certfile=self.certfile)
488 return sslconn, addr
489
490 # The methods overridden below this are mainly so that we
491 # can run it in a thread and be able to stop it from another
492 # You probably wouldn't need them in other uses.
493
494 def server_activate(self):
495 # We want to run this in a thread for testing purposes,
496 # so we override this to set timeout, so that we get
497 # a chance to stop the server
498 self.socket.settimeout(0.5)
499 HTTPServer.server_activate(self)
500
501 def serve_forever(self):
502 # We want this to run in a thread, so we use a slightly
503 # modified version of "forever".
504 self.active = True
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000505 while 1:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000506 try:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000507 # We need to lock while handling the request.
508 # Another thread can close the socket after self.active
509 # has been checked and before the request is handled.
510 # This causes an exception when using the closed socket.
511 with self.active_lock:
512 if not self.active:
513 break
514 self.handle_request()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000515 except socket.timeout:
516 pass
517 except KeyboardInterrupt:
518 self.server_close()
519 return
520 except:
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000521 sys.stdout.write(''.join(traceback.format_exception(*sys.exc_info())))
522 break
Neal Norwitzf9ff5f02008-03-31 05:39:26 +0000523 time.sleep(0.1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000524
525 def server_close(self):
526 # Again, we want this to run in a thread, so we need to override
527 # close to clear the "active" flag, so that serve_forever() will
528 # terminate.
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000529 with self.active_lock:
530 HTTPServer.server_close(self)
531 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000532
533 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
534
535 # need to override translate_path to get a known root,
536 # instead of using os.curdir, since the test could be
537 # run from anywhere
538
539 server_version = "TestHTTPS/1.0"
540
541 root = None
542
543 def translate_path(self, path):
544 """Translate a /-separated PATH to the local filename syntax.
545
546 Components that mean special things to the local file system
547 (e.g. drive or directory names) are ignored. (XXX They should
548 probably be diagnosed.)
549
550 """
551 # abandon query parameters
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000552 path = urllib.parse.urlparse(path)[2]
553 path = os.path.normpath(urllib.parse.unquote(path))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000554 words = path.split('/')
555 words = filter(None, words)
556 path = self.root
557 for word in words:
558 drive, word = os.path.splitdrive(word)
559 head, word = os.path.split(word)
560 if word in self.root: continue
561 path = os.path.join(path, word)
562 return path
563
564 def log_message(self, format, *args):
565
566 # we override this to suppress logging unless "verbose"
567
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000568 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000569 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
570 (self.server.server_address,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000571 self.server.server_port,
572 self.request.cipher(),
573 self.log_date_time_string(),
574 format%args))
Thomas Woutersed03b412007-08-28 21:37:11 +0000575
576
Trent Nelson78520002008-04-10 20:54:35 +0000577 def __init__(self, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000578 self.flag = None
579 self.active = False
580 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000581 self.port = support.find_unused_port()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000582 self.server = self.HTTPSServer(
Trent Nelson78520002008-04-10 20:54:35 +0000583 (HOST, self.port), self.RootedHTTPRequestHandler, certfile)
Thomas Woutersed03b412007-08-28 21:37:11 +0000584 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000585 self.daemon = True
Thomas Woutersed03b412007-08-28 21:37:11 +0000586
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000587 def __str__(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000588 return "<%s %s>" % (self.__class__.__name__, self.server)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000589
590 def start (self, flag=None):
591 self.flag = flag
592 threading.Thread.start(self)
593
Thomas Woutersed03b412007-08-28 21:37:11 +0000594 def run (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000595 self.active = True
596 if self.flag:
597 self.flag.set()
598 self.server.serve_forever()
599 self.active = False
600
601 def stop (self):
602 self.active = False
603 self.server.server_close()
604
605
Bill Janssen54cc54c2007-12-14 22:08:56 +0000606 class AsyncoreEchoServer(threading.Thread):
607
608 # this one's based on asyncore.dispatcher
609
610 class EchoServer (asyncore.dispatcher):
611
612 class ConnectionHandler (asyncore.dispatcher_with_send):
613
614 def __init__(self, conn, certfile):
615 self.socket = ssl.wrap_socket(conn, server_side=True,
616 certfile=certfile,
617 do_handshake_on_connect=False)
618 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000619 self._ssl_accepting = True
620 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000621
622 def readable(self):
623 if isinstance(self.socket, ssl.SSLSocket):
624 while self.socket.pending() > 0:
625 self.handle_read_event()
626 return True
627
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000628 def _do_ssl_handshake(self):
629 try:
630 self.socket.do_handshake()
631 except ssl.SSLError as err:
632 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
633 ssl.SSL_ERROR_WANT_WRITE):
634 return
635 elif err.args[0] == ssl.SSL_ERROR_EOF:
636 return self.handle_close()
637 raise
638 except socket.error as err:
639 if err.args[0] == errno.ECONNABORTED:
640 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000641 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000642 self._ssl_accepting = False
643
644 def handle_read(self):
645 if self._ssl_accepting:
646 self._do_ssl_handshake()
647 else:
648 data = self.recv(1024)
649 if support.verbose:
650 sys.stdout.write(" server: read %s from client\n" % repr(data))
651 if not data:
652 self.close()
653 else:
654 self.send(str(data, 'ASCII', 'strict').lower().encode('ASCII', 'strict'))
Bill Janssen54cc54c2007-12-14 22:08:56 +0000655
656 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000657 self.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000658 if test_support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000659 sys.stdout.write(" server: closed connection %s\n" % self.socket)
660
661 def handle_error(self):
662 raise
663
664 def __init__(self, port, certfile):
665 self.port = port
666 self.certfile = certfile
667 asyncore.dispatcher.__init__(self)
668 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
669 self.bind(('', port))
670 self.listen(5)
671
672 def handle_accept(self):
673 sock_obj, addr = self.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000674 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000675 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
676 self.ConnectionHandler(sock_obj, self.certfile)
677
678 def handle_error(self):
679 raise
680
Trent Nelson78520002008-04-10 20:54:35 +0000681 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000682 self.flag = None
683 self.active = False
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000684 self.port = support.find_unused_port()
Trent Nelson78520002008-04-10 20:54:35 +0000685 self.server = self.EchoServer(self.port, certfile)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000686 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000687 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000688
689 def __str__(self):
690 return "<%s %s>" % (self.__class__.__name__, self.server)
691
692 def start (self, flag=None):
693 self.flag = flag
694 threading.Thread.start(self)
695
696 def run (self):
697 self.active = True
698 if self.flag:
699 self.flag.set()
700 while self.active:
701 try:
702 asyncore.loop(1)
703 except:
704 pass
705
706 def stop (self):
707 self.active = False
708 self.server.close()
709
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000710 def badCertTest (certfile):
Trent Nelson78520002008-04-10 20:54:35 +0000711 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000712 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000713 cacerts=CERTFILE, chatty=False,
714 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000715 flag = threading.Event()
716 server.start(flag)
717 # wait for it to start
718 flag.wait()
719 # try to connect
720 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000721 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000722 s = ssl.wrap_socket(socket.socket(),
723 certfile=certfile,
724 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelson78520002008-04-10 20:54:35 +0000725 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000726 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000727 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000728 sys.stdout.write("\nSSLError is %s\n" % x)
Bill Janssenddc56692008-07-17 18:17:20 +0000729 except socket.error as x:
730 if support.verbose:
731 sys.stdout.write("\nsocket.error is %s\n" % x)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000732 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000733 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000734 "Use of invalid cert should have failed!")
735 finally:
736 server.stop()
737 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000738
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000739 def serverParamsTest (certfile, protocol, certreqs, cacertsfile,
Bill Janssen6e027db2007-11-15 22:23:56 +0000740 client_certfile, client_protocol=None,
741 indata="FOO\n",
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000742 ciphers=None, chatty=False, connectionchatty=False):
Thomas Woutersed03b412007-08-28 21:37:11 +0000743
Trent Nelson78520002008-04-10 20:54:35 +0000744 server = ThreadedEchoServer(certfile,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000745 certreqs=certreqs,
746 ssl_version=protocol,
747 cacerts=cacertsfile,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000748 ciphers=ciphers,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000749 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000750 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000751 flag = threading.Event()
752 server.start(flag)
753 # wait for it to start
754 flag.wait()
755 # try to connect
756 if client_protocol is None:
757 client_protocol = protocol
758 try:
Bill Janssen6e027db2007-11-15 22:23:56 +0000759 s = ssl.wrap_socket(socket.socket(),
Trent Nelson6b240cd2008-04-10 20:12:06 +0000760 server_side=False,
Bill Janssen6e027db2007-11-15 22:23:56 +0000761 certfile=client_certfile,
762 ca_certs=cacertsfile,
763 cert_reqs=certreqs,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000764 ciphers=ciphers,
Bill Janssen6e027db2007-11-15 22:23:56 +0000765 ssl_version=client_protocol)
Trent Nelson78520002008-04-10 20:54:35 +0000766 s.connect((HOST, server.port))
Bill Janssen6e027db2007-11-15 22:23:56 +0000767 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000768 raise support.TestFailed("Unexpected SSL error: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000769 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000770 raise support.TestFailed("Unexpected exception: " + str(x))
Bill Janssen6e027db2007-11-15 22:23:56 +0000771 else:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000772 bindata = indata.encode('ASCII', 'strict')
773 for arg in [bindata, bytearray(bindata), memoryview(bindata)]:
774 if connectionchatty:
775 if support.verbose:
776 sys.stdout.write(
777 " client: sending %s...\n" % (repr(indata)))
778 s.write(arg)
779 outdata = s.read()
780 if connectionchatty:
781 if support.verbose:
782 sys.stdout.write(" client: read %s\n" % repr(outdata))
783 outdata = str(outdata, 'ASCII', 'strict')
784 if outdata != indata.lower():
785 raise support.TestFailed(
786 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
787 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
788 repr(indata[:min(len(indata),20)].lower()), len(indata)))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000789 s.write("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +0000790 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000791 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000792 sys.stdout.write(" client: closing connection.\n")
793 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000794 finally:
795 server.stop()
796 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000797
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000798 def tryProtocolCombo (server_protocol,
799 client_protocol,
800 expectedToWork,
801 certsreqs=None):
Thomas Woutersed03b412007-08-28 21:37:11 +0000802
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000803 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000804 certsreqs = ssl.CERT_NONE
Thomas Woutersed03b412007-08-28 21:37:11 +0000805
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000806 if certsreqs == ssl.CERT_NONE:
807 certtype = "CERT_NONE"
808 elif certsreqs == ssl.CERT_OPTIONAL:
809 certtype = "CERT_OPTIONAL"
810 elif certsreqs == ssl.CERT_REQUIRED:
811 certtype = "CERT_REQUIRED"
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000812 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000813 formatstr = (expectedToWork and " %s->%s %s\n") or " {%s->%s} %s\n"
814 sys.stdout.write(formatstr %
815 (ssl.get_protocol_name(client_protocol),
816 ssl.get_protocol_name(server_protocol),
817 certtype))
818 try:
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000819 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
820 # will send an SSLv3 hello (rather than SSLv2) starting from
821 # OpenSSL 1.0.0 (see issue #8322).
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000822 serverParamsTest(CERTFILE, server_protocol, certsreqs,
Bill Janssen6e027db2007-11-15 22:23:56 +0000823 CERTFILE, CERTFILE, client_protocol,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000824 ciphers="ALL",
Bill Janssen6e027db2007-11-15 22:23:56 +0000825 chatty=False, connectionchatty=False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000826 except support.TestFailed:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000827 if expectedToWork:
828 raise
829 else:
830 if not expectedToWork:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000831 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000832 "Client protocol %s succeeded with server protocol %s!"
833 % (ssl.get_protocol_name(client_protocol),
834 ssl.get_protocol_name(server_protocol)))
835
836
Bill Janssen6e027db2007-11-15 22:23:56 +0000837 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000838
Trent Nelson6b240cd2008-04-10 20:12:06 +0000839 def testEcho (self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000840
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000841 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000842 sys.stdout.write("\n")
843 serverParamsTest(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
844 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
845 chatty=True, connectionchatty=True)
846
847 def testReadCert(self):
848
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000849 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000850 sys.stdout.write("\n")
851 s2 = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000852 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000853 certreqs=ssl.CERT_NONE,
854 ssl_version=ssl.PROTOCOL_SSLv23,
855 cacerts=CERTFILE,
856 chatty=False)
857 flag = threading.Event()
858 server.start(flag)
859 # wait for it to start
860 flag.wait()
861 # try to connect
862 try:
863 try:
864 s = ssl.wrap_socket(socket.socket(),
865 certfile=CERTFILE,
866 ca_certs=CERTFILE,
867 cert_reqs=ssl.CERT_REQUIRED,
868 ssl_version=ssl.PROTOCOL_SSLv23)
Trent Nelson78520002008-04-10 20:54:35 +0000869 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000870 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000871 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000872 "Unexpected SSL error: " + str(x))
873 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000874 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000875 "Unexpected exception: " + str(x))
876 else:
877 if not s:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000878 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000879 "Can't SSL-handshake with test server")
880 cert = s.getpeercert()
881 if not cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000882 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000883 "Can't get peer certificate.")
884 cipher = s.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000885 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000886 sys.stdout.write(pprint.pformat(cert) + '\n')
887 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
Bill Janssen6e027db2007-11-15 22:23:56 +0000888 if 'subject' not in cert:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000889 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000890 "No subject field in certificate: %s." %
891 pprint.pformat(cert))
892 if ((('organizationName', 'Python Software Foundation'),)
893 not in cert['subject']):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000894 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000895 "Missing or invalid 'organizationName' field in certificate subject; "
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000896 "should be 'Python Software Foundation'.")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000897 s.close()
898 finally:
899 server.stop()
900 server.join()
901
902 def testNULLcert(self):
903 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
904 "nullcert.pem"))
905 def testMalformedCert(self):
906 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
907 "badcert.pem"))
Bill Janssen58afe4c2008-09-08 16:45:19 +0000908 def testWrongCert(self):
909 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
910 "wrongcert.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000911 def testMalformedKey(self):
912 badCertTest(os.path.join(os.path.dirname(__file__) or os.curdir,
913 "badkey.pem"))
914
Trent Nelson6b240cd2008-04-10 20:12:06 +0000915 def testRudeShutdown(self):
916
917 listener_ready = threading.Event()
918 listener_gone = threading.Event()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000919 port = support.find_unused_port()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000920
921 # `listener` runs in a thread. It opens a socket listening on
922 # PORT, and sits in an accept() until the main thread connects.
923 # Then it rudely closes the socket, and sets Event `listener_gone`
924 # to let the main thread know the socket is gone.
925 def listener():
926 s = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000927 s.bind((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000928 s.listen(5)
929 listener_ready.set()
930 s.accept()
931 s = None # reclaim the socket object, which also closes it
932 listener_gone.set()
933
934 def connector():
935 listener_ready.wait()
936 s = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000937 s.connect((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000938 listener_gone.wait()
939 try:
940 ssl_sock = ssl.wrap_socket(s)
941 except IOError:
942 pass
943 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000944 raise support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +0000945 'connecting to closed SSL socket should have failed')
946
947 t = threading.Thread(target=listener)
948 t.start()
949 connector()
950 t.join()
951
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000952 def testProtocolSSL2(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000953 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000954 sys.stdout.write("\n")
955 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
956 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
957 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
958 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
959 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
960 tryProtocolCombo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
961
962 def testProtocolSSL23(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000963 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000964 sys.stdout.write("\n")
965 try:
966 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000967 except support.TestFailed as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000968 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000969 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000970 sys.stdout.write(
971 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
972 % str(x))
973 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
974 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
975 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
976
977 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
978 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
979 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
980
981 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
982 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
983 tryProtocolCombo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
984
985 def testProtocolSSL3(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000986 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000987 sys.stdout.write("\n")
988 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
989 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
990 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
991 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
992 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
993 tryProtocolCombo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
994
995 def testProtocolTLS1(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000996 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000997 sys.stdout.write("\n")
998 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
999 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1000 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1001 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1002 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1003 tryProtocolCombo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
1004
1005 def testSTARTTLS (self):
1006
Bill Janssen40a0f662008-08-12 16:56:25 +00001007 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001008
Trent Nelson78520002008-04-10 20:54:35 +00001009 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001010 ssl_version=ssl.PROTOCOL_TLSv1,
1011 starttls_server=True,
1012 chatty=True,
1013 connectionchatty=True)
1014 flag = threading.Event()
1015 server.start(flag)
1016 # wait for it to start
1017 flag.wait()
1018 # try to connect
1019 wrapped = False
1020 try:
1021 try:
1022 s = socket.socket()
1023 s.setblocking(1)
Trent Nelson78520002008-04-10 20:54:35 +00001024 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001025 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001026 raise support.TestFailed("Unexpected exception: " + str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001027 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001028 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001029 sys.stdout.write("\n")
1030 for indata in msgs:
Bill Janssen6e027db2007-11-15 22:23:56 +00001031 msg = indata.encode('ASCII', 'replace')
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001032 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001033 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +00001034 " client: sending %s...\n" % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001035 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +00001036 conn.write(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001037 outdata = conn.read()
1038 else:
Bill Janssen6e027db2007-11-15 22:23:56 +00001039 s.send(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001040 outdata = s.recv(1024)
1041 if (indata == "STARTTLS" and
Bill Janssen6e027db2007-11-15 22:23:56 +00001042 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001043 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001044 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001045 sys.stdout.write(
1046 " client: read %s from server, starting TLS...\n"
Bill Janssen6e027db2007-11-15 22:23:56 +00001047 % repr(msg))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001048 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001049 wrapped = True
Bill Janssen40a0f662008-08-12 16:56:25 +00001050 elif (indata == "ENDTLS" and
1051 str(outdata, 'ASCII', 'replace').strip().lower().startswith("ok")):
1052 if support.verbose:
1053 msg = str(outdata, 'ASCII', 'replace')
1054 sys.stdout.write(
1055 " client: read %s from server, ending TLS...\n"
1056 % repr(msg))
1057 s = conn.unwrap()
1058 wrapped = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001059 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001060 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001061 msg = str(outdata, 'ASCII', 'replace')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001062 sys.stdout.write(
Bill Janssen6e027db2007-11-15 22:23:56 +00001063 " client: read %s from server\n" % repr(msg))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001064 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001065 sys.stdout.write(" client: closing connection.\n")
1066 if wrapped:
Bill Janssen6e027db2007-11-15 22:23:56 +00001067 conn.write("over\n".encode("ASCII", "strict"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001068 else:
Bill Janssen40a0f662008-08-12 16:56:25 +00001069 s.send("over\n".encode("ASCII", "strict"))
Bill Janssen6e027db2007-11-15 22:23:56 +00001070 if wrapped:
1071 conn.close()
1072 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001073 s.close()
1074 finally:
1075 server.stop()
1076 server.join()
1077
Bill Janssen54cc54c2007-12-14 22:08:56 +00001078 def testSocketServer(self):
Bill Janssen6e027db2007-11-15 22:23:56 +00001079
Trent Nelson78520002008-04-10 20:54:35 +00001080 server = OurHTTPSServer(CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001081 flag = threading.Event()
1082 server.start(flag)
1083 # wait for it to start
1084 flag.wait()
1085 # try to connect
1086 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001087 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001088 sys.stdout.write('\n')
1089 d1 = open(CERTFILE, 'rb').read()
1090 d2 = ''
1091 # now fetch the same data from the HTTPS server
Trent Nelson78520002008-04-10 20:54:35 +00001092 url = 'https://%s:%d/%s' % (
1093 HOST, server.port, os.path.split(CERTFILE)[1])
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001094 f = urllib.request.urlopen(url)
Barry Warsaw820c1202008-06-12 04:06:45 +00001095 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001096 if dlen and (int(dlen) > 0):
1097 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001098 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001099 sys.stdout.write(
1100 " client: read %d bytes from remote server '%s'\n"
1101 % (len(d2), server))
1102 f.close()
1103 except:
1104 msg = ''.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001105 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001106 sys.stdout.write('\n' + msg)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001107 raise support.TestFailed(msg)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001108 else:
1109 if not (d1 == d2):
Bill Janssen6e027db2007-11-15 22:23:56 +00001110 print("d1 is", len(d1), repr(d1))
1111 print("d2 is", len(d2), repr(d2))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001112 raise support.TestFailed(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001113 "Couldn't fetch data from HTTPS server")
1114 finally:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001115 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001116 sys.stdout.write('stopping server\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001117 server.stop()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001118 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001119 sys.stdout.write('joining thread\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001120 server.join()
1121
Trent Nelson6b240cd2008-04-10 20:12:06 +00001122 def testAsyncoreServer(self):
1123
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001124 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001125 sys.stdout.write("\n")
1126
1127 indata="FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001128 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001129 flag = threading.Event()
1130 server.start(flag)
1131 # wait for it to start
1132 flag.wait()
1133 # try to connect
1134 try:
1135 s = ssl.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001136 s.connect((HOST, server.port))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001137 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001138 raise support.TestFailed("Unexpected SSL error: " + str(x))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001139 except Exception as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001140 raise support.TestFailed("Unexpected exception: " + str(x))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001141 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001142 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001143 sys.stdout.write(
1144 " client: sending %s...\n" % (repr(indata)))
1145 s.sendall(indata.encode('ASCII', 'strict'))
1146 outdata = s.recv()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001147 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001148 sys.stdout.write(" client: read %s\n" % repr(outdata))
1149 outdata = str(outdata, 'ASCII', 'strict')
1150 if outdata != indata.lower():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001151 raise support.TestFailed(
Trent Nelson6b240cd2008-04-10 20:12:06 +00001152 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1153 % (repr(outdata[:min(len(outdata),20)]), len(outdata),
1154 repr(indata[:min(len(indata),20)].lower()), len(indata)))
1155 s.write("over\n".encode("ASCII", "strict"))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001156 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001157 sys.stdout.write(" client: closing connection.\n")
1158 s.close()
1159 finally:
1160 server.stop()
1161 server.join()
1162
Bill Janssen58afe4c2008-09-08 16:45:19 +00001163 def testAllRecvAndSendMethods(self):
1164
1165 if support.verbose:
1166 sys.stdout.write("\n")
1167
1168 server = ThreadedEchoServer(CERTFILE,
1169 certreqs=ssl.CERT_NONE,
1170 ssl_version=ssl.PROTOCOL_TLSv1,
1171 cacerts=CERTFILE,
1172 chatty=True,
1173 connectionchatty=False)
1174 flag = threading.Event()
1175 server.start(flag)
1176 # wait for it to start
1177 flag.wait()
1178 # try to connect
1179 try:
1180 s = ssl.wrap_socket(socket.socket(),
1181 server_side=False,
1182 certfile=CERTFILE,
1183 ca_certs=CERTFILE,
1184 cert_reqs=ssl.CERT_NONE,
1185 ssl_version=ssl.PROTOCOL_TLSv1)
1186 s.connect((HOST, server.port))
1187 except ssl.SSLError as x:
Georg Brandl89fad142010-03-14 10:23:39 +00001188 self.fail("Unexpected SSL error: " + str(x))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001189 except Exception as x:
Georg Brandl89fad142010-03-14 10:23:39 +00001190 self.fail("Unexpected exception: " + str(x))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001191 else:
1192 # helper methods for standardising recv* method signatures
1193 def _recv_into():
1194 b = bytearray(b"\0"*100)
1195 count = s.recv_into(b)
1196 return b[:count]
1197
1198 def _recvfrom_into():
1199 b = bytearray(b"\0"*100)
1200 count, addr = s.recvfrom_into(b)
1201 return b[:count]
1202
1203 # (name, method, whether to expect success, *args)
1204 send_methods = [
1205 ('send', s.send, True, []),
1206 ('sendto', s.sendto, False, ["some.address"]),
1207 ('sendall', s.sendall, True, []),
1208 ]
1209 recv_methods = [
1210 ('recv', s.recv, True, []),
1211 ('recvfrom', s.recvfrom, False, ["some.address"]),
1212 ('recv_into', _recv_into, True, []),
1213 ('recvfrom_into', _recvfrom_into, False, []),
1214 ]
1215 data_prefix = "PREFIX_"
1216
1217 for meth_name, send_meth, expect_success, args in send_methods:
1218 indata = data_prefix + meth_name
1219 try:
1220 send_meth(indata.encode('ASCII', 'strict'), *args)
1221 outdata = s.read()
1222 outdata = str(outdata, 'ASCII', 'strict')
1223 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001224 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001225 "While sending with <<{name:s}>> bad data "
1226 "<<{outdata:s}>> ({nout:d}) received; "
1227 "expected <<{indata:s}>> ({nin:d})\n".format(
1228 name=meth_name, outdata=repr(outdata[:20]),
1229 nout=len(outdata),
1230 indata=repr(indata[:20]), nin=len(indata)
1231 )
1232 )
1233 except ValueError as e:
1234 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001235 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001236 "Failed to send with method <<{name:s}>>; "
1237 "expected to succeed.\n".format(name=meth_name)
1238 )
1239 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001240 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001241 "Method <<{name:s}>> failed with unexpected "
1242 "exception message: {exp:s}\n".format(
1243 name=meth_name, exp=e
1244 )
1245 )
1246
1247 for meth_name, recv_meth, expect_success, args in recv_methods:
1248 indata = data_prefix + meth_name
1249 try:
1250 s.send(indata.encode('ASCII', 'strict'))
1251 outdata = recv_meth(*args)
1252 outdata = str(outdata, 'ASCII', 'strict')
1253 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001254 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001255 "While receiving with <<{name:s}>> bad data "
1256 "<<{outdata:s}>> ({nout:d}) received; "
1257 "expected <<{indata:s}>> ({nin:d})\n".format(
1258 name=meth_name, outdata=repr(outdata[:20]),
1259 nout=len(outdata),
1260 indata=repr(indata[:20]), nin=len(indata)
1261 )
1262 )
1263 except ValueError as e:
1264 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001265 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001266 "Failed to receive with method <<{name:s}>>; "
1267 "expected to succeed.\n".format(name=meth_name)
1268 )
1269 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001270 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001271 "Method <<{name:s}>> failed with unexpected "
1272 "exception message: {exp:s}\n".format(
1273 name=meth_name, exp=e
1274 )
1275 )
1276 # consume data
1277 s.read()
1278
1279 s.write("over\n".encode("ASCII", "strict"))
1280 s.close()
1281 finally:
1282 server.stop()
1283 server.join()
1284
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001285 def test_handshake_timeout(self):
1286 # Issue #5103: SSL handshake must respect the socket timeout
1287 server = socket.socket(socket.AF_INET)
1288 host = "127.0.0.1"
1289 port = support.bind_port(server)
1290 started = threading.Event()
1291 finish = False
1292
1293 def serve():
1294 server.listen(5)
1295 started.set()
1296 conns = []
1297 while not finish:
1298 r, w, e = select.select([server], [], [], 0.1)
1299 if server in r:
1300 # Let the socket hang around rather than having
1301 # it closed by garbage collection.
1302 conns.append(server.accept()[0])
1303
1304 t = threading.Thread(target=serve)
1305 t.start()
1306 started.wait()
1307
1308 try:
1309 if 0:
1310 # Disabled until #8524 finds a solution
1311 try:
1312 c = socket.socket(socket.AF_INET)
1313 c.settimeout(1.0)
1314 c.connect((host, port))
1315 # Will attempt handshake and time out
1316 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1317 ssl.wrap_socket, c)
1318 finally:
1319 c.close()
1320 try:
1321 c = socket.socket(socket.AF_INET)
1322 c = ssl.wrap_socket(c)
1323 c.settimeout(0.2)
1324 # Will attempt handshake and time out
1325 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1326 c.connect, (host, port))
1327 finally:
1328 c.close()
1329 finally:
1330 finish = True
1331 t.join()
1332 server.close()
1333
Bill Janssen58afe4c2008-09-08 16:45:19 +00001334
Thomas Woutersed03b412007-08-28 21:37:11 +00001335def test_main(verbose=False):
1336 if skip_expected:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001337 raise unittest.SkipTest("No SSL support")
Thomas Woutersed03b412007-08-28 21:37:11 +00001338
Trent Nelson78520002008-04-10 20:54:35 +00001339 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Thomas Woutersed03b412007-08-28 21:37:11 +00001340 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
1341 "keycert.pem")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001342 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1343 os.path.dirname(__file__) or os.curdir,
1344 "https_svn_python_org_root.pem")
1345
1346 if (not os.path.exists(CERTFILE) or
1347 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001348 raise support.TestFailed("Can't read certificate files!")
Bill Janssen6e027db2007-11-15 22:23:56 +00001349
Thomas Woutersed03b412007-08-28 21:37:11 +00001350 tests = [BasicTests]
1351
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001352 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001353 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001354
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001355 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001356 thread_info = support.threading_setup()
1357 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001358 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001359
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001360 support.run_unittest(*tests)
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 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001364
1365if __name__ == "__main__":
1366 test_main()