def test_create_urllib3_context_ssl_version_and_ssl_min_max_version_errors( self, kwargs: Dict[str, Any]) -> None: with pytest.raises(ValueError) as e: ssl_.create_urllib3_context(**kwargs) assert str(e.value) == ( "Can't specify both 'ssl_version' and either 'ssl_minimum_version' or 'ssl_maximum_version'" )
def test_create_urllib3_context_default_ciphers( self, monkeypatch, use_default_sslcontext_ciphers): context = mock.create_autospec(ssl_.SSLContext) context.set_ciphers = mock.Mock() context.options = 0 monkeypatch.setattr(ssl_, "SSLContext", lambda *_, **__: context) monkeypatch.setattr(ssl_, "USE_DEFAULT_SSLCONTEXT_CIPHERS", use_default_sslcontext_ciphers) ssl_.create_urllib3_context() if use_default_sslcontext_ciphers: context.set_ciphers.assert_not_called() else: context.set_ciphers.assert_called_with(ssl_.DEFAULT_CIPHERS)
def test_https_pool_key_fields(self): """Assert the HTTPSPoolKey fields are honored when selecting a pool.""" connection_pool_kw = [ ('timeout', timeout.Timeout(3.14)), ('retries', retry.Retry(total=6, connect=2)), ('block', True), ('source_address', '127.0.0.1'), ('key_file', DEFAULT_CERTS['keyfile']), ('cert_file', DEFAULT_CERTS['certfile']), ('cert_reqs', 'CERT_REQUIRED'), ('ca_certs', DEFAULT_CA), ('ca_cert_dir', DEFAULT_CA_DIR), ('ssl_version', 'SSLv23'), ('ssl_context', ssl_.create_urllib3_context()), ] p = PoolManager() conn_pools = [ p.connection_from_url('https://example.com/'), p.connection_from_url('https://example.com:4333/'), p.connection_from_url('https://other.example.com/'), ] # Asking for a connection pool with the same key should give us an # existing pool. dup_pools = [] for key, value in connection_pool_kw: p.connection_pool_kw[key] = value conn_pools.append(p.connection_from_url('https://example.com/')) dup_pools.append(p.connection_from_url('https://example.com/')) assert all(x is not y for i, x in enumerate(conn_pools) for j, y in enumerate(conn_pools) if i != j) assert all(pool in conn_pools for pool in dup_pools) assert all(isinstance(key, PoolKey) for key in p.pools.keys())
def init_poolmanager(self, *args, **kwargs): context = create_urllib3_context() context.load_cert_chain(certfile=cert_path, keyfile=private_key_path, password=passphrase_key) kwargs['ssl_context'] = context return super().init_poolmanager(*args, **kwargs)
def get_connection(self, *args, **kwargs): conn = super(CloudflareAdapter, self).get_connection(*args, **kwargs) if conn.conn_kw.get("ssl_context"): conn.conn_kw["ssl_context"].set_ciphers(DEFAULT_CIPHERS) else: context = create_urllib3_context(ciphers=DEFAULT_CIPHERS) conn.conn_kw["ssl_context"] = context return conn
def init_poolmanager(self, connections, maxsize, block): """Extends the parent's method by adding minimum SSL version to the args. """ ssl_context = create_urllib3_context() ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 super().init_poolmanager(connections, maxsize, block, ssl_context=ssl_context)
def get_connection(self, *args, **kwargs): conn = super(CloudflareAdapter, self).get_connection(*args, **kwargs) if conn.conn_kw.get("ssl_context"): conn.conn_kw["ssl_context"].set_ciphers(DEFAULT_CIPHERS) else: context = create_urllib3_context(ciphers=DEFAULT_CIPHERS) conn.conn_kw["ssl_context"] = context return conn
def test_create_urllib3_context_pha(monkeypatch, pha, expected_pha): context = mock.create_autospec(ssl_.SSLContext) context.set_ciphers = mock.Mock() context.options = 0 context.post_handshake_auth = pha monkeypatch.setattr(ssl_, "SSLContext", lambda *_, **__: context) assert ssl_.create_urllib3_context() is context assert context.post_handshake_auth == expected_pha
def test_create_urllib3_context_set_ciphers(monkeypatch, ciphers, expected_ciphers): context = mock.create_autospec(ssl_.SSLContext) context.set_ciphers = mock.Mock() context.options = 0 monkeypatch.setattr(ssl_, "SSLContext", lambda *_, **__: context) assert ssl_.create_urllib3_context(ciphers=ciphers) is context assert context.set_ciphers.call_count == 1 assert context.set_ciphers.call_args == mock.call(expected_ciphers)
def __init__(self, cipher_suite=None, **kwargs): self.cipher_suite = cipher_suite params = dict(ssl_version=ssl.PROTOCOL_TLSv1) if hasattr(ssl, 'PROTOCOL_TLS'): params = dict(ssl_version=getattr(ssl, 'PROTOCOL_TLSv1_3', ssl.PROTOCOL_TLSv1_2), ciphers=cipher_suite) self.ssl_context = create_urllib3_context(**params) super(CloudflareAdapter, self).__init__(**kwargs)
def test_create_urllib3_context_set_ciphers(monkeypatch, ciphers, expected_ciphers): context = mock.create_autospec(ssl_.SSLContext) context.set_ciphers = mock.Mock() context.options = 0 monkeypatch.setattr(ssl_, "SSLContext", lambda *_, **__: context) assert ssl_.create_urllib3_context(ciphers=ciphers) is context assert context.set_ciphers.call_count == 1 assert context.set_ciphers.call_args == mock.call(expected_ciphers)
def init_poolmanager(self, connections, maxsize, block=False, *args, **kwargs): context = create_urllib3_context(ciphers=DESAdapter.CIPHERS) kwargs["ssl_context"] = context self.poolmanager = PoolManager( num_pools=connections, maxsize=maxsize, block=block, ssl_version=ssl.PROTOCOL_SSLv23, *args, **kwargs )
def _create_ssl_context( verify: bool, ssl_version: str = None, ciphers: str = None, ) -> 'ssl.SSLContext': return create_urllib3_context( ciphers=ciphers, ssl_version=resolve_ssl_version(ssl_version), # Since we are using a custom SSL context, we need to pass this # here manually, even though it’s also passed to the connection # in `super().cert_verify()`. cert_reqs=ssl.CERT_REQUIRED if verify else ssl.CERT_NONE)
def test_https_proxy_with_proxy_ssl_context(self): proxy_ssl_context = create_urllib3_context() proxy_ssl_context.load_verify_locations(DEFAULT_CA) with proxy_from_url( self.https_proxy_url, proxy_ssl_context=proxy_ssl_context, ca_certs=DEFAULT_CA, ) as https: r = https.request("GET", f"{self.https_url}/") assert r.status == 200 r = https.request("GET", f"{self.http_url}/") assert r.status == 200
def test_create_urllib3_context_set_ciphers(self, monkeypatch, ciphers, expected_ciphers): context = mock.create_autospec(ssl_.SSLContext) context.set_ciphers = mock.Mock() context.options = 0 monkeypatch.setattr(ssl_, "SSLContext", lambda *_, **__: context) assert ssl_.create_urllib3_context(ciphers=ciphers) is context if ciphers is None and ssl_.USE_DEFAULT_SSLCONTEXT_CIPHERS: assert context.set_ciphers.call_count == 0 else: assert context.set_ciphers.call_count == 1 assert context.set_ciphers.call_args == mock.call(expected_ciphers)
def connect(self): conn = self._new_conn() self._prepare_conn(conn) if self.ssl_context is None: self.ssl_context = create_urllib3_context( ssl_version=resolve_ssl_version(None), cert_reqs=resolve_cert_reqs(None), ) self.sock = ssl_wrap_socket(sock=conn, keyfile=self.key_file, certfile=self.cert_file, ssl_context=self.ssl_context, server_hostname=self.server_hostname)
def test_create_urllib3_context_pha( self, monkeypatch: pytest.MonkeyPatch, pha: Optional[bool], expected_pha: Optional[bool], ) -> None: context = mock.create_autospec(ssl_.SSLContext) context.set_ciphers = mock.Mock() context.options = 0 context.post_handshake_auth = pha monkeypatch.setattr(ssl_, "SSLContext", lambda *_, **__: context) assert ssl_.create_urllib3_context() is context assert context.post_handshake_auth == expected_pha
def test_pools_keyed_with_from_host(self): """Assert pools are still keyed correctly with connection_from_host.""" ssl_kw = [ ('key_file', DEFAULT_CERTS['keyfile']), ('cert_file', DEFAULT_CERTS['certfile']), ('cert_reqs', 'CERT_REQUIRED'), ('ca_certs', DEFAULT_CA), ('ca_cert_dir', DEFAULT_CA_DIR), ('ssl_version', 'SSLv23'), ('ssl_context', ssl_.create_urllib3_context()), ] p = PoolManager() conns = [p.connection_from_host('example.com', 443, scheme='https')] for k, v in ssl_kw: p.connection_pool_kw[k] = v conns.append( p.connection_from_host('example.com', 443, scheme='https')) assert all(x is not y for i, x in enumerate(conns) for j, y in enumerate(conns) if i != j)
def test_https_pool_key_fields(self): """Assert the HTTPSPoolKey fields are honored when selecting a pool.""" connection_pool_kw = [ ("timeout", timeout.Timeout(3.14)), ("retries", retry.Retry(total=6, connect=2)), ("block", True), ("source_address", "127.0.0.1"), ("key_file", DEFAULT_CERTS["keyfile"]), ("cert_file", DEFAULT_CERTS["certfile"]), ("cert_reqs", "CERT_REQUIRED"), ("ca_certs", DEFAULT_CA), ("ca_cert_dir", DEFAULT_CA_DIR), ("ssl_version", "SSLv23"), ("ssl_context", ssl_.create_urllib3_context()), ] p = PoolManager() conn_pools = [ p.connection_from_url("https://example.com/"), p.connection_from_url("https://example.com:4333/"), p.connection_from_url("https://other.example.com/"), ] # Asking for a connection pool with the same key should give us an # existing pool. dup_pools = [] for key, value in connection_pool_kw: p.connection_pool_kw[key] = value conn_pools.append(p.connection_from_url("https://example.com/")) dup_pools.append(p.connection_from_url("https://example.com/")) assert all( x is not y for i, x in enumerate(conn_pools) for j, y in enumerate(conn_pools) if i != j ) assert all(pool in conn_pools for pool in dup_pools) assert all(isinstance(key, PoolKey) for key in p.pools.keys())
def test_pools_keyed_with_from_host(self): """Assert pools are still keyed correctly with connection_from_host.""" ssl_kw = [ ("key_file", DEFAULT_CERTS["keyfile"]), ("cert_file", DEFAULT_CERTS["certfile"]), ("cert_reqs", "CERT_REQUIRED"), ("ca_certs", DEFAULT_CA), ("ca_cert_dir", DEFAULT_CA_DIR), ("ssl_version", "SSLv23"), ("ssl_context", ssl_.create_urllib3_context()), ] p = PoolManager() conns = [p.connection_from_host("example.com", 443, scheme="https")] for k, v in ssl_kw: p.connection_pool_kw[k] = v conns.append(p.connection_from_host("example.com", 443, scheme="https")) assert all( x is not y for i, x in enumerate(conns) for j, y in enumerate(conns) if i != j )
def proxy_manager_for(self, *args, **kwargs): context = create_urllib3_context(ciphers=CIPHERS) kwargs['ssl_context'] = context return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)
def init_poolmanager(self, *args, **kwargs): context = create_urllib3_context(ciphers=CIPHERS) kwargs['ssl_context'] = context return super(DESAdapter, self).init_poolmanager(*args, **kwargs)
def init_poolmanager(self, *args, **kwargs): ctx = create_urllib3_context(ciphers=DEFAULT_CIPHERS) super(CustomAdapter, self).init_poolmanager(*args, ssl_context=ctx, **kwargs)
def init_poolmanager(self, *args, **kwargs): if self.ca_curve is not None: context = create_urllib3_context() context.set_ecdh_curve(self.ca_curve.name) kwargs["ssl_context"] = context return super(TlsAdapter, self).init_poolmanager(*args, **kwargs)
def test_create_urllib3_context_ssl_version_and_ssl_min_max_version_no_error( self, kwargs: Dict[str, Any]) -> None: ssl_.create_urllib3_context(**kwargs)
def proxy_manager_for(self, *args, **kwargs): ssl_context = create_urllib3_context(options=SECURE_OPTIONS, ciphers=SECURE_CIPHERS) kwargs['ssl_context'] = ssl_context return super(HTTPSAdapter, self).proxy_manager_for(*args, **kwargs)
def init_poolmanager(self, *pool_args, **pool_kwargs): ctx = ssl_.create_urllib3_context(ciphers=CIPHERS, cert_reqs=ssl.CERT_REQUIRED, options=self.ssl_options, ssl_version=ssl.PROTOCOL_TLSv1_1) self.poolmanager = PoolManager(*pool_args, ssl_context=ctx, **pool_kwargs)
def init_poolmanager(self, *args, **kwargs): # OVERRIDE kwargs['ssl_context'] = create_urllib3_context(ciphers=EUSKADI_CIPHERS) return super().init_poolmanager(*args, **kwargs)
def run_http_request2(self, path, method, data=u'', headers={}, timeout=30): """Http client. Usage: res = http_client2('https', '/api', 'POST', port=443, data='', headers={}) :param proto: Request proto. Ex. http, https :param host: Request host. Ex. 10.102.90.30 :param port: Request port. [default=80] :param path: Request path. Ex. /api/ :param method: Request method. Ex. GET, POST, PUT, DELETE :param headers: Request headers. [default={}]. Ex. {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} :param data: Request data. [default={}]. Ex. {'@number': 12524, '@type': 'issue', '@action': 'show'} :param timeout: Request timeout. [default=30s] :raise RemoteException: """ try: path = self.conn[u'path'] + path proto = self.conn[u'proto'] host = self.conn[u'host'] if u'port' not in self.conn: if proto == u'http': port = 80 else: port = 443 else: port = self.conn[u'port'] # set simple authentication if self.user is not None: auth = base64.encodestring(u'%s:%s' % (self.user, self.pwd))\ .replace(u'\n', u'') headers[u'Authorization'] = u'Basic %s' % auth self.logger.info(u'Send http %s api request to %s://%s:%s%s' % (method, proto, host, port, path)) if data.lower().find(u'password') < 0: self.logger.debug(u'Send [headers=%s] [data=%s]' % (headers, data)) else: self.logger.debug(u'Send [headers=%s] [data=%s]' % (headers, u'xxxxxxx')) _host = host _port = port _headers = headers if self.proxy is not None: _host = self.proxy[0] _port = self.proxy[1] _headers = {} path = u'%s://%s:%s%s' % (proto, host, port, path) if proto == u'http': conn = httplib.HTTPConnection(_host, _port, timeout=timeout) else: if self.keyfile is None: # python >= 2.7.9 if version_info.major==2 and version_info.minor==7 and \ version_info.micro>8: ssl._create_default_https_context = ssl._create_unverified_context # python < 2.7.8 elif version_info.major==2 and version_info.minor==7 and \ version_info.micro<9: ssl._create_default_https_context = create_urllib3_context( cert_reqs=ssl.CERT_NONE) else: ssl._create_default_https_context = None conn = httplib.HTTPSConnection(_host, _port, timeout=timeout, key_file=self.keyfile, cert_file=self.certfile) if self.proxy is not None: conn.set_tunnel(host, port=port, headers=headers) self.logger.debug(u'set proxy %s' % self.proxy) headers = None conn.request(method, path, data, _headers) response = conn.getresponse() content_type = response.getheader(u'content-type') self.logger.info(u'Response status: %s %s' % (response.status, response.reason)) except httplib.HTTPException as ex: self.logger.error(ex, exc_info=True) raise BadRequestException(ex) except Exception as ex: self.logger.error(ex, exc_info=True) raise BadRequestException(ex) # evaluate response status # BAD_REQUEST 400 HTTP/1.1, RFC 2616, Section 10.4.1 if response.status == 400: res = response.read() self.logger.error(u'Response [content-type=%s] [data=%s]' % (content_type, truncate(res)), exc_info=True) raise BadRequestException(res) # UNAUTHORIZED 401 HTTP/1.1, RFC 2616, Section 10.4.2 elif response.status == 401: res = response.read() self.logger.error(u'Response [content-type=%s] [data=%s]' % (content_type, truncate(res)), exc_info=True) raise UnauthorizedException(res) # PAYMENT_REQUIRED 402 HTTP/1.1, RFC 2616, Section 10.4.3 # FORBIDDEN 403 HTTP/1.1, RFC 2616, Section 10.4.4 elif response.status == 403: res = response.read() self.logger.error(u'Response [content-type=%s] [data=%s]' % (content_type, truncate(res)), exc_info=True) raise ForbiddenException(res) # NOT_FOUND 404 HTTP/1.1, RFC 2616, Section 10.4.5 elif response.status == 404: res = response.read() self.logger.error(u'Response [content-type=%s] [data=%s]' % (content_type, truncate(res)), exc_info=True) raise NotFoundException(res) # METHOD_NOT_ALLOWED 405 HTTP/1.1, RFC 2616, Section 10.4.6 elif response.status == 405: res = response.read() self.logger.error(u'Response [content-type=%s] [data=%s]' % (content_type, truncate(res)), exc_info=True) raise MethodNotAllowedException(res) # NOT_ACCEPTABLE 406 HTTP/1.1, RFC 2616, Section 10.4.7 elif response.status == 406: res = response.read() self.logger.error(u'Response [content-type=%s] [data=%s]' % (content_type, truncate(res)), exc_info=True) raise NotAcceptableException(res) # PROXY_AUTHENTICATION_REQUIRED 407 HTTP/1.1, RFC 2616, Section 10.4.8 # REQUEST_TIMEOUT 408 elif response.status == 408: self.logger.error(u'REQUEST_TIMEOUT - 408', exc_info=True) raise TimeoutException(u'Timeout') # CONFLICT 409 elif response.status == 409: res = response.read() self.logger.error(u'Response [content-type=%s] [data=%s]' % (content_type, truncate(res)), exc_info=True) raise ConflictException(res) # UNSUPPORTED_MEDIA_TYPE 415 elif response.status == 415: res = response.read() self.logger.error(u'Response [content-type=%s] [data=%s]' % (content_type, truncate(res)), exc_info=True) raise UnsupporteMediaTypeException(res) # INTERNAL SERVER ERROR 500 elif response.status == 500: self.logger.error(u'SERVER_ERROR - 500', exc_info=True) raise ServerErrorException(u'Internal server error') # NO_CONTENT 204 HTTP/1.1, RFC 2616, Section 10.2.5 elif response.status == 204: res = None conn.close() return res # OK 200 HTTP/1.1, RFC 2616, Section 10.2.1 # CREATED 201 HTTP/1.1, RFC 2616, Section 10.2.2 # ACCEPTED 202 HTTP/1.1, RFC 2616, Section 10.2.3 # NON_AUTHORITATIVE_INFORMATION 203 HTTP/1.1, RFC 2616, Section 10.2.4 # RESET_CONTENT 205 HTTP/1.1, RFC 2616, Section 10.2.6 # PARTIAL_CONTENT 206 HTTP/1.1, RFC 2616, Section 10.2.7 # MULTI_STATUS 207 WEBDAV RFC 2518, Section 10.2 elif re.match(u'20[0-9]+', str(response.status)): res = response.read() self.logger.debug(u'Response [content-type=%s] [data=%s]' % (content_type, truncate(res))) if content_type == u'application/json': res_dict = json.loads(res) conn.close() return res_dict else: conn.close() return res return None
def proxy_manager_for(self, *args, **kwargs): context = create_urllib3_context(ciphers=CIPHERS) kwargs["ssl_context"] = context return super().proxy_manager_for(*args, **kwargs)
def init_poolmanager(self, *args, **kwargs): context = create_urllib3_context(ciphers=CIPHERS) kwargs["ssl_context"] = context return super().init_poolmanager(*args, **kwargs)
def CreateSSLContext(): """Returns a urrlib3 SSL context.""" return create_urllib3_context()