def tctx() -> context.Context: opts = options.Options() Proxyserver().load(opts) TermLog().load(opts) Core().load(opts) return context.Context( context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), opts)
def test_tls_clienthello(self): # only really testing for coverage here, there's no point in mirroring the individual conditions ta = tlsconfig.TlsConfig() with taddons.context(ta) as tctx: ctx = context.Context(context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options) ch = tls.ClientHelloData(ctx) ta.tls_clienthello(ch) assert not ch.establish_server_tls_first
def test_basic(self): c = context.Client(("127.0.0.1", 52314), ("127.0.0.1", 8080), 1607780791) assert not c.tls_established c.timestamp_tls_setup = 1607780792 assert c.tls_established assert c.connected c.state = context.ConnectionState.CAN_WRITE assert not c.connected
def test_fuzz_h1_request(data): tctx = context.Context( context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), opts) layer = http.HttpLayer(tctx, HTTPMode.regular) for _ in layer.handle_event(Start()): pass for chunk in data: for _ in layer.handle_event(DataReceived(tctx.client, chunk)): pass
def test_create_proxy_server_ssl_conn_verify_ok(self, tdata): ta = tlsconfig.TlsConfig() with taddons.context(ta) as tctx: ctx = context.Context(context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options) ctx.server.address = ("example.mitmproxy.org", 443) tctx.configure(ta, ssl_verify_upstream_trusted_ca=tdata.path( "mitmproxy/net/data/verificationcerts/trusted-root.crt")) tls_start = tls.TlsStartData(ctx.server, context=ctx) ta.tls_start(tls_start) tssl_client = tls_start.ssl_conn tssl_server = test_tls.SSLTest(server_side=True) assert self.do_handshake(tssl_client, tssl_server)
def h2_layer(opts): tctx = context.Context( context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), opts) tctx.client.alpn = b"h2" layer = http.HttpLayer(tctx, HTTPMode.regular) for _ in layer.handle_event(Start()): pass for _ in layer.handle_event( DataReceived(tctx.client, b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n')): pass return tctx, layer
def test_create_proxy_server_ssl_conn_verify_failed(self): ta = tlsconfig.TlsConfig() with taddons.context(ta) as tctx: ctx = context.Context(context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options) ctx.client.alpn_offers = [b"h2"] ctx.client.cipher_list = ["TLS_AES_256_GCM_SHA384", "ECDHE-RSA-AES128-SHA"] ctx.server.address = ("example.mitmproxy.org", 443) tls_start = tls.TlsStartData(ctx.server, context=ctx) ta.tls_start(tls_start) tssl_client = tls_start.ssl_conn tssl_server = test_tls.SSLTest(server_side=True) with pytest.raises(SSL.Error, match="certificate verify failed"): assert self.do_handshake(tssl_client, tssl_server)
def test_create_client_proxy_ssl_conn(self, tdata): ta = tlsconfig.TlsConfig() with taddons.context(ta) as tctx: ta.configure(["confdir"]) tctx.configure(ta, certs=[tdata.path("mitmproxy/net/data/verificationcerts/trusted-leaf.pem")]) ctx = context.Context(context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options) tctx.options.add_upstream_certs_to_client_chain = True tls_start = tls.TlsStartData(ctx.client, context=ctx) ta.tls_start(tls_start) tssl_server = tls_start.ssl_conn tssl_client = test_tls.SSLTest() assert self.do_handshake(tssl_client, tssl_server) assert tssl_client.obj.getpeercert()["subjectAltName"] == (("DNS", "example.mitmproxy.org"),)
def _h2_response(chunks): tctx = context.Context( context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), opts) playbook = Playbook(http.HttpLayer(tctx, HTTPMode.regular), hooks=False) server = Placeholder(context.Server) assert (playbook >> DataReceived( tctx.client, b"GET http://example.com/ HTTP/1.1\r\nHost: example.com\r\n\r\n") << OpenConnection(server) >> reply( None, side_effect=make_h2) << SendData(server, Placeholder())) for chunk in chunks: for _ in playbook.layer.handle_event( events.DataReceived(server(), chunk)): pass
def test_create_proxy_server_ssl_conn_insecure(self): ta = tlsconfig.TlsConfig() with taddons.context(ta) as tctx: ctx = context.Context(context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options) ctx.server.address = ("example.mitmproxy.org", 443) tctx.configure( ta, ssl_verify_upstream_trusted_ca=None, ssl_insecure=True, http2=False, ciphers_server="ALL" ) tls_start = tls.TlsStartData(ctx.server, context=ctx) ta.tls_start(tls_start) tssl_client = tls_start.ssl_conn tssl_server = test_tls.SSLTest(server_side=True) assert self.do_handshake(tssl_client, tssl_server)
def test_alpn_selection(self): ta = tlsconfig.TlsConfig() with taddons.context(ta) as tctx: ctx = context.Context(context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options) ctx.server.address = ("example.mitmproxy.org", 443) tls_start = tls.TlsStartData(ctx.server, context=ctx) def assert_alpn(http2, client_offers, expected): tctx.configure(ta, http2=http2) ctx.client.alpn_offers = client_offers ctx.server.alpn_offers = None ta.tls_start(tls_start) assert ctx.server.alpn_offers == expected assert_alpn(True, tls.HTTP_ALPNS + (b"foo",), tls.HTTP_ALPNS + (b"foo",)) assert_alpn(False, tls.HTTP_ALPNS + (b"foo",), tls.HTTP1_ALPNS + (b"foo",)) assert_alpn(True, [], tls.HTTP_ALPNS) assert_alpn(False, [], tls.HTTP1_ALPNS) ctx.client.timestamp_tls_setup = time.time() # make sure that we don't upgrade h1 to h2, # see comment in tlsconfig.py assert_alpn(True, [], [])
async def test_block_global(block_global, block_private, should_be_killed, address): ar = block.Block() with taddons.context(ar) as tctx: if compat.new_proxy_core: from mitmproxy.proxy2 import context tctx.configure(ar, block_global=block_global, block_private=block_private) client = context.Client(address, ("127.0.0.1", 8080), 1607699500) ar.client_connected(client) assert bool(client.error) == should_be_killed return tctx.options.block_global = block_global tctx.options.block_private = block_private with mock.patch('mitmproxy.proxy.protocol.base.Layer') as layer: layer.client_conn.address = address ar.clientconnect(layer) if should_be_killed: assert layer.reply.kill.called assert await tctx.master.await_log("killed", "warn") else: assert not layer.reply.kill.called
def test_get_cert(self, tdata): """Test that we generate a certificate matching the connection's context.""" ta = tlsconfig.TlsConfig() with taddons.context(ta) as tctx: ta.configure(["confdir"]) ctx = context.Context(context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options) # Edge case first: We don't have _any_ idea about the server, so we just return "mitmproxy" as subject. cert, pkey, chainfile = ta.get_cert(ctx) assert cert.cn == b"mitmproxy" # Here we have an existing server connection... ctx.server.address = ("server-address.example", 443) with open(tdata.path("mitmproxy/net/data/verificationcerts/trusted-leaf.crt"), "rb") as f: ctx.server.certificate_list = [certs.Cert.from_pem(f.read())] cert, pkey, chainfile = ta.get_cert(ctx) assert cert.cn == b"example.mitmproxy.org" assert cert.altnames == [b"example.mitmproxy.org", b"server-address.example"] # And now we also incorporate SNI. ctx.client.sni = b"sni.example" cert, pkey, chainfile = ta.get_cert(ctx) assert cert.altnames == [b"example.mitmproxy.org", b"sni.example"]
def tctx(): context.Context(context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options)
def _test_cancel(stream_req, stream_resp, draw): """ Test that we don't raise an exception if someone disconnects. """ tctx = context.Context( context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), opts) playbook, cff = start_h2_client(tctx) flow = Placeholder(HTTPFlow) server = Placeholder(Server) def maybe_stream(flow: HTTPFlow): if stream_req: flow.request.stream = True if stream_resp and flow.response: flow.response.stream = True hook_req_headers = http.HttpRequestHeadersHook(flow) hook_req = http.HttpRequestHook(flow) hook_resp_headers = http.HttpResponseHeadersHook(flow) hook_resp = http.HttpResponseHook(flow) hook_error = http.HttpErrorHook(flow) openconn = OpenConnection(server) send_upstream = SendData(server, Placeholder(bytes)) data_req = DataReceived( tctx.client, cff.build_headers_frame(example_request_headers).serialize()) data_reqbody = DataReceived( tctx.client, cff.build_data_frame(b"foo", flags=["END_STREAM"]).serialize()) data_resp = DataReceived( server, cff.build_headers_frame(example_response_headers).serialize()) data_respbody = DataReceived( server, cff.build_data_frame(b"bar", flags=["END_STREAM"]).serialize()) client_disc = ConnectionClosed(tctx.client) client_rst = DataReceived(tctx.client, cff.build_rst_stream_frame(1).serialize()) server_disc = ConnectionClosed(server) server_rst = DataReceived(server, cff.build_rst_stream_frame(1).serialize()) evts: Dict[str, Tuple[Any, Any, Any]] = {} # precondition, but-not-after-this evts["data_req"] = data_req, None, client_disc evts["data_reqbody"] = data_reqbody, data_req, client_disc evts["reply_hook_req_headers"] = reply( to=hook_req_headers, side_effect=maybe_stream), hook_req_headers, None evts["reply_hook_req"] = reply(to=hook_req), hook_req, None evts["reply_openconn"] = reply(None, to=openconn, side_effect=make_h2), openconn, None evts["data_resp"] = data_resp, send_upstream, server_disc evts["data_respbody"] = data_respbody, data_resp, server_disc evts["reply_hook_resp_headers"] = reply( to=hook_resp_headers, side_effect=maybe_stream), hook_resp_headers, None evts["reply_hook_resp"] = reply(to=hook_resp), hook_resp, None evts["reply_hook_error"] = reply(to=hook_error), hook_error, None evts["err_client_disc"] = client_disc, None, None evts["err_client_rst"] = client_rst, None, client_disc evts["err_server_disc"] = server_disc, send_upstream, None evts["err_server_rst"] = server_rst, send_upstream, server_disc def eq_maybe(a, b): # _eq helpfully raises a TypeError when placeholder types don't match # that is useful in (test) development, but may happen legitimately when fuzzing here. try: return _eq(a, b) except TypeError: return False while evts: candidates = [] for name, (evt, precon, negprecon) in evts.items(): precondition_ok = (precon is None or any( eq_maybe(x, precon) for x in playbook.actual)) neg_precondition_ok = ( negprecon is None or not any(eq_maybe(x, negprecon) for x in playbook.actual)) if precondition_ok and neg_precondition_ok: # crude hack to increase fuzzing efficiency: make it more likely that we progress. for i in range(1 if name.startswith("err_") else 3): candidates.append((name, evt)) if not candidates: break name, evt = draw(candidates) del evts[name] try: assert playbook >> evt except AssertionError: if any( isinstance(x, _TracebackInPlaybook) for x in playbook.actual): raise else: # add commands that the server issued. playbook.expected.extend( playbook.actual[len(playbook.expected):])
def test_basic(self): c = context.Client(("127.0.0.1", 52314), ("127.0.0.1", 8080), 1607780791) assert repr(c)