| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 1 | # | 
 | 2 | # Licensed to the Apache Software Foundation (ASF) under one | 
 | 3 | # or more contributor license agreements. See the NOTICE file | 
 | 4 | # distributed with this work for additional information | 
 | 5 | # regarding copyright ownership. The ASF licenses this file | 
 | 6 | # to you under the Apache License, Version 2.0 (the | 
 | 7 | # "License"); you may not use this file except in compliance | 
 | 8 | # with the License. You may obtain a copy of the License at | 
 | 9 | # | 
 | 10 | #   http://www.apache.org/licenses/LICENSE-2.0 | 
 | 11 | # | 
 | 12 | # Unless required by applicable law or agreed to in writing, | 
 | 13 | # software distributed under the License is distributed on an | 
 | 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
 | 15 | # KIND, either express or implied. See the License for the | 
 | 16 | # specific language governing permissions and limitations | 
 | 17 | # under the License. | 
 | 18 | # | 
 | 19 |  | 
| Nobuaki Sukegawa | 66f5053 | 2016-02-14 21:47:38 +0900 | [diff] [blame] | 20 | import inspect | 
| Nobuaki Sukegawa | 355116e | 2016-02-11 18:01:20 +0900 | [diff] [blame] | 21 | import logging | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 22 | import os | 
 | 23 | import platform | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 24 | import ssl | 
 | 25 | import sys | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 26 | import tempfile | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 27 | import threading | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 28 | import unittest | 
 | 29 | import warnings | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 30 | from contextlib import contextmanager | 
 | 31 |  | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 32 | import _import_local_thrift  # noqa | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 33 |  | 
 | 34 | SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__)) | 
 | 35 | ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(SCRIPT_DIR))) | 
 | 36 | SERVER_PEM = os.path.join(ROOT_DIR, 'test', 'keys', 'server.pem') | 
 | 37 | SERVER_CERT = os.path.join(ROOT_DIR, 'test', 'keys', 'server.crt') | 
 | 38 | SERVER_KEY = os.path.join(ROOT_DIR, 'test', 'keys', 'server.key') | 
| Nobuaki Sukegawa | f39f7db | 2016-02-04 15:09:41 +0900 | [diff] [blame] | 39 | CLIENT_CERT_NO_IP = os.path.join(ROOT_DIR, 'test', 'keys', 'client.crt') | 
 | 40 | CLIENT_KEY_NO_IP = os.path.join(ROOT_DIR, 'test', 'keys', 'client.key') | 
 | 41 | CLIENT_CERT = os.path.join(ROOT_DIR, 'test', 'keys', 'client_v3.crt') | 
 | 42 | CLIENT_KEY = os.path.join(ROOT_DIR, 'test', 'keys', 'client_v3.key') | 
 | 43 | CLIENT_CA = os.path.join(ROOT_DIR, 'test', 'keys', 'CA.pem') | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 44 |  | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 45 | TEST_CIPHERS = 'DES-CBC3-SHA' | 
 | 46 |  | 
 | 47 |  | 
 | 48 | class ServerAcceptor(threading.Thread): | 
| Nobuaki Sukegawa | 66f5053 | 2016-02-14 21:47:38 +0900 | [diff] [blame] | 49 |     def __init__(self, server, expect_failure=False): | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 50 |         super(ServerAcceptor, self).__init__() | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 51 |         self.daemon = True | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 52 |         self._server = server | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 53 |         self._listening = threading.Event() | 
 | 54 |         self._port = None | 
 | 55 |         self._port_bound = threading.Event() | 
 | 56 |         self._client = None | 
 | 57 |         self._client_accepted = threading.Event() | 
| Nobuaki Sukegawa | 66f5053 | 2016-02-14 21:47:38 +0900 | [diff] [blame] | 58 |         self._expect_failure = expect_failure | 
 | 59 |         frame = inspect.stack(3)[2] | 
 | 60 |         self.name = frame[3] | 
 | 61 |         del frame | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 62 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 63 |     def run(self): | 
 | 64 |         self._server.listen() | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 65 |         self._listening.set() | 
 | 66 |  | 
 | 67 |         try: | 
 | 68 |             address = self._server.handle.getsockname() | 
 | 69 |             if len(address) > 1: | 
 | 70 |                 # AF_INET addresses are 2-tuples (host, port) and AF_INET6 are | 
 | 71 |                 # 4-tuples (host, port, ...), but in each case port is in the second slot. | 
 | 72 |                 self._port = address[1] | 
 | 73 |         finally: | 
 | 74 |             self._port_bound.set() | 
 | 75 |  | 
 | 76 |         try: | 
 | 77 |             self._client = self._server.accept() | 
