Esempio n. 1
0
 def run_script_once(self, command, f):
     sc = self.addons.get("scriptloader")
     try:
         with self.handlecontext():
             sc.run_once(command, [f])
     except mitmproxy.exceptions.AddonError as e:
         signals.add_log("Script error: %s" % e, "warn")
Esempio n. 2
0
 def run_script_once(self, command, f):
     sc = self.addons.get("scriptloader")
     try:
         with self.handlecontext():
             sc.run_once(command, [f])
     except mitmproxy.exceptions.AddonError as e:
         signals.add_log("Script error: %s" % e, "warn")
Esempio n. 3
0
    def run(self):
        self.ui = urwid.raw_display.Screen()
        self.ui.set_terminal_properties(256)
        self.set_palette(self.palette)
        self.loop = urwid.MainLoop(
            urwid.SolidFill("x"),
            screen = self.ui,
            handle_mouse = not self.options.no_mouse,
        )
        self.ab = statusbar.ActionBar()

        if self.options.rfile:
            ret = self.load_flows_path(self.options.rfile)
            if ret and self.state.flow_count():
                signals.add_log(
                    "File truncated or corrupted. "
                    "Loaded as many flows as possible.",
                    "error"
                )
            elif ret and not self.state.flow_count():
                self.shutdown()
                print("Could not load file: {}".format(ret), file=sys.stderr)
                sys.exit(1)

        self.loop.set_alarm_in(0.01, self.ticker)
        if self.options.http2 and not tcp.HAS_ALPN:  # pragma: no cover
            def http2err(*args, **kwargs):
                signals.status_message.send(
                    message = "HTTP/2 disabled - OpenSSL 1.0.2+ required."
                              " Use --no-http2 to silence this warning.",
                    expire=5
                )
            self.loop.set_alarm_in(0.01, http2err)

        # It's not clear why we need to handle this explicitly - without this,
        # mitmproxy hangs on keyboard interrupt. Remove if we ever figure it
        # out.
        def exit(s, f):
            raise urwid.ExitMainLoop
        signal.signal(signal.SIGINT, exit)

        self.loop.set_alarm_in(
            0.0001,
            lambda *args: self.view_flowlist()
        )

        self.start()
        try:
            self.loop.run()
        except Exception:
            self.loop.stop()
            sys.stdout.flush()
            print(traceback.format_exc(), file=sys.stderr)
            print("mitmproxy has crashed!", file=sys.stderr)
            print("Please lodge a bug report at:", file=sys.stderr)
            print("\thttps://github.com/mitmproxy/mitmproxy", file=sys.stderr)
            print("Shutting down...", file=sys.stderr)
        sys.stderr.flush()
        self.shutdown()
Esempio n. 4
0
    def run(self):
        self.ui = urwid.raw_display.Screen()
        self.ui.set_terminal_properties(256)
        self.set_palette(self.palette)
        self.loop = urwid.MainLoop(
            urwid.SolidFill("x"),
            screen = self.ui,
            handle_mouse = not self.options.no_mouse,
        )
        self.ab = statusbar.ActionBar()

        if self.options.rfile:
            ret = self.load_flows_path(self.options.rfile)
            if ret and self.state.flow_count():
                signals.add_log(
                    "File truncated or corrupted. "
                    "Loaded as many flows as possible.",
                    "error"
                )
            elif ret and not self.state.flow_count():
                self.shutdown()
                print("Could not load file: {}".format(ret), file=sys.stderr)
                sys.exit(1)

        self.loop.set_alarm_in(0.01, self.ticker)
        if self.options.http2 and not tcp.HAS_ALPN:  # pragma: no cover
            def http2err(*args, **kwargs):
                signals.status_message.send(
                    message = "HTTP/2 disabled - OpenSSL 1.0.2+ required."
                              " Use --no-http2 to silence this warning.",
                    expire=5
                )
            self.loop.set_alarm_in(0.01, http2err)

        # It's not clear why we need to handle this explicitly - without this,
        # mitmproxy hangs on keyboard interrupt. Remove if we ever figure it
        # out.
        def exit(s, f):
            raise urwid.ExitMainLoop
        signal.signal(signal.SIGINT, exit)

        self.loop.set_alarm_in(
            0.0001,
            lambda *args: self.view_flowlist()
        )

        self.start()
        try:
            self.loop.run()
        except Exception:
            self.loop.stop()
            sys.stdout.flush()
            print(traceback.format_exc(), file=sys.stderr)
            print("mitmproxy has crashed!", file=sys.stderr)
            print("Please lodge a bug report at:", file=sys.stderr)
            print("\thttps://github.com/mitmproxy/mitmproxy", file=sys.stderr)
            print("Shutting down...", file=sys.stderr)
        sys.stderr.flush()
        self.shutdown()
