예제 #1
0
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)
예제 #2
0
 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
예제 #3
0
 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
예제 #4
0
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
예제 #5
0
    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)
예제 #6
0
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
예제 #7
0
    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)
예제 #8
0
    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"),)
예제 #9
0
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
예제 #10
0
    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)
예제 #11
0
    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, [], [])
예제 #12
0
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
예제 #13
0
    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"]
예제 #14
0
def tctx():
    context.Context(context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options)
예제 #15
0
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):])
예제 #16
0
 def test_basic(self):
     c = context.Client(("127.0.0.1", 52314), ("127.0.0.1", 8080),
                        1607780791)
     assert repr(c)