| Nobuaki Sukegawa | 66f5053 | 2016-02-14 21:47:38 +0900 | [diff] [blame] | 78 |         except Exception: | 
 | 79 |             logging.exception('error on server side (%s):' % self.name) | 
 | 80 |             if not self._expect_failure: | 
 | 81 |                 raise | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 82 |         finally: | 
 | 83 |             self._client_accepted.set() | 
 | 84 |  | 
 | 85 |     def await_listening(self): | 
 | 86 |         self._listening.wait() | 
 | 87 |  | 
 | 88 |     @property | 
 | 89 |     def port(self): | 
 | 90 |         self._port_bound.wait() | 
 | 91 |         return self._port | 
 | 92 |  | 
 | 93 |     @property | 
 | 94 |     def client(self): | 
 | 95 |         self._client_accepted.wait() | 
 | 96 |         return self._client | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 97 |  | 
 | 98 |  | 
 | 99 | # Python 2.6 compat | 
 | 100 | class AssertRaises(object): | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 101 |     def __init__(self, expected): | 
 | 102 |         self._expected = expected | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 103 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 104 |     def __enter__(self): | 
 | 105 |         pass | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 106 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 107 |     def __exit__(self, exc_type, exc_value, traceback): | 
 | 108 |         if not exc_type or not issubclass(exc_type, self._expected): | 
 | 109 |             raise Exception('fail') | 
 | 110 |         return True | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 111 |  | 
 | 112 |  | 
 | 113 | class TSSLSocketTest(unittest.TestCase): | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 114 |     def _server_socket(self, **kwargs): | 
 | 115 |         return TSSLServerSocket(port=0, **kwargs) | 
 | 116 |  | 
 | 117 |     @contextmanager | 
| Nobuaki Sukegawa | 66f5053 | 2016-02-14 21:47:38 +0900 | [diff] [blame] | 118 |     def _connectable_client(self, server, expect_failure=False, path=None, **client_kwargs): | 
 | 119 |         acc = ServerAcceptor(server, expect_failure) | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 120 |         try: | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 121 |             acc.start() | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 122 |             acc.await_listening() | 
 | 123 |  | 
 | 124 |             host, port = ('localhost', acc.port) if path is None else (None, None) | 
| Nobuaki Sukegawa | 66f5053 | 2016-02-14 21:47:38 +0900 | [diff] [blame] | 125 |             client = TSSLSocket(host, port, unix_socket=path, **client_kwargs) | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 126 |             yield acc, client | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 127 |         finally: | 
| Nobuaki Sukegawa | 25536ad | 2016-02-04 15:08:55 +0900 | [diff] [blame] | 128 |             if acc.client: | 
 | 129 |                 acc.client.close() | 
 | 130 |             server.close() | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 131 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 132 |     def _assert_connection_failure(self, server, path=None, **client_args): | 
| Nobuaki Sukegawa | 66f5053 | 2016-02-14 21:47:38 +0900 | [diff] [blame] | 133 |         logging.disable(logging.CRITICAL) | 
| Nobuaki Sukegawa | d2b4f24 | 2016-09-04 18:49:23 +0900 | [diff] [blame] | 134 |         try: | 
 | 135 |             with self._connectable_client(server, True, path=path, **client_args) as (acc, client): | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 136 |                 # We need to wait for a connection failure, but not too long.  20ms is a tunable | 
 | 137 |                 # compromise between test speed and stability | 
 | 138 |                 client.setTimeout(20) | 
 | 139 |                 with self._assert_raises(TTransportException): | 
 | 140 |                     client.open() | 
 | 141 |                 self.assertTrue(acc.client is None) | 