Esempio n. 5
0
 def _run_script_method(self, method, s, f):
     status, val = s.run(method, f)
     if val:
         if status:
             signals.add_log("Method %s return: %s" % (method, val), "debug")
         else:
             signals.add_log(
                 "Method %s error: %s" %
                 (method, val[1]), "error")
Esempio n. 6
0
 def _run_script_method(self, method, s, f):
     status, val = s.run(method, f)
     if val:
         if status:
             signals.add_log("Method %s return: %s" % (method, val),
                             "debug")
         else:
             signals.add_log("Method %s error: %s" % (method, val[1]),
                             "error")
Esempio n. 7
0
    def _get_content_view(self, message, viewmode, max_lines, _):
        description, lines, error = contentviews.get_message_content_view(
            viewmode, message)
        if error:
            signals.add_log(error, "error")
        # Give hint that you have to tab for the response.
        if description == "No content" and isinstance(message,
                                                      models.HTTPRequest):
            description = "No request content (press tab to view response)"

        # If the users has a wide terminal, he gets fewer lines; this should not be an issue.
        chars_per_line = 80
        max_chars = max_lines * chars_per_line
        total_chars = 0
        text_objects = []
        for line in lines:
            txt = []
            for (style, text) in line:
                if total_chars + len(text) > max_chars:
                    text = text[:max_chars - total_chars]
                txt.append((style, text))
                total_chars += len(text)
                if total_chars == max_chars:
                    break

            # round up to the next line.
            total_chars = int(
                math.ceil(total_chars / chars_per_line) * chars_per_line)

            text_objects.append(urwid.Text(txt))
            if total_chars == max_chars:
                text_objects.append(
                    urwid.Text([
                        ("highlight",
                         "Stopped displaying data after %d lines. Press " %
                         max_lines), ("key", "f"),
                        ("highlight", " to load all data.")
                    ]))
                break

        return description, text_objects
Esempio n. 8
0
    def _get_content_view(self, message, viewmode, max_lines, _):
        description, lines, error = contentviews.get_message_content_view(
            viewmode, message
        )
        if error:
            signals.add_log(error, "error")
        # Give hint that you have to tab for the response.
        if description == "No content" and isinstance(message, models.HTTPRequest):
            description = "No request content (press tab to view response)"

        # If the users has a wide terminal, he gets fewer lines; this should not be an issue.
        chars_per_line = 80
        max_chars = max_lines * chars_per_line
        total_chars = 0
        text_objects = []
        for line in lines:
            txt = []
            for (style, text) in line:
                if total_chars + len(text) > max_chars:
                    text = text[:max_chars - total_chars]
                txt.append((style, text))
                total_chars += len(text)
                if total_chars == max_chars:
                    break

            # round up to the next line.
            total_chars = int(math.ceil(total_chars / chars_per_line) * chars_per_line)

            text_objects.append(urwid.Text(txt))
            if total_chars == max_chars:
                text_objects.append(urwid.Text([
                    ("highlight", "Stopped displaying data after %d lines. Press " % max_lines),
                    ("key", "f"),
                    ("highlight", " to load all data.")
                ]))
                break

        return description, text_objects
Esempio n. 9
0
    def run_script_once(self, command, f):
        if not command:
            return
        signals.add_log("Running script on flow: %s" % command, "debug")

        try:
            s = script.Script(command)
            s.load()
        except script.ScriptException as e:
            signals.status_message.send(
                message='Error loading "{}".'.format(command)
            )
            signals.add_log('Error loading "{}":\n{}'.format(command, e), "error")
            return

        if f.request:
            self._run_script_method("request", s, f)
        if f.response:
            self._run_script_method("response", s, f)
        if f.error:
            self._run_script_method("error", s, f)
        s.unload()
        signals.flow_change.send(self, flow = f)
Esempio n. 10
0
    def run_script_once(self, command, f):
        if not command:
            return
        signals.add_log("Running script on flow: %s" % command, "debug")

        try:
            s = script.Script(command)
            s.load()
        except script.ScriptException as e:
            signals.status_message.send(
                message='Error loading "{}".'.format(command))
            signals.add_log('Error loading "{}":\n{}'.format(command, e),
                            "error")
            return

        if f.request:
            self._run_script_method("request", s, f)
        if f.response:
            self._run_script_method("response", s, f)
        if f.error:
            self._run_script_method("error", s, f)
        s.unload()
        signals.flow_change.send(self, flow=f)
