Esempio n. 1
0
def iterate(f):
    if isinstance(f, http.HTTPFlow):
        if f.request:
            yield "requestheaders", f
            yield "request", f
        if f.response:
            yield "responseheaders", f
            yield "response", f
        if f.error:
            yield "error", f
    elif isinstance(f, websocket.WebSocketFlow):
        messages = f.messages
        f.messages = []
        f.reply = controller.DummyReply()
        yield "websocket_start", f
        while messages:
            f.messages.append(messages.pop(0))
            yield "websocket_message", f
        if f.error:
            yield "websocket_error", f
        yield "websocket_end", f
    elif isinstance(f, tcp.TCPFlow):
        messages = f.messages
        f.messages = []
        f.reply = controller.DummyReply()
        yield "tcp_start", f
        while messages:
            f.messages.append(messages.pop(0))
            yield "tcp_message", f
        if f.error:
            yield "tcp_error", f
        yield "tcp_end", f
    else:
        raise TypeError()
Esempio n. 2
0
    def load_flow(self, f):
        """
        Loads a flow
        """
        if isinstance(f, models.HTTPFlow):
            if self.server and self.options.mode == "reverse":
                f.request.host = self.server.config.upstream_server.address.host
                f.request.port = self.server.config.upstream_server.address.port
                f.request.scheme = self.server.config.upstream_server.scheme

            f.reply = controller.DummyReply()
            if f.request:
                self.request(f)
            if f.response:
                self.responseheaders(f)
                self.response(f)
            if f.error:
                self.error(f)
        elif isinstance(f, models.TCPFlow):
            messages = f.messages
            f.messages = []
            f.reply = controller.DummyReply()
            self.tcp_open(f)
            while messages:
                f.messages.append(messages.pop(0))
                self.tcp_message(f)
            if f.error:
                self.tcp_error(f)
            self.tcp_close(f)
        else:
            raise NotImplementedError()
Esempio n. 3
0
 def log(self, message: str, level: str = "info") -> None:
     x = log.LogEntry(self.log_prefix + message, level)
     x.reply = controller.DummyReply()  # type: ignore
     asyncio_utils.create_task(
         self.master.addons.handle_lifecycle("log", x),
         name="ProxyConnectionHandler.log"
     )
Esempio n. 4
0
def tflow(
    *,
    client_conn: Optional[connection.Client] = None,
    server_conn: Optional[connection.Server] = None,
    req: Optional[http.Request] = None,
    resp: Union[bool, http.Response] = False,
    err: Union[bool, flow.Error] = False,
    ws: Union[bool, websocket.WebSocketData] = False,
) -> http.HTTPFlow:
    """Create a flow for testing."""
    if client_conn is None:
        client_conn = tclient_conn()
    if server_conn is None:
        server_conn = tserver_conn()
    if req is None:
        req = treq()

    if resp is True:
        resp = tresp()
    if err is True:
        err = terr()
    if ws is True:
        ws = twebsocket()

    assert resp is False or isinstance(resp, http.Response)
    assert err is False or isinstance(err, flow.Error)
    assert ws is False or isinstance(ws, websocket.WebSocketData)

    f = http.HTTPFlow(client_conn, server_conn)
    f.request = req
    f.response = resp or None
    f.error = err or None
    f.websocket = ws or None
    f.reply = controller.DummyReply()
    return f
Esempio n. 5
0
def tserver_conn() -> compat.Server:
    c = compat.Server.from_state(
        dict(
            id=str(uuid.uuid4()),
            address=("address", 22),
            source_address=("address", 22),
            ip_address=("192.168.0.1", 22),
            timestamp_start=946681202,
            timestamp_tcp_setup=946681203,
            timestamp_tls_setup=946681204,
            timestamp_end=946681205,
            tls_established=True,
            sni="address",
            alpn_proto_negotiated=None,
            tls_version="TLSv1.2",
            via=None,
            state=0,
            error=None,
            tls=False,
            certificate_list=[],
            alpn_offers=[],
            cipher_name=None,
            cipher_list=[],
            via2=None,
        ))
    c.reply = controller.DummyReply()
    c.rfile = io.BytesIO()
    c.wfile = io.BytesIO()
    return c
