PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/lib-python/modified-2.7/test/test_ssl.py

https://bitbucket.org/uiappstore/pypy
Python | 1360 lines | 1195 code | 87 blank | 78 comment | 178 complexity | b5a6855f1a437f988c39d550b8f07af6 MD5 | raw file
  1. # Test the support for SSL and sockets
  2. import sys
  3. import unittest
  4. from test import test_support
  5. import asyncore
  6. import socket
  7. import select
  8. import time
  9. import gc
  10. import os
  11. import errno
  12. import pprint
  13. import urllib, urlparse
  14. import traceback
  15. import weakref
  16. import functools
  17. import platform
  18. from BaseHTTPServer import HTTPServer
  19. from SimpleHTTPServer import SimpleHTTPRequestHandler
  20. ssl = test_support.import_module("ssl")
  21. HOST = test_support.HOST
  22. CERTFILE = None
  23. SVN_PYTHON_ORG_ROOT_CERT = None
  24. def handle_error(prefix):
  25. exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
  26. if test_support.verbose:
  27. sys.stdout.write(prefix + exc_format)
  28. class BasicTests(unittest.TestCase):
  29. def test_sslwrap_simple(self):
  30. # A crude test for the legacy API
  31. try:
  32. ssl.sslwrap_simple(socket.socket(socket.AF_INET))
  33. except IOError, e:
  34. if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
  35. pass
  36. else:
  37. raise
  38. try:
  39. ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
  40. except IOError, e:
  41. if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
  42. pass
  43. else:
  44. raise
  45. # Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
  46. def skip_if_broken_ubuntu_ssl(func):
  47. if hasattr(ssl, 'PROTOCOL_SSLv2'):
  48. # We need to access the lower-level wrapper in order to create an
  49. # implicit SSL context without trying to connect or listen.
  50. try:
  51. import _ssl
  52. except ImportError:
  53. # The returned function won't get executed, just ignore the error
  54. pass
  55. @functools.wraps(func)
  56. def f(*args, **kwargs):
  57. try:
  58. s = socket.socket(socket.AF_INET)
  59. _ssl.sslwrap(s._sock, 0, None, None,
  60. ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
  61. except ssl.SSLError as e:
  62. if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
  63. platform.linux_distribution() == ('debian', 'squeeze/sid', '')
  64. and 'Invalid SSL protocol variant specified' in str(e)):
  65. raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
  66. return func(*args, **kwargs)
  67. return f
  68. else:
  69. return func
  70. class BasicSocketTests(unittest.TestCase):
  71. def test_constants(self):
  72. #ssl.PROTOCOL_SSLv2
  73. ssl.PROTOCOL_SSLv23
  74. ssl.PROTOCOL_SSLv3
  75. ssl.PROTOCOL_TLSv1
  76. ssl.CERT_NONE
  77. ssl.CERT_OPTIONAL
  78. ssl.CERT_REQUIRED
  79. def test_random(self):
  80. v = ssl.RAND_status()
  81. if test_support.verbose:
  82. sys.stdout.write("\n RAND_status is %d (%s)\n"
  83. % (v, (v and "sufficient randomness") or
  84. "insufficient randomness"))
  85. try:
  86. ssl.RAND_egd(1)
  87. except TypeError:
  88. pass
  89. else:
  90. print "didn't raise TypeError"
  91. ssl.RAND_add("this is a random string", 75.0)
  92. def test_parse_cert(self):
  93. # note that this uses an 'unofficial' function in _ssl.c,
  94. # provided solely for this test, to exercise the certificate
  95. # parsing code
  96. p = ssl._ssl._test_decode_cert(CERTFILE, False)
  97. if test_support.verbose:
  98. sys.stdout.write("\n" + pprint.pformat(p) + "\n")
  99. def test_DER_to_PEM(self):
  100. with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
  101. pem = f.read()
  102. d1 = ssl.PEM_cert_to_DER_cert(pem)
  103. p2 = ssl.DER_cert_to_PEM_cert(d1)
  104. d2 = ssl.PEM_cert_to_DER_cert(p2)
  105. self.assertEqual(d1, d2)
  106. if not p2.startswith(ssl.PEM_HEADER + '\n'):
  107. self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
  108. if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
  109. self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
  110. def test_openssl_version(self):
  111. n = ssl.OPENSSL_VERSION_NUMBER
  112. t = ssl.OPENSSL_VERSION_INFO
  113. s = ssl.OPENSSL_VERSION
  114. self.assertIsInstance(n, (int, long))
  115. self.assertIsInstance(t, tuple)
  116. self.assertIsInstance(s, str)
  117. # Some sanity checks follow
  118. # >= 0.9
  119. self.assertGreaterEqual(n, 0x900000)
  120. # < 2.0
  121. self.assertLess(n, 0x20000000)
  122. major, minor, fix, patch, status = t
  123. self.assertGreaterEqual(major, 0)
  124. self.assertLess(major, 2)
  125. self.assertGreaterEqual(minor, 0)
  126. self.assertLess(minor, 256)
  127. self.assertGreaterEqual(fix, 0)
  128. self.assertLess(fix, 256)
  129. self.assertGreaterEqual(patch, 0)
  130. self.assertLessEqual(patch, 26)
  131. self.assertGreaterEqual(status, 0)
  132. self.assertLessEqual(status, 15)
  133. # Version string as returned by OpenSSL, the format might change
  134. self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
  135. (s, t))
  136. def test_ciphers(self):
  137. if not test_support.is_resource_enabled('network'):
  138. return
  139. remote = ("svn.python.org", 443)
  140. with test_support.transient_internet(remote[0]):
  141. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  142. cert_reqs=ssl.CERT_NONE, ciphers="ALL")
  143. s.connect(remote)
  144. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  145. cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
  146. s.connect(remote)
  147. # Error checking occurs when connecting, because the SSL context
  148. # isn't created before.
  149. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  150. cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
  151. with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
  152. s.connect(remote)
  153. @test_support.cpython_only
  154. def test_refcycle(self):
  155. # Issue #7943: an SSL object doesn't create reference cycles with
  156. # itself.
  157. s = socket.socket(socket.AF_INET)
  158. ss = ssl.wrap_socket(s)
  159. wr = weakref.ref(ss)
  160. del ss
  161. self.assertEqual(wr(), None)
  162. def test_wrapped_unconnected(self):
  163. # The _delegate_methods in socket.py are correctly delegated to by an
  164. # unconnected SSLSocket, so they will raise a socket.error rather than
  165. # something unexpected like TypeError.
  166. s = socket.socket(socket.AF_INET)
  167. ss = ssl.wrap_socket(s)
  168. self.assertRaises(socket.error, ss.recv, 1)
  169. self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
  170. self.assertRaises(socket.error, ss.recvfrom, 1)
  171. self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
  172. self.assertRaises(socket.error, ss.send, b'x')
  173. self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
  174. class NetworkedTests(unittest.TestCase):
  175. def test_connect(self):
  176. with test_support.transient_internet("svn.python.org"):
  177. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  178. cert_reqs=ssl.CERT_NONE)
  179. s.connect(("svn.python.org", 443))
  180. c = s.getpeercert()
  181. if c:
  182. self.fail("Peer cert %s shouldn't be here!")
  183. s.close()
  184. # this should fail because we have no verification certs
  185. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  186. cert_reqs=ssl.CERT_REQUIRED)
  187. try:
  188. s.connect(("svn.python.org", 443))
  189. except ssl.SSLError:
  190. pass
  191. finally:
  192. s.close()
  193. # this should succeed because we specify the root cert
  194. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  195. cert_reqs=ssl.CERT_REQUIRED,
  196. ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
  197. try:
  198. s.connect(("svn.python.org", 443))
  199. finally:
  200. s.close()
  201. def test_connect_ex(self):
  202. # Issue #11326: check connect_ex() implementation
  203. with test_support.transient_internet("svn.python.org"):
  204. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  205. cert_reqs=ssl.CERT_REQUIRED,
  206. ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
  207. try:
  208. self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
  209. self.assertTrue(s.getpeercert())
  210. finally:
  211. s.close()
  212. def test_non_blocking_connect_ex(self):
  213. # Issue #11326: non-blocking connect_ex() should allow handshake
  214. # to proceed after the socket gets ready.
  215. with test_support.transient_internet("svn.python.org"):
  216. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  217. cert_reqs=ssl.CERT_REQUIRED,
  218. ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
  219. do_handshake_on_connect=False)
  220. try:
  221. s.setblocking(False)
  222. rc = s.connect_ex(('svn.python.org', 443))
  223. # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
  224. self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
  225. # Wait for connect to finish
  226. select.select([], [s], [], 5.0)
  227. # Non-blocking handshake
  228. while True:
  229. try:
  230. s.do_handshake()
  231. break
  232. except ssl.SSLError as err:
  233. if err.args[0] == ssl.SSL_ERROR_WANT_READ:
  234. select.select([s], [], [], 5.0)
  235. elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
  236. select.select([], [s], [], 5.0)
  237. else:
  238. raise
  239. # SSL established
  240. self.assertTrue(s.getpeercert())
  241. finally:
  242. s.close()
  243. @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
  244. def test_makefile_close(self):
  245. # Issue #5238: creating a file-like object with makefile() shouldn't
  246. # delay closing the underlying "real socket" (here tested with its
  247. # file descriptor, hence skipping the test under Windows).
  248. with test_support.transient_internet("svn.python.org"):
  249. ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
  250. ss.connect(("svn.python.org", 443))
  251. fd = ss.fileno()
  252. f = ss.makefile()
  253. f.close()
  254. # The fd is still open
  255. os.read(fd, 0)
  256. # Closing the SSL socket should close the fd too
  257. ss.close()
  258. gc.collect()
  259. with self.assertRaises(OSError) as e:
  260. os.read(fd, 0)
  261. self.assertEqual(e.exception.errno, errno.EBADF)
  262. def test_non_blocking_handshake(self):
  263. with test_support.transient_internet("svn.python.org"):
  264. s = socket.socket(socket.AF_INET)
  265. s.connect(("svn.python.org", 443))
  266. s.setblocking(False)
  267. s = ssl.wrap_socket(s,
  268. cert_reqs=ssl.CERT_NONE,
  269. do_handshake_on_connect=False)
  270. count = 0
  271. while True:
  272. try:
  273. count += 1
  274. s.do_handshake()
  275. break
  276. except ssl.SSLError, err:
  277. if err.args[0] == ssl.SSL_ERROR_WANT_READ:
  278. select.select([s], [], [])
  279. elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
  280. select.select([], [s], [])
  281. else:
  282. raise
  283. s.close()
  284. if test_support.verbose:
  285. sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
  286. def test_get_server_certificate(self):
  287. with test_support.transient_internet("svn.python.org"):
  288. pem = ssl.get_server_certificate(("svn.python.org", 443))
  289. if not pem:
  290. self.fail("No server certificate on svn.python.org:443!")
  291. try:
  292. pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
  293. except ssl.SSLError:
  294. #should fail
  295. pass
  296. else:
  297. self.fail("Got server certificate %s for svn.python.org!" % pem)
  298. pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
  299. if not pem:
  300. self.fail("No server certificate on svn.python.org:443!")
  301. if test_support.verbose:
  302. sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
  303. def test_algorithms(self):
  304. # Issue #8484: all algorithms should be available when verifying a
  305. # certificate.
  306. # SHA256 was added in OpenSSL 0.9.8
  307. if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
  308. self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
  309. # NOTE: https://sha256.tbs-internet.com is another possible test host
  310. remote = ("sha256.tbs-internet.com", 443)
  311. sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
  312. with test_support.transient_internet("sha256.tbs-internet.com"):
  313. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  314. cert_reqs=ssl.CERT_REQUIRED,
  315. ca_certs=sha256_cert,)
  316. try:
  317. s.connect(remote)
  318. if test_support.verbose:
  319. sys.stdout.write("\nCipher with %r is %r\n" %
  320. (remote, s.cipher()))
  321. sys.stdout.write("Certificate is:\n%s\n" %
  322. pprint.pformat(s.getpeercert()))
  323. finally:
  324. s.close()
  325. try:
  326. import threading
  327. except ImportError:
  328. _have_threads = False
  329. else:
  330. _have_threads = True
  331. class ThreadedEchoServer(threading.Thread):
  332. class ConnectionHandler(threading.Thread):
  333. """A mildly complicated class, because we want it to work both
  334. with and without the SSL wrapper around the socket connection, so
  335. that we can test the STARTTLS functionality."""
  336. def __init__(self, server, connsock):
  337. self.server = server
  338. self.running = False
  339. self.sock = connsock
  340. self.sock.setblocking(1)
  341. self.sslconn = None
  342. threading.Thread.__init__(self)
  343. self.daemon = True
  344. def show_conn_details(self):
  345. if self.server.certreqs == ssl.CERT_REQUIRED:
  346. cert = self.sslconn.getpeercert()
  347. if test_support.verbose and self.server.chatty:
  348. sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
  349. cert_binary = self.sslconn.getpeercert(True)
  350. if test_support.verbose and self.server.chatty:
  351. sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
  352. cipher = self.sslconn.cipher()
  353. if test_support.verbose and self.server.chatty:
  354. sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
  355. def wrap_conn(self):
  356. try:
  357. self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
  358. certfile=self.server.certificate,
  359. ssl_version=self.server.protocol,
  360. ca_certs=self.server.cacerts,
  361. cert_reqs=self.server.certreqs,
  362. ciphers=self.server.ciphers)
  363. except ssl.SSLError:
  364. # XXX Various errors can have happened here, for example
  365. # a mismatching protocol version, an invalid certificate,
  366. # or a low-level bug. This should be made more discriminating.
  367. if self.server.chatty:
  368. handle_error("\n server: bad connection attempt from " +
  369. str(self.sock.getpeername()) + ":\n")
  370. self.close()
  371. self.running = False
  372. self.server.stop()
  373. return False
  374. else:
  375. return True
  376. def read(self):
  377. if self.sslconn:
  378. return self.sslconn.read()
  379. else:
  380. return self.sock.recv(1024)
  381. def write(self, bytes):
  382. if self.sslconn:
  383. return self.sslconn.write(bytes)
  384. else:
  385. return self.sock.send(bytes)
  386. def close(self):
  387. if self.sslconn:
  388. self.sslconn.close()
  389. else:
  390. self.sock._sock.close()
  391. def run(self):
  392. self.running = True
  393. if not self.server.starttls_server:
  394. if isinstance(self.sock, ssl.SSLSocket):
  395. self.sslconn = self.sock
  396. elif not self.wrap_conn():
  397. return
  398. self.show_conn_details()
  399. while self.running:
  400. try:
  401. msg = self.read()
  402. if not msg:
  403. # eof, so quit this handler
  404. self.running = False
  405. self.close()
  406. elif msg.strip() == 'over':
  407. if test_support.verbose and self.server.connectionchatty:
  408. sys.stdout.write(" server: client closed connection\n")
  409. self.close()
  410. return
  411. elif self.server.starttls_server and msg.strip() == 'STARTTLS':
  412. if test_support.verbose and self.server.connectionchatty:
  413. sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
  414. self.write("OK\n")
  415. if not self.wrap_conn():
  416. return
  417. elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
  418. if test_support.verbose and self.server.connectionchatty:
  419. sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
  420. self.write("OK\n")
  421. self.sslconn.unwrap()
  422. self.sslconn = None
  423. if test_support.verbose and self.server.connectionchatty:
  424. sys.stdout.write(" server: connection is now unencrypted...\n")
  425. else:
  426. if (test_support.verbose and
  427. self.server.connectionchatty):
  428. ctype = (self.sslconn and "encrypted") or "unencrypted"
  429. sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
  430. % (repr(msg), ctype, repr(msg.lower()), ctype))
  431. self.write(msg.lower())
  432. except ssl.SSLError:
  433. if self.server.chatty:
  434. handle_error("Test server failure:\n")
  435. self.close()
  436. self.running = False
  437. # normally, we'd just stop here, but for the test
  438. # harness, we want to stop the server
  439. self.server.stop()
  440. def __init__(self, certificate, ssl_version=None,
  441. certreqs=None, cacerts=None,
  442. chatty=True, connectionchatty=False, starttls_server=False,
  443. wrap_accepting_socket=False, ciphers=None):
  444. if ssl_version is None:
  445. ssl_version = ssl.PROTOCOL_TLSv1
  446. if certreqs is None:
  447. certreqs = ssl.CERT_NONE
  448. self.certificate = certificate
  449. self.protocol = ssl_version
  450. self.certreqs = certreqs
  451. self.cacerts = cacerts
  452. self.ciphers = ciphers
  453. self.chatty = chatty
  454. self.connectionchatty = connectionchatty
  455. self.starttls_server = starttls_server
  456. self.sock = socket.socket()
  457. self.flag = None
  458. if wrap_accepting_socket:
  459. self.sock = ssl.wrap_socket(self.sock, server_side=True,
  460. certfile=self.certificate,
  461. cert_reqs = self.certreqs,
  462. ca_certs = self.cacerts,
  463. ssl_version = self.protocol,
  464. ciphers = self.ciphers)
  465. if test_support.verbose and self.chatty:
  466. sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
  467. self.port = test_support.bind_port(self.sock)
  468. self.active = False
  469. threading.Thread.__init__(self)
  470. self.daemon = True
  471. def start(self, flag=None):
  472. self.flag = flag
  473. threading.Thread.start(self)
  474. def run(self):
  475. self.sock.settimeout(0.05)
  476. self.sock.listen(5)
  477. self.active = True
  478. if self.flag:
  479. # signal an event
  480. self.flag.set()
  481. while self.active:
  482. try:
  483. newconn, connaddr = self.sock.accept()
  484. if test_support.verbose and self.chatty:
  485. sys.stdout.write(' server: new connection from '
  486. + str(connaddr) + '\n')
  487. handler = self.ConnectionHandler(self, newconn)
  488. handler.start()
  489. except socket.timeout:
  490. pass
  491. except KeyboardInterrupt:
  492. self.stop()
  493. self.sock.close()
  494. def stop(self):
  495. self.active = False
  496. class AsyncoreEchoServer(threading.Thread):
  497. class EchoServer(asyncore.dispatcher):
  498. class ConnectionHandler(asyncore.dispatcher_with_send):
  499. def __init__(self, conn, certfile):
  500. asyncore.dispatcher_with_send.__init__(self, conn)
  501. self.socket = ssl.wrap_socket(conn, server_side=True,
  502. certfile=certfile,
  503. do_handshake_on_connect=False)
  504. self._ssl_accepting = True
  505. def readable(self):
  506. if isinstance(self.socket, ssl.SSLSocket):
  507. while self.socket.pending() > 0:
  508. self.handle_read_event()
  509. return True
  510. def _do_ssl_handshake(self):
  511. try:
  512. self.socket.do_handshake()
  513. except ssl.SSLError, err:
  514. if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
  515. ssl.SSL_ERROR_WANT_WRITE):
  516. return
  517. elif err.args[0] == ssl.SSL_ERROR_EOF:
  518. return self.handle_close()
  519. raise
  520. except socket.error, err:
  521. if err.args[0] == errno.ECONNABORTED:
  522. return self.handle_close()
  523. else:
  524. self._ssl_accepting = False
  525. def handle_read(self):
  526. if self._ssl_accepting:
  527. self._do_ssl_handshake()
  528. else:
  529. data = self.recv(1024)
  530. if data and data.strip() != 'over':
  531. self.send(data.lower())
  532. def handle_close(self):
  533. self.close()
  534. if test_support.verbose:
  535. sys.stdout.write(" server: closed connection %s\n" % self.socket)
  536. def handle_error(self):
  537. raise
  538. def __init__(self, certfile):
  539. self.certfile = certfile
  540. asyncore.dispatcher.__init__(self)
  541. self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
  542. self.port = test_support.bind_port(self.socket)
  543. self.listen(5)
  544. def handle_accept(self):
  545. sock_obj, addr = self.accept()
  546. if test_support.verbose:
  547. sys.stdout.write(" server: new connection from %s:%s\n" %addr)
  548. self.ConnectionHandler(sock_obj, self.certfile)
  549. def handle_error(self):
  550. raise
  551. def __init__(self, certfile):
  552. self.flag = None
  553. self.active = False
  554. self.server = self.EchoServer(certfile)
  555. self.port = self.server.port
  556. threading.Thread.__init__(self)
  557. self.daemon = True
  558. def __str__(self):
  559. return "<%s %s>" % (self.__class__.__name__, self.server)
  560. def start(self, flag=None):
  561. self.flag = flag
  562. threading.Thread.start(self)
  563. def run(self):
  564. self.active = True
  565. if self.flag:
  566. self.flag.set()
  567. while self.active:
  568. asyncore.loop(0.05)
  569. def stop(self):
  570. self.active = False
  571. self.server.close()
  572. class SocketServerHTTPSServer(threading.Thread):
  573. class HTTPSServer(HTTPServer):
  574. def __init__(self, server_address, RequestHandlerClass, certfile):
  575. HTTPServer.__init__(self, server_address, RequestHandlerClass)
  576. # we assume the certfile contains both private key and certificate
  577. self.certfile = certfile
  578. self.allow_reuse_address = True
  579. def __str__(self):
  580. return ('<%s %s:%s>' %
  581. (self.__class__.__name__,
  582. self.server_name,
  583. self.server_port))
  584. def get_request(self):
  585. # override this to wrap socket with SSL
  586. sock, addr = self.socket.accept()
  587. sslconn = ssl.wrap_socket(sock, server_side=True,
  588. certfile=self.certfile)
  589. return sslconn, addr
  590. class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
  591. # need to override translate_path to get a known root,
  592. # instead of using os.curdir, since the test could be
  593. # run from anywhere
  594. server_version = "TestHTTPS/1.0"
  595. root = None
  596. def translate_path(self, path):
  597. """Translate a /-separated PATH to the local filename syntax.
  598. Components that mean special things to the local file system
  599. (e.g. drive or directory names) are ignored. (XXX They should
  600. probably be diagnosed.)
  601. """
  602. # abandon query parameters
  603. path = urlparse.urlparse(path)[2]
  604. path = os.path.normpath(urllib.unquote(path))
  605. words = path.split('/')
  606. words = filter(None, words)
  607. path = self.root
  608. for word in words:
  609. drive, word = os.path.splitdrive(word)
  610. head, word = os.path.split(word)
  611. if word in self.root: continue
  612. path = os.path.join(path, word)
  613. return path
  614. def log_message(self, format, *args):
  615. # we override this to suppress logging unless "verbose"
  616. if test_support.verbose:
  617. sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
  618. (self.server.server_address,
  619. self.server.server_port,
  620. self.request.cipher(),
  621. self.log_date_time_string(),
  622. format%args))
  623. def __init__(self, certfile):
  624. self.flag = None
  625. self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
  626. self.server = self.HTTPSServer(
  627. (HOST, 0), self.RootedHTTPRequestHandler, certfile)
  628. self.port = self.server.server_port
  629. threading.Thread.__init__(self)
  630. self.daemon = True
  631. def __str__(self):
  632. return "<%s %s>" % (self.__class__.__name__, self.server)
  633. def start(self, flag=None):
  634. self.flag = flag
  635. threading.Thread.start(self)
  636. def run(self):
  637. if self.flag:
  638. self.flag.set()
  639. self.server.serve_forever(0.05)
  640. def stop(self):
  641. self.server.shutdown()
  642. def bad_cert_test(certfile):
  643. """
  644. Launch a server with CERT_REQUIRED, and check that trying to
  645. connect to it with the given client certificate fails.
  646. """
  647. server = ThreadedEchoServer(CERTFILE,
  648. certreqs=ssl.CERT_REQUIRED,
  649. cacerts=CERTFILE, chatty=False)
  650. flag = threading.Event()
  651. server.start(flag)
  652. # wait for it to start
  653. flag.wait()
  654. # try to connect
  655. try:
  656. try:
  657. s = ssl.wrap_socket(socket.socket(),
  658. certfile=certfile,
  659. ssl_version=ssl.PROTOCOL_TLSv1)
  660. s.connect((HOST, server.port))
  661. except ssl.SSLError, x:
  662. if test_support.verbose:
  663. sys.stdout.write("\nSSLError is %s\n" % x[1])
  664. except socket.error, x:
  665. if test_support.verbose:
  666. sys.stdout.write("\nsocket.error is %s\n" % x[1])
  667. else:
  668. raise AssertionError("Use of invalid cert should have failed!")
  669. finally:
  670. server.stop()
  671. server.join()
  672. def server_params_test(certfile, protocol, certreqs, cacertsfile,
  673. client_certfile, client_protocol=None, indata="FOO\n",
  674. ciphers=None, chatty=True, connectionchatty=False,
  675. wrap_accepting_socket=False):
  676. """
  677. Launch a server, connect a client to it and try various reads
  678. and writes.
  679. """
  680. server = ThreadedEchoServer(certfile,
  681. certreqs=certreqs,
  682. ssl_version=protocol,
  683. cacerts=cacertsfile,
  684. ciphers=ciphers,
  685. chatty=chatty,
  686. connectionchatty=connectionchatty,
  687. wrap_accepting_socket=wrap_accepting_socket)
  688. flag = threading.Event()
  689. server.start(flag)
  690. # wait for it to start
  691. flag.wait()
  692. # try to connect
  693. if client_protocol is None:
  694. client_protocol = protocol
  695. try:
  696. s = ssl.wrap_socket(socket.socket(),
  697. certfile=client_certfile,
  698. ca_certs=cacertsfile,
  699. ciphers=ciphers,
  700. cert_reqs=certreqs,
  701. ssl_version=client_protocol)
  702. s.connect((HOST, server.port))
  703. for arg in [indata, bytearray(indata), memoryview(indata)]:
  704. if connectionchatty:
  705. if test_support.verbose:
  706. sys.stdout.write(
  707. " client: sending %s...\n" % (repr(arg)))
  708. s.write(arg)
  709. outdata = s.read()
  710. if connectionchatty:
  711. if test_support.verbose:
  712. sys.stdout.write(" client: read %s\n" % repr(outdata))
  713. if outdata != indata.lower():
  714. raise AssertionError(
  715. "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
  716. % (outdata[:min(len(outdata),20)], len(outdata),
  717. indata[:min(len(indata),20)].lower(), len(indata)))
  718. s.write("over\n")
  719. if connectionchatty:
  720. if test_support.verbose:
  721. sys.stdout.write(" client: closing connection.\n")
  722. s.close()
  723. finally:
  724. server.stop()
  725. server.join()
  726. def try_protocol_combo(server_protocol,
  727. client_protocol,
  728. expect_success,
  729. certsreqs=None):
  730. if certsreqs is None:
  731. certsreqs = ssl.CERT_NONE
  732. certtype = {
  733. ssl.CERT_NONE: "CERT_NONE",
  734. ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
  735. ssl.CERT_REQUIRED: "CERT_REQUIRED",
  736. }[certsreqs]
  737. if test_support.verbose:
  738. formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
  739. sys.stdout.write(formatstr %
  740. (ssl.get_protocol_name(client_protocol),
  741. ssl.get_protocol_name(server_protocol),
  742. certtype))
  743. try:
  744. # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
  745. # will send an SSLv3 hello (rather than SSLv2) starting from
  746. # OpenSSL 1.0.0 (see issue #8322).
  747. server_params_test(CERTFILE, server_protocol, certsreqs,
  748. CERTFILE, CERTFILE, client_protocol,
  749. ciphers="ALL", chatty=False)
  750. # Protocol mismatch can result in either an SSLError, or a
  751. # "Connection reset by peer" error.
  752. except ssl.SSLError:
  753. if expect_success:
  754. raise
  755. except socket.error as e:
  756. if expect_success or e.errno != errno.ECONNRESET:
  757. raise
  758. else:
  759. if not expect_success:
  760. raise AssertionError(
  761. "Client protocol %s succeeded with server protocol %s!"
  762. % (ssl.get_protocol_name(client_protocol),
  763. ssl.get_protocol_name(server_protocol)))
  764. class ThreadedTests(unittest.TestCase):
  765. def test_rude_shutdown(self):
  766. """A brutal shutdown of an SSL server should raise an IOError
  767. in the client when attempting handshake.
  768. """
  769. listener_ready = threading.Event()
  770. listener_gone = threading.Event()
  771. s = socket.socket()
  772. port = test_support.bind_port(s, HOST)
  773. # `listener` runs in a thread. It sits in an accept() until
  774. # the main thread connects. Then it rudely closes the socket,
  775. # and sets Event `listener_gone` to let the main thread know
  776. # the socket is gone.
  777. def listener():
  778. s.listen(5)
  779. listener_ready.set()
  780. s.accept()
  781. s.close()
  782. listener_gone.set()
  783. def connector():
  784. listener_ready.wait()
  785. c = socket.socket()
  786. c.connect((HOST, port))
  787. listener_gone.wait()
  788. # XXX why is it necessary?
  789. test_support.gc_collect()
  790. try:
  791. ssl_sock = ssl.wrap_socket(c)
  792. except IOError:
  793. pass
  794. else:
  795. self.fail('connecting to closed SSL socket should have failed')
  796. t = threading.Thread(target=listener)
  797. t.start()
  798. try:
  799. connector()
  800. finally:
  801. t.join()
  802. @skip_if_broken_ubuntu_ssl
  803. def test_echo(self):
  804. """Basic test of an SSL client connecting to a server"""
  805. if test_support.verbose:
  806. sys.stdout.write("\n")
  807. server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
  808. CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
  809. chatty=True, connectionchatty=True)
  810. def test_getpeercert(self):
  811. if test_support.verbose:
  812. sys.stdout.write("\n")
  813. s2 = socket.socket()
  814. server = ThreadedEchoServer(CERTFILE,
  815. certreqs=ssl.CERT_NONE,
  816. ssl_version=ssl.PROTOCOL_SSLv23,
  817. cacerts=CERTFILE,
  818. chatty=False)
  819. flag = threading.Event()
  820. server.start(flag)
  821. # wait for it to start
  822. flag.wait()
  823. # try to connect
  824. try:
  825. s = ssl.wrap_socket(socket.socket(),
  826. certfile=CERTFILE,
  827. ca_certs=CERTFILE,
  828. cert_reqs=ssl.CERT_REQUIRED,
  829. ssl_version=ssl.PROTOCOL_SSLv23)
  830. s.connect((HOST, server.port))
  831. cert = s.getpeercert()
  832. self.assertTrue(cert, "Can't get peer certificate.")
  833. cipher = s.cipher()
  834. if test_support.verbose:
  835. sys.stdout.write(pprint.pformat(cert) + '\n')
  836. sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
  837. if 'subject' not in cert:
  838. self.fail("No subject field in certificate: %s." %
  839. pprint.pformat(cert))
  840. if ((('organizationName', 'Python Software Foundation'),)
  841. not in cert['subject']):
  842. self.fail(
  843. "Missing or invalid 'organizationName' field in certificate subject; "
  844. "should be 'Python Software Foundation'.")
  845. s.close()
  846. finally:
  847. server.stop()
  848. server.join()
  849. def test_empty_cert(self):
  850. """Connecting with an empty cert file"""
  851. bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
  852. "nullcert.pem"))
  853. def test_malformed_cert(self):
  854. """Connecting with a badly formatted certificate (syntax error)"""
  855. bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
  856. "badcert.pem"))
  857. def test_nonexisting_cert(self):
  858. """Connecting with a non-existing cert file"""
  859. bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
  860. "wrongcert.pem"))
  861. def test_malformed_key(self):
  862. """Connecting with a badly formatted key (syntax error)"""
  863. bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
  864. "badkey.pem"))
  865. @skip_if_broken_ubuntu_ssl
  866. def test_protocol_sslv2(self):
  867. """Connecting to an SSLv2 server with various client options"""
  868. if test_support.verbose:
  869. sys.stdout.write("\n")
  870. try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
  871. try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
  872. try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
  873. try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
  874. try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
  875. try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
  876. @skip_if_broken_ubuntu_ssl
  877. def test_protocol_sslv23(self):
  878. """Connecting to an SSLv23 server with various client options"""
  879. if test_support.verbose:
  880. sys.stdout.write("\n")
  881. try:
  882. try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
  883. except (ssl.SSLError, socket.error), x:
  884. # this fails on some older versions of OpenSSL (0.9.7l, for instance)
  885. if test_support.verbose:
  886. sys.stdout.write(
  887. " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
  888. % str(x))
  889. try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
  890. try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
  891. try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
  892. try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
  893. try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
  894. try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
  895. try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
  896. try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
  897. try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
  898. @skip_if_broken_ubuntu_ssl
  899. def test_protocol_sslv3(self):
  900. """Connecting to an SSLv3 server with various client options"""
  901. if test_support.verbose:
  902. sys.stdout.write("\n")
  903. try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
  904. try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
  905. try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
  906. if hasattr(ssl, 'PROTOCOL_SSLv2'):
  907. try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
  908. try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
  909. try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
  910. @skip_if_broken_ubuntu_ssl
  911. def test_protocol_tlsv1(self):
  912. """Connecting to a TLSv1 server with various client options"""
  913. if test_support.verbose:
  914. sys.stdout.write("\n")
  915. try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
  916. try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
  917. try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
  918. if hasattr(ssl, 'PROTOCOL_SSLv2'):
  919. try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
  920. try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
  921. try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
  922. def test_starttls(self):
  923. """Switching from clear text to encrypted and back again."""
  924. msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
  925. server = ThreadedEchoServer(CERTFILE,
  926. ssl_version=ssl.PROTOCOL_TLSv1,
  927. starttls_server=True,
  928. chatty=True,
  929. connectionchatty=True)
  930. flag = threading.Event()
  931. server.start(flag)
  932. # wait for it to start
  933. flag.wait()
  934. # try to connect
  935. wrapped = False
  936. try:
  937. s = socket.socket()
  938. s.setblocking(1)
  939. s.connect((HOST, server.port))
  940. if test_support.verbose:
  941. sys.stdout.write("\n")
  942. for indata in msgs:
  943. if test_support.verbose:
  944. sys.stdout.write(
  945. " client: sending %s...\n" % repr(indata))
  946. if wrapped:
  947. conn.write(indata)
  948. outdata = conn.read()
  949. else:
  950. s.send(indata)
  951. outdata = s.recv(1024)
  952. if (indata == "STARTTLS" and
  953. outdata.strip().lower().startswith("ok")):
  954. # STARTTLS ok, switch to secure mode
  955. if test_support.verbose:
  956. sys.stdout.write(
  957. " client: read %s from server, starting TLS...\n"
  958. % repr(outdata))
  959. conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
  960. wrapped = True
  961. elif (indata == "ENDTLS" and
  962. outdata.strip().lower().startswith("ok")):
  963. # ENDTLS ok, switch back to clear text
  964. if test_support.verbose:
  965. sys.stdout.write(
  966. " client: read %s from server, ending TLS...\n"
  967. % repr(outdata))
  968. s = conn.unwrap()
  969. wrapped = False
  970. else:
  971. if test_support.verbose:
  972. sys.stdout.write(
  973. " client: read %s from server\n" % repr(outdata))
  974. if test_support.verbose:
  975. sys.stdout.write(" client: closing connection.\n")
  976. if wrapped:
  977. conn.write("over\n")
  978. else:
  979. s.send("over\n")
  980. s.close()
  981. finally:
  982. server.stop()
  983. server.join()
  984. def test_socketserver(self):
  985. """Using a SocketServer to create and manage SSL connections."""
  986. server = SocketServerHTTPSServer(CERTFILE)
  987. flag = threading.Event()
  988. server.start(flag)
  989. # wait for it to start
  990. flag.wait()
  991. # try to connect
  992. try:
  993. if test_support.verbose:
  994. sys.stdout.write('\n')
  995. with open(CERTFILE, 'rb') as f:
  996. d1 = f.read()
  997. d2 = ''
  998. # now fetch the same data from the HTTPS server
  999. url = 'https://127.0.0.1:%d/%s' % (
  1000. server.port, os.path.split(CERTFILE)[1])
  1001. with test_support.check_py3k_warnings():
  1002. f = urllib.urlopen(url)
  1003. dlen = f.info().getheader("content-length")
  1004. if dlen and (int(dlen) > 0):
  1005. d2 = f.read(int(dlen))
  1006. if test_support.verbose:
  1007. sys.stdout.write(
  1008. " client: read %d bytes from remote server '%s'\n"
  1009. % (len(d2), server))
  1010. f.close()
  1011. self.assertEqual(d1, d2)
  1012. finally:
  1013. server.stop()
  1014. server.join()
  1015. def test_wrapped_accept(self):
  1016. """Check the accept() method on SSL sockets."""
  1017. if test_support.verbose:
  1018. sys.stdout.write("\n")
  1019. server_params_test(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
  1020. CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
  1021. chatty=True, connectionchatty=True,
  1022. wrap_accepting_socket=True)
  1023. def test_asyncore_server(self):
  1024. """Check the example asyncore integration."""
  1025. indata = "TEST MESSAGE of mixed case\n"
  1026. if test_support.verbose:
  1027. sys.stdout.write("\n")
  1028. server = AsyncoreEchoServer(CERTFILE)
  1029. flag = threading.Event()
  1030. server.start(flag)
  1031. # wait for it to start
  1032. flag.wait()
  1033. # try to connect
  1034. try:
  1035. s = ssl.wrap_socket(socket.socket())
  1036. s.connect(('127.0.0.1', server.port))
  1037. if test_support.verbose:
  1038. sys.stdout.write(
  1039. " client: sending %s...\n" % (repr(indata)))
  1040. s.write(indata)
  1041. outdata = s.read()
  1042. if test_support.verbose:
  1043. sys.stdout.write(" client: read %s\n" % repr(outdata))
  1044. if outdata != indata.lower():
  1045. self.fail(
  1046. "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
  1047. % (outdata[:min(len(outdata),20)], len(outdata),
  1048. indata[:min(len(indata),20)].lower(), len(indata)))
  1049. s.write("over\n")
  1050. if test_support.verbose:
  1051. sys.stdout.write(" client: closing connection.\n")
  1052. s.close()
  1053. finally:
  1054. server.stop()
  1055. # wait for server thread to end
  1056. server.join()
  1057. def test_recv_send(self):
  1058. """Test recv(), send() and friends."""
  1059. if test_support.verbose:
  1060. sys.stdout.write("\n")
  1061. server = ThreadedEchoServer(CERTFILE,
  1062. certreqs=ssl.CERT_NONE,
  1063. ssl_version=ssl.PROTOCOL_TLSv1,
  1064. cacerts=CERTFILE,
  1065. chatty=True,
  1066. connectionchatty=False)
  1067. flag = threading.Event()
  1068. server.start(flag)
  1069. # wait for it to start
  1070. flag.wait()
  1071. # try to connect
  1072. s = ssl.wrap_socket(socket.socket(),
  1073. server_side=False,
  1074. certfile=CERTFILE,
  1075. ca_certs=CERTFILE,
  1076. cert_reqs=ssl.CERT_NONE,
  1077. ssl_version=ssl.PROTOCOL_TLSv1)
  1078. s.connect((HOST, server.port))
  1079. try:
  1080. # helper methods for standardising recv* method signatures
  1081. def _recv_into():
  1082. b = bytearray("\0"*100)
  1083. count = s.recv_into(b)
  1084. return b[:count]
  1085. def _recvfrom_into():
  1086. b = bytearray("\0"*100)
  1087. count, addr = s.recvfrom_into(b)
  1088. return b[:count]
  1089. # (name, method, whether to expect success, *args)
  1090. send_methods = [
  1091. ('send', s.send, True, []),
  1092. ('sendto', s.sendto, False, ["some.address"]),
  1093. ('sendall', s.sendall, True, []),
  1094. ]
  1095. recv_methods = [
  1096. ('recv', s.recv, True, []),
  1097. ('recvfrom', s.recvfrom, False, ["some.address"]),
  1098. ('recv_into', _recv_into, True, []),
  1099. ('recvfrom_into', _recvfrom_into, False, []),
  1100. ]
  1101. data_prefix = u"PREFIX_"
  1102. for meth_name, send_meth, expect_success, args in send_methods:
  1103. indata = data_prefix + meth_name
  1104. try:
  1105. send_meth(indata.encode('ASCII', 'strict'), *args)
  1106. outdata = s.read()
  1107. outdata = outdata.decode('ASCII', 'strict')
  1108. if outdata != indata.lower():
  1109. self.fail(
  1110. "While sending with <<%s>> bad data "
  1111. "<<%r>> (%d) received; "
  1112. "expected <<%r>> (%d)\n" % (
  1113. meth_name, outdata[:20], len(outdata),
  1114. indata[:20], len(indata)
  1115. )
  1116. )
  1117. except ValueError as e:
  1118. if expect_success:
  1119. self.fail(
  1120. "Failed to send with method <<%s>>; "
  1121. "expected to succeed.\n" % (meth_name,)
  1122. )
  1123. if not str(e).startswith(meth_name):
  1124. self.fail(
  1125. "Method <<%s>> failed with unexpected "
  1126. "exception message: %s\n" % (
  1127. meth_name, e
  1128. )
  1129. )
  1130. for meth_name, recv_meth, expect_success, args in recv_methods:
  1131. indata = data_prefix + meth_name
  1132. try:
  1133. s.send(indata.encode('ASCII', 'strict'))
  1134. outdata = recv_meth(*args)
  1135. outdata = outdata.decode('ASCII', 'strict')
  1136. if outdata != indata.lower():
  1137. self.fail(
  1138. "While receiving with <<%s>> bad data "
  1139. "<<%r>> (%d) received; "
  1140. "expected <<%r>> (%d)\n" % (
  1141. meth_name, outdata[:20], len(outdata),
  1142. indata[:20], len(indata)
  1143. )
  1144. )
  1145. except ValueError as e:
  1146. if expect_success:
  1147. self.fail(
  1148. "Failed to receive with method <<%s>>; "
  1149. "expected to succeed.\n" % (meth_name,)
  1150. )
  1151. if not str(e).startswith(meth_name):
  1152. self.fail(
  1153. "Method <<%s>> failed with unexpected "
  1154. "exception message: %s\n" % (
  1155. meth_name, e
  1156. )
  1157. )
  1158. # consume data
  1159. s.read()
  1160. s.write("over\n".encode("ASCII", "strict"))
  1161. s.close()
  1162. finally:
  1163. server.stop()
  1164. server.join()
  1165. def test_handshake_timeout(self):
  1166. # Issue #5103: SSL handshake must respect the socket timeout
  1167. server = socket.socket(socket.AF_INET)
  1168. host = "127.0.0.1"
  1169. port = test_support.bind_port(server)
  1170. started = threading.Event()
  1171. finish = False
  1172. def serve():
  1173. server.listen(5)
  1174. started.set()
  1175. conns = []
  1176. while not finish:
  1177. r, w, e = select.select([server], [], [], 0.1)
  1178. if server in r:
  1179. # Let the socket hang around rather than having
  1180. # it closed by garbage collection.
  1181. conns.append(server.accept()[0])
  1182. t = threading.Thread(target=serve)
  1183. t.start()
  1184. started.wait()
  1185. try:
  1186. try:
  1187. c = socket.socket(socket.AF_INET)
  1188. c.settimeout(0.2)
  1189. c.connect((host, port))
  1190. # Will attempt handshake and time out
  1191. self.assertRaisesRegexp(ssl.SSLError, "timed out",
  1192. ssl.wrap_socket, c)
  1193. finally:
  1194. c.close()
  1195. try:
  1196. c = socket.socket(socket.AF_INET)
  1197. c.settimeout(0.2)
  1198. c = ssl.wrap_socket(c)
  1199. # Will attempt handshake and time out
  1200. self.assertRaisesRegexp(ssl.SSLError, "timed out",
  1201. c.connect, (host, port))
  1202. finally:
  1203. c.close()
  1204. finally:
  1205. finish = True
  1206. t.join()
  1207. server.close()
  1208. def test_main(verbose=False):
  1209. global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
  1210. CERTFILE = test_support.findfile("keycert.pem")
  1211. SVN_PYTHON_ORG_ROOT_CERT = test_support.findfile(
  1212. "https_svn_python_org_root.pem")
  1213. if (not os.path.exists(CERTFILE) or
  1214. not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
  1215. raise test_support.TestFailed("Can't read certificate files!")
  1216. tests = [BasicTests, BasicSocketTests]
  1217. if test_support.is_resource_enabled('network'):
  1218. tests.append(NetworkedTests)
  1219. if _have_threads:
  1220. thread_info = test_support.threading_setup()
  1221. if thread_info and test_support.is_resource_enabled('network'):
  1222. tests.append(ThreadedTests)
  1223. try:
  1224. test_support.run_unittest(*tests)
  1225. finally:
  1226. if _have_threads:
  1227. test_support.threading_cleanup(*thread_info)
  1228. if __name__ == "__main__":
  1229. test_main()