Esempio n. 11
0
 def keypress(self, xxx_todo_changeme, key):
     (maxcol,) = xxx_todo_changeme
     key = common.shortcuts(key)
     if key == "a":
         self.flow.accept_intercept(self.master)
         signals.flowlist_change.send(self)
     elif key == "d":
         if self.flow.killable:
             self.flow.kill(self.master)
         self.state.delete_flow(self.flow)
         signals.flowlist_change.send(self)
     elif key == "D":
         f = self.master.duplicate_flow(self.flow)
         self.master.state.set_focus_flow(f)
         signals.flowlist_change.send(self)
     elif key == "m":
         self.flow.marked = not self.flow.marked
         signals.flowlist_change.send(self)
     elif key == "M":
         if self.state.mark_filter:
             self.state.disable_marked_filter()
         else:
             self.state.enable_marked_filter()
         signals.flowlist_change.send(self)
     elif key == "r":
         try:
             self.master.replay_request(self.flow)
         except exceptions.ReplayException as e:
             signals.add_log("Replay error: %s" % e, "warn")
         signals.flowlist_change.send(self)
     elif key == "S":
         def stop_server_playback(response):
             if response == "y":
                 self.master.options.server_replay = []
         a = self.master.addons.get("serverplayback")
         if a.count():
             signals.status_prompt_onekey.send(
                 prompt = "Stop current server replay?",
                 keys = (
                     ("yes", "y"),
                     ("no", "n"),
                 ),
                 callback = stop_server_playback,
             )
         else:
             signals.status_prompt_onekey.send(
                 prompt = "Server Replay",
                 keys = (
                     ("all flows", "a"),
                     ("this flow", "t"),
                 ),
                 callback = self.server_replay_prompt,
             )
     elif key == "U":
         for f in self.state.flows:
             f.marked = False
         signals.flowlist_change.send(self)
     elif key == "V":
         if not self.flow.modified():
             signals.status_message.send(message="Flow not modified.")
             return
         self.state.revert(self.flow)
         signals.flowlist_change.send(self)
         signals.status_message.send(message="Reverted.")
     elif key == "w":
         signals.status_prompt_onekey.send(
             self,
             prompt = "Save",
             keys = (
                 ("listed flows", "l"),
                 ("this flow", "t"),
             ),
             callback = self.save_flows_prompt,
         )
     elif key == "X":
         if self.flow.killable:
             self.flow.kill(self.master)
     elif key == "enter":
         if self.flow.request:
             self.master.view_flow(self.flow)
     elif key == "|":
         signals.status_prompt_path.send(
             prompt = "Send flow to script",
             callback = self.master.run_script_once,
             args = (self.flow,)
         )
     elif key == "E":
         signals.status_prompt_onekey.send(
             self,
             prompt = "Export to file",
             keys = [(e[0], e[1]) for e in export.EXPORTERS],
             callback = common.export_to_clip_or_file,
             args = (None, self.flow, common.ask_save_path)
         )
     elif key == "C":
         signals.status_prompt_onekey.send(
             self,
             prompt = "Export to clipboard",
             keys = [(e[0], e[1]) for e in export.EXPORTERS],
             callback = common.export_to_clip_or_file,
             args = (None, self.flow, common.copy_to_clipboard_or_prompt)
         )
     elif key == "b":
         common.ask_save_body(None, self.flow)
     else:
         return key
Esempio n. 12
0
 def add_log(self, e, level):
     signals.add_log(e, level)
Esempio n. 13
0
 def add_log(self, e, level):
     signals.add_log(e, level)