Esempio n. 6
0
def tflow(client_conn=True, server_conn=True, req=True, resp=None, err=None):
    """
    @type client_conn: bool | None | mitmproxy.proxy.connection.ClientConnection
    @type server_conn: bool | None | mitmproxy.proxy.connection.ServerConnection
    @type req:         bool | None | mitmproxy.protocol.http.HTTPRequest
    @type resp:        bool | None | mitmproxy.protocol.http.HTTPResponse
    @type err:         bool | None | mitmproxy.protocol.primitives.Error
    @return:           mitmproxy.protocol.http.HTTPFlow
    """
    if client_conn is True:
        client_conn = tclient_conn()
    if server_conn is True:
        server_conn = tserver_conn()
    if req is True:
        req = netlib.tutils.treq()
    if resp is True:
        resp = netlib.tutils.tresp()
    if err is True:
        err = terr()

    if req:
        req = HTTPRequest.wrap(req)
    if resp:
        resp = HTTPResponse.wrap(resp)

    f = HTTPFlow(client_conn, server_conn)
    f.request = req
    f.response = resp
    f.error = err
    f.reply = controller.DummyReply()
    return f
Esempio n. 7
0
def tclient_conn() -> compat.Client:
    c = compat.Client.from_state(
        dict(
            id=str(uuid.uuid4()),
            address=("127.0.0.1", 22),
            mitmcert=None,
            tls_established=True,
            timestamp_start=946681200,
            timestamp_tls_setup=946681201,
            timestamp_end=946681206,
            sni="address",
            cipher_name="cipher",
            alpn_proto_negotiated=b"http/1.1",
            tls_version="TLSv1.2",
            tls_extensions=[(0x00, bytes.fromhex("000e00000b6578616d"))],
            state=0,
            sockname=("", 0),
            error=None,
            tls=False,
            certificate_list=[],
            alpn_offers=[],
            cipher_list=[],
        ))
    c.reply = controller.DummyReply()
    if not compat.new_proxy_core:
        c.rfile = io.BytesIO()
        c.wfile = io.BytesIO()
    return c
Esempio n. 8
0
 def copy(self):
     """Make a copy of this flow."""
     f = super().copy()
     f.live = False
     if self.reply is not None:
         f.reply = controller.DummyReply()
     return f
Esempio n. 9
0
def tserver_conn():
    """
    @return: mitmproxy.proxy.connection.ServerConnection
    """
    c = connections.ServerConnection.from_state(
        dict(
            id=str(uuid.uuid4()),
            address=("address", 22),
            source_address=("address", 22),
            ip_address=("192.168.0.1", 22),
            cert=None,
            timestamp_start=946681202,
            timestamp_tcp_setup=946681203,
            timestamp_tls_setup=946681204,
            timestamp_end=946681205,
            tls_established=False,
            sni="address",
            alpn_proto_negotiated=None,
            tls_version="TLSv1.2",
            via=None,
        ))
    c.reply = controller.DummyReply()
    c.rfile = io.BytesIO()
    c.wfile = io.BytesIO()
    return c
Esempio n. 10
0
    async def load_flow(self, f):
        """
        Loads a flow and links websocket & handshake flows
        """

        if isinstance(f, http.HTTPFlow):
            self._change_reverse_host(f)
            if 'websocket' in f.metadata:
                self.waiting_flows.append(f)

        if isinstance(f, websocket.WebSocketFlow):
            hfs = [
                hf for hf in self.waiting_flows
                if hf.id == f.metadata['websocket_handshake']
            ]
            if hfs:
                hf = hfs[0]
                f.handshake_flow = hf
                self.waiting_flows.remove(hf)
                self._change_reverse_host(f.handshake_flow)
            else:
                # this will fail - but at least it will load the remaining flows
                f.handshake_flow = http.HTTPFlow(None, None)

        f.reply = controller.DummyReply()
        for e, o in eventsequence.iterate(f):
            await self.addons.handle_lifecycle(e, o)
