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