blob: a82a7842fc863bf157088eacce79d99a6f211462 [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
Antoine Pitrou480a1242010-04-28 21:37:09 +000039 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000040 ssl.PROTOCOL_SSLv2
41 ssl.PROTOCOL_SSLv23
42 ssl.PROTOCOL_SSLv3
43 ssl.PROTOCOL_TLSv1
44 ssl.CERT_NONE
45 ssl.CERT_OPTIONAL
46 ssl.CERT_REQUIRED
Thomas Woutersed03b412007-08-28 21:37:11 +000047
Antoine Pitrou480a1242010-04-28 21:37:09 +000048 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000049 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +000050 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000051 sys.stdout.write("\n RAND_status is %d (%s)\n"
52 % (v, (v and "sufficient randomness") or
53 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +000054 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000055 ssl.RAND_egd(1)
56 except TypeError:
57 pass
Thomas Woutersed03b412007-08-28 21:37:11 +000058 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000059 print("didn't raise TypeError")
60 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +000061
Antoine Pitrou480a1242010-04-28 21:37:09 +000062 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000063 # note that this uses an 'unofficial' function in _ssl.c,
64 # provided solely for this test, to exercise the certificate
65 # parsing code
66 p = ssl._ssl._test_decode_cert(CERTFILE, False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000067 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000068 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +000069
Antoine Pitrou480a1242010-04-28 21:37:09 +000070 def test_DER_to_PEM(self):
71 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
72 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +000073 d1 = ssl.PEM_cert_to_DER_cert(pem)
74 p2 = ssl.DER_cert_to_PEM_cert(d1)
75 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +000076 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +000077 if not p2.startswith(ssl.PEM_HEADER + '\n'):
78 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
79 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
80 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +000081
Antoine Pitrou04f6a322010-04-05 21:40:07 +000082 def test_openssl_version(self):
83 n = ssl.OPENSSL_VERSION_NUMBER
84 t = ssl.OPENSSL_VERSION_INFO
85 s = ssl.OPENSSL_VERSION
86 self.assertIsInstance(n, int)
87 self.assertIsInstance(t, tuple)
88 self.assertIsInstance(s, str)
89 # Some sanity checks follow
90 # >= 0.9
91 self.assertGreaterEqual(n, 0x900000)
92 # < 2.0
93 self.assertLess(n, 0x20000000)
94 major, minor, fix, patch, status = t
95 self.assertGreaterEqual(major, 0)
96 self.assertLess(major, 2)
97 self.assertGreaterEqual(minor, 0)
98 self.assertLess(minor, 256)
99 self.assertGreaterEqual(fix, 0)
100 self.assertLess(fix, 256)
101 self.assertGreaterEqual(patch, 0)
102 self.assertLessEqual(patch, 26)
103 self.assertGreaterEqual(status, 0)
104 self.assertLessEqual(status, 15)
105 # Version string as returned by OpenSSL, the format might change
106 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
107 (s, t))
108
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000109 def test_ciphers(self):
110 if not support.is_resource_enabled('network'):
111 return
112 remote = ("svn.python.org", 443)
113 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
114 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
115 s.connect(remote)
116 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
117 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
118 s.connect(remote)
119 # Error checking occurs when connecting, because the SSL context
120 # isn't created before.
121 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
122 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
123 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
124 s.connect(remote)
125
Antoine Pitrou9d543662010-04-23 23:10:32 +0000126 @support.cpython_only
127 def test_refcycle(self):
128 # Issue #7943: an SSL object doesn't create reference cycles with
129 # itself.
130 s = socket.socket(socket.AF_INET)
131 ss = ssl.wrap_socket(s)
132 wr = weakref.ref(ss)
133 del ss
134 self.assertEqual(wr(), None)
135
Antoine Pitrou40f08742010-04-24 22:04:40 +0000136 def test_timeout(self):
137 # Issue #8524: when creating an SSL socket, the timeout of the
138 # original socket should be retained.
139 for timeout in (None, 0.0, 5.0):
140 s = socket.socket(socket.AF_INET)
141 s.settimeout(timeout)
142 ss = ssl.wrap_socket(s)
143 self.assertEqual(timeout, ss.gettimeout())
144
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000145
Bill Janssen6e027db2007-11-15 22:23:56 +0000146class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000147
Antoine Pitrou480a1242010-04-28 21:37:09 +0000148 def test_connect(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000149 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
150 cert_reqs=ssl.CERT_NONE)
151 s.connect(("svn.python.org", 443))
152 c = s.getpeercert()
153 if c:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000154 self.fail("Peer cert %s shouldn't be here!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000155 s.close()
156
157 # this should fail because we have no verification certs
158 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
159 cert_reqs=ssl.CERT_REQUIRED)
Thomas Woutersed03b412007-08-28 21:37:11 +0000160 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000161 s.connect(("svn.python.org", 443))
162 except ssl.SSLError:
163 pass
164 finally:
165 s.close()
166
167 # this should succeed because we specify the root cert
168 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
169 cert_reqs=ssl.CERT_REQUIRED,
170 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
171 try:
172 s.connect(("svn.python.org", 443))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000173 finally:
174 s.close()
175
Antoine Pitroue3220242010-04-24 11:13:53 +0000176 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
177 def test_makefile_close(self):
178 # Issue #5238: creating a file-like object with makefile() shouldn't
179 # delay closing the underlying "real socket" (here tested with its
180 # file descriptor, hence skipping the test under Windows).
181 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
182 ss.connect(("svn.python.org", 443))
183 fd = ss.fileno()
184 f = ss.makefile()
185 f.close()
186 # The fd is still open
187 os.read(fd, 0)
188 # Closing the SSL socket should close the fd too
189 ss.close()
190 gc.collect()
191 with self.assertRaises(OSError) as e:
192 os.read(fd, 0)
193 self.assertEqual(e.exception.errno, errno.EBADF)
194
Antoine Pitrou480a1242010-04-28 21:37:09 +0000195 def test_non_blocking_handshake(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000196 s = socket.socket(socket.AF_INET)
197 s.connect(("svn.python.org", 443))
198 s.setblocking(False)
199 s = ssl.wrap_socket(s,
200 cert_reqs=ssl.CERT_NONE,
201 do_handshake_on_connect=False)
202 count = 0
203 while True:
204 try:
205 count += 1
206 s.do_handshake()
207 break
208 except ssl.SSLError as err:
209 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
210 select.select([s], [], [])
211 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
212 select.select([], [s], [])
213 else:
214 raise
215 s.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000216 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000217 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000218
Antoine Pitrou480a1242010-04-28 21:37:09 +0000219 def test_get_server_certificate(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000220 pem = ssl.get_server_certificate(("svn.python.org", 443))
221 if not pem:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000222 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000223
224 return
225
226 try:
227 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
228 except ssl.SSLError as x:
229 #should fail
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000230 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000231 sys.stdout.write("%s\n" % x)
232 else:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000233 self.fail("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000234
235 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
236 if not pem:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000237 self.fail("No server certificate on svn.python.org:443!")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000238 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000239 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
240
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000241 def test_algorithms(self):
242 # Issue #8484: all algorithms should be available when verifying a
243 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000244 # SHA256 was added in OpenSSL 0.9.8
245 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
246 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000247 # NOTE: https://sha256.tbs-internet.com is another possible test host
248 remote = ("sha2.hboeck.de", 443)
249 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
250 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
251 cert_reqs=ssl.CERT_REQUIRED,
252 ca_certs=sha256_cert,)
253 with support.transient_internet():
254 try:
255 s.connect(remote)
256 if support.verbose:
257 sys.stdout.write("\nCipher with %r is %r\n" %
258 (remote, s.cipher()))
259 sys.stdout.write("Certificate is:\n%s\n" %
260 pprint.pformat(s.getpeercert()))
261 finally:
262 s.close()
263
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000264
265try:
266 import threading
267except ImportError:
268 _have_threads = False
269else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000270 _have_threads = True
271
272 class ThreadedEchoServer(threading.Thread):
273
274 class ConnectionHandler(threading.Thread):
275
276 """A mildly complicated class, because we want it to work both
277 with and without the SSL wrapper around the socket connection, so
278 that we can test the STARTTLS functionality."""
279
Bill Janssen6e027db2007-11-15 22:23:56 +0000280 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000281 self.server = server
282 self.running = False
283 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000284 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000285 self.sock.setblocking(1)
286 self.sslconn = None
287 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000288 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000289
Antoine Pitrou480a1242010-04-28 21:37:09 +0000290 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000291 try:
292 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
293 certfile=self.server.certificate,
294 ssl_version=self.server.protocol,
295 ca_certs=self.server.cacerts,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000296 cert_reqs=self.server.certreqs,
297 ciphers=self.server.ciphers)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000298 except ssl.SSLError:
299 # XXX Various errors can have happened here, for example
300 # a mismatching protocol version, an invalid certificate,
301 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000302 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000303 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000304 self.running = False
305 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000306 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000307 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000308 else:
309 if self.server.certreqs == ssl.CERT_REQUIRED:
310 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000311 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000312 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
313 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000314 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000315 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
316 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000317 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000318 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
319 return True
320
321 def read(self):
322 if self.sslconn:
323 return self.sslconn.read()
324 else:
325 return self.sock.recv(1024)
326
327 def write(self, bytes):
328 if self.sslconn:
329 return self.sslconn.write(bytes)
330 else:
331 return self.sock.send(bytes)
332
333 def close(self):
334 if self.sslconn:
335 self.sslconn.close()
336 else:
337 self.sock.close()
338
Antoine Pitrou480a1242010-04-28 21:37:09 +0000339 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000340 self.running = True
341 if not self.server.starttls_server:
342 if not self.wrap_conn():
343 return
344 while self.running:
345 try:
346 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000347 stripped = msg.strip()
348 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000349 # eof, so quit this handler
350 self.running = False
351 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000352 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000353 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000354 sys.stdout.write(" server: client closed connection\n")
355 self.close()
356 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000357 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000358 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000359 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000360 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000361 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000362 if not self.wrap_conn():
363 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000364 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000365 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000366 if support.verbose and self.server.connectionchatty:
367 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000368 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000369 self.sock = self.sslconn.unwrap()
370 self.sslconn = None
371 if support.verbose and self.server.connectionchatty:
372 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000373 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000374 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000375 self.server.connectionchatty):
376 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000377 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
378 % (msg, ctype, msg.lower(), ctype))
379 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000380 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000381 if self.server.chatty:
382 handle_error("Test server failure:\n")
383 self.close()
384 self.running = False
385 # normally, we'd just stop here, but for the test
386 # harness, we want to stop the server
387 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000388
Trent Nelson78520002008-04-10 20:54:35 +0000389 def __init__(self, certificate, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000390 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000391 chatty=True, connectionchatty=False, starttls_server=False,
392 ciphers=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000393 if ssl_version is None:
394 ssl_version = ssl.PROTOCOL_TLSv1
395 if certreqs is None:
396 certreqs = ssl.CERT_NONE
397 self.certificate = certificate
398 self.protocol = ssl_version
399 self.certreqs = certreqs
400 self.cacerts = cacerts
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000401 self.ciphers = ciphers
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000402 self.chatty = chatty
403 self.connectionchatty = connectionchatty
404 self.starttls_server = starttls_server
405 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000406 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000407 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000408 self.active = False
409 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000410 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000411
Antoine Pitrou480a1242010-04-28 21:37:09 +0000412 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000413 self.flag = flag
414 threading.Thread.start(self)
415
Antoine Pitrou480a1242010-04-28 21:37:09 +0000416 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000417 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000418 self.sock.listen(5)
419 self.active = True
420 if self.flag:
421 # signal an event
422 self.flag.set()
423 while self.active:
424 try:
425 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000426 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000427 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000428 + repr(connaddr) + '\n')
429 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000430 handler.start()
431 except socket.timeout:
432 pass
433 except KeyboardInterrupt:
434 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000435 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000436
Antoine Pitrou480a1242010-04-28 21:37:09 +0000437 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000438 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000439
Bill Janssen54cc54c2007-12-14 22:08:56 +0000440 class OurHTTPSServer(threading.Thread):
441
442 # This one's based on HTTPServer, which is based on SocketServer
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000443
444 class HTTPSServer(HTTPServer):
445
446 def __init__(self, server_address, RequestHandlerClass, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000447 HTTPServer.__init__(self, server_address, RequestHandlerClass)
448 # we assume the certfile contains both private key and certificate
449 self.certfile = certfile
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000450 self.allow_reuse_address = True
451
Bill Janssen6e027db2007-11-15 22:23:56 +0000452 def __str__(self):
453 return ('<%s %s:%s>' %
454 (self.__class__.__name__,
455 self.server_name,
456 self.server_port))
457
Antoine Pitrou480a1242010-04-28 21:37:09 +0000458 def get_request(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000459 # override this to wrap socket with SSL
460 sock, addr = self.socket.accept()
461 sslconn = ssl.wrap_socket(sock, server_side=True,
462 certfile=self.certfile)
463 return sslconn, addr
464
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000465 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000466 # need to override translate_path to get a known root,
467 # instead of using os.curdir, since the test could be
468 # run from anywhere
469
470 server_version = "TestHTTPS/1.0"
471
472 root = None
473
474 def translate_path(self, path):
475 """Translate a /-separated PATH to the local filename syntax.
476
477 Components that mean special things to the local file system
478 (e.g. drive or directory names) are ignored. (XXX They should
479 probably be diagnosed.)
480
481 """
482 # abandon query parameters
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000483 path = urllib.parse.urlparse(path)[2]
484 path = os.path.normpath(urllib.parse.unquote(path))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000485 words = path.split('/')
486 words = filter(None, words)
487 path = self.root
488 for word in words:
489 drive, word = os.path.splitdrive(word)
490 head, word = os.path.split(word)
491 if word in self.root: continue
492 path = os.path.join(path, word)
493 return path
494
495 def log_message(self, format, *args):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000496 # we override this to suppress logging unless "verbose"
497
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000498 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000499 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
500 (self.server.server_address,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000501 self.server.server_port,
502 self.request.cipher(),
503 self.log_date_time_string(),
504 format%args))
Thomas Woutersed03b412007-08-28 21:37:11 +0000505
506
Trent Nelson78520002008-04-10 20:54:35 +0000507 def __init__(self, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000508 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000509 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
510 self.server = self.HTTPSServer(
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000511 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
512 self.port = self.server.server_port
Thomas Woutersed03b412007-08-28 21:37:11 +0000513 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000514 self.daemon = True
Thomas Woutersed03b412007-08-28 21:37:11 +0000515
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000516 def __str__(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000517 return "<%s %s>" % (self.__class__.__name__, self.server)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000518
Antoine Pitrou480a1242010-04-28 21:37:09 +0000519 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000520 self.flag = flag
521 threading.Thread.start(self)
522
Antoine Pitrou480a1242010-04-28 21:37:09 +0000523 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000524 if self.flag:
525 self.flag.set()
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000526 self.server.serve_forever(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000527
Antoine Pitrou480a1242010-04-28 21:37:09 +0000528 def stop(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000529 self.server.shutdown()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000530
531
Bill Janssen54cc54c2007-12-14 22:08:56 +0000532 class AsyncoreEchoServer(threading.Thread):
533
534 # this one's based on asyncore.dispatcher
535
536 class EchoServer (asyncore.dispatcher):
537
538 class ConnectionHandler (asyncore.dispatcher_with_send):
539
540 def __init__(self, conn, certfile):
541 self.socket = ssl.wrap_socket(conn, server_side=True,
542 certfile=certfile,
543 do_handshake_on_connect=False)
544 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000545 self._ssl_accepting = True
546 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000547
548 def readable(self):
549 if isinstance(self.socket, ssl.SSLSocket):
550 while self.socket.pending() > 0:
551 self.handle_read_event()
552 return True
553
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000554 def _do_ssl_handshake(self):
555 try:
556 self.socket.do_handshake()
557 except ssl.SSLError as err:
558 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
559 ssl.SSL_ERROR_WANT_WRITE):
560 return
561 elif err.args[0] == ssl.SSL_ERROR_EOF:
562 return self.handle_close()
563 raise
564 except socket.error as err:
565 if err.args[0] == errno.ECONNABORTED:
566 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000567 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000568 self._ssl_accepting = False
569
570 def handle_read(self):
571 if self._ssl_accepting:
572 self._do_ssl_handshake()
573 else:
574 data = self.recv(1024)
575 if support.verbose:
576 sys.stdout.write(" server: read %s from client\n" % repr(data))
577 if not data:
578 self.close()
579 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000580 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000581
582 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000583 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000584 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000585 sys.stdout.write(" server: closed connection %s\n" % self.socket)
586
587 def handle_error(self):
588 raise
589
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000590 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000591 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000592 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
593 self.port = support.bind_port(sock, '')
594 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000595 self.listen(5)
596
597 def handle_accept(self):
598 sock_obj, addr = self.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000599 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000600 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
601 self.ConnectionHandler(sock_obj, self.certfile)
602
603 def handle_error(self):
604 raise
605
Trent Nelson78520002008-04-10 20:54:35 +0000606 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000607 self.flag = None
608 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000609 self.server = self.EchoServer(certfile)
610 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000611 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000612 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000613
614 def __str__(self):
615 return "<%s %s>" % (self.__class__.__name__, self.server)
616
617 def start (self, flag=None):
618 self.flag = flag
619 threading.Thread.start(self)
620
Antoine Pitrou480a1242010-04-28 21:37:09 +0000621 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000622 self.active = True
623 if self.flag:
624 self.flag.set()
625 while self.active:
626 try:
627 asyncore.loop(1)
628 except:
629 pass
630
Antoine Pitrou480a1242010-04-28 21:37:09 +0000631 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000632 self.active = False
633 self.server.close()
634
Antoine Pitrou480a1242010-04-28 21:37:09 +0000635 def bad_cert_test(certfile):
636 """
637 Launch a server with CERT_REQUIRED, and check that trying to
638 connect to it with the given client certificate fails.
639 """
Trent Nelson78520002008-04-10 20:54:35 +0000640 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000641 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000642 cacerts=CERTFILE, chatty=False,
643 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000644 flag = threading.Event()
645 server.start(flag)
646 # wait for it to start
647 flag.wait()
648 # try to connect
649 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000650 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000651 s = ssl.wrap_socket(socket.socket(),
652 certfile=certfile,
653 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelson78520002008-04-10 20:54:35 +0000654 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000655 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000656 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000657 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000658 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000659 if support.verbose:
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000660 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000661 else:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000662 self.fail("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000663 finally:
664 server.stop()
665 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000666
Antoine Pitrou480a1242010-04-28 21:37:09 +0000667 def server_params_test(certfile, protocol, certreqs, cacertsfile,
668 client_certfile, client_protocol=None, indata=b"FOO\n",
669 ciphers=None, chatty=True, connectionchatty=False):
670 """
671 Launch a server, connect a client to it and try various reads
672 and writes.
673 """
Trent Nelson78520002008-04-10 20:54:35 +0000674 server = ThreadedEchoServer(certfile,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000675 certreqs=certreqs,
676 ssl_version=protocol,
677 cacerts=cacertsfile,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000678 ciphers=ciphers,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000679 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000680 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000681 flag = threading.Event()
682 server.start(flag)
683 # wait for it to start
684 flag.wait()
685 # try to connect
686 if client_protocol is None:
687 client_protocol = protocol
688 try:
Bill Janssen6e027db2007-11-15 22:23:56 +0000689 s = ssl.wrap_socket(socket.socket(),
690 certfile=client_certfile,
691 ca_certs=cacertsfile,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000692 ciphers=ciphers,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000693 cert_reqs=certreqs,
Bill Janssen6e027db2007-11-15 22:23:56 +0000694 ssl_version=client_protocol)
Trent Nelson78520002008-04-10 20:54:35 +0000695 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +0000696 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000697 if connectionchatty:
698 if support.verbose:
699 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +0000700 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000701 s.write(arg)
702 outdata = s.read()
703 if connectionchatty:
704 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000705 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000706 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000707 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +0000708 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
709 % (outdata[:20], len(outdata),
710 indata[:20].lower(), len(indata)))
711 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000712 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000713 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000714 sys.stdout.write(" client: closing connection.\n")
715 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000716 finally:
717 server.stop()
718 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000719
Antoine Pitrou480a1242010-04-28 21:37:09 +0000720 def try_protocol_combo(server_protocol,
721 client_protocol,
722 expect_success,
723 certsreqs=None):
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000724 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000725 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +0000726 certtype = {
727 ssl.CERT_NONE: "CERT_NONE",
728 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
729 ssl.CERT_REQUIRED: "CERT_REQUIRED",
730 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000731 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000732 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000733 sys.stdout.write(formatstr %
734 (ssl.get_protocol_name(client_protocol),
735 ssl.get_protocol_name(server_protocol),
736 certtype))
737 try:
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000738 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
739 # will send an SSLv3 hello (rather than SSLv2) starting from
740 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou480a1242010-04-28 21:37:09 +0000741 server_params_test(CERTFILE, server_protocol, certsreqs,
742 CERTFILE, CERTFILE, client_protocol,
743 ciphers="ALL", chatty=False,
744 connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000745 # Protocol mismatch can result in either an SSLError, or a
746 # "Connection reset by peer" error.
747 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000748 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000749 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000750 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000751 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000752 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000753 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000754 if not expect_success:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000755 self.fail(
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000756 "Client protocol %s succeeded with server protocol %s!"
757 % (ssl.get_protocol_name(client_protocol),
758 ssl.get_protocol_name(server_protocol)))
759
760
Bill Janssen6e027db2007-11-15 22:23:56 +0000761 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000762
Antoine Pitrou480a1242010-04-28 21:37:09 +0000763 def test_echo(self):
764 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000765 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000766 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000767 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
768 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
769 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000770
Antoine Pitrou480a1242010-04-28 21:37:09 +0000771 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000772 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000773 sys.stdout.write("\n")
774 s2 = socket.socket()
Trent Nelson78520002008-04-10 20:54:35 +0000775 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000776 certreqs=ssl.CERT_NONE,
777 ssl_version=ssl.PROTOCOL_SSLv23,
778 cacerts=CERTFILE,
779 chatty=False)
780 flag = threading.Event()
781 server.start(flag)
782 # wait for it to start
783 flag.wait()
784 # try to connect
785 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000786 s = ssl.wrap_socket(socket.socket(),
787 certfile=CERTFILE,
788 ca_certs=CERTFILE,
789 cert_reqs=ssl.CERT_REQUIRED,
790 ssl_version=ssl.PROTOCOL_SSLv23)
791 s.connect((HOST, server.port))
792 cert = s.getpeercert()
793 self.assertTrue(cert, "Can't get peer certificate.")
794 cipher = s.cipher()
795 if support.verbose:
796 sys.stdout.write(pprint.pformat(cert) + '\n')
797 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
798 if 'subject' not in cert:
799 self.fail("No subject field in certificate: %s." %
800 pprint.pformat(cert))
801 if ((('organizationName', 'Python Software Foundation'),)
802 not in cert['subject']):
803 self.fail(
804 "Missing or invalid 'organizationName' field in certificate subject; "
805 "should be 'Python Software Foundation'.")
806 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000807 finally:
808 server.stop()
809 server.join()
810
Antoine Pitrou480a1242010-04-28 21:37:09 +0000811 def test_empty_cert(self):
812 """Connecting with an empty cert file"""
813 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
814 "nullcert.pem"))
815 def test_malformed_cert(self):
816 """Connecting with a badly formatted certificate (syntax error)"""
817 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
818 "badcert.pem"))
819 def test_nonexisting_cert(self):
820 """Connecting with a non-existing cert file"""
821 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
822 "wrongcert.pem"))
823 def test_malformed_key(self):
824 """Connecting with a badly formatted key (syntax error)"""
825 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
826 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000827
Antoine Pitrou480a1242010-04-28 21:37:09 +0000828 def test_rude_shutdown(self):
829 """A brutal shutdown of an SSL server should raise an IOError
830 in the client when attempting handshake.
831 """
Trent Nelson6b240cd2008-04-10 20:12:06 +0000832 listener_ready = threading.Event()
833 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000834
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000835 s = socket.socket()
836 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000837
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000838 # `listener` runs in a thread. It sits in an accept() until
839 # the main thread connects. Then it rudely closes the socket,
840 # and sets Event `listener_gone` to let the main thread know
841 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +0000842 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +0000843 s.listen(5)
844 listener_ready.set()
845 s.accept()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000846 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000847 listener_gone.set()
848
849 def connector():
850 listener_ready.wait()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000851 c = socket.socket()
852 c.connect((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +0000853 listener_gone.wait()
854 try:
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000855 ssl_sock = ssl.wrap_socket(c)
Trent Nelson6b240cd2008-04-10 20:12:06 +0000856 except IOError:
857 pass
858 else:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000859 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +0000860
861 t = threading.Thread(target=listener)
862 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000863 try:
864 connector()
865 finally:
866 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +0000867
Antoine Pitrou480a1242010-04-28 21:37:09 +0000868 def test_protocol_sslv2(self):
869 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000870 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000871 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000872 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
873 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
874 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
875 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
876 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
877 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000878
Antoine Pitrou480a1242010-04-28 21:37:09 +0000879 def test_protocol_sslv23(self):
880 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000881 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000882 sys.stdout.write("\n")
883 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000884 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000885 except (ssl.SSLError, socket.error) as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000886 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000887 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000888 sys.stdout.write(
889 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
890 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +0000891 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
892 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
893 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000894
Antoine Pitrou480a1242010-04-28 21:37:09 +0000895 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
896 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
897 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000898
Antoine Pitrou480a1242010-04-28 21:37:09 +0000899 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
900 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
901 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000902
Antoine Pitrou480a1242010-04-28 21:37:09 +0000903 def test_protocol_sslv3(self):
904 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000905 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000906 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000907 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
908 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
909 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
910 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
911 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
912 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000913
Antoine Pitrou480a1242010-04-28 21:37:09 +0000914 def test_protocol_tlsv1(self):
915 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000916 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000917 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000918 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
919 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
920 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
921 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
922 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
923 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000924
Antoine Pitrou480a1242010-04-28 21:37:09 +0000925 def test_starttls(self):
926 """Switching from clear text to encrypted and back again."""
927 msgs = (b"msg 1", b"MSG 2", b"STARTTLS", b"MSG 3", b"msg 4", b"ENDTLS", b"msg 5", b"msg 6")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000928
Trent Nelson78520002008-04-10 20:54:35 +0000929 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000930 ssl_version=ssl.PROTOCOL_TLSv1,
931 starttls_server=True,
932 chatty=True,
933 connectionchatty=True)
934 flag = threading.Event()
935 server.start(flag)
936 # wait for it to start
937 flag.wait()
938 # try to connect
939 wrapped = False
940 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000941 s = socket.socket()
942 s.setblocking(1)
943 s.connect((HOST, server.port))
944 if support.verbose:
945 sys.stdout.write("\n")
946 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000947 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000948 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +0000949 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000950 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000951 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000952 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000953 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000954 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000955 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +0000956 msg = outdata.strip().lower()
957 if indata == b"STARTTLS" and msg.startswith(b"ok"):
958 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000959 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000960 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +0000961 " client: read %r from server, starting TLS...\n"
962 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000963 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
964 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +0000965 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
966 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000967 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000968 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +0000969 " client: read %r from server, ending TLS...\n"
970 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000971 s = conn.unwrap()
972 wrapped = False
973 else:
974 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000975 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +0000976 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000977 if support.verbose:
978 sys.stdout.write(" client: closing connection.\n")
979 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000980 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000981 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000982 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000983 if wrapped:
984 conn.close()
985 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000986 s.close()
987 finally:
988 server.stop()
989 server.join()
990
Antoine Pitrou480a1242010-04-28 21:37:09 +0000991 def test_socketserver(self):
992 """Using a SocketServer to create and manage SSL connections."""
Trent Nelson78520002008-04-10 20:54:35 +0000993 server = OurHTTPSServer(CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000994 flag = threading.Event()
995 server.start(flag)
996 # wait for it to start
997 flag.wait()
998 # try to connect
999 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001000 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001001 sys.stdout.write('\n')
Antoine Pitrou480a1242010-04-28 21:37:09 +00001002 with open(CERTFILE, 'rb') as f:
1003 d1 = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001004 d2 = ''
1005 # now fetch the same data from the HTTPS server
Trent Nelson78520002008-04-10 20:54:35 +00001006 url = 'https://%s:%d/%s' % (
1007 HOST, server.port, os.path.split(CERTFILE)[1])
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001008 f = urllib.request.urlopen(url)
Barry Warsaw820c1202008-06-12 04:06:45 +00001009 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001010 if dlen and (int(dlen) > 0):
1011 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001012 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001013 sys.stdout.write(
1014 " client: read %d bytes from remote server '%s'\n"
1015 % (len(d2), server))
1016 f.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001017 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001018 finally:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001019 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001020 sys.stdout.write('stopping server\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001021 server.stop()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001022 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001023 sys.stdout.write('joining thread\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001024 server.join()
1025
Antoine Pitrou480a1242010-04-28 21:37:09 +00001026 def test_asyncore_server(self):
1027 """Check the example asyncore integration."""
1028 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001029
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001030 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001031 sys.stdout.write("\n")
1032
Antoine Pitrou480a1242010-04-28 21:37:09 +00001033 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001034 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001035 flag = threading.Event()
1036 server.start(flag)
1037 # wait for it to start
1038 flag.wait()
1039 # try to connect
1040 try:
1041 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001042 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001043 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001044 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001045 " client: sending %r...\n" % indata)
1046 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001047 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001048 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001049 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001050 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001051 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001052 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1053 % (outdata[:20], len(outdata),
1054 indata[:20].lower(), len(indata)))
1055 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001056 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001057 sys.stdout.write(" client: closing connection.\n")
1058 s.close()
1059 finally:
1060 server.stop()
1061 server.join()
1062
Antoine Pitrou480a1242010-04-28 21:37:09 +00001063 def test_recv_send(self):
1064 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001065 if support.verbose:
1066 sys.stdout.write("\n")
1067
1068 server = ThreadedEchoServer(CERTFILE,
1069 certreqs=ssl.CERT_NONE,
1070 ssl_version=ssl.PROTOCOL_TLSv1,
1071 cacerts=CERTFILE,
1072 chatty=True,
1073 connectionchatty=False)
1074 flag = threading.Event()
1075 server.start(flag)
1076 # wait for it to start
1077 flag.wait()
1078 # try to connect
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001079 s = ssl.wrap_socket(socket.socket(),
1080 server_side=False,
1081 certfile=CERTFILE,
1082 ca_certs=CERTFILE,
1083 cert_reqs=ssl.CERT_NONE,
1084 ssl_version=ssl.PROTOCOL_TLSv1)
1085 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001086 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001087 # helper methods for standardising recv* method signatures
1088 def _recv_into():
1089 b = bytearray(b"\0"*100)
1090 count = s.recv_into(b)
1091 return b[:count]
1092
1093 def _recvfrom_into():
1094 b = bytearray(b"\0"*100)
1095 count, addr = s.recvfrom_into(b)
1096 return b[:count]
1097
1098 # (name, method, whether to expect success, *args)
1099 send_methods = [
1100 ('send', s.send, True, []),
1101 ('sendto', s.sendto, False, ["some.address"]),
1102 ('sendall', s.sendall, True, []),
1103 ]
1104 recv_methods = [
1105 ('recv', s.recv, True, []),
1106 ('recvfrom', s.recvfrom, False, ["some.address"]),
1107 ('recv_into', _recv_into, True, []),
1108 ('recvfrom_into', _recvfrom_into, False, []),
1109 ]
1110 data_prefix = "PREFIX_"
1111
1112 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001113 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001114 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001115 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001116 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001117 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001118 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001119 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001120 "<<{outdata:r}>> ({nout:d}) received; "
1121 "expected <<{indata:r}>> ({nin:d})\n".format(
1122 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001123 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001124 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001125 )
1126 )
1127 except ValueError as e:
1128 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001129 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001130 "Failed to send with method <<{name:s}>>; "
1131 "expected to succeed.\n".format(name=meth_name)
1132 )
1133 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001134 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001135 "Method <<{name:s}>> failed with unexpected "
1136 "exception message: {exp:s}\n".format(
1137 name=meth_name, exp=e
1138 )
1139 )
1140
1141 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001142 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001143 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001144 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001145 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001146 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001147 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001148 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001149 "<<{outdata:r}>> ({nout:d}) received; "
1150 "expected <<{indata:r}>> ({nin:d})\n".format(
1151 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001152 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001153 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001154 )
1155 )
1156 except ValueError as e:
1157 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001158 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001159 "Failed to receive with method <<{name:s}>>; "
1160 "expected to succeed.\n".format(name=meth_name)
1161 )
1162 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001163 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001164 "Method <<{name:s}>> failed with unexpected "
1165 "exception message: {exp:s}\n".format(
1166 name=meth_name, exp=e
1167 )
1168 )
1169 # consume data
1170 s.read()
1171
Antoine Pitrou480a1242010-04-28 21:37:09 +00001172 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001173 s.close()
1174 finally:
1175 server.stop()
1176 server.join()
1177
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001178 def test_handshake_timeout(self):
1179 # Issue #5103: SSL handshake must respect the socket timeout
1180 server = socket.socket(socket.AF_INET)
1181 host = "127.0.0.1"
1182 port = support.bind_port(server)
1183 started = threading.Event()
1184 finish = False
1185
1186 def serve():
1187 server.listen(5)
1188 started.set()
1189 conns = []
1190 while not finish:
1191 r, w, e = select.select([server], [], [], 0.1)
1192 if server in r:
1193 # Let the socket hang around rather than having
1194 # it closed by garbage collection.
1195 conns.append(server.accept()[0])
1196
1197 t = threading.Thread(target=serve)
1198 t.start()
1199 started.wait()
1200
1201 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001202 try:
1203 c = socket.socket(socket.AF_INET)
1204 c.settimeout(0.2)
1205 c.connect((host, port))
1206 # Will attempt handshake and time out
1207 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1208 ssl.wrap_socket, c)
1209 finally:
1210 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001211 try:
1212 c = socket.socket(socket.AF_INET)
1213 c = ssl.wrap_socket(c)
1214 c.settimeout(0.2)
1215 # Will attempt handshake and time out
1216 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1217 c.connect, (host, port))
1218 finally:
1219 c.close()
1220 finally:
1221 finish = True
1222 t.join()
1223 server.close()
1224
Bill Janssen58afe4c2008-09-08 16:45:19 +00001225
Thomas Woutersed03b412007-08-28 21:37:11 +00001226def test_main(verbose=False):
1227 if skip_expected:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001228 raise unittest.SkipTest("No SSL support")
Thomas Woutersed03b412007-08-28 21:37:11 +00001229
Trent Nelson78520002008-04-10 20:54:35 +00001230 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
Thomas Woutersed03b412007-08-28 21:37:11 +00001231 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
1232 "keycert.pem")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001233 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1234 os.path.dirname(__file__) or os.curdir,
1235 "https_svn_python_org_root.pem")
1236
1237 if (not os.path.exists(CERTFILE) or
1238 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001239 raise support.TestFailed("Can't read certificate files!")
Bill Janssen6e027db2007-11-15 22:23:56 +00001240
Thomas Woutersed03b412007-08-28 21:37:11 +00001241 tests = [BasicTests]
1242
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001243 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001244 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001245
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001246 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001247 thread_info = support.threading_setup()
1248 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001249 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001250
Antoine Pitrou480a1242010-04-28 21:37:09 +00001251 try:
1252 support.run_unittest(*tests)
1253 finally:
1254 if _have_threads:
1255 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001256
1257if __name__ == "__main__":
1258 test_main()