Esempio n. 11
0
def twebsocketflow(client_conn=True,
                   server_conn=True,
                   messages=True,
                   err=None,
                   handshake_flow=True):

    if client_conn is True:
        client_conn = tclient_conn()
    if server_conn is True:
        server_conn = tserver_conn()
    if handshake_flow is True:
        req = http.HTTPRequest("relative",
                               "GET",
                               "http",
                               "example.com",
                               "80",
                               "/ws",
                               "HTTP/1.1",
                               headers=net_http.Headers(
                                   connection="upgrade",
                                   upgrade="websocket",
                                   sec_websocket_version="13",
                                   sec_websocket_key="1234",
                               ),
                               content=b'')
        resp = http.HTTPResponse(
            "HTTP/1.1",
            101,
            reason=net_http.status_codes.RESPONSES.get(101),
            headers=net_http.Headers(
                connection='upgrade',
                upgrade='websocket',
                sec_websocket_accept=b'',
            ),
            content=b'',
        )
        handshake_flow = http.HTTPFlow(client_conn, server_conn)
        handshake_flow.request = req
        handshake_flow.response = resp

    f = websocket.WebSocketFlow(client_conn, server_conn, handshake_flow)
    handshake_flow.metadata['websocket_flow'] = f

    if messages is True:
        messages = [
            websocket.WebSocketMessage(websockets.OPCODE.BINARY, True,
                                       b"hello binary"),
            websocket.WebSocketMessage(websockets.OPCODE.TEXT, True,
                                       "hello text".encode()),
            websocket.WebSocketMessage(websockets.OPCODE.TEXT, False,
                                       "it's me".encode()),
        ]
    if err is True:
        err = terr()

    f.messages = messages
    f.error = err
    f.reply = controller.DummyReply()
    return f
Esempio n. 12
0
 def test_simple(self):
     reply = controller.DummyReply()
     for _ in range(2):
         reply.take()
         reply.commit()
         reply.mark_reset()
         reply.reset()
     assert reply.state == "start"
Esempio n. 13
0
 def test_reset(self):
     reply = controller.DummyReply()
     reply.ack()
     reply.take()
     reply.commit()
     reply.mark_reset()
     assert reply.state == "committed"
     reply.reset()
     assert reply.state == "start"
Esempio n. 14
0
 def tick(self, master):
     if self.flows and not self.current:
         self.current = self.flows.pop(0).copy()
         if not self.testing:
             master.replay_request(self.current)
         else:
             self.current.reply = controller.DummyReply()
             master.request(self.current)
             if self.current.response:
                 master.response(self.current)
Esempio n. 15
0
 def test_reset(self):
     reply = controller.DummyReply()
     reply.take()
     with pytest.raises(ControlException):
         reply.mark_reset()
     reply.commit()
     reply.mark_reset()
     assert reply.state == "committed"
     reply.reset()
     assert reply.state == "start"
Esempio n. 16
0
 async def cycle(self, master, content):
     f = tflow.tflow(req=tutils.treq(content=content))
     layer = mock.Mock("mitmproxy.proxy.protocol.base.Layer")
     layer.client_conn = f.client_conn
     layer.reply = controller.DummyReply()
     await master.addons.handle_lifecycle("clientconnect", layer)
     for i in eventsequence.iterate(f):
         await master.addons.handle_lifecycle(*i)
     await master.addons.handle_lifecycle("clientdisconnect", layer)
     return f