Esempio n. 14
0
    def keypress(self, xxx_todo_changeme, key):
        (maxcol, ) = xxx_todo_changeme
        key = common.shortcuts(key)
        if key == "a":
            self.flow.accept_intercept(self.master)
            signals.flowlist_change.send(self)
        elif key == "d":
            if self.flow.killable:
                self.flow.kill(self.master)
            self.state.delete_flow(self.flow)
            signals.flowlist_change.send(self)
        elif key == "D":
            f = self.master.duplicate_flow(self.flow)
            self.master.state.set_focus_flow(f)
            signals.flowlist_change.send(self)
        elif key == "m":
            self.flow.marked = not self.flow.marked
            signals.flowlist_change.send(self)
        elif key == "M":
            if self.state.mark_filter:
                self.state.disable_marked_filter()
            else:
                self.state.enable_marked_filter()
            signals.flowlist_change.send(self)
        elif key == "r":
            try:
                self.master.replay_request(self.flow)
            except exceptions.ReplayException as e:
                signals.add_log("Replay error: %s" % e, "warn")
            signals.flowlist_change.send(self)
        elif key == "S":

            def stop_server_playback(response):
                if response == "y":
                    self.master.options.server_replay = []

            a = self.master.addons.get("serverplayback")
            if a.count():
                signals.status_prompt_onekey.send(
                    prompt="Stop current server replay?",
                    keys=(
                        ("yes", "y"),
                        ("no", "n"),
                    ),
                    callback=stop_server_playback,
                )
            else:
                signals.status_prompt_onekey.send(
                    prompt="Server Replay",
                    keys=(
                        ("all flows", "a"),
                        ("this flow", "t"),
                    ),
                    callback=self.server_replay_prompt,
                )
        elif key == "U":
            for f in self.state.flows:
                f.marked = False
            signals.flowlist_change.send(self)
        elif key == "V":
            if not self.flow.modified():
                signals.status_message.send(message="Flow not modified.")
                return
            self.state.revert(self.flow)
            signals.flowlist_change.send(self)
            signals.status_message.send(message="Reverted.")
        elif key == "w":
            signals.status_prompt_onekey.send(
                self,
                prompt="Save",
                keys=(
                    ("listed flows", "l"),
                    ("this flow", "t"),
                ),
                callback=self.save_flows_prompt,
            )
        elif key == "X":
            if self.flow.killable:
                self.flow.kill(self.master)
        elif key == "enter":
            if self.flow.request:
                self.master.view_flow(self.flow)
        elif key == "|":
            signals.status_prompt_path.send(
                prompt="Send flow to script",
                callback=self.master.run_script_once,
                args=(self.flow, ))
        elif key == "E":
            signals.status_prompt_onekey.send(
                self,
                prompt="Export to file",
                keys=[(e[0], e[1]) for e in export.EXPORTERS],
                callback=common.export_to_clip_or_file,
                args=(None, self.flow, common.ask_save_path))
        elif key == "C":
            signals.status_prompt_onekey.send(
                self,
                prompt="Export to clipboard",
                keys=[(e[0], e[1]) for e in export.EXPORTERS],
                callback=common.export_to_clip_or_file,
                args=(None, self.flow, common.copy_to_clipboard_or_prompt))
        elif key == "b":
            common.ask_save_body(None, self.flow)
        else:
            return key
Esempio n. 15
0
    def keypress(self, size, key):
        conn = None  # type: Optional[Union[models.HTTPRequest, models.HTTPResponse]]
        if self.tab_offset == TAB_REQ:
            conn = self.flow.request
        elif self.tab_offset == TAB_RESP:
            conn = self.flow.response

        key = super(self.__class__, self).keypress(size, key)

        # Special case: Space moves over to the next flow.
        # We need to catch that before applying common.shortcuts()
        if key == " ":
            self.view_next_flow(self.flow)
            return

        key = common.shortcuts(key)
        if key in ("up", "down", "page up", "page down"):
            # Pass scroll events to the wrapped widget
            self._w.keypress(size, key)
        elif key == "a":
            self.flow.accept_intercept(self.master)
            signals.flow_change.send(self, flow = self.flow)
        elif key == "A":
            self.master.accept_all()
            signals.flow_change.send(self, flow = self.flow)
        elif key == "d":
            if self.state.flow_count() == 1:
                self.master.view_flowlist()
            elif self.state.view.index(self.flow) == len(self.state.view) - 1:
                self.view_prev_flow(self.flow)
            else:
                self.view_next_flow(self.flow)
            f = self.flow
            if f.killable:
                f.kill(self.master)
            self.state.delete_flow(f)
        elif key == "D":
            f = self.master.duplicate_flow(self.flow)
            signals.pop_view_state.send(self)
            self.master.view_flow(f)
            signals.status_message.send(message="Duplicated.")
        elif key == "p":
            self.view_prev_flow(self.flow)
        elif key == "r":
            try:
                self.master.replay_request(self.flow)
            except exceptions.ReplayException as e:
                signals.add_log("Replay error: %s" % e, "warn")
            signals.flow_change.send(self, flow = self.flow)
        elif key == "V":
            if self.flow.modified():
                self.state.revert(self.flow)
                signals.flow_change.send(self, flow = self.flow)
                signals.status_message.send(message="Reverted.")
            else:
                signals.status_message.send(message="Flow not modified.")
        elif key == "W":
            signals.status_prompt_path.send(
                prompt = "Save this flow",
                callback = self.master.save_one_flow,
                args = (self.flow,)
            )
        elif key == "|":
            signals.status_prompt_path.send(
                prompt = "Send flow to script",
                callback = self.master.run_script_once,
                args = (self.flow,)
            )
        elif key == "e":
            self.flow = common.add_key_log(self.flow, key)
            if self.tab_offset == TAB_REQ:

                signals.status_prompt_onekey.send(
                    prompt="Edit request",
                    keys=(
                        ("cookies", "c"),
                        ("query", "q"),
                        ("path", "p"),
                        ("url", "u"),
                        ("header", "h"),
                        ("form", "f"),
                        ("raw body", "r"),
                        ("method", "m"),
                    ),
                    callback=self.edit
                )
            elif self.tab_offset == TAB_RESP:
                signals.status_prompt_onekey.send(
                    prompt="Edit response",
                    keys=(
                        ("cookies", "c"),
                        ("code", "o"),
                        ("message", "m"),
                        ("header", "h"),
                        ("raw body", "r"),
                    ),
                    callback=self.edit
                )
            else:
                signals.status_message.send(
                    message="Tab to the request or response",
                    expire=1
                )
        elif key in set("bfgmxvzEC") and not conn:
            signals.status_message.send(
                message = "Tab to the request or response",
                expire = 1
            )
            return
        elif key == "b":
            if self.tab_offset == TAB_REQ:
                common.ask_save_body("q", self.flow)
            else:
                common.ask_save_body("s", self.flow)
        elif key == "f":
            signals.status_message.send(message="Loading all body data...")
            self.state.add_flow_setting(
                self.flow,
                (self.tab_offset, "fullcontents"),
                True
            )
            signals.flow_change.send(self, flow = self.flow)
            signals.status_message.send(message="")
        elif key == "m":
            p = list(contentviews.view_prompts)
            p.insert(0, ("Clear", "C"))
            signals.status_prompt_onekey.send(
                self,
                prompt = "Display mode",
                keys = p,
                callback = self.change_this_display_mode
            )
        elif key == "E":
            if self.tab_offset == TAB_REQ:
                scope = "q"
            else:
                scope = "s"
            signals.status_prompt_onekey.send(
                self,
                prompt = "Export to file",
                keys = [(e[0], e[1]) for e in export.EXPORTERS],
                callback = common.export_to_clip_or_file,
                args = (scope, self.flow, common.ask_save_path)
            )
        elif key == "C":
            if self.tab_offset == TAB_REQ:
                scope = "q"
            else:
                scope = "s"
            signals.status_prompt_onekey.send(
                self,
                prompt = "Export to clipboard",
                keys = [(e[0], e[1]) for e in export.EXPORTERS],
                callback = common.export_to_clip_or_file,
                args = (scope, self.flow, common.copy_to_clipboard_or_prompt)
            )
        elif key == "x":
            conn.content = None
            signals.flow_change.send(self, flow=self.flow)
        elif key == "v":
            if conn.raw_content:
                t = conn.headers.get("content-type")
                if "EDITOR" in os.environ or "PAGER" in os.environ:
                    self.master.spawn_external_viewer(conn.get_content(strict=False), t)
                else:
                    signals.status_message.send(
                        message = "Error! Set $EDITOR or $PAGER."
                    )
        elif key == "z":
            self.flow.backup()
            e = conn.headers.get("content-encoding", "identity")
            if e != "identity":
                try:
                    conn.decode()
                except ValueError:
                    signals.status_message.send(
                        message = "Could not decode - invalid data?"
                    )
            else:
                signals.status_prompt_onekey.send(
                    prompt = "Select encoding: ",
                    keys = (
                        ("gzip", "z"),
                        ("deflate", "d"),
                        ("brotli", "b"),
                    ),
                    callback = self.encode_callback,
                    args = (conn,)
                )
            signals.flow_change.send(self, flow = self.flow)
        else:
            # Key is not handled here.
            return key
