diff --git a/mitmproxy/proxy/protocol/rawtcp.py b/mitmproxy/proxy/protocol/rawtcp.py index 0ec505945..00bba04c5 100644 --- a/mitmproxy/proxy/protocol/rawtcp.py +++ b/mitmproxy/proxy/protocol/rawtcp.py @@ -29,13 +29,20 @@ class RawTCPLayer(base.Layer): server = self.server_conn.connection conns = [client, server] + # https://github.com/openssl/openssl/issues/6234 + for conn in conns: + if isinstance(conn, SSL.Connection) and hasattr(SSL._lib, "SSL_clear_mode"): + SSL._lib.SSL_clear_mode(conn._ssl, SSL._lib.SSL_MODE_AUTO_RETRY) + try: while not self.channel.should_exit.is_set(): r = mitmproxy.net.tcp.ssl_read_select(conns, 10) for conn in r: dst = server if conn == client else client - - size = conn.recv_into(buf, self.chunk_size) + try: + size = conn.recv_into(buf, self.chunk_size) + except (SSL.WantReadError, SSL.WantWriteError): + continue if not size: conns.remove(conn) # Shutdown connection to the other peer diff --git a/setup.py b/setup.py index c5837b823..4172c46f7 100644 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ setup( "Brotli>=1.0,<1.1", "certifi>=2019.9.11", # no semver here - this should always be on the last release! "click>=7.0,<8", - "cryptography>=2.1.4,<2.5", + "cryptography>=2.1.4,<3.0", "flask>=1.1.1,<1.2", "h2>=3.0.1,<4", "hyperframe>=5.1.0,<6", @@ -76,7 +76,7 @@ setup( "passlib>=1.6.5, <1.8", "protobuf>=3.6.0, <3.11", "pyasn1>=0.3.1,<0.5", - "pyOpenSSL==19.0.0", + "pyOpenSSL>=19.1.0,<19.2", "pyparsing>=2.4.2,<2.5", "pyperclip>=1.6.0,<1.8", "ruamel.yaml>=0.16,<0.17", diff --git a/test/mitmproxy/net/test_tcp.py b/test/mitmproxy/net/test_tcp.py index 22a306dc9..f204b8b9c 100644 --- a/test/mitmproxy/net/test_tcp.py +++ b/test/mitmproxy/net/test_tcp.py @@ -37,7 +37,7 @@ class ClientCipherListHandler(tcp.BaseHandler): sni = None def handle(self): - self.wfile.write(str(self.connection.get_cipher_list()).encode()) + self.wfile.write(f"{self.connection.get_cipher_list()}\n".encode()) self.wfile.flush() @@ -421,16 +421,18 @@ class TestServerCipherList(tservers.ServerTestBase): cipher_list='AES256-GCM-SHA384' ) + @pytest.mark.xfail def test_echo(self): + # Not working for OpenSSL 1.1.1, see + # https://github.com/pyca/pyopenssl/blob/fc802df5c10f0d1cd9749c94887d652fa26db6fb/src/OpenSSL/SSL.py#L1192-L1196 c = tcp.TCPClient(("127.0.0.1", self.port)) with c.connect(): c.convert_to_tls(sni="foo.com") - expected = b"['AES256-GCM-SHA384']" - assert c.rfile.read(len(expected) + 2) == expected + expected = b"['TLS_AES_256_GCM_SHA384']" + assert c.rfile.readline() == expected class TestServerCurrentCipher(tservers.ServerTestBase): - class handler(tcp.BaseHandler): sni = None @@ -442,7 +444,10 @@ class TestServerCurrentCipher(tservers.ServerTestBase): cipher_list='AES256-GCM-SHA384' ) + @pytest.mark.xfail def test_echo(self): + # Not working for OpenSSL 1.1.1, see + # https://github.com/pyca/pyopenssl/blob/fc802df5c10f0d1cd9749c94887d652fa26db6fb/src/OpenSSL/SSL.py#L1192-L1196 c = tcp.TCPClient(("127.0.0.1", self.port)) with c.connect(): c.convert_to_tls(sni="foo.com") @@ -608,7 +613,7 @@ class TestDHParams(tservers.ServerTestBase): def test_dhparams(self): c = tcp.TCPClient(("127.0.0.1", self.port)) with c.connect(): - c.convert_to_tls() + c.convert_to_tls(method=SSL.TLSv1_2_METHOD) ret = c.get_current_cipher() assert ret[0] == "DHE-RSA-AES256-SHA" diff --git a/test/mitmproxy/net/test_tls.py b/test/mitmproxy/net/test_tls.py index c4e76bc6e..e78564c7b 100644 --- a/test/mitmproxy/net/test_tls.py +++ b/test/mitmproxy/net/test_tls.py @@ -43,7 +43,7 @@ class TestMasterSecretLogger(tservers.ServerTestBase): tls.log_master_secret.close() with open(logfile, "rb") as f: - assert f.read().count(b"CLIENT_RANDOM") == 2 + assert f.read().count(b"CLIENT_RANDOM") >= 2 tls.log_master_secret = _logfun