Esempio n. 17
0
def twebsocketflow(messages=True,
                   err=None,
                   close_code=None,
                   close_reason='') -> http.HTTPFlow:
    flow = http.HTTPFlow(tclient_conn(), tserver_conn())
    flow.request = http.Request(
        "example.com",
        80,
        b"GET",
        b"http",
        b"example.com",
        b"/ws",
        b"HTTP/1.1",
        headers=http.Headers(
            connection="upgrade",
            upgrade="websocket",
            sec_websocket_version="13",
            sec_websocket_key="1234",
        ),
        content=b'',
        trailers=None,
        timestamp_start=946681200,
        timestamp_end=946681201,
    )
    flow.response = http.Response(
        b"HTTP/1.1",
        101,
        reason=b"Switching Protocols",
        headers=http.Headers(
            connection='upgrade',
            upgrade='websocket',
            sec_websocket_accept=b'',
        ),
        content=b'',
        trailers=None,
        timestamp_start=946681202,
        timestamp_end=946681203,
    )

    flow.websocket = twebsocket()

    flow.websocket.close_reason = close_reason

    if close_code is not None:
        flow.websocket.close_code = close_code
    else:
        if err is True:
            # ABNORMAL_CLOSURE
            flow.websocket.close_code = 1006
        else:
            # NORMAL_CLOSURE
            flow.websocket.close_code = 1000

    flow.reply = controller.DummyReply()
    return flow
Esempio n. 18
0
def _iterate_tcp(f: tcp.TCPFlow) -> TEventGenerator:
    messages = f.messages
    f.messages = []
    f.reply = controller.DummyReply()
    yield "tcp_start", f
    while messages:
        f.messages.append(messages.pop(0))
        yield "tcp_message", f
    if f.error:
        yield "tcp_error", f
    yield "tcp_end", f
Esempio n. 19
0
def _iterate_websocket(f: websocket.WebSocketFlow) -> TEventGenerator:
    messages = f.messages
    f.messages = []
    f.reply = controller.DummyReply()
    yield "websocket_start", f
    while messages:
        f.messages.append(messages.pop(0))
        yield "websocket_message", f
    if f.error:
        yield "websocket_error", f
    yield "websocket_end", f
Esempio n. 20
0
    async def load_flow(self, f):
        """
        Loads a flow
        """

        if isinstance(f, http.HTTPFlow):
            self._change_reverse_host(f)

        f.reply = controller.DummyReply()
        for e in eventsequence.iterate(f):
            await self.addons.handle_lifecycle(e)
Esempio n. 21
0
 def load_flow(self, f):
     """
     Loads a flow
     """
     if isinstance(f, http.HTTPFlow):
         if self.options.mode.startswith("reverse:"):
             _, upstream_spec = server_spec.parse_with_mode(self.options.mode)
             f.request.host, f.request.port = upstream_spec.address
             f.request.scheme = upstream_spec.scheme
     f.reply = controller.DummyReply()
     for e, o in eventsequence.iterate(f):
         self.addons.handle_lifecycle(e, o)
Esempio n. 22
0
 def load_flow(self, f):
     """
     Loads a flow
     """
     if isinstance(f, http.HTTPFlow):
         if self.server and self.options.mode.startswith("reverse:"):
             f.request.host = self.server.config.upstream_server.address[0]
             f.request.port = self.server.config.upstream_server.address[1]
             f.request.scheme = self.server.config.upstream_server.scheme
     f.reply = controller.DummyReply()
     for e, o in eventsequence.iterate(f):
         self.addons.handle_lifecycle(e, o)
Esempio n. 23
0
 def load_flow(self, f):
     """
     Loads a flow
     """
     if isinstance(f, models.HTTPFlow):
         if self.server and self.options.mode == "reverse":
             f.request.host = self.server.config.upstream_server.address.host
             f.request.port = self.server.config.upstream_server.address.port
             f.request.scheme = self.server.config.upstream_server.scheme
     f.reply = controller.DummyReply()
     for e, o in event_sequence(f):
         getattr(self, e)(o)
Esempio n. 24
0
 async def cycle(self, master, content):
     f = tflow.tflow(req=tutils.treq(content=content))
     layer = mock.Mock("mitmproxy.proxy.protocol.base.Layer")
     layer.client_conn = f.client_conn
     layer.reply = controller.DummyReply()
     await master.addons.handle_lifecycle(
         server_hooks.ClientConnectedHook(layer))
     for e in eventsequence.iterate(f):
         await master.addons.handle_lifecycle(e)
     await master.addons.handle_lifecycle(
         server_hooks.ClientDisconnectedHook(layer))
     return f