Esempio n. 16
0
    def _get_content_view(self, message, viewmode, max_lines, _):

        try:
            content = message.content
            if content != message.raw_content:
                enc = "[decoded {}]".format(
                    message.headers.get("content-encoding"))
            else:
                enc = None
        except ValueError:
            content = message.raw_content
            enc = "[cannot decode]"
        try:
            query = None
            if isinstance(message, models.HTTPRequest):
                query = message.query
            description, lines = contentviews.get_content_view(
                viewmode, content, headers=message.headers, query=query)
        except exceptions.ContentViewException:
            s = "Content viewer failed: \n" + traceback.format_exc()
            signals.add_log(s, "error")
            description, lines = contentviews.get_content_view(
                contentviews.get("Raw"), content, headers=message.headers)
            description = description.replace(
                "Raw", "Couldn't parse: falling back to Raw")

        if enc:
            description = " ".join([enc, description])

        # Give hint that you have to tab for the response.
        if description == "No content" and isinstance(message,
                                                      models.HTTPRequest):
            description = "No request content (press tab to view response)"

        # If the users has a wide terminal, he gets fewer lines; this should not be an issue.
        chars_per_line = 80
        max_chars = max_lines * chars_per_line
        total_chars = 0
        text_objects = []
        for line in lines:
            txt = []
            for (style, text) in line:
                if total_chars + len(text) > max_chars:
                    text = text[:max_chars - total_chars]
                txt.append((style, text))
                total_chars += len(text)
                if total_chars == max_chars:
                    break

            # round up to the next line.
            total_chars = int(
                math.ceil(total_chars / chars_per_line) * chars_per_line)

            text_objects.append(urwid.Text(txt))
            if total_chars == max_chars:
                text_objects.append(
                    urwid.Text([
                        ("highlight",
                         "Stopped displaying data after %d lines. Press " %
                         max_lines), ("key", "f"),
                        ("highlight", " to load all data.")
                    ]))
                break

        return description, text_objects