| Nobuaki Sukegawa | d2b4f24 | 2016-09-04 18:49:23 +0900 | [diff] [blame] | 142 |         finally: | 
 | 143 |             logging.disable(logging.NOTSET) | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 144 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 145 |     def _assert_raises(self, exc): | 
 | 146 |         if sys.hexversion >= 0x020700F0: | 
 | 147 |             return self.assertRaises(exc) | 
 | 148 |         else: | 
 | 149 |             return AssertRaises(exc) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 150 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 151 |     def _assert_connection_success(self, server, path=None, **client_args): | 
 | 152 |         with self._connectable_client(server, path=path, **client_args) as (acc, client): | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 153 |             client.open() | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 154 |             try: | 
 | 155 |                 self.assertTrue(acc.client is not None) | 
 | 156 |             finally: | 
 | 157 |                 client.close() | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 158 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 159 |     # deprecated feature | 
 | 160 |     def test_deprecation(self): | 
 | 161 |         with warnings.catch_warnings(record=True) as w: | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 162 |             warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__) | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 163 |             TSSLSocket('localhost', 0, validate=True, ca_certs=SERVER_CERT) | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 164 |             self.assertEqual(len(w), 1) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 165 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 166 |         with warnings.catch_warnings(record=True) as w: | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 167 |             warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__) | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 168 |             # Deprecated signature | 
 | 169 |             # def __init__(self, host='localhost', port=9090, validate=True, ca_certs=None, keyfile=None, certfile=None, unix_socket=None, ciphers=None): | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 170 |             TSSLSocket('localhost', 0, True, SERVER_CERT, CLIENT_KEY, CLIENT_CERT, None, TEST_CIPHERS) | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 171 |             self.assertEqual(len(w), 7) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 172 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 173 |         with warnings.catch_warnings(record=True) as w: | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 174 |             warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__) | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 175 |             # Deprecated signature | 
 | 176 |             # def __init__(self, host=None, port=9090, certfile='cert.pem', unix_socket=None, ciphers=None): | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 177 |             TSSLServerSocket(None, 0, SERVER_PEM, None, TEST_CIPHERS) | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 178 |             self.assertEqual(len(w), 3) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 179 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 180 |     # deprecated feature | 
 | 181 |     def test_set_cert_reqs_by_validate(self): | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 182 |         with warnings.catch_warnings(record=True) as w: | 
 | 183 |             warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__) | 
 | 184 |             c1 = TSSLSocket('localhost', 0, validate=True, ca_certs=SERVER_CERT) | 
 | 185 |             self.assertEqual(c1.cert_reqs, ssl.CERT_REQUIRED) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 186 |  | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 187 |             c1 = TSSLSocket('localhost', 0, validate=False) | 
 | 188 |             self.assertEqual(c1.cert_reqs, ssl.CERT_NONE) | 
 | 189 |  | 
 | 190 |             self.assertEqual(len(w), 2) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 191 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 192 |     # deprecated feature | 
 | 193 |     def test_set_validate_by_cert_reqs(self): | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 194 |         with warnings.catch_warnings(record=True) as w: | 
 | 195 |             warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__) | 
 | 196 |             c1 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_NONE) | 
 | 197 |             self.assertFalse(c1.validate) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 198 |  | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 199 |             c2 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT) | 
 | 200 |             self.assertTrue(c2.validate) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 201 |  | 
