Example #1
0
 def filtexp(self):
     text = []
     text.extend(common.format_keyvals(flowfilter.help, indent=4))
     text.append(
         urwid.Text(
             [
                 "\n",
                 ("text", "    Regexes are Python-style.\n"),
                 ("text", "    Regexes can be specified as quoted strings.\n"),
                 ("text", "    Header matching (~h, ~hq, ~hs) is against a string of the form \"name: value\".\n"),
                 ("text", "    Expressions with no operators are regex matches against URL.\n"),
                 ("text", "    Default binary operator is &.\n"),
                 ("head", "\n    Examples:\n"),
             ]
         )
     )
     examples = [
         (r"google\.com", r"Url containing \"google.com"),
         ("~q ~b test", r"Requests where body contains \"test\""),
         (r"!(~q & ~t \"text/html\")", "Anything but requests with a text/html content type."),
     ]
     text.extend(
         common.format_keyvals(examples, indent=4)
     )
     return CListBox(text)
Example #2
0
 def filtexp(self):
     text = []
     text.extend(common.format_keyvals(flowfilter.help, indent=4))
     text.append(
         urwid.Text(
             [
                 "\n",
                 ("text", "    Regexes are Python-style.\n"),
                 ("text", "    Regexes can be specified as quoted strings.\n"),
                 ("text", "    Header matching (~h, ~hq, ~hs) is against a string of the form \"name: value\".\n"),
                 ("text", "    Expressions with no operators are regex matches against URL.\n"),
                 ("text", "    Default binary operator is &.\n"),
                 ("head", "\n    Examples:\n"),
             ]
         )
     )
     examples = [
         (r"google\.com", r"Url containing \"google.com"),
         ("~q ~b test", r"Requests where body contains \"test\""),
         (r"!(~q & ~t \"text/html\")", "Anything but requests with a text/html content type."),
     ]
     text.extend(
         common.format_keyvals(examples, indent=4)
     )
     return CListBox(text)
Example #3
0
    def helptext(self):
        text = []
        text.append(urwid.Text([("head", "This view:\n")]))
        text.extend(self.help_context)

        text.append(urwid.Text([("head", "\n\nMovement:\n")]))
        keys = [
            ("j, k", "down, up"),
            ("h, l", "left, right (in some contexts)"),
            ("g, G", "go to beginning, end"),
            ("space", "page down"),
            ("pg up/down", "page up/down"),
            ("ctrl+b/ctrl+f", "page up/down"),
            ("arrows", "up, down, left, right"),
        ]
        text.extend(
            common.format_keyvals(
                keys,
                key="key",
                val="text",
                indent=4))

        text.append(urwid.Text([("head", "\n\nGlobal keys:\n")]))
        keys = [
            ("i", "set interception pattern"),
            ("O", "options"),
            ("q", "quit / return to previous page"),
            ("Q", "quit without confirm prompt"),
            ("R", "replay of requests/responses from file"),
        ]
        text.extend(
            common.format_keyvals(keys, key="key", val="text", indent=4)
        )

        text.append(urwid.Text([("head", "\n\nFilter expressions:\n")]))
        text.extend(common.format_keyvals(flowfilter.help, key="key", val="text", indent=4))

        text.append(
            urwid.Text(
                [
                    "\n",
                    ("text", "    Regexes are Python-style.\n"),
                    ("text", "    Regexes can be specified as quoted strings.\n"),
                    ("text", "    Header matching (~h, ~hq, ~hs) is against a string of the form \"name: value\".\n"),
                    ("text", "    Expressions with no operators are regex matches against URL.\n"),
                    ("text", "    Default binary operator is &.\n"),
                    ("head", "\n    Examples:\n"),
                ]
            )
        )
        examples = [
            ("google\.com", "Url containing \"google.com"),
            ("~q ~b test", "Requests where body contains \"test\""),
            ("!(~q & ~t \"text/html\")", "Anything but requests with a text/html content type."),
        ]
        text.extend(
            common.format_keyvals(examples, key="key", val="text", indent=4)
        )
        return text
Example #4
0
    def helptext(self):
        text = []
        text.append(urwid.Text([("head", "This view:\n")]))
        text.extend(self.help_context)

        text.append(urwid.Text([("head", "\n\nMovement:\n")]))
        keys = [
            ("j, k", "down, up"),
            ("h, l", "left, right (in some contexts)"),
            ("g, G", "go to beginning, end"),
            ("space", "page down"),
            ("pg up/down", "page up/down"),
            ("ctrl+b/ctrl+f", "page up/down"),
            ("arrows", "up, down, left, right"),
        ]
        text.extend(
            common.format_keyvals(
                keys,
                key="key",
                val="text",
                indent=4))

        text.append(urwid.Text([("head", "\n\nGlobal keys:\n")]))
        keys = [
            ("i", "set interception pattern"),
            ("o", "options"),
            ("q", "quit / return to previous page"),
            ("Q", "quit without confirm prompt"),
            ("R", "replay of requests/responses from file"),
        ]
        text.extend(
            common.format_keyvals(keys, key="key", val="text", indent=4)
        )

        text.append(urwid.Text([("head", "\n\nFilter expressions:\n")]))
        text.extend(common.format_keyvals(flowfilter.help, key="key", val="text", indent=4))

        text.append(
            urwid.Text(
                [
                    "\n",
                    ("text", "    Regexes are Python-style.\n"),
                    ("text", "    Regexes can be specified as quoted strings.\n"),
                    ("text", "    Header matching (~h, ~hq, ~hs) is against a string of the form \"name: value\".\n"),
                    ("text", "    Expressions with no operators are regex matches against URL.\n"),
                    ("text", "    Default binary operator is &.\n"),
                    ("head", "\n    Examples:\n"),
                ]
            )
        )
        examples = [
            ("google\.com", "Url containing \"google.com"),
            ("~q ~b test", "Requests where body contains \"test\""),
            ("!(~q & ~t \"text/html\")", "Anything but requests with a text/html content type."),
        ]
        text.extend(
            common.format_keyvals(examples, key="key", val="text", indent=4)
        )
        return text