Esempio n. 17
0
    def _get_content_view(self, message, viewmode, max_lines, _):

        try:
            content = message.content
            if content != message.raw_content:
                enc = "[decoded {}]".format(
                    message.headers.get("content-encoding")
                )
            else:
                enc = None
        except ValueError:
            content = message.raw_content
            enc = "[cannot decode]"
        try:
            query = None
            if isinstance(message, models.HTTPRequest):
                query = message.query
            description, lines = contentviews.get_content_view(
                viewmode, content, headers=message.headers, query=query
            )
        except exceptions.ContentViewException:
            s = "Content viewer failed: \n" + traceback.format_exc()
            signals.add_log(s, "error")
            description, lines = contentviews.get_content_view(
                contentviews.get("Raw"), content, headers=message.headers
            )
            description = description.replace("Raw", "Couldn't parse: falling back to Raw")

        if enc:
            description = " ".join([enc, description])

        # Give hint that you have to tab for the response.
        if description == "No content" and isinstance(message, models.HTTPRequest):
            description = "No request content (press tab to view response)"

        # If the users has a wide terminal, he gets fewer lines; this should not be an issue.
        chars_per_line = 80
        max_chars = max_lines * chars_per_line
        total_chars = 0
        text_objects = []
        for line in lines:
            txt = []
            for (style, text) in line:
                if total_chars + len(text) > max_chars:
                    text = text[:max_chars - total_chars]
                txt.append((style, text))
                total_chars += len(text)
                if total_chars == max_chars:
                    break

            # round up to the next line.
            total_chars = int(math.ceil(total_chars / chars_per_line) * chars_per_line)

            text_objects.append(urwid.Text(txt))
            if total_chars == max_chars:
                text_objects.append(urwid.Text([
                    ("highlight", "Stopped displaying data after %d lines. Press " % max_lines),
                    ("key", "f"),
                    ("highlight", " to load all data.")
                ]))
                break

        return description, text_objects