| Nobuaki Sukegawa | 6a0ca7f | 2016-02-13 03:11:16 +0900 | [diff] [blame] | 202 |             c3 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_OPTIONAL, ca_certs=SERVER_CERT) | 
 | 203 |             self.assertTrue(c3.validate) | 
 | 204 |  | 
 | 205 |             self.assertEqual(len(w), 3) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 206 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 207 |     def test_unix_domain_socket(self): | 
 | 208 |         if platform.system() == 'Windows': | 
 | 209 |             print('skipping test_unix_domain_socket') | 
 | 210 |             return | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 211 |         fd, path = tempfile.mkstemp() | 
 | 212 |         os.close(fd) | 
 | 213 |         try: | 
 | 214 |             server = self._server_socket(unix_socket=path, keyfile=SERVER_KEY, certfile=SERVER_CERT) | 
 | 215 |             self._assert_connection_success(server, path=path, cert_reqs=ssl.CERT_NONE) | 
 | 216 |         finally: | 
 | 217 |             os.unlink(path) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 218 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 219 |     def test_server_cert(self): | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 220 |         server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) | 
 | 221 |         self._assert_connection_success(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 222 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 223 |         server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) | 
 | 224 |         # server cert not in ca_certs | 
 | 225 |         self._assert_connection_failure(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=CLIENT_CERT) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 226 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 227 |         server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) | 
 | 228 |         self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 229 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 230 |     def test_set_server_cert(self): | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 231 |         server = self._server_socket(keyfile=SERVER_KEY, certfile=CLIENT_CERT) | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 232 |         with self._assert_raises(Exception): | 
 | 233 |             server.certfile = 'foo' | 
 | 234 |         with self._assert_raises(Exception): | 
 | 235 |             server.certfile = None | 
 | 236 |         server.certfile = SERVER_CERT | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 237 |         self._assert_connection_success(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 238 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 239 |     def test_client_cert(self): | 
| Nobuaki Sukegawa | e8ba787 | 2017-02-12 21:14:48 +0900 | [diff] [blame] | 240 |         if not _match_has_ipaddress: | 
 | 241 |             print('skipping test_client_cert') | 
 | 242 |             return | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 243 |         server = self._server_socket( | 
 | 244 |             cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY, | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 245 |             certfile=SERVER_CERT, ca_certs=CLIENT_CERT) | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 246 |         self._assert_connection_failure(server, cert_reqs=ssl.CERT_NONE, certfile=SERVER_CERT, keyfile=SERVER_KEY) | 
| Nobuaki Sukegawa | f39f7db | 2016-02-04 15:09:41 +0900 | [diff] [blame] | 247 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 248 |         server = self._server_socket( | 
 | 249 |             cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY, | 
| Nobuaki Sukegawa | f39f7db | 2016-02-04 15:09:41 +0900 | [diff] [blame] | 250 |             certfile=SERVER_CERT, ca_certs=CLIENT_CA) | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 251 |         self._assert_connection_failure(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT_NO_IP, keyfile=CLIENT_KEY_NO_IP) | 
| Nobuaki Sukegawa | f39f7db | 2016-02-04 15:09:41 +0900 | [diff] [blame] | 252 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 253 |         server = self._server_socket( | 
 | 254 |             cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY, | 
| Nobuaki Sukegawa | f39f7db | 2016-02-04 15:09:41 +0900 | [diff] [blame] | 255 |             certfile=SERVER_CERT, ca_certs=CLIENT_CA) | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 256 |         self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT, keyfile=CLIENT_KEY) | 
| Nobuaki Sukegawa | f39f7db | 2016-02-04 15:09:41 +0900 | [diff] [blame] | 257 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 258 |         server = self._server_socket( | 
 | 259 |             cert_reqs=ssl.CERT_OPTIONAL, keyfile=SERVER_KEY, | 
| Nobuaki Sukegawa | f39f7db | 2016-02-04 15:09:41 +0900 | [diff] [blame] | 260 |             certfile=SERVER_CERT, ca_certs=CLIENT_CA) | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 261 |         self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT, keyfile=CLIENT_KEY) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 262 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 263 |     def test_ciphers(self): | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 264 |         server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ciphers=TEST_CIPHERS) | 
 | 265 |         self._assert_connection_success(server, ca_certs=SERVER_CERT, ciphers=TEST_CIPHERS) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 266 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 267 |         if not TSSLSocket._has_ciphers: | 
 | 268 |             # unittest.skip is not available for Python 2.6 | 
 | 269 |             print('skipping test_ciphers') | 
 | 270 |             return | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 271 |         server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) | 
 | 272 |         self._assert_connection_failure(server, ca_certs=SERVER_CERT, ciphers='NULL') | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 273 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 274 |         server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ciphers=TEST_CIPHERS) | 
 | 275 |         self._assert_connection_failure(server, ca_certs=SERVER_CERT, ciphers='NULL') | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 276 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 277 |     def test_ssl2_and_ssl3_disabled(self): | 
 | 278 |         if not hasattr(ssl, 'PROTOCOL_SSLv3'): | 
 | 279 |             print('PROTOCOL_SSLv3 is not available') | 
 | 280 |         else: | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 281 |             server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) | 
 | 282 |             self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv3) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 283 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 284 |             server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv3) | 
 | 285 |             self._assert_connection_failure(server, ca_certs=SERVER_CERT) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 286 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 287 |         if not hasattr(ssl, 'PROTOCOL_SSLv2'): | 
 | 288 |             print('PROTOCOL_SSLv2 is not available') | 
 | 289 |         else: | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 290 |             server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) | 
 | 291 |             self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv2) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 292 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 293 |             server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv2) | 
 | 294 |             self._assert_connection_failure(server, ca_certs=SERVER_CERT) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 295 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 296 |     def test_newer_tls(self): | 
 | 297 |         if not TSSLSocket._has_ssl_context: | 
 | 298 |             # unittest.skip is not available for Python 2.6 | 
 | 299 |             print('skipping test_newer_tls') | 
 | 300 |             return | 
 | 301 |         if not hasattr(ssl, 'PROTOCOL_TLSv1_2'): | 
 | 302 |             print('PROTOCOL_TLSv1_2 is not available') | 
 | 303 |         else: | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 304 |             server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2) | 
 | 305 |             self._assert_connection_success(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 306 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 307 |         if not hasattr(ssl, 'PROTOCOL_TLSv1_1'): | 
 | 308 |             print('PROTOCOL_TLSv1_1 is not available') | 
 | 309 |         else: | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 310 |             server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1) | 
 | 311 |             self._assert_connection_success(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 312 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 313 |         if not hasattr(ssl, 'PROTOCOL_TLSv1_1') or not hasattr(ssl, 'PROTOCOL_TLSv1_2'): | 
 | 314 |             print('PROTOCOL_TLSv1_1 and/or PROTOCOL_TLSv1_2 is not available') | 
 | 315 |         else: | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 316 |             server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2) | 
 | 317 |             self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 318 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 319 |     def test_ssl_context(self): | 
 | 320 |         if not TSSLSocket._has_ssl_context: | 
 | 321 |             # unittest.skip is not available for Python 2.6 | 
 | 322 |             print('skipping test_ssl_context') | 
 | 323 |             return | 
 | 324 |         server_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) | 
 | 325 |         server_context.load_cert_chain(SERVER_CERT, SERVER_KEY) | 
