Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 3
0
def test_context():
    with taddons.context() as tctx:
        c = context.Context(tflow.tclient_conn(), tctx.options)
        assert repr(c)
        c.layers.append(1)
        c2 = c.fork()
        c.layers.append(2)
        c2.layers.append(3)
        assert c.layers == [1, 2]
        assert c2.layers == [1, 3]
Exemplo n.º 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
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 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)
Exemplo n.º 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"),)
Exemplo n.º 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
Exemplo n.º 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)
Exemplo n.º 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, [], [])
Exemplo n.º 12
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"]
Exemplo n.º 13
0
def tctx():
    context.Context(context.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options)
Exemplo n.º 14
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):])