Esempio n. 18
0
    def keypress(self, xxx_todo_changeme, key):
        (maxcol,) = xxx_todo_changeme
        key = common.shortcuts(key)

        # Test keys are number 1 to 6, flow must me marked before run test on it.
        if key == "1":
            for f in self.state.flows:
                if f.marked:
                    f.authentication = self.test_authentication(f)
                    signals.flowlist_change.send(self)

        if key == "2":
            for f in self.state.flows:
                if f.marked:
                    f.authentication = self.gather_authentication_result(f)
                    signals.flowlist_change.send(self)

        if key == "3":
            cnt = 1
            for f in self.state.flows:
                if f.marked:
                    f.authorization = self.test_authorization(f)
                    signals.flowlist_change.send(self)

        if key == "4":
            for f in self.state.flows:
                if f.marked:
                    f.authorization = self.gather_authorization_result(f)
                    signals.flowlist_change.send(self)

        # payu salt in req or resp
        if key == "5":
            for f in self.state.flows:
                if f.marked:
                    f.payu_salt_leak = self.test_payu_salt_leak(f)
                    signals.flowlist_change.send(self) 

        # otp in resp
        if key == "6":
            for f in self.state.flows:
                if f.marked:
                    f.otp_leak = self.test_otp_leak(f)
                    signals.flowlist_change.send(self)


        if key == "R":
            self.master.repeater(self.flow)
            signals.status_message.send(message="Repeating request 64 times")
            signals.flowlist_change.send(self)
        if key == "a":
            self.flow.accept_intercept(self.master)
            signals.flowlist_change.send(self)
        elif key == "d":
            if self.flow.killable:
                self.flow.kill(self.master)
            self.state.delete_flow(self.flow)
            signals.flowlist_change.send(self)
        elif key == "D":
            f = self.master.duplicate_flow(self.flow)
            self.master.state.set_focus_flow(f)
            signals.flowlist_change.send(self)
        elif key == "f1":
            self.flow.authentication += 1
            self.flow.authentication %= 3
            signals.flowlist_change.send(self)
        elif key == "f2":
            self.flow.authorization += 1
            self.flow.authorization %= 3
            signals.flowlist_change.send(self)
        elif key == "f3":
            self.flow.payu_salt_leak += 1
            self.flow.payu_salt_leak %= 3
            signals.flowlist_change.send(self)
        elif key == "f4":
            self.flow.otp_leak += 1
            self.flow.otp_leak %= 3
            signals.flowlist_change.send(self)
        elif key == "u":
            for f in self.master.state.view:
                f.marked = not f.marked
            signals.flowlist_change.send(self)
        elif key == "m":
            self.flow.marked = not self.flow.marked
            signals.flowlist_change.send(self)
        elif key == "M":
            if self.state.mark_filter:
                self.state.disable_marked_filter()
            else:
                self.state.enable_marked_filter()
            signals.flowlist_change.send(self)
        elif key == "N":

            self.state.set_view_filter("!(.gif) & !(.js) & !(.css) & !(.ttf) & !(.png) & !(.svg) & !(gstatic) & !(.ico) & !(.jpg) & !(.jpeg) & !(.woff) & !(.woff2) & !(fbcdn) & !(google) & !(facebook)")
            signals.flowlist_change.send(self)
        elif key == "v":
            self.state.set_view_filter("")
            signals.flowlist_change.send(self)
        elif key == "r":
            try:
                self.master.replay_request(self.flow)
            except exceptions.ReplayException as e:
                signals.add_log("Replay error: %s" % e, "warn")
            signals.flowlist_change.send(self)
        elif key == "S":
            def stop_server_playback(response):
                if response == "y":
                    self.master.options.server_replay = []
            a = self.master.addons.get("serverplayback")
            if a.count():
                signals.status_prompt_onekey.send(
                    prompt = "Stop current server replay?",
                    keys = (
                        ("yes", "y"),
                        ("no", "n"),
                    ),
                    callback = stop_server_playback,
                )
            else:
                signals.status_prompt_onekey.send(
                    prompt = "Server Replay",
                    keys = (
                        ("all flows", "a"),
                        ("this flow", "t"),
                    ),
                    callback = self.server_replay_prompt,
                )
        elif key == "U":
            for f in self.state.flows:
                f.marked = False
            signals.flowlist_change.send(self)
        elif key == "V":
            if not self.flow.modified():
                signals.status_message.send(message="Flow not modified.")
                return
            self.state.revert(self.flow)
            signals.flowlist_change.send(self)
            signals.status_message.send(message="Reverted.")
        elif key == "w":
            signals.status_prompt_onekey.send(
                self,
                prompt = "Save",
                keys = (("listed flows as swagger", "s"),
                    ("listed flows as report", "r"),
                    ("listed flows as har", "h"),
                    ("listed flows", "l"),
                    ("this flow", "t"),
                ),
                callback = self.save_flows_prompt,
            )
        elif key == "X":
            if self.flow.killable:
                self.flow.kill(self.master)
        elif key == "z":
            # create a copy since used in for loop
            copy_of_state_view = self.state.view[:]
            for f in copy_of_state_view:
                signals.add_log("Len of state.view %d " % len(self.state.view), level="info")
                if f.killable:
                    f.kill(self.master)
                self.state.delete_flow(f)
            signals.flowlist_change.send(self)
        elif key == "enter":
            if self.flow.request:
                self.flow = common.add_key_log(self.flow, "enter")
                signals.flowlist_change.send(self)
                self.master.view_flow(self.flow)
        elif key == "|":
            signals.status_prompt_path.send(
                prompt = "Send flow to script",
                callback = self.master.run_script_once,
                args = (self.flow,)
            )
        elif key == "E":
            signals.status_prompt_onekey.send(
                self,
                prompt = "Export to file",
                keys = [(e[0], e[1]) for e in export.EXPORTERS],
                callback = common.export_to_clip_or_file,
                args = (None, self.flow, common.ask_save_path)
            )
        elif key == "C":
            signals.status_prompt_onekey.send(
                self,
                prompt = "Export to clipboard",
                keys = [(e[0], e[1]) for e in export.EXPORTERS],
                callback = common.export_to_clip_or_file,
                args = (None, self.flow, common.copy_to_clipboard_or_prompt)
            )
        elif key == "b":
            common.ask_save_body(None, self.flow)
        else:
            return key