Example #5
0
def test_format_keyvals():
    assert common.format_keyvals([
        ("aa", "bb"),
        ("cc", "dd"),
        ("ee", None),
    ])
    wrapped = urwid.Pile(
        urwid.SimpleFocusListWalker(common.format_keyvals([("foo", "bar")])))
    assert wrapped.render((30, ))
    assert common.format_keyvals([("aa", wrapped)])
Example #6
0
    def conn_text(self, conn):
        if conn:
            txt = common.format_keyvals(
                [(h + ":", v) for (h, v) in conn.headers.items(multi=True)],
                key="header",
                val="text")
            viewmode = self.viewmode_get()
            msg, body = self.content_view(viewmode, conn)

            cols = [
                urwid.Text([
                    ("heading", msg),
                ]),
                urwid.Text([
                    " ",
                    ('heading', "["),
                    ('heading_key', "m"),
                    ('heading', (":%s]" % viewmode)),
                ],
                           align="right")
            ]
            title = urwid.AttrWrap(urwid.Columns(cols), "heading")

            txt.append(title)
            txt.extend(body)
        else:
            txt = [
                urwid.Text(""),
                urwid.Text([
                    ("highlight", "No response. Press "),
                    ("key", "e"),
                    ("highlight", " and edit any aspect to add one."),
                ])
            ]
        return searchable.Searchable(self.view, txt)
