cheroot/test/test_ssl.py:326: TypeError: argument of type 'int' is not iterable
❓ I'm submitting a ...
- [X] 🐞 bug report
- [ ] 🐣 feature request
- [ ] ❓ question about the decisions made in the repository
🐞 Describe the bug. What is the current behavior? Getting a TypeError when running tests under Py3
❓ What is the motivation / use case for changing the behavior?
💡 To Reproduce LANG=C.utf-8 /usr/bin/python3 -m pytest --ignore=build
💡 Expected behavior test passes
📋 Details
___ test_tls_client_auth[VerifyMode.CERT_REQUIRED-False-localhost-pyopenssl] ___
mocker = <pytest_mock.MockFixture object at 0x7f126e781a90>
tls_http_server = <generator object tls_http_server.<locals>.start_srv at 0x7f126e9c0a20>
adapter_type = 'pyopenssl', ca = <trustme.CA object at 0x7f126e781be0>
tls_certificate = <trustme.LeafCert object at 0x7f126cf17be0>
tls_certificate_chain_pem_path = '/tmp/tmp_1ydbkz8.pem'
tls_certificate_private_key_pem_path = '/tmp/tmppnq0li9y.pem'
tls_ca_certificate_pem_path = '/tmp/tmprtqcxjrb.pem', is_trusted_cert = False
tls_client_identity = 'localhost'
tls_verify_mode = <VerifyMode.CERT_REQUIRED: 2>
@pytest.mark.parametrize(
'adapter_type',
(
'builtin',
'pyopenssl',
),
)
@pytest.mark.parametrize(
'is_trusted_cert,tls_client_identity',
(
(True, 'localhost'), (True, '127.0.0.1'),
(True, '*.localhost'), (True, 'not_localhost'),
(False, 'localhost'),
),
)
@pytest.mark.parametrize(
'tls_verify_mode',
(
ssl.CERT_NONE, # server shouldn't validate client cert
ssl.CERT_OPTIONAL, # same as CERT_REQUIRED in client mode, don't use
ssl.CERT_REQUIRED, # server should validate if client cert CA is OK
),
)
def test_tls_client_auth(
# FIXME: remove twisted logic, separate tests
mocker,
tls_http_server, adapter_type,
ca,
tls_certificate,
tls_certificate_chain_pem_path,
tls_certificate_private_key_pem_path,
tls_ca_certificate_pem_path,
is_trusted_cert, tls_client_identity,
tls_verify_mode,
):
"""Verify that client TLS certificate auth works correctly."""
test_cert_rejection = (
tls_verify_mode != ssl.CERT_NONE
and not is_trusted_cert
)
interface, _host, port = _get_conn_data(ANY_INTERFACE_IPV4)
client_cert_root_ca = ca if is_trusted_cert else trustme.CA()
with mocker.mock_module.patch(
'idna.core.ulabel',
return_value=ntob(tls_client_identity),
):
client_cert = client_cert_root_ca.issue_server_cert(
# FIXME: change to issue_cert once new trustme is out
ntou(tls_client_identity),
)
del client_cert_root_ca
with client_cert.private_key_and_cert_chain_pem.tempfile() as cl_pem:
tls_adapter_cls = get_ssl_adapter_class(name=adapter_type)
tls_adapter = tls_adapter_cls(
tls_certificate_chain_pem_path,
tls_certificate_private_key_pem_path,
)
if adapter_type == 'pyopenssl':
tls_adapter.context = tls_adapter.get_context()
tls_adapter.context.set_verify(
_stdlib_to_openssl_verify[tls_verify_mode],
lambda conn, cert, errno, depth, preverify_ok: preverify_ok,
)
else:
tls_adapter.context.verify_mode = tls_verify_mode
ca.configure_trust(tls_adapter.context)
tls_certificate.configure_cert(tls_adapter.context)
tlshttpserver = tls_http_server.send(
(
(interface, port),
tls_adapter,
),
)
interface, _host, port = _get_conn_data(tlshttpserver.bind_addr)
make_https_request = functools.partial(
requests.get,
'https://' + interface + ':' + str(port) + '/',
# Server TLS certificate verification:
verify=tls_ca_certificate_pem_path,
# Client TLS certificate verification:
cert=cl_pem,
)
if not test_cert_rejection:
resp = make_https_request()
is_req_successful = resp.status_code == 200
if (
not is_req_successful
and IS_PYOPENSSL_SSL_VERSION_1_0
and adapter_type == 'builtin'
and tls_verify_mode == ssl.CERT_REQUIRED
and tls_client_identity == 'localhost'
and is_trusted_cert
):
pytest.xfail(
'OpenSSL 1.0 has problems with verifying client certs',
)
assert is_req_successful
assert resp.text == 'Hello world!'
return
with pytest.raises(requests.exceptions.SSLError) as ssl_err:
make_https_request()
err_text = ssl_err.value.args[0].reason.args[0].args[0]
expected_substring = (
'sslv3 alert bad certificate' if IS_LIBRESSL_BACKEND
else 'tlsv1 alert unknown ca'
)
if IS_PYPY and six.PY3 and IS_MACOS and adapter_type == 'pyopenssl':
expected_substring = 'tlsv1 alert unknown ca'
> assert expected_substring in err_text
E TypeError: argument of type 'int' is not iterable
cheroot/test/test_ssl.py:326: TypeError
📋 Environment
- Cheroot version: 6.5.4
- Python version: 3.7.6
- OS: Fedora 31
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Reran this on 6.5.6: maybe more of the error could help? I'm not sure how to debug this.
_host = '127.0.0.1'
adapter_type = 'pyopenssl'
ca = <trustme.CA object at 0x7f0a7b265250>
cl_pem = '/tmp/tmp93eiln0c.pem'
client_cert = <trustme.LeafCert object at 0x7f0a79a3bb90>
err_text = 1
expected_ssl_errors = (<class 'requests.exceptions.SSLError'>,)
expected_substrings = ('tlsv1 alert unknown ca',)
interface = '127.0.0.1'
is_trusted_cert = False
make_https_request = functools.partial(<function get at 0x7f0a7c26fb00>, 'https://127.0.0.1:60843/', verify='/tmp/tmpt3k6ufop.pem', cert='/tmp/tmp93eiln0c.pem')
mocker = <pytest_mock.MockFixture object at 0x7f0a7b265b50>
port = 60843
ssl_err = <ExceptionInfo SSLError tblen=6>
test_cert_rejection = True
tls_adapter = <cheroot.ssl.pyopenssl.pyOpenSSLAdapter object at 0x7f0a79a39390>
tls_adapter_cls = <class 'cheroot.ssl.pyopenssl.pyOpenSSLAdapter'>
tls_ca_certificate_pem_path = '/tmp/tmpt3k6ufop.pem'
tls_certificate = <trustme.LeafCert object at 0x7f0a799caf50>
tls_certificate_chain_pem_path = '/tmp/tmpede6i683.pem'
tls_certificate_private_key_pem_path = '/tmp/tmpwc6kdpox.pem'
tls_client_identity = 'localhost'
tls_http_server = <generator object tls_http_server.<locals>.start_srv at 0x7f0a7b25cb50>
tls_verify_mode = <VerifyMode.CERT_REQUIRED: 2>
tlshttpserver = <cheroot.server.HTTPServer object at 0x7f0a79a2add0>
cheroot/test/test_ssl.py:365:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.0 = <tuple_iterator object at 0x7f0a79a3bb50>
> assert any(e in err_text for e in expected_substrings)
E TypeError: argument of type 'int' is not iterable
.0 = <tuple_iterator object at 0x7f0a79a3bb50>
e = 'tlsv1 alert unknown ca'
err_text = 1
cheroot/test/test_ssl.py:365: TypeError
------------------------------------------------------------------------------------------------------------ Captured stderr call ------------------------------------------------------------------------------------------------------------
Exception ignored in: <_io.FileIO name='/tmp/tmpede6i683.pem' mode='rb' closefd=True>
ResourceWarning: unclosed file <_io.BufferedReader name='/tmp/tmpede6i683.pem'>
Hey @radez, could you please figure out what's in ssl_err in your case?
Could you please prepare a Docker image with reproducer? I tried this under fedora:31 from dockerhub but I'm getting different errors. I need the exact same env in order to reproduce the problem.
I've not used reproducer. I'll have to read some docs on it. Is ssl_err a log?
I realized that ssl_err was one of the fields in the report: value is: ExceptionInfo SSLError tblen=6 It just had brackets around it so it probably got stripped out or something.
@radez we need to figure out what nested attribute holds the error reason.