def __init__(self, options, server): master.Master.__init__(self, options, server) self.has_errored = False self.addons.add(termlog.TermLog()) self.addons.add(*addons.default_addons()) self.addons.add(dumper.Dumper()) # This line is just for type hinting self.options = self.options # type: Options if not self.options.no_server: self.add_log( "Proxy server listening at http://{}".format(server.address), "info" ) if self.server and self.options.http2 and not tcp.HAS_ALPN: # pragma: no cover self.add_log( "ALPN support missing (OpenSSL 1.0.2+ required)!\n" "HTTP/2 is disabled. Use --no-http2 to silence this warning.", "error" ) if options.rfile: try: self.load_flows_file(options.rfile) except exceptions.FlowReadException as v: self.add_log("Flow file corrupted.", "error") raise DumpError(v)
def __init__( self, options: Options, server, with_termlog=True, with_dumper=True, ) -> None: master.Master.__init__(self, options, server) self.has_errored = False if with_termlog: self.addons.add(termlog.TermLog()) self.addons.add(*addons.default_addons()) if with_dumper: self.addons.add(dumper.Dumper()) if not self.options.no_server: self.add_log( "Proxy server listening at http://{}:{}".format( server.address[0], server.address[1]), "info") if options.rfile: try: self.load_flows_file(options.rfile) except exceptions.FlowReadException as v: self.add_log("Flow file corrupted.", "error") raise DumpError(v)
def test_echo_request_line(): sio = io.StringIO() d = dumper.Dumper(sio) with taddons.context(options=dump.Options()) as ctx: ctx.configure(d, flow_detail=3, showhost=True) f = tflow.tflow(client_conn=None, server_conn=True, resp=True) f.request.is_replay = True d._echo_request_line(f) assert "[replay]" in sio.getvalue() sio.truncate(0) f = tflow.tflow(client_conn=None, server_conn=True, resp=True) f.request.is_replay = False d._echo_request_line(f) assert "[replay]" not in sio.getvalue() sio.truncate(0) f = tflow.tflow(client_conn=None, server_conn=True, resp=True) f.request.http_version = "nonstandard" d._echo_request_line(f) assert "nonstandard" in sio.getvalue() sio.truncate(0) ctx.configure(d, flow_detail=0, showhost=True) f = tflow.tflow(client_conn=None, server_conn=True, resp=True) terminalWidth = max(shutil.get_terminal_size()[0] - 25, 50) f.request.url = "http://address:22/" + ("x" * terminalWidth) + "textToBeTruncated" d._echo_request_line(f) assert "textToBeTruncated" not in sio.getvalue() sio.truncate(0)
def test_echo_trailer(): sio = io.StringIO() sio_err = io.StringIO() d = dumper.Dumper(sio, sio_err) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=3) f = tflow.tflow(client_conn=True, server_conn=True, resp=True) f.request.headers["content-type"] = "text/html" f.request.headers["transfer-encoding"] = "chunked" f.request.headers["trailer"] = "my-little-request-trailer" f.request.content = b"some request content\n" * 100 f.request.trailers = Headers([(b"my-little-request-trailer", b"foobar-request-trailer")]) f.response.headers["transfer-encoding"] = "chunked" f.response.headers["trailer"] = "my-little-response-trailer" f.response.content = b"some response content\n" * 100 f.response.trailers = Headers([(b"my-little-response-trailer", b"foobar-response-trailer")]) d.echo_flow(f) t = sio.getvalue() assert "content-type" in t assert "cut off" in t assert "some request content" in t assert "foobar-request-trailer" in t assert "some response content" in t assert "foobar-response-trailer" in t
def test_styling(): sio = io.StringIO() d = dumper.Dumper(sio) d.out_has_vt_codes = True with taddons.context(d): d.response(tflow.tflow(resp=True)) assert "\x1b[" in sio.getvalue()
def test_http2(): sio = io.StringIO() d = dumper.Dumper(sio) with taddons.context(d): f = tflow.tflow(resp=True) f.response.http_version = b"HTTP/2.0" d.response(f) assert "HTTP/2.0 200 OK" in sio.getvalue()
def test_contentview(self, view_auto): view_auto.side_effect = exceptions.ContentViewException("") sio = io.StringIO() d = dumper.Dumper(sio) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=4, verbosity='debug') d.response(tflow.tflow()) assert ctx.master.has_log("content viewer failed")
def test_contentview(self, view_auto): view_auto.side_effect = exceptions.ContentViewException("") sio = io.StringIO() d = dumper.Dumper(sio) with taddons.context(options=dump.Options()) as ctx: ctx.configure(d, flow_detail=4, verbosity=3) d.response(tflow.tflow()) assert "Content viewer failed" in ctx.master.event_log[0][1]
async def test_contentview(): with mock.patch("mitmproxy.contentviews.auto.ViewAuto.__call__") as va: va.side_effect = ValueError("") sio = io.StringIO() d = dumper.Dumper(sio) with taddons.context(d) as tctx: tctx.configure(d, flow_detail=4) d.response(tflow.tflow()) await tctx.master.await_log("content viewer failed")
async def test_contentview(self): with mock.patch("mitmproxy.contentviews.auto.ViewAuto.__call__") as va: va.side_effect = exceptions.ContentViewException("") sio = io.StringIO() sio_err = io.StringIO() d = dumper.Dumper(sio, sio_err) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=4) d.response(tflow.tflow()) assert await ctx.master.await_log("content viewer failed")
def test_echo_body(): f = tflow.tflow(client_conn=True, server_conn=True, resp=True) f.response.headers["content-type"] = "text/html" f.response.content = b"foo bar voing\n" * 100 sio = io.StringIO() d = dumper.Dumper(sio) with taddons.context(options=dump.Options()) as ctx: ctx.configure(d, flow_detail=3) d._echo_message(f.response) t = sio.getvalue() assert "cut off" in t
def test_simple(self): d = dumper.Dumper() sio = io.StringIO() updated = {"tfile", "flow_detail"} d.configure(dump.Options(tfile=sio, flow_detail=0), updated) d.response(tflow.tflow()) assert not sio.getvalue() d.configure(dump.Options(tfile=sio, flow_detail=4), updated) d.response(tflow.tflow()) assert sio.getvalue() sio = io.StringIO() d.configure(dump.Options(tfile=sio, flow_detail=4), updated) d.response(tflow.tflow(resp=True)) assert "<<" in sio.getvalue() sio = io.StringIO() d.configure(dump.Options(tfile=sio, flow_detail=4), updated) d.response(tflow.tflow(err=True)) assert "<<" in sio.getvalue() sio = io.StringIO() d.configure(dump.Options(tfile=sio, flow_detail=4), updated) flow = tflow.tflow() flow.request = mitmproxy.test.tutils.treq() flow.request.stickycookie = True flow.client_conn = mock.MagicMock() flow.client_conn.address.host = "foo" flow.response = mitmproxy.test.tutils.tresp(content=None) flow.response.is_replay = True flow.response.status_code = 300 d.response(flow) assert sio.getvalue() sio = io.StringIO() d.configure(dump.Options(tfile=sio, flow_detail=4), updated) flow = tflow.tflow(resp=mitmproxy.test.tutils.tresp(content=b"{")) flow.response.headers["content-type"] = "application/json" flow.response.status_code = 400 d.response(flow) assert sio.getvalue() sio = io.StringIO() d.configure(dump.Options(tfile=sio), updated) flow = tflow.tflow() flow.request.content = None flow.response = http.HTTPResponse.wrap(mitmproxy.test.tutils.tresp()) flow.response.content = None d.response(flow) assert "content missing" in sio.getvalue()
def test_tcp(): sio = io.StringIO() d = dumper.Dumper(sio) with taddons.context(options=dump.Options()) as ctx: ctx.configure(d, flow_detail=3, showhost=True) f = tflow.ttcpflow(client_conn=True, server_conn=True) d.tcp_message(f) assert "it's me" in sio.getvalue() sio.truncate(0) f = tflow.ttcpflow(client_conn=True, err=True) d.tcp_error(f) assert "Error in TCP" in sio.getvalue()
def test_contentview(self, view_auto): view_auto.side_effect = exceptions.ContentViewException("") sio = io.StringIO() o = dump.Options( flow_detail=4, verbosity=3, tfile=sio, ) m = mastertest.RecordingMaster(o, proxy.DummyServer()) d = dumper.Dumper() m.addons.add(d) m.response(tflow.tflow()) assert "Content viewer failed" in m.event_log[0][1]
def __init__( self, options: options.Options, with_termlog=True, with_dumper=True, ) -> None: super().__init__(options) self.errorcheck = ErrorCheck() if with_termlog: self.addons.add(termlog.TermLog(), termstatus.TermStatus()) self.addons.add(*addons.default_addons()) if with_dumper: self.addons.add(dumper.Dumper()) self.addons.add(keepserving.KeepServing(), self.errorcheck)
def test_configure(): d = dumper.Dumper() with taddons.context(options=dump.Options()) as ctx: ctx.configure(d, filtstr="~b foo") assert d.filter f = tflow.tflow(resp=True) assert not d.match(f) f.response.content = b"foo" assert d.match(f) ctx.configure(d, filtstr=None) assert not d.filter tutils.raises(exceptions.OptionsError, ctx.configure, d, filtstr="~~") assert not d.filter
def __init__( self, options: options.Options, server, with_termlog=True, with_dumper=True, ) -> None: master.Master.__init__(self, options, server) self.errorcheck = ErrorCheck() if with_termlog: self.addons.add(termlog.TermLog(), termstatus.TermStatus()) self.addons.add(*addons.default_addons()) if with_dumper: self.addons.add(dumper.Dumper()) self.addons.add(readstdin.ReadStdin(), keepserving.KeepServing(), self.errorcheck)
def test_configure(): d = dumper.Dumper() with taddons.context(d) as ctx: ctx.configure(d, view_filter="~b foo") assert d.filter f = tflow.tflow(resp=True) assert not d.match(f) f.response.content = b"foo" assert d.match(f) ctx.configure(d, view_filter=None) assert not d.filter with pytest.raises(exceptions.OptionsError): ctx.configure(d, view_filter="~~") assert not d.filter
def test_websocket(): sio = io.StringIO() d = dumper.Dumper(sio) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=3, showhost=True) f = tflow.twebsocketflow() d.websocket_message(f) assert "it's me" in sio.getvalue() sio.truncate(0) d.websocket_end(f) assert "WebSocket connection closed by" in sio.getvalue() f = tflow.twebsocketflow(client_conn=True, err=True) d.websocket_error(f) assert "Error in WebSocket" in sio.getvalue()
def __init__( self, options: options.Options, with_termlog=True, with_dumper=True, ) -> None: super().__init__(options) if with_termlog: self.addons.add(termlog.TermLog()) self.addons.add(*addons.default_addons()) if with_dumper: self.addons.add(dumper.Dumper()) self.addons.add( keepserving.KeepServing(), readfile.ReadFileStdin(), errorcheck.ErrorCheck(), )
def __init__( self, options: options.Options, mode, flow_name, ) -> None: super().__init__(options) self.addons.add(termlog.TermLog()) self.addons.add(termstatus.TermStatus()) self.addons.add(keepserving.KeepServing()) self.addons.add(*addons.default_addons()) if mode == "fuzz": self.addons.add(dumper.Dumper()) self.addons.add(FuzzResponseAnalyzer()) if mode == "runfuzz": self.addons.add(FuzzResponseAnalyzer()) if mode == "capture": self.addons.add(Capture(flow_name)) if mode == "intercept": self.addons.add(Interceptor())
def __init__( self, options: options.Options, server, with_termlog=True, with_dumper=True, ) -> None: master.Master.__init__(self, options, server) self.has_errored = False if with_termlog: self.addons.add(termlog.TermLog(), termstatus.TermStatus()) self.addons.add(*addons.default_addons()) if with_dumper: self.addons.add(dumper.Dumper()) if options.rfile: try: self.load_flows_file(options.rfile) except exceptions.FlowReadException as v: self.add_log("Flow file corrupted.", "error") raise exceptions.OptionsError(v)
def test_echo_request_line(): d = dumper.Dumper() sio = io.StringIO() with taddons.context(options=dump.Options()) as ctx: ctx.configure(d, tfile=sio, flow_detail=3, showhost=True) f = tflow.tflow(client_conn=None, server_conn=True, resp=True) f.request.is_replay = True d._echo_request_line(f) assert "[replay]" in sio.getvalue() sio.truncate(0) f = tflow.tflow(client_conn=None, server_conn=True, resp=True) f.request.is_replay = False d._echo_request_line(f) assert "[replay]" not in sio.getvalue() sio.truncate(0) f = tflow.tflow(client_conn=None, server_conn=True, resp=True) f.request.http_version = "nonstandard" d._echo_request_line(f) assert "nonstandard" in sio.getvalue() sio.truncate(0)
def test_websocket(): sio = io.StringIO() d = dumper.Dumper(sio) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=3, showhost=True) f = tflow.twebsocketflow() d.websocket_message(f) assert "it's me" in sio.getvalue() sio.truncate(0) d.websocket_end(f) assert "WebSocket connection closed by" in sio.getvalue() sio.truncate(0) f = tflow.twebsocketflow(err=True) d.websocket_end(f) assert "Error in WebSocket" in sio.getvalue() assert "(reason:" not in sio.getvalue() sio.truncate(0) f = tflow.twebsocketflow(err=True, close_reason='Some lame excuse') d.websocket_end(f) assert "Error in WebSocket" in sio.getvalue() assert "(reason: Some lame excuse)" in sio.getvalue() sio.truncate(0) f = tflow.twebsocketflow(close_code=4000) d.websocket_end(f) assert "UNKNOWN_ERROR=4000" in sio.getvalue() assert "(reason:" not in sio.getvalue() sio.truncate(0) f = tflow.twebsocketflow(close_code=4000, close_reason='I swear I had a reason') d.websocket_end(f) assert "UNKNOWN_ERROR=4000" in sio.getvalue() assert "(reason: I swear I had a reason)" in sio.getvalue()
def test_simple(): sio = io.StringIO() d = dumper.Dumper(sio) with taddons.context(options=dump.Options()) as ctx: ctx.configure(d, flow_detail=0) d.response(tflow.tflow(resp=True)) assert not sio.getvalue() sio.truncate(0) ctx.configure(d, flow_detail=1) d.response(tflow.tflow(resp=True)) assert sio.getvalue() sio.truncate(0) ctx.configure(d, flow_detail=1) d.error(tflow.tflow(err=True)) assert sio.getvalue() sio.truncate(0) ctx.configure(d, flow_detail=4) d.response(tflow.tflow(resp=True)) assert sio.getvalue() sio.truncate(0) ctx.configure(d, flow_detail=4) d.response(tflow.tflow(resp=True)) assert "<<" in sio.getvalue() sio.truncate(0) ctx.configure(d, flow_detail=4) d.response(tflow.tflow(err=True)) assert "<<" in sio.getvalue() sio.truncate(0) ctx.configure(d, flow_detail=4) flow = tflow.tflow() flow.request = tutils.treq() flow.request.stickycookie = True flow.client_conn = mock.MagicMock() flow.client_conn.address.host = "foo" flow.response = tutils.tresp(content=None) flow.response.is_replay = True flow.response.status_code = 300 d.response(flow) assert sio.getvalue() sio.truncate(0) ctx.configure(d, flow_detail=4) flow = tflow.tflow(resp=tutils.tresp(content=b"{")) flow.response.headers["content-type"] = "application/json" flow.response.status_code = 400 d.response(flow) assert sio.getvalue() sio.truncate(0) ctx.configure(d, flow_detail=4) flow = tflow.tflow() flow.request.content = None flow.response = http.HTTPResponse.wrap(tutils.tresp()) flow.response.content = None d.response(flow) assert "content missing" in sio.getvalue() sio.truncate(0)
def show(flow_detail, flows): d = dumper.Dumper() with taddons.context(options=dump.Options()) as ctx: ctx.configure(d, flow_detail=flow_detail) for f in flows: ctx.cycle(d, f)
def test_simple(): sio = io.StringIO() sio_err = io.StringIO() d = dumper.Dumper(sio, sio_err) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=0) d.response(tflow.tflow(resp=True)) assert not sio.getvalue() sio.truncate(0) assert not sio_err.getvalue() sio_err.truncate(0) ctx.configure(d, flow_detail=1) d.response(tflow.tflow(resp=True)) assert sio.getvalue() sio.truncate(0) assert not sio_err.getvalue() sio_err.truncate(0) ctx.configure(d, flow_detail=1) d.error(tflow.tflow(err=True)) assert sio.getvalue() sio.truncate(0) assert not sio_err.getvalue() sio_err.truncate(0) ctx.configure(d, flow_detail=4) d.response(tflow.tflow(resp=True)) assert sio.getvalue() sio.truncate(0) assert not sio_err.getvalue() sio_err.truncate(0) ctx.configure(d, flow_detail=4) d.response(tflow.tflow(resp=True)) assert "<<" in sio.getvalue() sio.truncate(0) assert not sio_err.getvalue() sio_err.truncate(0) ctx.configure(d, flow_detail=4) d.response(tflow.tflow(err=True)) assert "<<" in sio.getvalue() sio.truncate(0) assert not sio_err.getvalue() sio_err.truncate(0) ctx.configure(d, flow_detail=4) flow = tflow.tflow() flow.request = tutils.treq() flow.client_conn = mock.MagicMock() flow.client_conn.peername[0] = "foo" flow.response = tutils.tresp(content=None) flow.is_replay = "response" flow.response.status_code = 300 d.response(flow) assert sio.getvalue() sio.truncate(0) assert not sio_err.getvalue() sio_err.truncate(0) ctx.configure(d, flow_detail=4) flow = tflow.tflow(resp=tutils.tresp(content=b"{")) flow.response.headers["content-type"] = "application/json" flow.response.status_code = 400 d.response(flow) assert sio.getvalue() sio.truncate(0) assert not sio_err.getvalue() sio_err.truncate(0) ctx.configure(d, flow_detail=4) flow = tflow.tflow() flow.request.content = None flow.response = tutils.tresp(content=None) d.response(flow) assert "content missing" in sio.getvalue() sio.truncate(0) assert not sio_err.getvalue() sio_err.truncate(0)
def show(flow_detail, flows): d = dumper.Dumper() with taddons.context() as ctx: ctx.configure(d, flow_detail=flow_detail) for f in flows: run_async(ctx.cycle(d, f))