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:
Aldo Cortesi 2012-04-03 11:10:25 +12:00
parent f526e5fa12
commit 61fab03b24
6 changed files with 113 additions and 5 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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"]

View File

@ -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):