mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-23 00:01:36 +00:00
Add a details page, available from a flow view with the 'X' shortcut
At the moment, this shows the upstream SSL certificate details. More fine-grained detail that doesn't fit in the flow view itself will be added.
This commit is contained in:
parent
f526e5fa12
commit
61fab03b24
@ -151,6 +151,10 @@ class SSLCert:
|
||||
def digest(self, name):
|
||||
return self.cert.digest(name)
|
||||
|
||||
@property
|
||||
def issuer(self):
|
||||
return self.cert.get_issuer().get_components()
|
||||
|
||||
@property
|
||||
def notbefore(self):
|
||||
return self.cert.get_notBefore()
|
||||
@ -186,7 +190,7 @@ class SSLCert:
|
||||
@property
|
||||
def cn(self):
|
||||
cn = None
|
||||
for i in self.cert.get_subject().get_components():
|
||||
for i in self.subject:
|
||||
if i[0] == "CN":
|
||||
cn = i[1]
|
||||
return cn
|
||||
@ -199,7 +203,7 @@ class SSLCert:
|
||||
if ext.get_short_name() == "subjectAltName":
|
||||
dec = decode(ext.get_data(), asn1Spec=_GeneralNames())
|
||||
for i in dec[0]:
|
||||
altnames.append(i[0])
|
||||
altnames.append(i[0].asOctets())
|
||||
return altnames
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ import mailcap, mimetypes, tempfile, os, subprocess, glob, time, shlex
|
||||
import os.path, sys, weakref
|
||||
import urwid
|
||||
from .. import controller, utils, flow
|
||||
import flowlist, flowview, help, common, grideditor, palettes, contentview
|
||||
import flowlist, flowview, help, common, grideditor, palettes, contentview, flowdetailview
|
||||
|
||||
EVENTLOG_SIZE = 500
|
||||
|
||||
@ -547,6 +547,13 @@ class ConsoleMaster(flow.FlowMaster):
|
||||
self.header = None
|
||||
self.make_view()
|
||||
|
||||
def view_flowdetails(self, flow):
|
||||
h = flowdetailview.FlowDetailsView(self, flow, (self.statusbar, self.body, self.header))
|
||||
self.statusbar = StatusBar(self, flowdetailview.footer)
|
||||
self.body = h
|
||||
self.header = None
|
||||
self.make_view()
|
||||
|
||||
def view_grideditor(self, ge):
|
||||
self.body = ge
|
||||
self.header = None
|
||||
|
@ -61,8 +61,8 @@ def format_keyvals(lst, key="key", val="text", indent=0):
|
||||
maxk,
|
||||
urwid.Text([(key, kv[0] or "")])
|
||||
),
|
||||
urwid.Text([(val, kv[1])])
|
||||
])
|
||||
kv[1] if isinstance(kv[1], urwid.Widget) else urwid.Text([(val, kv[1])])
|
||||
])
|
||||
ret.append(urwid.Columns(cols, dividechars = 2))
|
||||
return ret
|
||||
|
||||
|
93
libmproxy/console/flowdetailview.py
Normal file
93
libmproxy/console/flowdetailview.py
Normal file
@ -0,0 +1,93 @@
|
||||
# Copyright (C) 2012 Aldo Cortesi
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import urwid
|
||||
import common
|
||||
from .. import filt, version
|
||||
|
||||
footer = [
|
||||
('heading_key', "q"), ":back ",
|
||||
]
|
||||
|
||||
class FlowDetailsView(urwid.ListBox):
|
||||
def __init__(self, master, flow, state):
|
||||
self.master, self.flow, self.state = master, flow, state
|
||||
urwid.ListBox.__init__(
|
||||
self,
|
||||
self.flowtext()
|
||||
)
|
||||
|
||||
def keypress(self, size, key):
|
||||
key = common.shortcuts(key)
|
||||
if key == "q":
|
||||
self.master.statusbar = self.state[0]
|
||||
self.master.body = self.state[1]
|
||||
self.master.header = self.state[2]
|
||||
self.master.make_view()
|
||||
return None
|
||||
elif key == "?":
|
||||
key = None
|
||||
return urwid.ListBox.keypress(self, size, key)
|
||||
|
||||
def flowtext(self):
|
||||
text = []
|
||||
|
||||
title = urwid.Text("Flow details")
|
||||
title = urwid.Padding(title, align="left", width=("relative", 100))
|
||||
title = urwid.AttrWrap(title, "heading")
|
||||
text.append(title)
|
||||
|
||||
if self.flow.response:
|
||||
c = self.flow.response.get_cert()
|
||||
if c:
|
||||
text.append(urwid.Text([("head", "Server Certificate:")]))
|
||||
parts = [
|
||||
["Type", "%s, %s bits"%c.keyinfo],
|
||||
["Valid to", c.notafter],
|
||||
["Valid from", c.notbefore],
|
||||
["Serial", str(c.serial)],
|
||||
]
|
||||
|
||||
parts.append(
|
||||
[
|
||||
"Subject",
|
||||
urwid.BoxAdapter(
|
||||
urwid.ListBox(common.format_keyvals(c.subject, key="highlight", val="text")),
|
||||
len(c.subject)
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
parts.append(
|
||||
[
|
||||
"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(c.altnames)
|
||||
]
|
||||
)
|
||||
text.extend(common.format_keyvals(parts, key="key", val="text", indent=4))
|
||||
return text
|
||||
|
||||
|
@ -67,6 +67,7 @@ def _mkhelp():
|
||||
("v", "view body in external viewer"),
|
||||
("w", "save all flows matching current limit"),
|
||||
("W", "save this flow"),
|
||||
("X", "view flow details"),
|
||||
("z", "encode/decode a request/response"),
|
||||
("tab", "toggle request/response view"),
|
||||
("space", "next flow"),
|
||||
@ -497,6 +498,8 @@ class FlowView(common.WWrap):
|
||||
"Send flow to script: ", self.state.last_script,
|
||||
self.master.run_script_once, self.flow
|
||||
)
|
||||
elif key == "X":
|
||||
self.master.view_flowdetails(self.flow)
|
||||
elif key == "z":
|
||||
if conn:
|
||||
e = conn.headers["content-encoding"] or ["identity"]
|
||||
|
@ -64,6 +64,7 @@ class uSSLCert(libpry.AutoTree):
|
||||
assert c.subject
|
||||
assert c.keyinfo == ("RSA", 2048)
|
||||
assert c.serial
|
||||
assert c.issuer
|
||||
c.has_expired
|
||||
|
||||
def test_der(self):
|
||||
|
Loading…
Reference in New Issue
Block a user