/Lib/test/test_ssl.py
Python | 1900 lines | 1742 code | 83 blank | 75 comment | 91 complexity | ada7ae328deaa1636e2e30bac0863730 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1# Test the support for SSL and sockets 2 3import sys 4import unittest 5from test import support 6import socket 7import select 8import time 9import gc 10import os 11import errno 12import pprint 13import tempfile 14import urllib.request 15import traceback 16import asyncore 17import weakref 18import platform 19import functools 20 21ssl = support.import_module("ssl") 22 23PROTOCOLS = [ 24 ssl.PROTOCOL_SSLv3, 25 ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1 26] 27if hasattr(ssl, 'PROTOCOL_SSLv2'): 28 PROTOCOLS.append(ssl.PROTOCOL_SSLv2) 29 30HOST = support.HOST 31 32data_file = lambda name: os.path.join(os.path.dirname(__file__), name) 33 34# The custom key and certificate files used in test_ssl are generated 35# using Lib/test/make_ssl_certs.py. 36# Other certificates are simply fetched from the Internet servers they 37# are meant to authenticate. 38 39CERTFILE = data_file("keycert.pem") 40BYTES_CERTFILE = os.fsencode(CERTFILE) 41ONLYCERT = data_file("ssl_cert.pem") 42ONLYKEY = data_file("ssl_key.pem") 43BYTES_ONLYCERT = os.fsencode(ONLYCERT) 44BYTES_ONLYKEY = os.fsencode(ONLYKEY) 45CERTFILE_PROTECTED = data_file("keycert.passwd.pem") 46ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem") 47KEY_PASSWORD = "somepass" 48CAPATH = data_file("capath") 49BYTES_CAPATH = os.fsencode(CAPATH) 50 51SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem") 52 53EMPTYCERT = data_file("nullcert.pem") 54BADCERT = data_file("badcert.pem") 55WRONGCERT = data_file("XXXnonexisting.pem") 56BADKEY = data_file("badkey.pem") 57NOKIACERT = data_file("nokia.pem") 58 59DHFILE = data_file("dh512.pem") 60BYTES_DHFILE = os.fsencode(DHFILE) 61 62def handle_error(prefix): 63 exc_format = ' '.join(traceback.format_exception(*sys.exc_info())) 64 if support.verbose: 65 sys.stdout.write(prefix + exc_format) 66 67def can_clear_options(): 68 # 0.9.8m or higher 69 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15) 70 71def no_sslv2_implies_sslv3_hello(): 72 # 0.9.7h or higher 73 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15) 74 75 76# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2 77def skip_if_broken_ubuntu_ssl(func): 78 if hasattr(ssl, 'PROTOCOL_SSLv2'): 79 @functools.wraps(func) 80 def f(*args, **kwargs): 81 try: 82 ssl.SSLContext(ssl.PROTOCOL_SSLv2) 83 except ssl.SSLError: 84 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and 85 platform.linux_distribution() == ('debian', 'squeeze/sid', '')): 86 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour") 87 return func(*args, **kwargs) 88 return f 89 else: 90 return func 91 92 93class BasicSocketTests(unittest.TestCase): 94 95 def test_constants(self): 96 #ssl.PROTOCOL_SSLv2 97 ssl.PROTOCOL_SSLv23 98 ssl.PROTOCOL_SSLv3 99 ssl.PROTOCOL_TLSv1 100 ssl.CERT_NONE 101 ssl.CERT_OPTIONAL 102 ssl.CERT_REQUIRED 103 ssl.OP_CIPHER_SERVER_PREFERENCE 104 ssl.OP_SINGLE_DH_USE 105 if ssl.HAS_ECDH: 106 ssl.OP_SINGLE_ECDH_USE 107 if ssl.OPENSSL_VERSION_INFO >= (1, 0): 108 ssl.OP_NO_COMPRESSION 109 self.assertIn(ssl.HAS_SNI, {True, False}) 110 self.assertIn(ssl.HAS_ECDH, {True, False}) 111 112 def test_random(self): 113 v = ssl.RAND_status() 114 if support.verbose: 115 sys.stdout.write("\n RAND_status is %d (%s)\n" 116 % (v, (v and "sufficient randomness") or 117 "insufficient randomness")) 118 119 data, is_cryptographic = ssl.RAND_pseudo_bytes(16) 120 self.assertEqual(len(data), 16) 121 self.assertEqual(is_cryptographic, v == 1) 122 if v: 123 data = ssl.RAND_bytes(16) 124 self.assertEqual(len(data), 16) 125 else: 126 self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16) 127 128 try: 129 ssl.RAND_egd(1) 130 except TypeError: 131 pass 132 else: 133 print("didn't raise TypeError") 134 ssl.RAND_add("this is a random string", 75.0) 135 136 def test_parse_cert(self): 137 # note that this uses an 'unofficial' function in _ssl.c, 138 # provided solely for this test, to exercise the certificate 139 # parsing code 140 p = ssl._ssl._test_decode_cert(CERTFILE) 141 if support.verbose: 142 sys.stdout.write("\n" + pprint.pformat(p) + "\n") 143 self.assertEqual(p['issuer'], 144 ((('countryName', 'XY'),), 145 (('localityName', 'Castle Anthrax'),), 146 (('organizationName', 'Python Software Foundation'),), 147 (('commonName', 'localhost'),)) 148 ) 149 self.assertEqual(p['notAfter'], 'Oct 5 23:01:56 2020 GMT') 150 self.assertEqual(p['notBefore'], 'Oct 8 23:01:56 2010 GMT') 151 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E') 152 self.assertEqual(p['subject'], 153 ((('countryName', 'XY'),), 154 (('localityName', 'Castle Anthrax'),), 155 (('organizationName', 'Python Software Foundation'),), 156 (('commonName', 'localhost'),)) 157 ) 158 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),)) 159 # Issue #13034: the subjectAltName in some certificates 160 # (notably projects.developer.nokia.com:443) wasn't parsed 161 p = ssl._ssl._test_decode_cert(NOKIACERT) 162 if support.verbose: 163 sys.stdout.write("\n" + pprint.pformat(p) + "\n") 164 self.assertEqual(p['subjectAltName'], 165 (('DNS', 'projects.developer.nokia.com'), 166 ('DNS', 'projects.forum.nokia.com')) 167 ) 168 169 def test_DER_to_PEM(self): 170 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f: 171 pem = f.read() 172 d1 = ssl.PEM_cert_to_DER_cert(pem) 173 p2 = ssl.DER_cert_to_PEM_cert(d1) 174 d2 = ssl.PEM_cert_to_DER_cert(p2) 175 self.assertEqual(d1, d2) 176 if not p2.startswith(ssl.PEM_HEADER + '\n'): 177 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2) 178 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'): 179 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2) 180 181 def test_openssl_version(self): 182 n = ssl.OPENSSL_VERSION_NUMBER 183 t = ssl.OPENSSL_VERSION_INFO 184 s = ssl.OPENSSL_VERSION 185 self.assertIsInstance(n, int) 186 self.assertIsInstance(t, tuple) 187 self.assertIsInstance(s, str) 188 # Some sanity checks follow 189 # >= 0.9 190 self.assertGreaterEqual(n, 0x900000) 191 # < 2.0 192 self.assertLess(n, 0x20000000) 193 major, minor, fix, patch, status = t 194 self.assertGreaterEqual(major, 0) 195 self.assertLess(major, 2) 196 self.assertGreaterEqual(minor, 0) 197 self.assertLess(minor, 256) 198 self.assertGreaterEqual(fix, 0) 199 self.assertLess(fix, 256) 200 self.assertGreaterEqual(patch, 0) 201 self.assertLessEqual(patch, 26) 202 self.assertGreaterEqual(status, 0) 203 self.assertLessEqual(status, 15) 204 # Version string as returned by OpenSSL, the format might change 205 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)), 206 (s, t)) 207 208 @support.cpython_only 209 def test_refcycle(self): 210 # Issue #7943: an SSL object doesn't create reference cycles with 211 # itself. 212 s = socket.socket(socket.AF_INET) 213 ss = ssl.wrap_socket(s) 214 wr = weakref.ref(ss) 215 del ss 216 self.assertEqual(wr(), None) 217 218 def test_wrapped_unconnected(self): 219 # Methods on an unconnected SSLSocket propagate the original 220 # socket.error raise by the underlying socket object. 221 s = socket.socket(socket.AF_INET) 222 ss = ssl.wrap_socket(s) 223 self.assertRaises(socket.error, ss.recv, 1) 224 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x')) 225 self.assertRaises(socket.error, ss.recvfrom, 1) 226 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1) 227 self.assertRaises(socket.error, ss.send, b'x') 228 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0)) 229 230 def test_timeout(self): 231 # Issue #8524: when creating an SSL socket, the timeout of the 232 # original socket should be retained. 233 for timeout in (None, 0.0, 5.0): 234 s = socket.socket(socket.AF_INET) 235 s.settimeout(timeout) 236 ss = ssl.wrap_socket(s) 237 self.assertEqual(timeout, ss.gettimeout()) 238 239 def test_errors(self): 240 sock = socket.socket() 241 self.assertRaisesRegex(ValueError, 242 "certfile must be specified", 243 ssl.wrap_socket, sock, keyfile=CERTFILE) 244 self.assertRaisesRegex(ValueError, 245 "certfile must be specified for server-side operations", 246 ssl.wrap_socket, sock, server_side=True) 247 self.assertRaisesRegex(ValueError, 248 "certfile must be specified for server-side operations", 249 ssl.wrap_socket, sock, server_side=True, certfile="") 250 s = ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) 251 self.assertRaisesRegex(ValueError, "can't connect in server-side mode", 252 s.connect, (HOST, 8080)) 253 with self.assertRaises(IOError) as cm: 254 with socket.socket() as sock: 255 ssl.wrap_socket(sock, certfile=WRONGCERT) 256 self.assertEqual(cm.exception.errno, errno.ENOENT) 257 with self.assertRaises(IOError) as cm: 258 with socket.socket() as sock: 259 ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT) 260 self.assertEqual(cm.exception.errno, errno.ENOENT) 261 with self.assertRaises(IOError) as cm: 262 with socket.socket() as sock: 263 ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT) 264 self.assertEqual(cm.exception.errno, errno.ENOENT) 265 266 def test_match_hostname(self): 267 def ok(cert, hostname): 268 ssl.match_hostname(cert, hostname) 269 def fail(cert, hostname): 270 self.assertRaises(ssl.CertificateError, 271 ssl.match_hostname, cert, hostname) 272 273 cert = {'subject': ((('commonName', 'example.com'),),)} 274 ok(cert, 'example.com') 275 ok(cert, 'ExAmple.cOm') 276 fail(cert, 'www.example.com') 277 fail(cert, '.example.com') 278 fail(cert, 'example.org') 279 fail(cert, 'exampleXcom') 280 281 cert = {'subject': ((('commonName', '*.a.com'),),)} 282 ok(cert, 'foo.a.com') 283 fail(cert, 'bar.foo.a.com') 284 fail(cert, 'a.com') 285 fail(cert, 'Xa.com') 286 fail(cert, '.a.com') 287 288 cert = {'subject': ((('commonName', 'a.*.com'),),)} 289 ok(cert, 'a.foo.com') 290 fail(cert, 'a..com') 291 fail(cert, 'a.com') 292 293 cert = {'subject': ((('commonName', 'f*.com'),),)} 294 ok(cert, 'foo.com') 295 ok(cert, 'f.com') 296 fail(cert, 'bar.com') 297 fail(cert, 'foo.a.com') 298 fail(cert, 'bar.foo.com') 299 300 # Slightly fake real-world example 301 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT', 302 'subject': ((('commonName', 'linuxfrz.org'),),), 303 'subjectAltName': (('DNS', 'linuxfr.org'), 304 ('DNS', 'linuxfr.com'), 305 ('othername', '<unsupported>'))} 306 ok(cert, 'linuxfr.org') 307 ok(cert, 'linuxfr.com') 308 # Not a "DNS" entry 309 fail(cert, '<unsupported>') 310 # When there is a subjectAltName, commonName isn't used 311 fail(cert, 'linuxfrz.org') 312 313 # A pristine real-world example 314 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', 315 'subject': ((('countryName', 'US'),), 316 (('stateOrProvinceName', 'California'),), 317 (('localityName', 'Mountain View'),), 318 (('organizationName', 'Google Inc'),), 319 (('commonName', 'mail.google.com'),))} 320 ok(cert, 'mail.google.com') 321 fail(cert, 'gmail.com') 322 # Only commonName is considered 323 fail(cert, 'California') 324 325 # Neither commonName nor subjectAltName 326 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', 327 'subject': ((('countryName', 'US'),), 328 (('stateOrProvinceName', 'California'),), 329 (('localityName', 'Mountain View'),), 330 (('organizationName', 'Google Inc'),))} 331 fail(cert, 'mail.google.com') 332 333 # No DNS entry in subjectAltName but a commonName 334 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT', 335 'subject': ((('countryName', 'US'),), 336 (('stateOrProvinceName', 'California'),), 337 (('localityName', 'Mountain View'),), 338 (('commonName', 'mail.google.com'),)), 339 'subjectAltName': (('othername', 'blabla'), )} 340 ok(cert, 'mail.google.com') 341 342 # No DNS entry subjectAltName and no commonName 343 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT', 344 'subject': ((('countryName', 'US'),), 345 (('stateOrProvinceName', 'California'),), 346 (('localityName', 'Mountain View'),), 347 (('organizationName', 'Google Inc'),)), 348 'subjectAltName': (('othername', 'blabla'),)} 349 fail(cert, 'google.com') 350 351 # Empty cert / no cert 352 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com') 353 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com') 354 355 def test_server_side(self): 356 # server_hostname doesn't work for server sockets 357 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 358 with socket.socket() as sock: 359 self.assertRaises(ValueError, ctx.wrap_socket, sock, True, 360 server_hostname="some.hostname") 361 362 def test_unknown_channel_binding(self): 363 # should raise ValueError for unknown type 364 s = socket.socket(socket.AF_INET) 365 ss = ssl.wrap_socket(s) 366 with self.assertRaises(ValueError): 367 ss.get_channel_binding("unknown-type") 368 369 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES, 370 "'tls-unique' channel binding not available") 371 def test_tls_unique_channel_binding(self): 372 # unconnected should return None for known type 373 s = socket.socket(socket.AF_INET) 374 ss = ssl.wrap_socket(s) 375 self.assertIsNone(ss.get_channel_binding("tls-unique")) 376 # the same for server-side 377 s = socket.socket(socket.AF_INET) 378 ss = ssl.wrap_socket(s, server_side=True, certfile=CERTFILE) 379 self.assertIsNone(ss.get_channel_binding("tls-unique")) 380 381class ContextTests(unittest.TestCase): 382 383 @skip_if_broken_ubuntu_ssl 384 def test_constructor(self): 385 if hasattr(ssl, 'PROTOCOL_SSLv2'): 386 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2) 387 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 388 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3) 389 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 390 self.assertRaises(TypeError, ssl.SSLContext) 391 self.assertRaises(ValueError, ssl.SSLContext, -1) 392 self.assertRaises(ValueError, ssl.SSLContext, 42) 393 394 @skip_if_broken_ubuntu_ssl 395 def test_protocol(self): 396 for proto in PROTOCOLS: 397 ctx = ssl.SSLContext(proto) 398 self.assertEqual(ctx.protocol, proto) 399 400 def test_ciphers(self): 401 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 402 ctx.set_ciphers("ALL") 403 ctx.set_ciphers("DEFAULT") 404 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"): 405 ctx.set_ciphers("^$:,;?*'dorothyx") 406 407 @skip_if_broken_ubuntu_ssl 408 def test_options(self): 409 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 410 # OP_ALL is the default value 411 self.assertEqual(ssl.OP_ALL, ctx.options) 412 ctx.options |= ssl.OP_NO_SSLv2 413 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2, 414 ctx.options) 415 ctx.options |= ssl.OP_NO_SSLv3 416 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, 417 ctx.options) 418 if can_clear_options(): 419 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1 420 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3, 421 ctx.options) 422 ctx.options = 0 423 self.assertEqual(0, ctx.options) 424 else: 425 with self.assertRaises(ValueError): 426 ctx.options = 0 427 428 def test_verify(self): 429 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 430 # Default value 431 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) 432 ctx.verify_mode = ssl.CERT_OPTIONAL 433 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL) 434 ctx.verify_mode = ssl.CERT_REQUIRED 435 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) 436 ctx.verify_mode = ssl.CERT_NONE 437 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) 438 with self.assertRaises(TypeError): 439 ctx.verify_mode = None 440 with self.assertRaises(ValueError): 441 ctx.verify_mode = 42 442 443 def test_load_cert_chain(self): 444 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 445 # Combined key and cert in a single file 446 ctx.load_cert_chain(CERTFILE) 447 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE) 448 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE) 449 with self.assertRaises(IOError) as cm: 450 ctx.load_cert_chain(WRONGCERT) 451 self.assertEqual(cm.exception.errno, errno.ENOENT) 452 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 453 ctx.load_cert_chain(BADCERT) 454 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 455 ctx.load_cert_chain(EMPTYCERT) 456 # Separate key and cert 457 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 458 ctx.load_cert_chain(ONLYCERT, ONLYKEY) 459 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY) 460 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY) 461 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 462 ctx.load_cert_chain(ONLYCERT) 463 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 464 ctx.load_cert_chain(ONLYKEY) 465 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 466 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT) 467 # Mismatching key and cert 468 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 469 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"): 470 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY) 471 # Password protected key and cert 472 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD) 473 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode()) 474 ctx.load_cert_chain(CERTFILE_PROTECTED, 475 password=bytearray(KEY_PASSWORD.encode())) 476 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD) 477 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode()) 478 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, 479 bytearray(KEY_PASSWORD.encode())) 480 with self.assertRaisesRegex(TypeError, "should be a string"): 481 ctx.load_cert_chain(CERTFILE_PROTECTED, password=True) 482 with self.assertRaises(ssl.SSLError): 483 ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass") 484 with self.assertRaisesRegex(ValueError, "cannot be longer"): 485 # openssl has a fixed limit on the password buffer. 486 # PEM_BUFSIZE is generally set to 1kb. 487 # Return a string larger than this. 488 ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400) 489 # Password callback 490 def getpass_unicode(): 491 return KEY_PASSWORD 492 def getpass_bytes(): 493 return KEY_PASSWORD.encode() 494 def getpass_bytearray(): 495 return bytearray(KEY_PASSWORD.encode()) 496 def getpass_badpass(): 497 return "badpass" 498 def getpass_huge(): 499 return b'a' * (1024 * 1024) 500 def getpass_bad_type(): 501 return 9 502 def getpass_exception(): 503 raise Exception('getpass error') 504 class GetPassCallable: 505 def __call__(self): 506 return KEY_PASSWORD 507 def getpass(self): 508 return KEY_PASSWORD 509 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode) 510 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes) 511 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray) 512 ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable()) 513 ctx.load_cert_chain(CERTFILE_PROTECTED, 514 password=GetPassCallable().getpass) 515 with self.assertRaises(ssl.SSLError): 516 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass) 517 with self.assertRaisesRegex(ValueError, "cannot be longer"): 518 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge) 519 with self.assertRaisesRegex(TypeError, "must return a string"): 520 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type) 521 with self.assertRaisesRegex(Exception, "getpass error"): 522 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception) 523 # Make sure the password function isn't called if it isn't needed 524 ctx.load_cert_chain(CERTFILE, password=getpass_exception) 525 526 def test_load_verify_locations(self): 527 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 528 ctx.load_verify_locations(CERTFILE) 529 ctx.load_verify_locations(cafile=CERTFILE, capath=None) 530 ctx.load_verify_locations(BYTES_CERTFILE) 531 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None) 532 self.assertRaises(TypeError, ctx.load_verify_locations) 533 self.assertRaises(TypeError, ctx.load_verify_locations, None, None) 534 with self.assertRaises(IOError) as cm: 535 ctx.load_verify_locations(WRONGCERT) 536 self.assertEqual(cm.exception.errno, errno.ENOENT) 537 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 538 ctx.load_verify_locations(BADCERT) 539 ctx.load_verify_locations(CERTFILE, CAPATH) 540 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH) 541 542 # Issue #10989: crash if the second argument type is invalid 543 self.assertRaises(TypeError, ctx.load_verify_locations, None, True) 544 545 def test_load_dh_params(self): 546 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 547 ctx.load_dh_params(DHFILE) 548 if os.name != 'nt': 549 ctx.load_dh_params(BYTES_DHFILE) 550 self.assertRaises(TypeError, ctx.load_dh_params) 551 self.assertRaises(TypeError, ctx.load_dh_params, None) 552 with self.assertRaises(FileNotFoundError) as cm: 553 ctx.load_dh_params(WRONGCERT) 554 self.assertEqual(cm.exception.errno, errno.ENOENT) 555 with self.assertRaisesRegex(ssl.SSLError, "PEM routines"): 556 ctx.load_dh_params(CERTFILE) 557 558 @skip_if_broken_ubuntu_ssl 559 def test_session_stats(self): 560 for proto in PROTOCOLS: 561 ctx = ssl.SSLContext(proto) 562 self.assertEqual(ctx.session_stats(), { 563 'number': 0, 564 'connect': 0, 565 'connect_good': 0, 566 'connect_renegotiate': 0, 567 'accept': 0, 568 'accept_good': 0, 569 'accept_renegotiate': 0, 570 'hits': 0, 571 'misses': 0, 572 'timeouts': 0, 573 'cache_full': 0, 574 }) 575 576 def test_set_default_verify_paths(self): 577 # There's not much we can do to test that it acts as expected, 578 # so just check it doesn't crash or raise an exception. 579 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 580 ctx.set_default_verify_paths() 581 582 @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build") 583 def test_set_ecdh_curve(self): 584 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 585 ctx.set_ecdh_curve("prime256v1") 586 ctx.set_ecdh_curve(b"prime256v1") 587 self.assertRaises(TypeError, ctx.set_ecdh_curve) 588 self.assertRaises(TypeError, ctx.set_ecdh_curve, None) 589 self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo") 590 self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo") 591 592 593class NetworkedTests(unittest.TestCase): 594 595 def test_connect(self): 596 with support.transient_internet("svn.python.org"): 597 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 598 cert_reqs=ssl.CERT_NONE) 599 try: 600 s.connect(("svn.python.org", 443)) 601 self.assertEqual({}, s.getpeercert()) 602 finally: 603 s.close() 604 605 # this should fail because we have no verification certs 606 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 607 cert_reqs=ssl.CERT_REQUIRED) 608 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed", 609 s.connect, ("svn.python.org", 443)) 610 s.close() 611 612 # this should succeed because we specify the root cert 613 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 614 cert_reqs=ssl.CERT_REQUIRED, 615 ca_certs=SVN_PYTHON_ORG_ROOT_CERT) 616 try: 617 s.connect(("svn.python.org", 443)) 618 self.assertTrue(s.getpeercert()) 619 finally: 620 s.close() 621 622 def test_connect_ex(self): 623 # Issue #11326: check connect_ex() implementation 624 with support.transient_internet("svn.python.org"): 625 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 626 cert_reqs=ssl.CERT_REQUIRED, 627 ca_certs=SVN_PYTHON_ORG_ROOT_CERT) 628 try: 629 self.assertEqual(0, s.connect_ex(("svn.python.org", 443))) 630 self.assertTrue(s.getpeercert()) 631 finally: 632 s.close() 633 634 def test_non_blocking_connect_ex(self): 635 # Issue #11326: non-blocking connect_ex() should allow handshake 636 # to proceed after the socket gets ready. 637 with support.transient_internet("svn.python.org"): 638 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 639 cert_reqs=ssl.CERT_REQUIRED, 640 ca_certs=SVN_PYTHON_ORG_ROOT_CERT, 641 do_handshake_on_connect=False) 642 try: 643 s.setblocking(False) 644 rc = s.connect_ex(('svn.python.org', 443)) 645 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere 646 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK)) 647 # Wait for connect to finish 648 select.select([], [s], [], 5.0) 649 # Non-blocking handshake 650 while True: 651 try: 652 s.do_handshake() 653 break 654 except ssl.SSLWantReadError: 655 select.select([s], [], [], 5.0) 656 except ssl.SSLWantWriteError: 657 select.select([], [s], [], 5.0) 658 # SSL established 659 self.assertTrue(s.getpeercert()) 660 finally: 661 s.close() 662 663 def test_timeout_connect_ex(self): 664 # Issue #12065: on a timeout, connect_ex() should return the original 665 # errno (mimicking the behaviour of non-SSL sockets). 666 with support.transient_internet("svn.python.org"): 667 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 668 cert_reqs=ssl.CERT_REQUIRED, 669 ca_certs=SVN_PYTHON_ORG_ROOT_CERT, 670 do_handshake_on_connect=False) 671 try: 672 s.settimeout(0.0000001) 673 rc = s.connect_ex(('svn.python.org', 443)) 674 if rc == 0: 675 self.skipTest("svn.python.org responded too quickly") 676 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK)) 677 finally: 678 s.close() 679 680 def test_connect_with_context(self): 681 with support.transient_internet("svn.python.org"): 682 # Same as test_connect, but with a separately created context 683 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 684 s = ctx.wrap_socket(socket.socket(socket.AF_INET)) 685 s.connect(("svn.python.org", 443)) 686 try: 687 self.assertEqual({}, s.getpeercert()) 688 finally: 689 s.close() 690 # Same with a server hostname 691 s = ctx.wrap_socket(socket.socket(socket.AF_INET), 692 server_hostname="svn.python.org") 693 if ssl.HAS_SNI: 694 s.connect(("svn.python.org", 443)) 695 s.close() 696 else: 697 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443)) 698 # This should fail because we have no verification certs 699 ctx.verify_mode = ssl.CERT_REQUIRED 700 s = ctx.wrap_socket(socket.socket(socket.AF_INET)) 701 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed", 702 s.connect, ("svn.python.org", 443)) 703 s.close() 704 # This should succeed because we specify the root cert 705 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT) 706 s = ctx.wrap_socket(socket.socket(socket.AF_INET)) 707 s.connect(("svn.python.org", 443)) 708 try: 709 cert = s.getpeercert() 710 self.assertTrue(cert) 711 finally: 712 s.close() 713 714 def test_connect_capath(self): 715 # Verify server certificates using the `capath` argument 716 # NOTE: the subject hashing algorithm has been changed between 717 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must 718 # contain both versions of each certificate (same content, different 719 # filename) for this test to be portable across OpenSSL releases. 720 with support.transient_internet("svn.python.org"): 721 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 722 ctx.verify_mode = ssl.CERT_REQUIRED 723 ctx.load_verify_locations(capath=CAPATH) 724 s = ctx.wrap_socket(socket.socket(socket.AF_INET)) 725 s.connect(("svn.python.org", 443)) 726 try: 727 cert = s.getpeercert() 728 self.assertTrue(cert) 729 finally: 730 s.close() 731 # Same with a bytes `capath` argument 732 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 733 ctx.verify_mode = ssl.CERT_REQUIRED 734 ctx.load_verify_locations(capath=BYTES_CAPATH) 735 s = ctx.wrap_socket(socket.socket(socket.AF_INET)) 736 s.connect(("svn.python.org", 443)) 737 try: 738 cert = s.getpeercert() 739 self.assertTrue(cert) 740 finally: 741 s.close() 742 743 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows") 744 def test_makefile_close(self): 745 # Issue #5238: creating a file-like object with makefile() shouldn't 746 # delay closing the underlying "real socket" (here tested with its 747 # file descriptor, hence skipping the test under Windows). 748 with support.transient_internet("svn.python.org"): 749 ss = ssl.wrap_socket(socket.socket(socket.AF_INET)) 750 ss.connect(("svn.python.org", 443)) 751 fd = ss.fileno() 752 f = ss.makefile() 753 f.close() 754 # The fd is still open 755 os.read(fd, 0) 756 # Closing the SSL socket should close the fd too 757 ss.close() 758 gc.collect() 759 with self.assertRaises(OSError) as e: 760 os.read(fd, 0) 761 self.assertEqual(e.exception.errno, errno.EBADF) 762 763 def test_non_blocking_handshake(self): 764 with support.transient_internet("svn.python.org"): 765 s = socket.socket(socket.AF_INET) 766 s.connect(("svn.python.org", 443)) 767 s.setblocking(False) 768 s = ssl.wrap_socket(s, 769 cert_reqs=ssl.CERT_NONE, 770 do_handshake_on_connect=False) 771 count = 0 772 while True: 773 try: 774 count += 1 775 s.do_handshake() 776 break 777 except ssl.SSLWantReadError: 778 select.select([s], [], []) 779 except ssl.SSLWantWriteError: 780 select.select([], [s], []) 781 s.close() 782 if support.verbose: 783 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count) 784 785 def test_get_server_certificate(self): 786 def _test_get_server_certificate(host, port, cert=None): 787 with support.transient_internet(host): 788 pem = ssl.get_server_certificate((host, port)) 789 if not pem: 790 self.fail("No server certificate on %s:%s!" % (host, port)) 791 792 try: 793 pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE) 794 except ssl.SSLError as x: 795 #should fail 796 if support.verbose: 797 sys.stdout.write("%s\n" % x) 798 else: 799 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port)) 800 801 pem = ssl.get_server_certificate((host, port), ca_certs=cert) 802 if not pem: 803 self.fail("No server certificate on %s:%s!" % (host, port)) 804 if support.verbose: 805 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem)) 806 807 _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT) 808 if support.IPV6_ENABLED: 809 _test_get_server_certificate('ipv6.google.com', 443) 810 811 def test_ciphers(self): 812 remote = ("svn.python.org", 443) 813 with support.transient_internet(remote[0]): 814 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 815 cert_reqs=ssl.CERT_NONE, ciphers="ALL") 816 s.connect(remote) 817 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 818 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") 819 s.connect(remote) 820 # Error checking can happen at instantiation or when connecting 821 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"): 822 with socket.socket(socket.AF_INET) as sock: 823 s = ssl.wrap_socket(sock, 824 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx") 825 s.connect(remote) 826 827 def test_algorithms(self): 828 # Issue #8484: all algorithms should be available when verifying a 829 # certificate. 830 # SHA256 was added in OpenSSL 0.9.8 831 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15): 832 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION) 833 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host) 834 remote = ("sha256.tbs-internet.com", 443) 835 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem") 836 with support.transient_internet("sha256.tbs-internet.com"): 837 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 838 cert_reqs=ssl.CERT_REQUIRED, 839 ca_certs=sha256_cert,) 840 try: 841 s.connect(remote) 842 if support.verbose: 843 sys.stdout.write("\nCipher with %r is %r\n" % 844 (remote, s.cipher())) 845 sys.stdout.write("Certificate is:\n%s\n" % 846 pprint.pformat(s.getpeercert())) 847 finally: 848 s.close() 849 850 851try: 852 import threading 853except ImportError: 854 _have_threads = False 855else: 856 _have_threads = True 857 858 from test.ssl_servers import make_https_server 859 860 class ThreadedEchoServer(threading.Thread): 861 862 class ConnectionHandler(threading.Thread): 863 864 """A mildly complicated class, because we want it to work both 865 with and without the SSL wrapper around the socket connection, so 866 that we can test the STARTTLS functionality.""" 867 868 def __init__(self, server, connsock, addr): 869 self.server = server 870 self.running = False 871 self.sock = connsock 872 self.addr = addr 873 self.sock.setblocking(1) 874 self.sslconn = None 875 threading.Thread.__init__(self) 876 self.daemon = True 877 878 def wrap_conn(self): 879 try: 880 self.sslconn = self.server.context.wrap_socket( 881 self.sock, server_side=True) 882 except ssl.SSLError as e: 883 # XXX Various errors can have happened here, for example 884 # a mismatching protocol version, an invalid certificate, 885 # or a low-level bug. This should be made more discriminating. 886 self.server.conn_errors.append(e) 887 if self.server.chatty: 888 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n") 889 self.running = False 890 self.server.stop() 891 self.close() 892 return False 893 else: 894 if self.server.context.verify_mode == ssl.CERT_REQUIRED: 895 cert = self.sslconn.getpeercert() 896 if support.verbose and self.server.chatty: 897 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n") 898 cert_binary = self.sslconn.getpeercert(True) 899 if support.verbose and self.server.chatty: 900 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n") 901 cipher = self.sslconn.cipher() 902 if support.verbose and self.server.chatty: 903 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n") 904 return True 905 906 def read(self): 907 if self.sslconn: 908 return self.sslconn.read() 909 else: 910 return self.sock.recv(1024) 911 912 def write(self, bytes): 913 if self.sslconn: 914 return self.sslconn.write(bytes) 915 else: 916 return self.sock.send(bytes) 917 918 def close(self): 919 if self.sslconn: 920 self.sslconn.close() 921 else: 922 self.sock.close() 923 924 def run(self): 925 self.running = True 926 if not self.server.starttls_server: 927 if not self.wrap_conn(): 928 return 929 while self.running: 930 try: 931 msg = self.read() 932 stripped = msg.strip() 933 if not stripped: 934 # eof, so quit this handler 935 self.running = False 936 self.close() 937 elif stripped == b'over': 938 if support.verbose and self.server.connectionchatty: 939 sys.stdout.write(" server: client closed connection\n") 940 self.close() 941 return 942 elif (self.server.starttls_server and 943 stripped == b'STARTTLS'): 944 if support.verbose and self.server.connectionchatty: 945 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n") 946 self.write(b"OK\n") 947 if not self.wrap_conn(): 948 return 949 elif (self.server.starttls_server and self.sslconn 950 and stripped == b'ENDTLS'): 951 if support.verbose and self.server.connectionchatty: 952 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n") 953 self.write(b"OK\n") 954 self.sock = self.sslconn.unwrap() 955 self.sslconn = None 956 if support.verbose and self.server.connectionchatty: 957 sys.stdout.write(" server: connection is now unencrypted...\n") 958 elif stripped == b'CB tls-unique': 959 if support.verbose and self.server.connectionchatty: 960 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n") 961 data = self.sslconn.get_channel_binding("tls-unique") 962 self.write(repr(data).encode("us-ascii") + b"\n") 963 else: 964 if (support.verbose and 965 self.server.connectionchatty): 966 ctype = (self.sslconn and "encrypted") or "unencrypted" 967 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n" 968 % (msg, ctype, msg.lower(), ctype)) 969 self.write(msg.lower()) 970 except socket.error: 971 if self.server.chatty: 972 handle_error("Test server failure:\n") 973 self.close() 974 self.running = False 975 # normally, we'd just stop here, but for the test 976 # harness, we want to stop the server 977 self.server.stop() 978 979 def __init__(self, certificate=None, ssl_version=None, 980 certreqs=None, cacerts=None, 981 chatty=True, connectionchatty=False, starttls_server=False, 982 ciphers=None, context=None): 983 if context: 984 self.context = context 985 else: 986 self.context = ssl.SSLContext(ssl_version 987 if ssl_version is not None 988 else ssl.PROTOCOL_TLSv1) 989 self.context.verify_mode = (certreqs if certreqs is not None 990 else ssl.CERT_NONE) 991 if cacerts: 992 self.context.load_verify_locations(cacerts) 993 if certificate: 994 self.context.load_cert_chain(certificate) 995 if ciphers: 996 self.context.set_ciphers(ciphers) 997 self.chatty = chatty 998 self.connectionchatty = connectionchatty 999 self.starttls_server = starttls_server 1000 self.sock = socket.socket() 1001 self.port = support.bind_port(self.sock) 1002 self.flag = None 1003 self.active = False 1004 self.conn_errors = [] 1005 threading.Thread.__init__(self) 1006 self.daemon = True 1007 1008 def __enter__(self): 1009 self.start(threading.Event()) 1010 self.flag.wait() 1011 return self 1012 1013 def __exit__(self, *args): 1014 self.stop() 1015 self.join() 1016 1017 def start(self, flag=None): 1018 self.flag = flag 1019 threading.Thread.start(self) 1020 1021 def run(self): 1022 self.sock.settimeout(0.05) 1023 self.sock.listen(5) 1024 self.active = True 1025 if self.flag: 1026 # signal an event 1027 self.flag.set() 1028 while self.active: 1029 try: 1030 newconn, connaddr = self.sock.accept() 1031 if support.verbose and self.chatty: 1032 sys.stdout.write(' server: new connection from ' 1033 + repr(connaddr) + '\n') 1034 handler = self.ConnectionHandler(self, newconn, connaddr) 1035 handler.start() 1036 handler.join() 1037 except socket.timeout: 1038 pass 1039 except KeyboardInterrupt: 1040 self.stop() 1041 self.sock.close() 1042 1043 def stop(self): 1044 self.active = False 1045 1046 class AsyncoreEchoServer(threading.Thread): 1047 1048 # this one's based on asyncore.dispatcher 1049 1050 class EchoServer (asyncore.dispatcher): 1051 1052 class ConnectionHandler (asyncore.dispatcher_with_send): 1053 1054 def __init__(self, conn, certfile): 1055 self.socket = ssl.wrap_socket(conn, server_side=True, 1056 certfile=certfile, 1057 do_handshake_on_connect=False) 1058 asyncore.dispatcher_with_send.__init__(self, self.socket) 1059 self._ssl_accepting = True 1060 self._do_ssl_handshake() 1061 1062 def readable(self): 1063 if isinstance(self.socket, ssl.SSLSocket): 1064 while self.socket.pending() > 0: 1065 self.handle_read_event() 1066 return True 1067 1068 def _do_ssl_handshake(self): 1069 try: 1070 self.socket.do_handshake() 1071 except (ssl.SSLWantReadError, ssl.SSLWantWriteError): 1072 return 1073 except ssl.SSLEOFError: 1074 return self.handle_close() 1075 except ssl.SSLError: 1076 raise 1077 except socket.error as err: 1078 if err.args[0] == errno.ECONNABORTED: 1079 return self.handle_close() 1080 else: 1081 self._ssl_accepting = False 1082 1083 def handle_read(self): 1084 if self._ssl_accepting: 1085 self._do_ssl_handshake() 1086 else: 1087 data = self.recv(1024) 1088 if support.verbose: 1089 sys.stdout.write(" server: read %s from client\n" % repr(data)) 1090 if not data: 1091 self.close() 1092 else: 1093 self.send(data.lower()) 1094 1095 def handle_close(self): 1096 self.close() 1097 if support.verbose: 1098 sys.stdout.write(" server: closed connection %s\n" % self.socket) 1099 1100 def handle_error(self): 1101 raise 1102 1103 def __init__(self, certfile): 1104 self.certfile = certfile 1105 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1106 self.port = support.bind_port(sock, '') 1107 asyncore.dispatcher.__init__(self, sock) 1108 self.listen(5) 1109 1110 def handle_accepted(self, sock_obj, addr): 1111 if support.verbose: 1112 sys.stdout.write(" server: new connection from %s:%s\n" %addr) 1113 self.ConnectionHandler(sock_obj, self.certfile) 1114 1115 def handle_error(self): 1116 raise 1117 1118 def __init__(self, certfile): 1119 self.flag = None 1120 self.active = False 1121 self.server = self.EchoServer(certfile) 1122 self.port = self.server.port 1123 threading.Thread.__init__(self) 1124 self.daemon = True 1125 1126 def __str__(self): 1127 return "<%s %s>" % (self.__class__.__name__, self.server) 1128 1129 def __enter__(self): 1130 self.start(threading.Event()) 1131 self.flag.wait() 1132 return self 1133 1134 def __exit__(self, *args): 1135 if support.verbose: 1136 sys.stdout.write(" cleanup: stopping server.\n") 1137 self.stop() 1138 if support.verbose: 1139 sys.stdout.write(" cleanup: joining server thread.\n") 1140 self.join() 1141 if support.verbose: 1142 sys.stdout.write(" cleanup: successfully joined.\n") 1143 1144 def start (self, flag=None): 1145 self.flag = flag 1146 threading.Thread.start(self) 1147 1148 def run(self): 1149 self.active = True 1150 if self.flag: 1151 self.flag.set() 1152 while self.active: 1153 try: 1154 asyncore.loop(1) 1155 except: 1156 pass 1157 1158 def stop(self): 1159 self.active = False 1160 self.server.close() 1161 1162 def bad_cert_test(certfile): 1163 """ 1164 Launch a server with CERT_REQUIRED, and check that trying to 1165 connect to it with the given client certificate fails. 1166 """ 1167 server = ThreadedEchoServer(CERTFILE, 1168 certreqs=ssl.CERT_REQUIRED, 1169 cacerts=CERTFILE, chatty=False, 1170 connectionchatty=False) 1171 with serv…
Large files files are truncated, but you can click here to view the full file