Esempio n. 19
0
    def keypress(self, size, key):
        conn = None  # type: Optional[Union[models.HTTPRequest, models.HTTPResponse]]
        if self.tab_offset == TAB_REQ:
            conn = self.flow.request
        elif self.tab_offset == TAB_RESP:
            conn = self.flow.response

        key = super().keypress(size, key)

        # Special case: Space moves over to the next flow.
        # We need to catch that before applying common.shortcuts()
        if key == " ":
            self.view_next_flow(self.flow)
            return

        key = common.shortcuts(key)
        if key in ("up", "down", "page up", "page down"):
            # Pass scroll events to the wrapped widget
            self._w.keypress(size, key)
        elif key == "a":
            self.flow.resume(self.master)
            signals.flow_change.send(self, flow = self.flow)
        elif key == "A":
            self.master.accept_all()
            signals.flow_change.send(self, flow = self.flow)
        elif key == "d":
            if self.state.flow_count() == 1:
                self.master.view_flowlist()
            elif self.state.view.index(self.flow) == len(self.state.view) - 1:
                self.view_prev_flow(self.flow)
            else:
                self.view_next_flow(self.flow)
            f = self.flow
            if f.killable:
                f.kill(self.master)
            self.state.delete_flow(f)
        elif key == "D":
            f = self.master.state.duplicate_flow(self.flow)
            signals.pop_view_state.send(self)
            self.master.view_flow(f)
            signals.status_message.send(message="Duplicated.")
        elif key == "p":
            self.view_prev_flow(self.flow)
        elif key == "r":
            try:
                self.master.replay_request(self.flow)
            except exceptions.ReplayException as e:
                signals.add_log("Replay error: %s" % e, "warn")
            signals.flow_change.send(self, flow = self.flow)
        elif key == "V":
            if self.flow.modified():
                self.state.revert(self.flow)
                signals.flow_change.send(self, flow = self.flow)
                signals.status_message.send(message="Reverted.")
            else:
                signals.status_message.send(message="Flow not modified.")
        elif key == "W":
            signals.status_prompt_path.send(
                prompt = "Save this flow",
                callback = self.master.save_one_flow,
                args = (self.flow,)
            )
        elif key == "|":
            signals.status_prompt_path.send(
                prompt = "Send flow to script",
                callback = self.master.run_script_once,
                args = (self.flow,)
            )
        elif key == "e":
            if self.tab_offset == TAB_REQ:
                signals.status_prompt_onekey.send(
                    prompt="Edit request",
                    keys=(
                        ("cookies", "c"),
                        ("query", "q"),
                        ("path", "p"),
                        ("url", "u"),
                        ("header", "h"),
                        ("form", "f"),
                        ("raw body", "r"),
                        ("method", "m"),
                    ),
                    callback=self.edit
                )
            elif self.tab_offset == TAB_RESP:
                signals.status_prompt_onekey.send(
                    prompt="Edit response",
                    keys=(
                        ("cookies", "c"),
                        ("code", "o"),
                        ("message", "m"),
                        ("header", "h"),
                        ("raw body", "r"),
                    ),
                    callback=self.edit
                )
            else:
                signals.status_message.send(
                    message="Tab to the request or response",
                    expire=1
                )
        elif key in set("bfgmxvzEC") and not conn:
            signals.status_message.send(
                message = "Tab to the request or response",
                expire = 1
            )
            return
        elif key == "b":
            if self.tab_offset == TAB_REQ:
                common.ask_save_body("q", self.flow)
            else:
                common.ask_save_body("s", self.flow)
        elif key == "f":
            signals.status_message.send(message="Loading all body data...")
            self.state.add_flow_setting(
                self.flow,
                (self.tab_offset, "fullcontents"),
                True
            )
            signals.flow_change.send(self, flow = self.flow)
            signals.status_message.send(message="")
        elif key == "m":
            p = list(contentviews.view_prompts)
            p.insert(0, ("Clear", "C"))
            signals.status_prompt_onekey.send(
                self,
                prompt = "Display mode",
                keys = p,
                callback = self.change_this_display_mode
            )
        elif key == "E":
            if self.tab_offset == TAB_REQ:
                scope = "q"
            else:
                scope = "s"
            signals.status_prompt_onekey.send(
                self,
                prompt = "Export to file",
                keys = [(e[0], e[1]) for e in export.EXPORTERS],
                callback = common.export_to_clip_or_file,
                args = (scope, self.flow, common.ask_save_path)
            )
        elif key == "C":
            if self.tab_offset == TAB_REQ:
                scope = "q"
            else:
                scope = "s"
            signals.status_prompt_onekey.send(
                self,
                prompt = "Export to clipboard",
                keys = [(e[0], e[1]) for e in export.EXPORTERS],
                callback = common.export_to_clip_or_file,
                args = (scope, self.flow, common.copy_to_clipboard_or_prompt)
            )
        elif key == "x":
            conn.content = None
            signals.flow_change.send(self, flow=self.flow)
        elif key == "v":
            if conn.raw_content:
                t = conn.headers.get("content-type")
                if "EDITOR" in os.environ or "PAGER" in os.environ:
                    self.master.spawn_external_viewer(conn.get_content(strict=False), t)
                else:
                    signals.status_message.send(
                        message = "Error! Set $EDITOR or $PAGER."
                    )
        elif key == "z":
            self.flow.backup()
            e = conn.headers.get("content-encoding", "identity")
            if e != "identity":
                try:
                    conn.decode()
                except ValueError:
                    signals.status_message.send(
                        message = "Could not decode - invalid data?"
                    )
            else:
                signals.status_prompt_onekey.send(
                    prompt = "Select encoding: ",
                    keys = (
                        ("gzip", "z"),
                        ("deflate", "d"),
                        ("brotli", "b"),
                    ),
                    callback = self.encode_callback,
                    args = (conn,)
                )
            signals.flow_change.send(self, flow = self.flow)
        else:
            # Key is not handled here.
            return key