| Nobuaki Sukegawa | f39f7db | 2016-02-04 15:09:41 +0900 | [diff] [blame] | 326 |         server_context.load_verify_locations(CLIENT_CA) | 
 | 327 |         server_context.verify_mode = ssl.CERT_REQUIRED | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 328 |         server = self._server_socket(ssl_context=server_context) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 329 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 330 |         client_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) | 
 | 331 |         client_context.load_cert_chain(CLIENT_CERT, CLIENT_KEY) | 
 | 332 |         client_context.load_verify_locations(SERVER_CERT) | 
| Nobuaki Sukegawa | f39f7db | 2016-02-04 15:09:41 +0900 | [diff] [blame] | 333 |         client_context.verify_mode = ssl.CERT_REQUIRED | 
| Nobuaki Sukegawa | f39f7db | 2016-02-04 15:09:41 +0900 | [diff] [blame] | 334 |  | 
| John Sirois | ac06704 | 2016-02-12 08:10:13 -0700 | [diff] [blame] | 335 |         self._assert_connection_success(server, ssl_context=client_context) | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 336 |  | 
| James E. King, III | 0ad20bd | 2017-09-30 15:44:16 -0700 | [diff] [blame^] | 337 |  | 
| Nobuaki Sukegawa | ad83586 | 2015-12-23 23:32:09 +0900 | [diff] [blame] | 338 | if __name__ == '__main__': | 
| Nobuaki Sukegawa | d2b4f24 | 2016-09-04 18:49:23 +0900 | [diff] [blame] | 339 |     logging.basicConfig(level=logging.WARN) | 
| Nobuaki Sukegawa | e8ba787 | 2017-02-12 21:14:48 +0900 | [diff] [blame] | 340 |     from thrift.transport.TSSLSocket import TSSLSocket, TSSLServerSocket, _match_has_ipaddress | 
| Nobuaki Sukegawa | d2b4f24 | 2016-09-04 18:49:23 +0900 | [diff] [blame] | 341 |     from thrift.transport.TTransport import TTransportException | 
 | 342 |  | 
| Nobuaki Sukegawa | 10308cb | 2016-02-03 01:57:03 +0900 | [diff] [blame] | 343 |     unittest.main() |