14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Test the support for SSL and sockets
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport unittest
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom test import test_support
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport asyncore
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport socket
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport select
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport time
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport gc
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport os
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport errno
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport pprint
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport urllib, urlparse
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport traceback
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport weakref
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport functools
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport platform
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom BaseHTTPServer import HTTPServer
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom SimpleHTTPServer import SimpleHTTPRequestHandler
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmssl = test_support.import_module("ssl")
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmHOST = test_support.HOST
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmCERTFILE = None
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSVN_PYTHON_ORG_ROOT_CERT = None
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef handle_error(prefix):
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if test_support.verbose:
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        sys.stdout.write(prefix + exc_format)
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass BasicTests(unittest.TestCase):
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_sslwrap_simple(self):
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # A crude test for the legacy API
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ssl.sslwrap_simple(socket.socket(socket.AF_INET))
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        except IOError, e:
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                pass
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else:
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        except IOError, e:
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                pass
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else:
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef skip_if_broken_ubuntu_ssl(func):
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if hasattr(ssl, 'PROTOCOL_SSLv2'):
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # We need to access the lower-level wrapper in order to create an
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # implicit SSL context without trying to connect or listen.
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            import _ssl
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        except ImportError:
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # The returned function won't get executed, just ignore the error
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @functools.wraps(func)
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def f(*args, **kwargs):
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s = socket.socket(socket.AF_INET)
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                _ssl.sslwrap(s._sock, 0, None, None,
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            except ssl.SSLError as e:
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    platform.linux_distribution() == ('debian', 'squeeze/sid', '')
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    and 'Invalid SSL protocol variant specified' in str(e)):
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return func(*args, **kwargs)
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return f
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else:
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return func
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass BasicSocketTests(unittest.TestCase):
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_constants(self):
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        #ssl.PROTOCOL_SSLv2
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ssl.PROTOCOL_SSLv23
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ssl.PROTOCOL_SSLv3
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ssl.PROTOCOL_TLSv1
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ssl.CERT_NONE
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ssl.CERT_OPTIONAL
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ssl.CERT_REQUIRED
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_random(self):
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        v = ssl.RAND_status()
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if test_support.verbose:
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            sys.stdout.write("\n RAND_status is %d (%s)\n"
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             % (v, (v and "sufficient randomness") or
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "insufficient randomness"))
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ssl.RAND_egd(1)
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        except TypeError:
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            print "didn't raise TypeError"
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ssl.RAND_add("this is a random string", 75.0)
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_parse_cert(self):
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # note that this uses an 'unofficial' function in _ssl.c,
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # provided solely for this test, to exercise the certificate
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # parsing code
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = ssl._ssl._test_decode_cert(CERTFILE, False)
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if test_support.verbose:
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            sys.stdout.write("\n" + pprint.pformat(p) + "\n")
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_DER_to_PEM(self):
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pem = f.read()
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        d1 = ssl.PEM_cert_to_DER_cert(pem)
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p2 = ssl.DER_cert_to_PEM_cert(d1)
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        d2 = ssl.PEM_cert_to_DER_cert(p2)
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(d1, d2)
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if not p2.startswith(ssl.PEM_HEADER + '\n'):
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_openssl_version(self):
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        n = ssl.OPENSSL_VERSION_NUMBER
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        t = ssl.OPENSSL_VERSION_INFO
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        s = ssl.OPENSSL_VERSION
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIsInstance(n, (int, long))
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIsInstance(t, tuple)
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIsInstance(s, str)
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Some sanity checks follow
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # >= 0.9
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertGreaterEqual(n, 0x900000)
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # < 2.0
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertLess(n, 0x20000000)
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        major, minor, fix, patch, status = t
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertGreaterEqual(major, 0)
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertLess(major, 2)
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertGreaterEqual(minor, 0)
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertLess(minor, 256)
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertGreaterEqual(fix, 0)
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertLess(fix, 256)
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertGreaterEqual(patch, 0)
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertLessEqual(patch, 26)
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertGreaterEqual(status, 0)
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertLessEqual(status, 15)
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Version string as returned by OpenSSL, the format might change
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        (s, t))
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_ciphers(self):
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if not test_support.is_resource_enabled('network'):
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        remote = ("svn.python.org", 443)
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with test_support.transient_internet(remote[0]):
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_NONE, ciphers="ALL")
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.connect(remote)
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.connect(remote)
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # Error checking occurs when connecting, because the SSL context
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # isn't created before.
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.connect(remote)
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    @test_support.cpython_only
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_refcycle(self):
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Issue #7943: an SSL object doesn't create reference cycles with
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # itself.
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        s = socket.socket(socket.AF_INET)
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ss = ssl.wrap_socket(s)
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        wr = weakref.ref(ss)
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        del ss
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wr(), None)
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_wrapped_unconnected(self):
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # The _delegate_methods in socket.py are correctly delegated to by an
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # unconnected SSLSocket, so they will raise a socket.error rather than
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # something unexpected like TypeError.
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        s = socket.socket(socket.AF_INET)
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ss = ssl.wrap_socket(s)
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(socket.error, ss.recv, 1)
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(socket.error, ss.recvfrom, 1)
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(socket.error, ss.send, b'x')
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass NetworkedTests(unittest.TestCase):
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_connect(self):
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with test_support.transient_internet("svn.python.org"):
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_NONE)
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.connect(("svn.python.org", 443))
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c = s.getpeercert()
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if c:
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.fail("Peer cert %s shouldn't be here!")
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.close()
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # this should fail because we have no verification certs
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_REQUIRED)
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.connect(("svn.python.org", 443))
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            except ssl.SSLError:
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                pass
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.close()
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # this should succeed because we specify the root cert
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_REQUIRED,
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.connect(("svn.python.org", 443))
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.close()
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_connect_ex(self):
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Issue #11326: check connect_ex() implementation
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with test_support.transient_internet("svn.python.org"):
2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_REQUIRED,
2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertTrue(s.getpeercert())
2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.close()
2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_non_blocking_connect_ex(self):
2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Issue #11326: non-blocking connect_ex() should allow handshake
2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # to proceed after the socket gets ready.
2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with test_support.transient_internet("svn.python.org"):
2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_REQUIRED,
2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                do_handshake_on_connect=False)
2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.setblocking(False)
2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                rc = s.connect_ex(('svn.python.org', 443))
2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # Wait for connect to finish
2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                select.select([], [s], [], 5.0)
2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # Non-blocking handshake
2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                while True:
2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    try:
2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        s.do_handshake()
2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        break
2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    except ssl.SSLError as err:
2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if err.args[0] == ssl.SSL_ERROR_WANT_READ:
2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            select.select([s], [], [], 5.0)
2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            select.select([], [s], [], 5.0)
2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        else:
2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            raise
2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # SSL established
2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertTrue(s.getpeercert())
2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.close()
2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_makefile_close(self):
2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Issue #5238: creating a file-like object with makefile() shouldn't
2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # delay closing the underlying "real socket" (here tested with its
2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # file descriptor, hence skipping the test under Windows).
2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with test_support.transient_internet("svn.python.org"):
2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ss.connect(("svn.python.org", 443))
2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            fd = ss.fileno()
2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            f = ss.makefile()
2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            f.close()
2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # The fd is still open
2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            os.read(fd, 0)
2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # Closing the SSL socket should close the fd too
2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ss.close()
2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            gc.collect()
2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            with self.assertRaises(OSError) as e:
2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                os.read(fd, 0)
2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(e.exception.errno, errno.EBADF)
2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_non_blocking_handshake(self):
2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with test_support.transient_internet("svn.python.org"):
2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = socket.socket(socket.AF_INET)
2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.connect(("svn.python.org", 443))
2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.setblocking(False)
2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(s,
2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_NONE,
2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                do_handshake_on_connect=False)
2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            count = 0
2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            while True:
3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                try:
3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    count += 1
3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    s.do_handshake()
3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    break
3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                except ssl.SSLError, err:
3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if err.args[0] == ssl.SSL_ERROR_WANT_READ:
3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        select.select([s], [], [])
3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        select.select([], [s], [])
3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    else:
3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        raise
3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.close()
3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_get_server_certificate(self):
3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with test_support.transient_internet("svn.python.org"):
3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pem = ssl.get_server_certificate(("svn.python.org", 443))
3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if not pem:
3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.fail("No server certificate on svn.python.org:443!")
3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            except ssl.SSLError:
3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                #should fail
3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                pass
3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else:
3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.fail("Got server certificate %s for svn.python.org!" % pem)
3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if not pem:
3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.fail("No server certificate on svn.python.org:443!")
3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_algorithms(self):
3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Issue #8484: all algorithms should be available when verifying a
3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # certificate.
3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # SHA256 was added in OpenSSL 0.9.8
3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # NOTE: https://sha256.tbs-internet.com is another possible test host
3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        remote = ("sha256.tbs-internet.com", 443)
3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with test_support.transient_internet("sha256.tbs-internet.com"):
3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_REQUIRED,
3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                ca_certs=sha256_cert,)
3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.connect(remote)
3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write("\nCipher with %r is %r\n" %
3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                     (remote, s.cipher()))
3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write("Certificate is:\n%s\n" %
3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                     pprint.pformat(s.getpeercert()))
3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.close()
3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry:
3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    import threading
3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept ImportError:
3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _have_threads = False
3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmelse:
3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _have_threads = True
3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    class ThreadedEchoServer(threading.Thread):
3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class ConnectionHandler(threading.Thread):
3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """A mildly complicated class, because we want it to work both
3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            with and without the SSL wrapper around the socket connection, so
3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            that we can test the STARTTLS functionality."""
3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __init__(self, server, connsock):
3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.server = server
3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.running = False
3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.sock = connsock
3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.sock.setblocking(1)
3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.sslconn = None
3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                threading.Thread.__init__(self)
3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.daemon = True
3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def show_conn_details(self):
3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if self.server.certreqs == ssl.CERT_REQUIRED:
3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    cert = self.sslconn.getpeercert()
3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if test_support.verbose and self.server.chatty:
3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    cert_binary = self.sslconn.getpeercert(True)
3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if test_support.verbose and self.server.chatty:
3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                cipher = self.sslconn.cipher()
3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose and self.server.chatty:
3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def wrap_conn(self):
3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                try:
3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                   certfile=self.server.certificate,
3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                   ssl_version=self.server.protocol,
4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                   ca_certs=self.server.cacerts,
4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                   cert_reqs=self.server.certreqs,
4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                   ciphers=self.server.ciphers)
4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                except ssl.SSLError:
4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    # XXX Various errors can have happened here, for example
4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    # a mismatching protocol version, an invalid certificate,
4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    # or a low-level bug. This should be made more discriminating.
4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if self.server.chatty:
4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        handle_error("\n server:  bad connection attempt from " +
4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                     str(self.sock.getpeername()) + ":\n")
4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.close()
4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.running = False
4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.server.stop()
4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return False
4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else:
4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return True
4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def read(self):
4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if self.sslconn:
4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return self.sslconn.read()
4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else:
4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return self.sock.recv(1024)
4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def write(self, bytes):
4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if self.sslconn:
4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return self.sslconn.write(bytes)
4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else:
4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return self.sock.send(bytes)
4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def close(self):
4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if self.sslconn:
4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.sslconn.close()
4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else:
4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.sock._sock.close()
4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def run(self):
4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.running = True
4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if not self.server.starttls_server:
4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if isinstance(self.sock, ssl.SSLSocket):
4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        self.sslconn = self.sock
4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    elif not self.wrap_conn():
4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        return
4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.show_conn_details()
4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                while self.running:
4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    try:
4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        msg = self.read()
4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if not msg:
4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            # eof, so quit this handler
4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.running = False
4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.close()
4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        elif msg.strip() == 'over':
4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            if test_support.verbose and self.server.connectionchatty:
4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                sys.stdout.write(" server: client closed connection\n")
4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.close()
4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            return
4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        elif self.server.starttls_server and msg.strip() == 'STARTTLS':
4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            if test_support.verbose and self.server.connectionchatty:
4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.write("OK\n")
4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            if not self.wrap_conn():
4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                return
4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            if test_support.verbose and self.server.connectionchatty:
4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.write("OK\n")
4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.sslconn.unwrap()
4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.sslconn = None
4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            if test_support.verbose and self.server.connectionchatty:
4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                sys.stdout.write(" server: connection is now unencrypted...\n")
4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        else:
4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            if (test_support.verbose and
4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                self.server.connectionchatty):
4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                ctype = (self.sslconn and "encrypted") or "unencrypted"
4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                 % (repr(msg), ctype, repr(msg.lower()), ctype))
4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.write(msg.lower())
4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    except ssl.SSLError:
4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if self.server.chatty:
4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            handle_error("Test server failure:\n")
4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        self.close()
4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        self.running = False
4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        # normally, we'd just stop here, but for the test
4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        # harness, we want to stop the server
4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        self.server.stop()
4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def __init__(self, certificate, ssl_version=None,
4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     certreqs=None, cacerts=None,
4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     chatty=True, connectionchatty=False, starttls_server=False,
4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     wrap_accepting_socket=False, ciphers=None):
4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if ssl_version is None:
4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                ssl_version = ssl.PROTOCOL_TLSv1
4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if certreqs is None:
4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                certreqs = ssl.CERT_NONE
4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.certificate = certificate
4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.protocol = ssl_version
4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.certreqs = certreqs
4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.cacerts = cacerts
4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.ciphers = ciphers
4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.chatty = chatty
5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.connectionchatty = connectionchatty
5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.starttls_server = starttls_server
5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.sock = socket.socket()
5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.flag = None
5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if wrap_accepting_socket:
5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.sock = ssl.wrap_socket(self.sock, server_side=True,
5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                            certfile=self.certificate,
5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                            cert_reqs = self.certreqs,
5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                            ca_certs = self.cacerts,
5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                            ssl_version = self.protocol,
5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                            ciphers = self.ciphers)
5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose and self.chatty:
5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(' server:  wrapped server socket as %s\n' % str(self.sock))
5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.port = test_support.bind_port(self.sock)
5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.active = False
5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            threading.Thread.__init__(self)
5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.daemon = True
5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def start(self, flag=None):
5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.flag = flag
5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            threading.Thread.start(self)
5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def run(self):
5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.sock.settimeout(0.05)
5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.sock.listen(5)
5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.active = True
5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if self.flag:
5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # signal an event
5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.flag.set()
5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            while self.active:
5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                try:
5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    newconn, connaddr = self.sock.accept()
5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if test_support.verbose and self.chatty:
5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        sys.stdout.write(' server:  new connection from '
5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                         + str(connaddr) + '\n')
5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    handler = self.ConnectionHandler(self, newconn)
5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    handler.start()
5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                except socket.timeout:
5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    pass
5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                except KeyboardInterrupt:
5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.stop()
5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.sock.close()
5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def stop(self):
5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.active = False
5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    class AsyncoreEchoServer(threading.Thread):
5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class EchoServer(asyncore.dispatcher):
5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            class ConnectionHandler(asyncore.dispatcher_with_send):
5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                def __init__(self, conn, certfile):
5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    asyncore.dispatcher_with_send.__init__(self, conn)
5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.socket = ssl.wrap_socket(conn, server_side=True,
5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                  certfile=certfile,
5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                  do_handshake_on_connect=False)
5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self._ssl_accepting = True
5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                def readable(self):
5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if isinstance(self.socket, ssl.SSLSocket):
5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        while self.socket.pending() > 0:
5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.handle_read_event()
5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return True
5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                def _do_ssl_handshake(self):
5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    try:
5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        self.socket.do_handshake()
5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    except ssl.SSLError, err:
5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                           ssl.SSL_ERROR_WANT_WRITE):
5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            return
5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        elif err.args[0] == ssl.SSL_ERROR_EOF:
5734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            return self.handle_close()
5744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        raise
5754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    except socket.error, err:
5764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if err.args[0] == errno.ECONNABORTED:
5774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            return self.handle_close()
5784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    else:
5794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        self._ssl_accepting = False
5804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                def handle_read(self):
5824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if self._ssl_accepting:
5834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        self._do_ssl_handshake()
5844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    else:
5854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        data = self.recv(1024)
5864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if data and data.strip() != 'over':
5874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.send(data.lower())
5884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                def handle_close(self):
5904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.close()
5914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if test_support.verbose:
5924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        sys.stdout.write(" server:  closed connection %s\n" % self.socket)
5934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                def handle_error(self):
5954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    raise
5964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __init__(self, certfile):
5984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.certfile = certfile
5994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                asyncore.dispatcher.__init__(self)
6004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
6014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.port = test_support.bind_port(self.socket)
6024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.listen(5)
6034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def handle_accept(self):
6054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sock_obj, addr = self.accept()
6064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
6074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(" server:  new connection from %s:%s\n" %addr)
6084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.ConnectionHandler(sock_obj, self.certfile)
6094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def handle_error(self):
6114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise
6124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def __init__(self, certfile):
6144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.flag = None
6154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.active = False
6164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.server = self.EchoServer(certfile)
6174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.port = self.server.port
6184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            threading.Thread.__init__(self)
6194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.daemon = True
6204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def __str__(self):
6224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return "<%s %s>" % (self.__class__.__name__, self.server)
6234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def start(self, flag=None):
6254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.flag = flag
6264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            threading.Thread.start(self)
6274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def run(self):
6294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.active = True
6304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if self.flag:
6314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.flag.set()
6324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            while self.active:
6334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                asyncore.loop(0.05)
6344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def stop(self):
6364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.active = False
6374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.server.close()
6384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    class SocketServerHTTPSServer(threading.Thread):
6404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class HTTPSServer(HTTPServer):
6424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __init__(self, server_address, RequestHandlerClass, certfile):
6444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                HTTPServer.__init__(self, server_address, RequestHandlerClass)
6454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # we assume the certfile contains both private key and certificate
6464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.certfile = certfile
6474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.allow_reuse_address = True
6484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __str__(self):
6504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return ('<%s %s:%s>' %
6514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        (self.__class__.__name__,
6524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         self.server_name,
6534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         self.server_port))
6544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def get_request(self):
6564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # override this to wrap socket with SSL
6574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sock, addr = self.socket.accept()
6584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sslconn = ssl.wrap_socket(sock, server_side=True,
6594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                          certfile=self.certfile)
6604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return sslconn, addr
6614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
6634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # need to override translate_path to get a known root,
6644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # instead of using os.curdir, since the test could be
6654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # run from anywhere
6664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server_version = "TestHTTPS/1.0"
6684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            root = None
6704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def translate_path(self, path):
6724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                """Translate a /-separated PATH to the local filename syntax.
6734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Components that mean special things to the local file system
6754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (e.g. drive or directory names) are ignored.  (XXX They should
6764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                probably be diagnosed.)
6774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                """
6794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # abandon query parameters
6804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                path = urlparse.urlparse(path)[2]
6814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                path = os.path.normpath(urllib.unquote(path))
6824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                words = path.split('/')
6834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                words = filter(None, words)
6844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                path = self.root
6854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                for word in words:
6864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    drive, word = os.path.splitdrive(word)
6874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    head, word = os.path.split(word)
6884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if word in self.root: continue
6894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    path = os.path.join(path, word)
6904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return path
6914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def log_message(self, format, *args):
6934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # we override this to suppress logging unless "verbose"
6954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
6974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(" server (%s:%d %s):\n   [%s] %s\n" %
6984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                     (self.server.server_address,
6994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      self.server.server_port,
7004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      self.request.cipher(),
7014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      self.log_date_time_string(),
7024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      format%args))
7034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def __init__(self, certfile):
7064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.flag = None
7074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
7084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.server = self.HTTPSServer(
7094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (HOST, 0), self.RootedHTTPRequestHandler, certfile)
7104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.port = self.server.server_port
7114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            threading.Thread.__init__(self)
7124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.daemon = True
7134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def __str__(self):
7154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return "<%s %s>" % (self.__class__.__name__, self.server)
7164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def start(self, flag=None):
7184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.flag = flag
7194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            threading.Thread.start(self)
7204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def run(self):
7224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if self.flag:
7234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.flag.set()
7244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.server.serve_forever(0.05)
7254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def stop(self):
7274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.server.shutdown()
7284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def bad_cert_test(certfile):
7314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """
7324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Launch a server with CERT_REQUIRED, and check that trying to
7334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        connect to it with the given client certificate fails.
7344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """
7354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        server = ThreadedEchoServer(CERTFILE,
7364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    certreqs=ssl.CERT_REQUIRED,
7374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    cacerts=CERTFILE, chatty=False)
7384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        flag = threading.Event()
7394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        server.start(flag)
7404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # wait for it to start
7414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        flag.wait()
7424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # try to connect
7434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
7444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
7454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s = ssl.wrap_socket(socket.socket(),
7464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    certfile=certfile,
7474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    ssl_version=ssl.PROTOCOL_TLSv1)
7484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.connect((HOST, server.port))
7494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            except ssl.SSLError, x:
7504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
7514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write("\nSSLError is %s\n" % x[1])
7524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            except socket.error, x:
7534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
7544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write("\nsocket.error is %s\n" % x[1])
7554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else:
7564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise AssertionError("Use of invalid cert should have failed!")
7574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        finally:
7584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server.stop()
7594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server.join()
7604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def server_params_test(certfile, protocol, certreqs, cacertsfile,
7624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           client_certfile, client_protocol=None, indata="FOO\n",
7634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           ciphers=None, chatty=True, connectionchatty=False,
7644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           wrap_accepting_socket=False):
7654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """
7664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Launch a server, connect a client to it and try various reads
7674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        and writes.
7684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """
7694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        server = ThreadedEchoServer(certfile,
7704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    certreqs=certreqs,
7714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    ssl_version=protocol,
7724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    cacerts=cacertsfile,
7734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    ciphers=ciphers,
7744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    chatty=chatty,
7754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    connectionchatty=connectionchatty,
7764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    wrap_accepting_socket=wrap_accepting_socket)
7774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        flag = threading.Event()
7784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        server.start(flag)
7794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # wait for it to start
7804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        flag.wait()
7814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # try to connect
7824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if client_protocol is None:
7834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            client_protocol = protocol
7844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
7854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(),
7864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                certfile=client_certfile,
7874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                ca_certs=cacertsfile,
7884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                ciphers=ciphers,
7894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=certreqs,
7904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                ssl_version=client_protocol)
7914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.connect((HOST, server.port))
7924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for arg in [indata, bytearray(indata), memoryview(indata)]:
7934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if connectionchatty:
7944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if test_support.verbose:
7954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        sys.stdout.write(
7964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            " client:  sending %s...\n" % (repr(arg)))
7974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.write(arg)
7984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                outdata = s.read()
7994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if connectionchatty:
8004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if test_support.verbose:
8014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        sys.stdout.write(" client:  read %s\n" % repr(outdata))
8024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if outdata != indata.lower():
8034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    raise AssertionError(
8044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
8054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        % (outdata[:min(len(outdata),20)], len(outdata),
8064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           indata[:min(len(indata),20)].lower(), len(indata)))
8074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.write("over\n")
8084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if connectionchatty:
8094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
8104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(" client:  closing connection.\n")
8114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.close()
8124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        finally:
8134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server.stop()
8144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server.join()
8154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def try_protocol_combo(server_protocol,
8174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           client_protocol,
8184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           expect_success,
8194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           certsreqs=None):
8204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if certsreqs is None:
8214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            certsreqs = ssl.CERT_NONE
8224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        certtype = {
8234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ssl.CERT_NONE: "CERT_NONE",
8244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
8254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ssl.CERT_REQUIRED: "CERT_REQUIRED",
8264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }[certsreqs]
8274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if test_support.verbose:
8284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
8294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            sys.stdout.write(formatstr %
8304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             (ssl.get_protocol_name(client_protocol),
8314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              ssl.get_protocol_name(server_protocol),
8324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              certtype))
8334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
8344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
8354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # will send an SSLv3 hello (rather than SSLv2) starting from
8364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # OpenSSL 1.0.0 (see issue #8322).
8374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server_params_test(CERTFILE, server_protocol, certsreqs,
8384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               CERTFILE, CERTFILE, client_protocol,
8394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               ciphers="ALL", chatty=False)
8404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Protocol mismatch can result in either an SSLError, or a
8414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # "Connection reset by peer" error.
8424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        except ssl.SSLError:
8434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if expect_success:
8444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise
8454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        except socket.error as e:
8464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if expect_success or e.errno != errno.ECONNRESET:
8474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise
8484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
8494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if not expect_success:
8504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise AssertionError(
8514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "Client protocol %s succeeded with server protocol %s!"
8524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    % (ssl.get_protocol_name(client_protocol),
8534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                       ssl.get_protocol_name(server_protocol)))
8544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    class ThreadedTests(unittest.TestCase):
8574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_rude_shutdown(self):
8594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """A brutal shutdown of an SSL server should raise an IOError
8604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            in the client when attempting handshake.
8614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """
8624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            listener_ready = threading.Event()
8634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            listener_gone = threading.Event()
8644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = socket.socket()
8664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            port = test_support.bind_port(s, HOST)
8674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # `listener` runs in a thread.  It sits in an accept() until
8694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # the main thread connects.  Then it rudely closes the socket,
8704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # and sets Event `listener_gone` to let the main thread know
8714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # the socket is gone.
8724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def listener():
8734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.listen(5)
8744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                listener_ready.set()
8754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.accept()
8764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.close()
8774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                listener_gone.set()
8784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def connector():
8804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                listener_ready.wait()
8814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                c = socket.socket()
8824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                c.connect((HOST, port))
8834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                listener_gone.wait()
8844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                try:
8854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    ssl_sock = ssl.wrap_socket(c)
8864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                except IOError:
8874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    pass
8884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else:
8894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.fail('connecting to closed SSL socket should have failed')
8904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            t = threading.Thread(target=listener)
8924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            t.start()
8934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
8944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                connector()
8954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
8964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                t.join()
8974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @skip_if_broken_ubuntu_ssl
8994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_echo(self):
9004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Basic test of an SSL client connecting to a server"""
9014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
9024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\n")
9034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
9044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
9054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               chatty=True, connectionchatty=True)
9064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_getpeercert(self):
9084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
9094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\n")
9104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s2 = socket.socket()
9114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server = ThreadedEchoServer(CERTFILE,
9124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        certreqs=ssl.CERT_NONE,
9134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        ssl_version=ssl.PROTOCOL_SSLv23,
9144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        cacerts=CERTFILE,
9154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        chatty=False)
9164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            flag = threading.Event()
9174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server.start(flag)
9184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # wait for it to start
9194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            flag.wait()
9204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # try to connect
9214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
9224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s = ssl.wrap_socket(socket.socket(),
9234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    certfile=CERTFILE,
9244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    ca_certs=CERTFILE,
9254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    cert_reqs=ssl.CERT_REQUIRED,
9264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    ssl_version=ssl.PROTOCOL_SSLv23)
9274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.connect((HOST, server.port))
9284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                cert = s.getpeercert()
9294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertTrue(cert, "Can't get peer certificate.")
9304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                cipher = s.cipher()
9314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
9324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(pprint.pformat(cert) + '\n')
9334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
9344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if 'subject' not in cert:
9354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.fail("No subject field in certificate: %s." %
9364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              pprint.pformat(cert))
9374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if ((('organizationName', 'Python Software Foundation'),)
9384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    not in cert['subject']):
9394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.fail(
9404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "Missing or invalid 'organizationName' field in certificate subject; "
9414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "should be 'Python Software Foundation'.")
9424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.close()
9434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
9444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.stop()
9454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.join()
9464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_empty_cert(self):
9484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Connecting with an empty cert file"""
9494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
9504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      "nullcert.pem"))
9514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_malformed_cert(self):
9524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Connecting with a badly formatted certificate (syntax error)"""
9534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
9544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                       "badcert.pem"))
9554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_nonexisting_cert(self):
9564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Connecting with a non-existing cert file"""
9574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
9584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                       "wrongcert.pem"))
9594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_malformed_key(self):
9604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Connecting with a badly formatted key (syntax error)"""
9614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
9624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                       "badkey.pem"))
9634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @skip_if_broken_ubuntu_ssl
9654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_protocol_sslv2(self):
9664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Connecting to an SSLv2 server with various client options"""
9674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
9684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\n")
9694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
9704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
9714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
9724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
9734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
9744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
9754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @skip_if_broken_ubuntu_ssl
9774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_protocol_sslv23(self):
9784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Connecting to an SSLv23 server with various client options"""
9794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
9804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\n")
9814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
9824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
9834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            except (ssl.SSLError, socket.error), x:
9844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # this fails on some older versions of OpenSSL (0.9.7l, for instance)
9854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
9864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(
9874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
9884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        % str(x))
9894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
9904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
9914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
9924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
9944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
9954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
9964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
9984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
9994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
10004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @skip_if_broken_ubuntu_ssl
10024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_protocol_sslv3(self):
10034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Connecting to an SSLv3 server with various client options"""
10044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
10054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\n")
10064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
10074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
10084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
10094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if hasattr(ssl, 'PROTOCOL_SSLv2'):
10104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
10114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
10124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
10134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @skip_if_broken_ubuntu_ssl
10154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_protocol_tlsv1(self):
10164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Connecting to a TLSv1 server with various client options"""
10174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
10184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\n")
10194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
10204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
10214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
10224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if hasattr(ssl, 'PROTOCOL_SSLv2'):
10234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
10244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
10254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
10264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_starttls(self):
10284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Switching from clear text to encrypted and back again."""
10294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
10304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server = ThreadedEchoServer(CERTFILE,
10324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        ssl_version=ssl.PROTOCOL_TLSv1,
10334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        starttls_server=True,
10344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        chatty=True,
10354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        connectionchatty=True)
10364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            flag = threading.Event()
10374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server.start(flag)
10384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # wait for it to start
10394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            flag.wait()
10404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # try to connect
10414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            wrapped = False
10424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
10434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s = socket.socket()
10444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.setblocking(1)
10454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.connect((HOST, server.port))
10464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
10474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write("\n")
10484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                for indata in msgs:
10494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if test_support.verbose:
10504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        sys.stdout.write(
10514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            " client:  sending %s...\n" % repr(indata))
10524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if wrapped:
10534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        conn.write(indata)
10544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        outdata = conn.read()
10554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    else:
10564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        s.send(indata)
10574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        outdata = s.recv(1024)
10584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if (indata == "STARTTLS" and
10594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        outdata.strip().lower().startswith("ok")):
10604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        # STARTTLS ok, switch to secure mode
10614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if test_support.verbose:
10624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            sys.stdout.write(
10634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                " client:  read %s from server, starting TLS...\n"
10644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                % repr(outdata))
10654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
10664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        wrapped = True
10674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    elif (indata == "ENDTLS" and
10684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        outdata.strip().lower().startswith("ok")):
10694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        # ENDTLS ok, switch back to clear text
10704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if test_support.verbose:
10714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            sys.stdout.write(
10724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                " client:  read %s from server, ending TLS...\n"
10734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                % repr(outdata))
10744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        s = conn.unwrap()
10754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        wrapped = False
10764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    else:
10774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if test_support.verbose:
10784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            sys.stdout.write(
10794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                " client:  read %s from server\n" % repr(outdata))
10804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
10814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(" client:  closing connection.\n")
10824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if wrapped:
10834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    conn.write("over\n")
10844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else:
10854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    s.send("over\n")
10864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.close()
10874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
10884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.stop()
10894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.join()
10904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_socketserver(self):
10924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Using a SocketServer to create and manage SSL connections."""
10934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server = SocketServerHTTPSServer(CERTFILE)
10944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            flag = threading.Event()
10954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server.start(flag)
10964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # wait for it to start
10974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            flag.wait()
10984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # try to connect
10994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
11004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
11014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write('\n')
11024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                with open(CERTFILE, 'rb') as f:
11034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    d1 = f.read()
11044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                d2 = ''
11054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # now fetch the same data from the HTTPS server
11064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                url = 'https://127.0.0.1:%d/%s' % (
11074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    server.port, os.path.split(CERTFILE)[1])
11084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                with test_support.check_py3k_warnings():
11094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    f = urllib.urlopen(url)
11104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                dlen = f.info().getheader("content-length")
11114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if dlen and (int(dlen) > 0):
11124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    d2 = f.read(int(dlen))
11134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if test_support.verbose:
11144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        sys.stdout.write(
11154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            " client: read %d bytes from remote server '%s'\n"
11164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            % (len(d2), server))
11174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                f.close()
11184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertEqual(d1, d2)
11194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
11204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.stop()
11214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.join()
11224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_wrapped_accept(self):
11244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Check the accept() method on SSL sockets."""
11254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
11264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\n")
11274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server_params_test(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
11284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
11294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               chatty=True, connectionchatty=True,
11304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               wrap_accepting_socket=True)
11314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_asyncore_server(self):
11334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Check the example asyncore integration."""
11344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            indata = "TEST MESSAGE of mixed case\n"
11354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
11374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\n")
11384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server = AsyncoreEchoServer(CERTFILE)
11394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            flag = threading.Event()
11404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server.start(flag)
11414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # wait for it to start
11424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            flag.wait()
11434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # try to connect
11444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
11454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s = ssl.wrap_socket(socket.socket())
11464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.connect(('127.0.0.1', server.port))
11474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
11484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(
11494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        " client:  sending %s...\n" % (repr(indata)))
11504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.write(indata)
11514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                outdata = s.read()
11524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
11534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(" client:  read %s\n" % repr(outdata))
11544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if outdata != indata.lower():
11554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.fail(
11564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
11574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        % (outdata[:min(len(outdata),20)], len(outdata),
11584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           indata[:min(len(indata),20)].lower(), len(indata)))
11594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.write("over\n")
11604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if test_support.verbose:
11614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    sys.stdout.write(" client:  closing connection.\n")
11624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.close()
11634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
11644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.stop()
11654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # wait for server thread to end
11664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.join()
11674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_recv_send(self):
11694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """Test recv(), send() and friends."""
11704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if test_support.verbose:
11714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sys.stdout.write("\n")
11724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server = ThreadedEchoServer(CERTFILE,
11744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        certreqs=ssl.CERT_NONE,
11754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        ssl_version=ssl.PROTOCOL_TLSv1,
11764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        cacerts=CERTFILE,
11774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        chatty=True,
11784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        connectionchatty=False)
11794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            flag = threading.Event()
11804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server.start(flag)
11814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # wait for it to start
11824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            flag.wait()
11834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # try to connect
11844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = ssl.wrap_socket(socket.socket(),
11854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                server_side=False,
11864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                certfile=CERTFILE,
11874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                ca_certs=CERTFILE,
11884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                cert_reqs=ssl.CERT_NONE,
11894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                ssl_version=ssl.PROTOCOL_TLSv1)
11904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s.connect((HOST, server.port))
11914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
11924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # helper methods for standardising recv* method signatures
11934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                def _recv_into():
11944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    b = bytearray("\0"*100)
11954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    count = s.recv_into(b)
11964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return b[:count]
11974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                def _recvfrom_into():
11994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    b = bytearray("\0"*100)
12004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    count, addr = s.recvfrom_into(b)
12014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return b[:count]
12024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # (name, method, whether to expect success, *args)
12044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                send_methods = [
12054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    ('send', s.send, True, []),
12064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    ('sendto', s.sendto, False, ["some.address"]),
12074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    ('sendall', s.sendall, True, []),
12084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                ]
12094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                recv_methods = [
12104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    ('recv', s.recv, True, []),
12114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    ('recvfrom', s.recvfrom, False, ["some.address"]),
12124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    ('recv_into', _recv_into, True, []),
12134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    ('recvfrom_into', _recvfrom_into, False, []),
12144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                ]
12154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                data_prefix = u"PREFIX_"
12164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                for meth_name, send_meth, expect_success, args in send_methods:
12184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    indata = data_prefix + meth_name
12194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    try:
12204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        send_meth(indata.encode('ASCII', 'strict'), *args)
12214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        outdata = s.read()
12224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        outdata = outdata.decode('ASCII', 'strict')
12234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if outdata != indata.lower():
12244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.fail(
12254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "While sending with <<%s>> bad data "
12264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "<<%r>> (%d) received; "
12274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "expected <<%r>> (%d)\n" % (
12284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    meth_name, outdata[:20], len(outdata),
12294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    indata[:20], len(indata)
12304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                )
12314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            )
12324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    except ValueError as e:
12334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if expect_success:
12344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.fail(
12354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "Failed to send with method <<%s>>; "
12364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "expected to succeed.\n" % (meth_name,)
12374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            )
12384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if not str(e).startswith(meth_name):
12394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.fail(
12404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "Method <<%s>> failed with unexpected "
12414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "exception message: %s\n" % (
12424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    meth_name, e
12434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                )
12444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            )
12454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                for meth_name, recv_meth, expect_success, args in recv_methods:
12474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    indata = data_prefix + meth_name
12484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    try:
12494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        s.send(indata.encode('ASCII', 'strict'))
12504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        outdata = recv_meth(*args)
12514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        outdata = outdata.decode('ASCII', 'strict')
12524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if outdata != indata.lower():
12534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.fail(
12544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "While receiving with <<%s>> bad data "
12554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "<<%r>> (%d) received; "
12564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "expected <<%r>> (%d)\n" % (
12574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    meth_name, outdata[:20], len(outdata),
12584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    indata[:20], len(indata)
12594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                )
12604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            )
12614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    except ValueError as e:
12624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if expect_success:
12634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.fail(
12644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "Failed to receive with method <<%s>>; "
12654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "expected to succeed.\n" % (meth_name,)
12664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            )
12674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if not str(e).startswith(meth_name):
12684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            self.fail(
12694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "Method <<%s>> failed with unexpected "
12704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "exception message: %s\n" % (
12714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    meth_name, e
12724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                )
12734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            )
12744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        # consume data
12754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        s.read()
12764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.write("over\n".encode("ASCII", "strict"))
12784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s.close()
12794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
12804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.stop()
12814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.join()
12824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def test_handshake_timeout(self):
12844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # Issue #5103: SSL handshake must respect the socket timeout
12854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            server = socket.socket(socket.AF_INET)
12864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            host = "127.0.0.1"
12874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            port = test_support.bind_port(server)
12884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            started = threading.Event()
12894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finish = False
12904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def serve():
12924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.listen(5)
12934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                started.set()
12944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                conns = []
12954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                while not finish:
12964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    r, w, e = select.select([server], [], [], 0.1)
12974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if server in r:
12984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        # Let the socket hang around rather than having
12994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        # it closed by garbage collection.
13004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        conns.append(server.accept()[0])
13014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            t = threading.Thread(target=serve)
13034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            t.start()
13044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            started.wait()
13054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
13074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                try:
13084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    c = socket.socket(socket.AF_INET)
13094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    c.settimeout(0.2)
13104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    c.connect((host, port))
13114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    # Will attempt handshake and time out
13124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.assertRaisesRegexp(ssl.SSLError, "timed out",
13134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                            ssl.wrap_socket, c)
13144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                finally:
13154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    c.close()
13164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                try:
13174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    c = socket.socket(socket.AF_INET)
13184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    c.settimeout(0.2)
13194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    c = ssl.wrap_socket(c)
13204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    # Will attempt handshake and time out
13214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.assertRaisesRegexp(ssl.SSLError, "timed out",
13224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                            c.connect, (host, port))
13234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                finally:
13244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    c.close()
13254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            finally:
13264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                finish = True
13274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                t.join()
13284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                server.close()
13294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_main(verbose=False):
13324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT
13334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
13344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "keycert.pem")
13354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
13364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        os.path.dirname(__file__) or os.curdir,
13374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        "https_svn_python_org_root.pem")
13384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (not os.path.exists(CERTFILE) or
13404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
13414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        raise test_support.TestFailed("Can't read certificate files!")
13424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    tests = [BasicTests, BasicSocketTests]
13444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if test_support.is_resource_enabled('network'):
13464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        tests.append(NetworkedTests)
13474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if _have_threads:
13494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        thread_info = test_support.threading_setup()
13504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if thread_info and test_support.is_resource_enabled('network'):
13514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            tests.append(ThreadedTests)
13524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    try:
13544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        test_support.run_unittest(*tests)
13554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    finally:
13564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if _have_threads:
13574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            test_support.threading_cleanup(*thread_info)
13584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__":
13604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_main()
1361