Example #1
0
    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'"
        )
Example #2
0
    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)
Example #3
0
    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())
Example #4
0
 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)
Example #5
0
 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
Example #6
0
 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)
Example #7
0
    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
Example #8
0
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
Example #9
0
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)
Example #10
0
    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)
Example #11
0
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)
Example #12
0
 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
     )
Example #13
0
 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)
Example #14
0
    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
Example #15
0
    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)
Example #16
0
    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)
Example #17
0
    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
Example #18
0
    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)
Example #19
0
    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())
Example #20
0
    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
        )
Example #21
0
 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)
Example #22
0
 def init_poolmanager(self, *args, **kwargs):
     context = create_urllib3_context(ciphers=CIPHERS)
     kwargs['ssl_context'] = context
     return super(DESAdapter, self).init_poolmanager(*args, **kwargs)
Example #23
0
 def init_poolmanager(self, *args, **kwargs):
     ctx = create_urllib3_context(ciphers=DEFAULT_CIPHERS)
     super(CustomAdapter, self).init_poolmanager(*args,
                                                 ssl_context=ctx,
                                                 **kwargs)
Example #24
0
 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)
Example #25
0
 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)
Example #26
0
 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)
Example #27
0
 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)
Example #28
0
 def init_poolmanager(self, *args, **kwargs):
     # OVERRIDE
     kwargs['ssl_context'] = create_urllib3_context(ciphers=EUSKADI_CIPHERS)
     return super().init_poolmanager(*args, **kwargs)
Example #29
0
    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
Example #30
0
 def proxy_manager_for(self, *args, **kwargs):
     context = create_urllib3_context(ciphers=CIPHERS)
     kwargs["ssl_context"] = context
     return super().proxy_manager_for(*args, **kwargs)
Example #31
0
 def init_poolmanager(self, *args, **kwargs):
     context = create_urllib3_context(ciphers=CIPHERS)
     kwargs["ssl_context"] = context
     return super().init_poolmanager(*args, **kwargs)
Example #32
0
def CreateSSLContext():
    """Returns a urrlib3 SSL context."""
    return create_urllib3_context()