Esempio n. 25
0
def _iterate_tcp(f: tcp.TCPFlow) -> TEventGenerator:
    messages = f.messages
    f.messages = []
    f.reply = controller.DummyReply()
    yield layers.tcp.TcpStartHook(f)
    while messages:
        f.messages.append(messages.pop(0))
        yield layers.tcp.TcpMessageHook(f)
    if f.error:
        yield layers.tcp.TcpErrorHook(f)
    else:
        yield layers.tcp.TcpEndHook(f)
Esempio n. 26
0
def _iterate_websocket(f: websocket.WebSocketFlow) -> TEventGenerator:
    messages = f.messages
    f.messages = []
    f.reply = controller.DummyReply()
    yield layers.websocket.WebsocketStartHook(f)
    while messages:
        f.messages.append(messages.pop(0))
        yield layers.websocket.WebsocketMessageHook(f)
    if f.error:
        yield layers.websocket.WebsocketErrorHook(f)
    else:
        yield layers.websocket.WebsocketEndHook(f)
Esempio n. 27
0
def tdummyflow(client_conn=True, server_conn=True, err=None):
    if client_conn is True:
        client_conn = tclient_conn()
    if server_conn is True:
        server_conn = tserver_conn()
    if err is True:
        err = terr()

    f = DummyFlow(client_conn, server_conn)
    f.error = err
    f.reply = controller.DummyReply()
    return f
Esempio n. 28
0
 def cycle(self, master, content):
     f = tutils.tflow(req=netlib.tutils.treq(content=content))
     l = proxy.Log("connect")
     l.reply = controller.DummyReply()
     master.log(l)
     master.clientconnect(f.client_conn)
     master.serverconnect(f.server_conn)
     master.request(f)
     if not f.error:
         f.response = models.HTTPResponse.wrap(netlib.tutils.tresp(content=content))
         master.response(f)
     master.clientdisconnect(f)
     return f
Esempio n. 29
0
    def test_simple(self):
        class tAddon:
            def log(self, _):
                ctx.master.should_exit.set()

        with taddons.context() as ctx:
            ctx.master.addons.add(tAddon())
            assert not ctx.master.should_exit.is_set()
            msg = TMsg()
            msg.reply = controller.DummyReply()
            ctx.master.event_queue.put(("log", msg))
            ctx.master.run()
            assert ctx.master.should_exit.is_set()
Esempio n. 30
0
def twebsocketflow(messages=True, err=None) -> http.HTTPFlow:
    flow = http.HTTPFlow(tclient_conn(), tserver_conn())
    flow.request = http.Request(
        "example.com",
        80,
        b"GET",
        b"http",
        b"example.com",
        b"/ws",
        b"HTTP/1.1",
        headers=http.Headers(
            connection="upgrade",
            upgrade="websocket",
            sec_websocket_version="13",
            sec_websocket_key="1234",
        ),
        content=b'',
        trailers=None,
        timestamp_start=946681200,
        timestamp_end=946681201,
    )
    flow.response = http.Response(
        b"HTTP/1.1",
        101,
        reason=b"Switching Protocols",
        headers=http.Headers(
            connection='upgrade',
            upgrade='websocket',
            sec_websocket_accept=b'',
        ),
        content=b'',
        trailers=None,
        timestamp_start=946681202,
        timestamp_end=946681203,
    )
    flow.websocket = websocket.WebSocketData()

    if messages is True:
        flow.websocket.messages = [
            websocket.WebSocketMessage(Opcode.BINARY, True, b"hello binary",
                                       946681203),
            websocket.WebSocketMessage(Opcode.TEXT, True, b"hello text",
                                       946681204),
            websocket.WebSocketMessage(Opcode.TEXT, False, b"it's me",
                                       946681205),
        ]
    if err is True:
        flow.error = terr()

    flow.reply = controller.DummyReply()
    return flow