Example #7
0
def _mkhelp():
    text = []
    keys = [
        ("enter/space", "select"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #8
0
def _mkhelp():
    text = []
    keys = [
        ("enter/space", "select"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #9
0
def _mkhelp():
    text = []
    keys = [
        ("A", "accept all intercepted flows"),
        ("a", "accept this intercepted flow"),
        ("b", "save request/response body"),
        ("C", "export flow to clipboard"),
        ("d", "delete flow"),
        ("D", "duplicate flow"),
        ("e", "toggle eventlog"),
        ("E", "export flow to file"),
        ("f", "filter view"),
        ("F", "toggle follow flow list"),
        ("L", "load saved flows"),
        ("m", "toggle flow mark"),
        ("M", "toggle marked flow view"),
        ("n", "create a new request"),
        ("o", "set flow order"),
        ("r", "replay request"),
        ("S", "server replay request/s"),
        ("U", "unmark all marked flows"),
        ("v", "reverse flow order"),
        ("V", "revert changes to request"),
        ("w", "save flows "),
        ("W", "stream flows to file"),
        ("X", "kill and delete flow, even if it's mid-intercept"),
        ("z", "clear flow list or eventlog"),
        ("tab", "tab between eventlog and flow list"),
        ("enter", "view flow"),
        ("|", "run script on this flow"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #10
0
def _mkhelp():
    text = []
    keys = [
        ("enter", "execute command"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #11
0
 def make_help(self):
     text = [
         urwid.Text([("text", "Editor control:\n")])
     ]
     keys = [
         ("A", "insert row before cursor"),
         ("a", "add row after cursor"),
         ("d", "delete row"),
         ("e", "spawn external editor on current field"),
         ("q", "save changes and exit editor"),
         ("r", "read value from file"),
         ("R", "read unescaped value from file"),
         ("esc", "save changes and exit editor"),
         ("tab", "next field"),
         ("enter", "edit field"),
     ]
     text.extend(
         common.format_keyvals(keys, key="key", val="text", indent=4)
     )
     text.append(
         urwid.Text(
             [
                 "\n",
                 ("text", "Values are escaped Python-style strings.\n"),
             ]
         )
     )
     return text
Example #12
0
 def make_help(self):
     text = [
         urwid.Text([("text", "Editor control:\n")])
     ]
     keys = [
         ("A", "insert row before cursor"),
         ("a", "add row after cursor"),
         ("d", "delete row"),
         ("e", "spawn external editor on current field"),
         ("q", "save changes and exit editor"),
         ("r", "read value from file"),
         ("R", "read unescaped value from file"),
         ("esc", "save changes and exit editor"),
         ("tab", "next field"),
         ("enter", "edit field"),
     ]
     text.extend(
         common.format_keyvals(keys, key="key", val="text", indent=4)
     )
     text.append(
         urwid.Text(
             [
                 "\n",
                 ("text", "Values are escaped Python-style strings.\n"),
             ]
         )
     )
     return text
Example #13
0
def _mkhelp():
    text = []
    keys = [
        ("enter", "execute command"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #14
0
def _mkhelp():
    text = []
    keys = [
        ("A", "accept all intercepted flows"),
        ("a", "accept this intercepted flow"),
        ("b", "save request/response body"),
        ("C", "export flow to clipboard"),
        ("d", "delete flow"),
        ("D", "duplicate flow"),
        ("e", "toggle eventlog"),
        ("E", "export flow to file"),
        ("f", "filter view"),
        ("F", "toggle follow flow list"),
        ("L", "load saved flows"),
        ("m", "toggle flow mark"),
        ("M", "toggle marked flow view"),
        ("n", "create a new request"),
        ("o", "set flow order"),
        ("r", "replay request"),
        ("S", "server replay request/s"),
        ("U", "unmark all marked flows"),
        ("v", "reverse flow order"),
        ("V", "revert changes to request"),
        ("w", "save flows "),
        ("W", "stream flows to file"),
        ("X", "kill and delete flow, even if it's mid-intercept"),
        ("z", "clear flow list or eventlog"),
        ("tab", "tab between eventlog and flow list"),
        ("enter", "view flow"),
        ("|", "run script on this flow"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #15
0
 def format_keys(self, binds):
     kvs = []
     for b in binds:
         k = b.key
         if b.key == " ":
             k = "space"
         kvs.append((k, b.help or b.command))
     return common.format_keyvals(kvs)
Example #16
0
def _mkhelp():
    text = []
    keys = [
        ("enter/space", "activate option"),
        ("C", "clear all options"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #17
0
 def make_help(self):
     text = []
     keys = [
         ("enter", "choose option"),
         ("esc", "exit chooser"),
     ]
     text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
     return text
Example #18
0
def test_format_keyvals():
    assert common.format_keyvals([
        ("aa", "bb"),
        None,
        ("cc", "dd"),
        (None, "dd"),
        (None, "dd"),
    ])
Example #19
0
 def make_help(self):
     text = []
     keys = [
         ("enter", "choose option"),
         ("esc", "exit chooser"),
     ]
     text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
     return text
Example #20
0
 def format_keys(self, binds):
     kvs = []
     for b in binds:
         k = b.key
         if b.key == " ":
             k = "space"
         kvs.append((k, b.help or b.command))
     return common.format_keyvals(kvs)
Example #21
0
def _mkhelp():
    text = []
    keys = [
        ("enter/space", "activate option"),
        ("C", "clear all options"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #22
0
def test_format_keyvals():
    assert common.format_keyvals(
        [
            ("aa", "bb"),
            None,
            ("cc", "dd"),
            (None, "dd"),
            (None, "dd"),
        ]
    )
Example #23
0
def _mkhelp():
    text = []
    keys = [
        ("enter", "edit option"),
        ("D", "reset all to defaults"),
        ("d", "reset this option to default"),
        ("l", "load options from file"),
        ("w", "save options to file"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #24
0
    def conn_text(self, conn):
        if conn:
            hdrs = []
            for k, v in conn.headers.fields:
                # This will always force an ascii representation of headers. For example, if the server sends a
                #
                #     X-Authors: Made with ❤ in Hamburg
                #
                # header, mitmproxy will display the following:
                #
                #     X-Authors: Made with \xe2\x9d\xa4 in Hamburg.
                #
                # The alternative would be to just use the header's UTF-8 representation and maybe
                # do `str.replace("\t", "\\t")` to exempt tabs from urwid's special characters escaping [1].
                # That would in some terminals allow rendering UTF-8 characters, but the mapping
                # wouldn't be bijective, i.e. a user couldn't distinguish "\\t" and "\t".
                # Also, from a security perspective, a mitmproxy user couldn't be fooled by homoglyphs.
                #
                # 1) https://github.com/mitmproxy/mitmproxy/issues/1833
                #    https://github.com/urwid/urwid/blob/6608ee2c9932d264abd1171468d833b7a4082e13/urwid/display_common.py#L35-L36,

                k = strutils.bytes_to_escaped_str(k) + ":"
                v = strutils.bytes_to_escaped_str(v)
                hdrs.append((k, v))
            txt = common.format_keyvals(hdrs, key_format="header")
            viewmode = self.master.commands.call("console.flowview.mode")
            msg, body = self.content_view(viewmode, conn)

            cols = [
                urwid.Text([
                    ("heading", msg),
                ]),
                urwid.Text([
                    " ",
                    ('heading', "["),
                    ('heading_key', "m"),
                    ('heading', (":%s]" % viewmode)),
                ],
                           align="right")
            ]
            title = urwid.AttrWrap(urwid.Columns(cols), "heading")

            txt.append(title)
            txt.extend(body)
        else:
            txt = [
                urwid.Text(""),
                urwid.Text([
                    ("highlight", "No response. Press "),
                    ("key", "e"),
                    ("highlight", " and edit any aspect to add one."),
                ])
            ]
        return searchable.Searchable(txt)
Example #25
0
 def make_help(self):
     h = super().make_help()
     text = [urwid.Text([("text", "Special keys:\n")])]
     keys = [
         ("U", "add User-Agent header"),
     ]
     text.extend(
         common.format_keyvals(keys, key="key", val="text", indent=4))
     text.append(urwid.Text([("text", "\n")]))
     text.extend(h)
     return text
Example #26
0
def _mkhelp():
    text = []
    keys = [
        ("enter", "edit option"),
        ("D", "reset all to defaults"),
        ("d", "reset this option to default"),
        ("l", "load options from file"),
        ("w", "save options to file"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #27
0
def test_format_keyvals():
    assert common.format_keyvals(
        [
            ("aa", "bb"),
            ("cc", "dd"),
            ("ee", None),
        ]
    )
    wrapped = urwid.BoxAdapter(
        urwid.ListBox(
            urwid.SimpleFocusListWalker(
                common.format_keyvals([("foo", "bar")])
            )
        ), 1
    )
    assert wrapped.render((30, ))
    assert common.format_keyvals(
        [
            ("aa", wrapped)
        ]
    )
Example #28
0
 def make_help(self):
     h = super().make_help()
     text = [
         urwid.Text([("text", "Special keys:\n")])
     ]
     keys = [
         ("U", "add User-Agent header"),
     ]
     text.extend(
         common.format_keyvals(keys, key="key", val="text", indent=4)
     )
     text.append(urwid.Text([("text", "\n")]))
     text.extend(h)
     return text
Example #29
0
def _mkhelp():
    text = []
    keys = [
        ("A", "accept all intercepted flows"),
        ("a", "accept this intercepted flow"),
        ("b", "save request/response body"),
        ("C", "export flow to clipboard"),
        ("D", "duplicate flow"),
        ("d", "delete flow"),
        ("e", "edit request/response"),
        ("f", "load full body data"),
        ("m",
         "change body display mode for this entity\n(default mode can be changed in the options)"
         ),
        (None, common.highlight_key("automatic", "a") +
         [("text", ": automatic detection")]),
        (None, common.highlight_key("hex", "e") + [("text", ": Hex")]),
        (None, common.highlight_key("html", "h") + [("text", ": HTML")]),
        (None, common.highlight_key("image", "i") + [("text", ": Image")]),
        (None,
         common.highlight_key("javascript", "j") + [("text", ": JavaScript")]),
        (None, common.highlight_key("json", "s") + [("text", ": JSON")]),
        (None, common.highlight_key("urlencoded", "u") +
         [("text", ": URL-encoded data")]),
        (None, common.highlight_key("raw", "r") + [("text", ": raw data")]),
        (None, common.highlight_key("xml", "x") + [("text", ": XML")]),
        ("E", "export flow to file"),
        ("r", "replay request"),
        ("V", "revert changes to request"),
        ("v", "view body in external viewer"),
        ("w", "save all flows matching current view filter"),
        ("W", "save this flow"),
        ("x", "delete body"),
        ("z", "encode/decode a request/response"),
        ("tab", "next tab"),
        ("h, l", "previous tab, next tab"),
        ("space", "next flow"),
        ("|", "run script on this flow"),
        ("/", "search (case sensitive)"),
        ("n", "repeat search forward"),
        ("N", "repeat search backwards"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #30
0
    def conn_text(self, conn):
        if conn:
            txt = common.format_keyvals(
                [(h + ":", v) for (h, v) in conn.headers.items(multi=True)],
                key = "header",
                val = "text"
            )
            viewmode = self.viewmode_get()
            msg, body = self.content_view(viewmode, conn)

            cols = [
                urwid.Text(
                    [
                        ("heading", msg),
                    ]
                ),
                urwid.Text(
                    [
                        " ",
                        ('heading', "["),
                        ('heading_key', "m"),
                        ('heading', (":%s]" % viewmode)),
                    ],
                    align="right"
                )
            ]
            title = urwid.AttrWrap(urwid.Columns(cols), "heading")

            txt.append(title)
            txt.extend(body)
        else:
            txt = [
                urwid.Text(""),
                urwid.Text(
                    [
                        ("highlight", "No response. Press "),
                        ("key", "e"),
                        ("highlight", " and edit any aspect to add one."),
                    ]
                )
            ]
        return searchable.Searchable(self.view, txt)
Example #31
0
    def conn_text(self, conn, flowtype):
        _conn = conn
        if flowtype is FlowType.Request:
            conn = conn.request
        else:
            conn = conn.response
        if conn:
            txt = common.format_keyvals(
                [(h + ":", v) for (h, v) in conn.headers.items(multi=True)],
                key="header",
                val="text")
            viewmode = self.master.commands.call("console.flowview.mode")
            msg, body = self.content_view(viewmode, _conn, flowtype)

            cols = [
                urwid.Text([
                    ("heading", msg),
                ]),
                urwid.Text([
                    " ",
                    ('heading', "["),
                    ('heading_key', "m"),
                    ('heading', (":%s]" % viewmode)),
                ],
                           align="right")
            ]
            title = urwid.AttrWrap(urwid.Columns(cols), "heading")

            txt.append(title)
            txt.extend(body)
        else:
            txt = [
                urwid.Text(""),
                urwid.Text([
                    ("highlight", "No response. Press "),
                    ("key", "e"),
                    ("highlight", " and edit any aspect to add one."),
                ])
            ]
        return searchable.Searchable(txt)
Example #32
0
def flowdetails(state, flow):
    text = []

    cc = flow.client_conn
    sc = flow.server_conn
    req = flow.request
    resp = flow.response

    if sc is not None:
        text.append(urwid.Text([("head", "Server Connection:")]))
        parts = [
            ["Address", repr(sc.address)],
            ["Resolved Address", repr(sc.ip_address)],
        ]

        text.extend(
            common.format_keyvals(parts, key="key", val="text", indent=4))

        c = sc.cert
        if c:
            text.append(urwid.Text([("head", "Server Certificate:")]))
            parts = [["Type", "%s, %s bits" % c.keyinfo],
                     ["SHA1 digest", c.digest("sha1")],
                     ["Valid to", str(c.notafter)],
                     ["Valid from", str(c.notbefore)],
                     ["Serial", str(c.serial)],
                     [
                         "Subject",
                         urwid.BoxAdapter(
                             urwid.ListBox(
                                 common.format_keyvals(c.subject,
                                                       key="highlight",
                                                       val="text")),
                             len(c.subject))
                     ],
                     [
                         "Issuer",
                         urwid.BoxAdapter(
                             urwid.ListBox(
                                 common.format_keyvals(c.issuer,
                                                       key="highlight",
                                                       val="text")),
                             len(c.issuer))
                     ]]

            if c.altnames:
                parts.append(
                    ["Alt names", ", ".join(str(x) for x in c.altnames)])
            text.extend(
                common.format_keyvals(parts, key="key", val="text", indent=4))

    if cc is not None:
        text.append(urwid.Text([("head", "Client Connection:")]))

        parts = [
            ["Address", repr(cc.address)],
        ]
        if cc.sni:
            parts.append(["Server Name Indication", cc.sni])

        text.extend(
            common.format_keyvals(parts, key="key", val="text", indent=4))

    parts = []

    if cc is not None and cc.timestamp_start:
        parts.append([
            "Client conn. established",
            maybe_timestamp(cc, "timestamp_start")
        ])
        if cc.ssl_established:
            parts.append([
                "Client conn. TLS handshake",
                maybe_timestamp(cc, "timestamp_ssl_setup")
            ])
    if sc is not None and sc.timestamp_start:
        parts.append(
            ["Server conn. initiated",
             maybe_timestamp(sc, "timestamp_start")])
        parts.append([
            "Server conn. TCP handshake",
            maybe_timestamp(sc, "timestamp_tcp_setup")
        ])
        if sc.ssl_established:
            parts.append([
                "Server conn. TLS handshake",
                maybe_timestamp(sc, "timestamp_ssl_setup")
            ])
    if req is not None and req.timestamp_start:
        parts.append(
            ["First request byte",
             maybe_timestamp(req, "timestamp_start")])
        parts.append(
            ["Request complete",
             maybe_timestamp(req, "timestamp_end")])
    if resp is not None and resp.timestamp_start:
        parts.append(
            ["First response byte",
             maybe_timestamp(resp, "timestamp_start")])
        parts.append(
            ["Response complete",
             maybe_timestamp(resp, "timestamp_end")])

    if parts:
        # sort operations by timestamp
        parts = sorted(parts, key=lambda p: p[1])

        text.append(urwid.Text([("head", "Timing:")]))
        text.extend(
            common.format_keyvals(parts, key="key", val="text", indent=4))
    return searchable.Searchable(state, text)
Example #33
0
    def conn_text(self, conn):
        if conn:
            hdrs = []
            for k, v in conn.headers.fields:
                # This will always force an ascii representation of headers. For example, if the server sends a
                #
                #     X-Authors: Made with ❤ in Hamburg
                #
                # header, mitmproxy will display the following:
                #
                #     X-Authors: Made with \xe2\x9d\xa4 in Hamburg.
                #
                # The alternative would be to just use the header's UTF-8 representation and maybe
                # do `str.replace("\t", "\\t")` to exempt tabs from urwid's special characters escaping [1].
                # That would in some terminals allow rendering UTF-8 characters, but the mapping
                # wouldn't be bijective, i.e. a user couldn't distinguish "\\t" and "\t".
                # Also, from a security perspective, a mitmproxy user couldn't be fooled by homoglyphs.
                #
                # 1) https://github.com/mitmproxy/mitmproxy/issues/1833
                #    https://github.com/urwid/urwid/blob/6608ee2c9932d264abd1171468d833b7a4082e13/urwid/display_common.py#L35-L36,

                k = strutils.bytes_to_escaped_str(k) + ":"
                v = strutils.bytes_to_escaped_str(v)
                hdrs.append((k, v))
            txt = common.format_keyvals(
                hdrs,
                key_format="header"
            )
            viewmode = self.master.commands.call("console.flowview.mode")
            msg, body = self.content_view(viewmode, conn)

            cols = [
                urwid.Text(
                    [
                        ("heading", msg),
                    ]
                ),
                urwid.Text(
                    [
                        " ",
                        ('heading', "["),
                        ('heading_key', "m"),
                        ('heading', (":%s]" % viewmode)),
                    ],
                    align="right"
                )
            ]
            title = urwid.AttrWrap(urwid.Columns(cols), "heading")

            txt.append(title)
            txt.extend(body)
        else:
            txt = [
                urwid.Text(""),
                urwid.Text(
                    [
                        ("highlight", "No response. Press "),
                        ("key", "e"),
                        ("highlight", " and edit any aspect to add one."),
                    ]
                )
            ]
        return searchable.Searchable(txt)
Example #34
0
def flowdetails(state, flow: http.HTTPFlow):
    text = []

    sc = flow.server_conn
    cc = flow.client_conn
    req = flow.request
    resp = flow.response
    metadata = flow.metadata

    if metadata is not None and len(metadata) > 0:
        parts = [(str(k), repr(v)) for k, v in metadata.items()]
        text.append(urwid.Text([("head", "Metadata:")]))
        text.extend(common.format_keyvals(parts, indent=4))

    if sc is not None and sc.ip_address:
        text.append(urwid.Text([("head", "Server Connection:")]))
        parts = [
            ("Address", human.format_address(sc.address)),
        ]
        if sc.ip_address:
            parts.append(("Resolved Address", human.format_address(sc.ip_address)))
        if resp:
            parts.append(("HTTP Version", resp.http_version))
        if sc.alpn_proto_negotiated:
            parts.append(("ALPN", sc.alpn_proto_negotiated))

        text.extend(
            common.format_keyvals(parts, indent=4)
        )

        c = sc.cert
        if c:
            text.append(urwid.Text([("head", "Server Certificate:")]))
            parts = [
                ("Type", "%s, %s bits" % c.keyinfo),
                ("SHA1 digest", c.digest("sha1")),
                ("Valid to", str(c.notafter)),
                ("Valid from", str(c.notbefore)),
                ("Serial", str(c.serial)),
                (
                    "Subject",
                    urwid.BoxAdapter(
                        urwid.ListBox(
                            common.format_keyvals(
                                c.subject,
                                key_format="highlight"
                            )
                        ),
                        len(c.subject)
                    )
                ),
                (
                    "Issuer",
                    urwid.BoxAdapter(
                        urwid.ListBox(
                            common.format_keyvals(
                                c.issuer,
                                key_format="highlight"
                            )
                        ),
                        len(c.issuer)
                    )
                )
            ]

            if c.altnames:
                parts.append(
                    (
                        "Alt names",
                        ", ".join(strutils.bytes_to_escaped_str(x) for x in c.altnames)
                    )
                )
            text.extend(
                common.format_keyvals(parts, indent=4)
            )

    if cc is not None:
        text.append(urwid.Text([("head", "Client Connection:")]))

        parts = [
            ("Address", "{}:{}".format(cc.address[0], cc.address[1])),
        ]
        if req:
            parts.append(("HTTP Version", req.http_version))
        if cc.tls_version:
            parts.append(("TLS Version", cc.tls_version))
        if cc.sni:
            parts.append(("Server Name Indication", cc.sni))
        if cc.cipher_name:
            parts.append(("Cipher Name", cc.cipher_name))
        if cc.alpn_proto_negotiated:
            parts.append(("ALPN", cc.alpn_proto_negotiated))

        text.extend(
            common.format_keyvals(parts, indent=4)
        )

    parts = []

    if cc is not None and cc.timestamp_start:
        parts.append(
            (
                "Client conn. established",
                maybe_timestamp(cc, "timestamp_start")
            )
        )
        if cc.tls_established:
            parts.append(
                (
                    "Client conn. TLS handshake",
                    maybe_timestamp(cc, "timestamp_tls_setup")
                )
            )

    if sc is not None and sc.timestamp_start:
        parts.append(
            (
                "Server conn. initiated",
                maybe_timestamp(sc, "timestamp_start")
            )
        )
        parts.append(
            (
                "Server conn. TCP handshake",
                maybe_timestamp(sc, "timestamp_tcp_setup")
            )
        )
        if sc.tls_established:
            parts.append(
                (
                    "Server conn. TLS handshake",
                    maybe_timestamp(sc, "timestamp_tls_setup")
                )
            )

    if req is not None and req.timestamp_start:
        parts.append(
            (
                "First request byte",
                maybe_timestamp(req, "timestamp_start")
            )
        )
        parts.append(
            (
                "Request complete",
                maybe_timestamp(req, "timestamp_end")
            )
        )

    if resp is not None and resp.timestamp_start:
        parts.append(
            (
                "First response byte",
                maybe_timestamp(resp, "timestamp_start")
            )
        )
        parts.append(
            (
                "Response complete",
                maybe_timestamp(resp, "timestamp_end")
            )
        )

    if parts:
        # sort operations by timestamp
        parts = sorted(parts, key=lambda p: p[1])

        text.append(urwid.Text([("head", "Timing:")]))
        text.extend(common.format_keyvals(parts, indent=4))

    return searchable.Searchable(text)
def flowdetails(state, flow: http.HTTPFlow):
    text = []

    sc = flow.server_conn
    cc = flow.client_conn
    req = flow.request
    resp = flow.response
    metadata = flow.metadata

    if metadata is not None and len(metadata) > 0:
        parts = [[str(k), repr(v)] for k, v in metadata.items()]
        text.append(urwid.Text([("head", "Metadata:")]))
        text.extend(
            common.format_keyvals(parts, key="key", val="text", indent=4))

    if sc is not None and sc.ip_address:
        text.append(urwid.Text([("head", "Server Connection:")]))
        parts = [
            ["Address", human.format_address(sc.address)],
        ]
        if sc.ip_address:
            parts.append(
                ["Resolved Address",
                 human.format_address(sc.ip_address)])
        if resp:
            parts.append(["HTTP Version", resp.http_version])
        if sc.alpn_proto_negotiated:
            parts.append(["ALPN", sc.alpn_proto_negotiated])

        text.extend(
            common.format_keyvals(parts, key="key", val="text", indent=4))

        c = sc.cert
        if c:
            text.append(urwid.Text([("head", "Server Certificate:")]))
            parts = [["Type", "%s, %s bits" % c.keyinfo],
                     ["SHA1 digest", c.digest("sha1")],
                     ["Valid to", str(c.notafter)],
                     ["Valid from", str(c.notbefore)],
                     ["Serial", str(c.serial)],
                     [
                         "Subject",
                         urwid.BoxAdapter(
                             urwid.ListBox(
                                 common.format_keyvals(c.subject,
                                                       key="highlight",
                                                       val="text")),
                             len(c.subject))
                     ],
                     [
                         "Issuer",
                         urwid.BoxAdapter(
                             urwid.ListBox(
                                 common.format_keyvals(c.issuer,
                                                       key="highlight",
                                                       val="text")),
                             len(c.issuer))
                     ]]

            if c.altnames:
                parts.append([
                    "Alt names", ", ".join(
                        strutils.bytes_to_escaped_str(x) for x in c.altnames)
                ])
            text.extend(
                common.format_keyvals(parts, key="key", val="text", indent=4))

    if cc is not None:
        text.append(urwid.Text([("head", "Client Connection:")]))

        parts = [
            ["Address", "{}:{}".format(cc.address[0], cc.address[1])],
        ]
        if req:
            parts.append(["HTTP Version", req.http_version])
        if cc.tls_version:
            parts.append(["TLS Version", cc.tls_version])
        if cc.sni:
            parts.append(["Server Name Indication", cc.sni])
        if cc.cipher_name:
            parts.append(["Cipher Name", cc.cipher_name])
        if cc.alpn_proto_negotiated:
            parts.append(["ALPN", cc.alpn_proto_negotiated])

        text.extend(
            common.format_keyvals(parts, key="key", val="text", indent=4))

    parts = []

    if cc is not None and cc.timestamp_start:
        parts.append([
            "Client conn. established",
            maybe_timestamp(cc, "timestamp_start")
        ])
        if cc.ssl_established:
            parts.append([
                "Client conn. TLS handshake",
                maybe_timestamp(cc, "timestamp_ssl_setup")
            ])

    if sc is not None and sc.timestamp_start:
        parts.append(
            ["Server conn. initiated",
             maybe_timestamp(sc, "timestamp_start")])
        parts.append([
            "Server conn. TCP handshake",
            maybe_timestamp(sc, "timestamp_tcp_setup")
        ])
        if sc.ssl_established:
            parts.append([
                "Server conn. TLS handshake",
                maybe_timestamp(sc, "timestamp_ssl_setup")
            ])

    if req is not None and req.timestamp_start:
        parts.append(
            ["First request byte",
             maybe_timestamp(req, "timestamp_start")])
        parts.append(
            ["Request complete",
             maybe_timestamp(req, "timestamp_end")])

    if resp is not None and resp.timestamp_start:
        parts.append(
            ["First response byte",
             maybe_timestamp(resp, "timestamp_start")])
        parts.append(
            ["Response complete",
             maybe_timestamp(resp, "timestamp_end")])

    if parts:
        # sort operations by timestamp
        parts = sorted(parts, key=lambda p: p[1])

        text.append(urwid.Text([("head", "Timing:")]))
        text.extend(
            common.format_keyvals(parts, key="key", val="text", indent=4))

    return searchable.Searchable(text)
Example #36
0
def _mkhelp():
    text = []
    keys = [
        ("A", "accept all intercepted flows"),
        ("a", "accept this intercepted flow"),
        ("b", "save request/response body"),
        ("C", "export flow to clipboard"),
        ("D", "duplicate flow"),
        ("d", "delete flow"),
        ("e", "edit request/response"),
        ("f", "load full body data"),
        ("m", "change body display mode for this entity\n(default mode can be changed in the options)"),
        (None,
         common.highlight_key("automatic", "a") +
         [("text", ": automatic detection")]
         ),
        (None,
         common.highlight_key("hex", "e") +
         [("text", ": Hex")]
         ),
        (None,
         common.highlight_key("html", "h") +
         [("text", ": HTML")]
         ),
        (None,
         common.highlight_key("image", "i") +
         [("text", ": Image")]
         ),
        (None,
         common.highlight_key("javascript", "j") +
         [("text", ": JavaScript")]
         ),
        (None,
         common.highlight_key("json", "s") +
         [("text", ": JSON")]
         ),
        (None,
         common.highlight_key("urlencoded", "u") +
         [("text", ": URL-encoded data")]
         ),
        (None,
         common.highlight_key("raw", "r") +
         [("text", ": raw data")]
         ),
        (None,
         common.highlight_key("xml", "x") +
         [("text", ": XML")]
         ),
        ("E", "export flow to file"),
        ("r", "replay request"),
        ("V", "revert changes to request"),
        ("v", "view body in external viewer"),
        ("w", "save all flows matching current view filter"),
        ("W", "save this flow"),
        ("x", "delete body"),
        ("z", "encode/decode a request/response"),
        ("tab", "next tab"),
        ("h, l", "previous tab, next tab"),
        ("space", "next flow"),
        ("|", "run script on this flow"),
        ("/", "search (case sensitive)"),
        ("n", "repeat search forward"),
        ("N", "repeat search backwards"),
    ]
    text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
    return text
Example #37
0
def flowdetails(state, flow: mitmproxy.flow.Flow):
    text = []

    sc = flow.server_conn
    cc = flow.client_conn
    req: typing.Optional[http.Request]
    resp: typing.Optional[http.Response]
    if isinstance(flow, http.HTTPFlow):
        req = flow.request
        resp = flow.response
    else:
        req = None
        resp = None
    metadata = flow.metadata

    if metadata is not None and len(metadata) > 0:
        parts = [(str(k), repr(v)) for k, v in metadata.items()]
        text.append(urwid.Text([("head", "Metadata:")]))
        text.extend(common.format_keyvals(parts, indent=4))

    if sc is not None and sc.peername:
        text.append(urwid.Text([("head", "Server Connection:")]))
        parts = [
            ("Address", human.format_address(sc.address)),
        ]
        if sc.peername:
            parts.append(("Resolved Address", human.format_address(sc.peername)))
        if resp:
            parts.append(("HTTP Version", resp.http_version))
        if sc.alpn:
            parts.append(("ALPN", strutils.bytes_to_escaped_str(sc.alpn)))

        text.extend(
            common.format_keyvals(parts, indent=4)
        )

        if sc.certificate_list:
            c = sc.certificate_list[0]
            text.append(urwid.Text([("head", "Server Certificate:")]))
            parts = [
                ("Type", "%s, %s bits" % c.keyinfo),
                ("SHA256 digest", c.fingerprint().hex()),
                ("Valid to", str(c.notafter)),
                ("Valid from", str(c.notbefore)),
                ("Serial", str(c.serial)),
                ("Subject", urwid.Pile(common.format_keyvals(c.subject, key_format="highlight"))),
                ("Issuer", urwid.Pile(common.format_keyvals(c.issuer, key_format="highlight")))
            ]

            if c.altnames:
                parts.append(("Alt names", ", ".join(c.altnames)))
            text.extend(
                common.format_keyvals(parts, indent=4)
            )

    if cc is not None:
        text.append(urwid.Text([("head", "Client Connection:")]))

        parts = [
            ("Address", human.format_address(cc.peername)),
        ]
        if req:
            parts.append(("HTTP Version", req.http_version))
        if cc.tls_version:
            parts.append(("TLS Version", cc.tls_version))
        if cc.sni:
            parts.append(("Server Name Indication", cc.sni))
        if cc.cipher:
            parts.append(("Cipher Name", cc.cipher))
        if cc.alpn:
            parts.append(("ALPN", strutils.bytes_to_escaped_str(cc.alpn)))

        text.extend(
            common.format_keyvals(parts, indent=4)
        )

    parts = []

    if cc is not None and cc.timestamp_start:
        parts.append(
            (
                "Client conn. established",
                maybe_timestamp(cc, "timestamp_start")
            )
        )
        if cc.tls_established:
            parts.append(
                (
                    "Client conn. TLS handshake",
                    maybe_timestamp(cc, "timestamp_tls_setup")
                )
            )
        parts.append(
            (
                "Client conn. closed",
                maybe_timestamp(cc, "timestamp_end")
            )
        )

    if sc is not None and sc.timestamp_start:
        parts.append(
            (
                "Server conn. initiated",
                maybe_timestamp(sc, "timestamp_start")
            )
        )
        parts.append(
            (
                "Server conn. TCP handshake",
                maybe_timestamp(sc, "timestamp_tcp_setup")
            )
        )
        if sc.tls_established:
            parts.append(
                (
                    "Server conn. TLS handshake",
                    maybe_timestamp(sc, "timestamp_tls_setup")
                )
            )
        parts.append(
            (
                "Server conn. closed",
                maybe_timestamp(sc, "timestamp_end")
            )
        )

    if req is not None and req.timestamp_start:
        parts.append(
            (
                "First request byte",
                maybe_timestamp(req, "timestamp_start")
            )
        )
        parts.append(
            (
                "Request complete",
                maybe_timestamp(req, "timestamp_end")
            )
        )

    if resp is not None and resp.timestamp_start:
        parts.append(
            (
                "First response byte",
                maybe_timestamp(resp, "timestamp_start")
            )
        )
        parts.append(
            (
                "Response complete",
                maybe_timestamp(resp, "timestamp_end")
            )
        )

    if parts:
        # sort operations by timestamp
        parts = sorted(parts, key=lambda p: p[1])

        text.append(urwid.Text([("head", "Timing:")]))
        text.extend(common.format_keyvals(parts, indent=4))

    return searchable.Searchable(text)
Example #38
0
def flowdetails(state, flow):
    text = []

    cc = flow.client_conn
    sc = flow.server_conn
    req = flow.request
    resp = flow.response

    if sc is not None:
        text.append(urwid.Text([("head", "Server Connection:")]))
        parts = [
            ["Address", repr(sc.address)],
            ["Resolved Address", repr(sc.ip_address)],
        ]

        text.extend(
            common.format_keyvals(parts, key="key", val="text", indent=4)
        )

        c = sc.cert
        if c:
            text.append(urwid.Text([("head", "Server Certificate:")]))
            parts = [
                ["Type", "%s, %s bits" % c.keyinfo],
                ["SHA1 digest", c.digest("sha1")],
                ["Valid to", str(c.notafter)],
                ["Valid from", str(c.notbefore)],
                ["Serial", str(c.serial)],
                [
                    "Subject",
                    urwid.BoxAdapter(
                        urwid.ListBox(
                            common.format_keyvals(
                                c.subject,
                                key="highlight",
                                val="text"
                            )
                        ),
                        len(c.subject)
                    )
                ],
                [
                    "Issuer",
                    urwid.BoxAdapter(
                        urwid.ListBox(
                            common.format_keyvals(
                                c.issuer, key="highlight", val="text"
                            )
                        ),
                        len(c.issuer)
                    )
                ]
            ]

            if c.altnames:
                parts.append(
                    [
                        "Alt names",
                        ", ".join(str(x) for x in c.altnames)
                    ]
                )
            text.extend(
                common.format_keyvals(parts, key="key", val="text", indent=4)
            )

    if cc is not None:
        text.append(urwid.Text([("head", "Client Connection:")]))

        parts = [
            ["Address", repr(cc.address)],
        ]
        if cc.tls_version:
            parts.append(["TLS Version", cc.tls_version])
        if cc.sni:
            parts.append(["Server Name Indication", cc.sni])
        if cc.cipher_name:
            parts.append(["Cipher Name", cc.cipher_name])

        text.extend(
            common.format_keyvals(parts, key="key", val="text", indent=4)
        )

    parts = []

    if cc is not None and cc.timestamp_start:
        parts.append(
            [
                "Client conn. established",
                maybe_timestamp(cc, "timestamp_start")
            ]
        )
        if cc.ssl_established:
            parts.append(
                [
                    "Client conn. TLS handshake",
                    maybe_timestamp(cc, "timestamp_ssl_setup")
                ]
            )
    if sc is not None and sc.timestamp_start:
        parts.append(
            [
                "Server conn. initiated",
                maybe_timestamp(sc, "timestamp_start")
            ]
        )
        parts.append(
            [
                "Server conn. TCP handshake",
                maybe_timestamp(sc, "timestamp_tcp_setup")
            ]
        )
        if sc.ssl_established:
            parts.append(
                [
                    "Server conn. TLS handshake",
                    maybe_timestamp(sc, "timestamp_ssl_setup")
                ]
            )
    if req is not None and req.timestamp_start:
        parts.append(
            [
                "First request byte",
                maybe_timestamp(req, "timestamp_start")
            ]
        )
        parts.append(
            [
                "Request complete",
                maybe_timestamp(req, "timestamp_end")
            ]
        )
    if resp is not None and resp.timestamp_start:
        parts.append(
            [
                "First response byte",
                maybe_timestamp(resp, "timestamp_start")
            ]
        )
        parts.append(
            [
                "Response complete",
                maybe_timestamp(resp, "timestamp_end")
            ]
        )

    if parts:
        # sort operations by timestamp
        parts = sorted(parts, key=lambda p: p[1])

        text.append(urwid.Text([("head", "Timing:")]))
        text.extend(common.format_keyvals(parts, key="key", val="text", indent=4))
    return searchable.Searchable(state, text)