mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-27 02:24:18 +00:00
pathoc -S dumps information on the remote SSL certificate chain
This commit is contained in:
parent
0177eb899a
commit
53334e437c
@ -2,6 +2,7 @@ import sys, os
|
|||||||
from netlib import tcp, http
|
from netlib import tcp, http
|
||||||
import netlib.utils
|
import netlib.utils
|
||||||
import language, utils
|
import language, utils
|
||||||
|
import OpenSSL.crypto
|
||||||
|
|
||||||
class PathocError(Exception): pass
|
class PathocError(Exception): pass
|
||||||
|
|
||||||
@ -70,7 +71,6 @@ class Pathoc(tcp.TCPClient):
|
|||||||
self.connection.get_peer_cert_chain()
|
self.connection.get_peer_cert_chain()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def request(self, spec):
|
def request(self, spec):
|
||||||
"""
|
"""
|
||||||
Return an (httpversion, code, msg, headers, content) tuple.
|
Return an (httpversion, code, msg, headers, content) tuple.
|
||||||
@ -97,7 +97,7 @@ class Pathoc(tcp.TCPClient):
|
|||||||
print >> fp, "%s (unprintables escaped):"%header
|
print >> fp, "%s (unprintables escaped):"%header
|
||||||
print >> fp, netlib.utils.cleanBin(data)
|
print >> fp, netlib.utils.cleanBin(data)
|
||||||
|
|
||||||
def print_request(self, spec, showreq, showresp, explain, hexdump, ignorecodes, ignoretimeout, fp=sys.stdout):
|
def print_request(self, spec, showreq, showresp, explain, showssl, hexdump, ignorecodes, ignoretimeout, fp=sys.stdout):
|
||||||
"""
|
"""
|
||||||
Performs a series of requests, and prints results to the specified
|
Performs a series of requests, and prints results to the specified
|
||||||
file descriptor.
|
file descriptor.
|
||||||
@ -106,6 +106,7 @@ class Pathoc(tcp.TCPClient):
|
|||||||
showreq: Print requests
|
showreq: Print requests
|
||||||
showresp: Print responses
|
showresp: Print responses
|
||||||
explain: Print request explanation
|
explain: Print request explanation
|
||||||
|
showssl: Print info on SSL connection
|
||||||
hexdump: When printing requests or responses, use hex dump output
|
hexdump: When printing requests or responses, use hex dump output
|
||||||
ignorecodes: Sequence of return codes to ignore
|
ignorecodes: Sequence of return codes to ignore
|
||||||
|
|
||||||
@ -145,6 +146,7 @@ class Pathoc(tcp.TCPClient):
|
|||||||
if req:
|
if req:
|
||||||
if ignorecodes and resp and resp[1] in ignorecodes:
|
if ignorecodes and resp and resp[1] in ignorecodes:
|
||||||
return
|
return
|
||||||
|
|
||||||
if explain:
|
if explain:
|
||||||
print >> fp, ">> Spec:", r.spec()
|
print >> fp, ">> Spec:", r.spec()
|
||||||
|
|
||||||
@ -156,4 +158,30 @@ class Pathoc(tcp.TCPClient):
|
|||||||
else:
|
else:
|
||||||
if resp:
|
if resp:
|
||||||
self._show_summary(fp, *resp)
|
self._show_summary(fp, *resp)
|
||||||
|
|
||||||
|
if self.sslinfo:
|
||||||
|
print >> fp, "SSL certificate chain:\n"
|
||||||
|
for i in self.sslinfo.certchain:
|
||||||
|
print >> fp, "\tSubject: ",
|
||||||
|
for cn in i.get_subject().get_components():
|
||||||
|
print >> fp, "%s=%s"%cn,
|
||||||
|
print >> fp
|
||||||
|
print >> fp, "\tIssuer: ",
|
||||||
|
for cn in i.get_issuer().get_components():
|
||||||
|
print >> fp, "%s=%s"%cn,
|
||||||
|
print >> fp
|
||||||
|
print >> fp, "\tVersion: %s"%i.get_version()
|
||||||
|
print >> fp, "\tValidity: %s - %s"%(i.get_notBefore(),i.get_notAfter())
|
||||||
|
print >> fp, "\tSerial: %s"%i.get_serial_number()
|
||||||
|
print >> fp, "\tAlgorithm: %s"%i.get_signature_algorithm()
|
||||||
|
pk = i.get_pubkey()
|
||||||
|
types = {
|
||||||
|
OpenSSL.crypto.TYPE_RSA: "RSA",
|
||||||
|
OpenSSL.crypto.TYPE_DSA: "DSA"
|
||||||
|
}
|
||||||
|
t = types.get(pk.type(), "Uknown")
|
||||||
|
print >> fp, "\tPubkey: %s bit %s"%(pk.bits(), t)
|
||||||
|
print >> fp
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
5
pathoc
5
pathoc
@ -81,6 +81,10 @@ if __name__ == "__main__":
|
|||||||
"-I", dest="ignorecodes", type=str, default="",
|
"-I", dest="ignorecodes", type=str, default="",
|
||||||
help="Comma-separated list of response codes to ignore"
|
help="Comma-separated list of response codes to ignore"
|
||||||
)
|
)
|
||||||
|
group.add_argument(
|
||||||
|
"-S", dest="showssl", action="store_true", default=False,
|
||||||
|
help="Show info on SSL connection"
|
||||||
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"-e", dest="explain", action="store_true", default=False,
|
"-e", dest="explain", action="store_true", default=False,
|
||||||
help="Explain requests"
|
help="Explain requests"
|
||||||
@ -153,6 +157,7 @@ if __name__ == "__main__":
|
|||||||
showreq=args.showreq,
|
showreq=args.showreq,
|
||||||
showresp=args.showresp,
|
showresp=args.showresp,
|
||||||
explain=args.explain,
|
explain=args.explain,
|
||||||
|
showssl=args.showssl,
|
||||||
hexdump=args.hexdump,
|
hexdump=args.hexdump,
|
||||||
ignorecodes=codes,
|
ignorecodes=codes,
|
||||||
ignoretimeout=args.ignoretimeout
|
ignoretimeout=args.ignoretimeout
|
||||||
|
@ -34,6 +34,28 @@ class _TestDaemon:
|
|||||||
r = c.request("get:/api/info")
|
r = c.request("get:/api/info")
|
||||||
assert tuple(json.loads(r.content)["version"]) == version.IVERSION
|
assert tuple(json.loads(r.content)["version"]) == version.IVERSION
|
||||||
|
|
||||||
|
def tval(self, requests, showreq=False, showresp=False, explain=False,
|
||||||
|
showssl=False, hexdump=False, timeout=None, ignorecodes=None,
|
||||||
|
ignoretimeout=None):
|
||||||
|
c = pathoc.Pathoc(("127.0.0.1", self.d.port), ssl=self.ssl)
|
||||||
|
c.connect()
|
||||||
|
if timeout:
|
||||||
|
c.settimeout(timeout)
|
||||||
|
s = cStringIO.StringIO()
|
||||||
|
for i in requests:
|
||||||
|
c.print_request(
|
||||||
|
i,
|
||||||
|
showreq = showreq,
|
||||||
|
showresp = showresp,
|
||||||
|
explain = explain,
|
||||||
|
showssl = showssl,
|
||||||
|
hexdump = hexdump,
|
||||||
|
ignorecodes = ignorecodes,
|
||||||
|
ignoretimeout = ignoretimeout,
|
||||||
|
fp = s
|
||||||
|
)
|
||||||
|
return s.getvalue()
|
||||||
|
|
||||||
|
|
||||||
class TestDaemonSSL(_TestDaemon):
|
class TestDaemonSSL(_TestDaemon):
|
||||||
ssl = True
|
ssl = True
|
||||||
@ -50,6 +72,9 @@ class TestDaemonSSL(_TestDaemon):
|
|||||||
d = json.loads(r.content)
|
d = json.loads(r.content)
|
||||||
assert d["log"][0]["request"]["sni"] == "foobar.com"
|
assert d["log"][0]["request"]["sni"] == "foobar.com"
|
||||||
|
|
||||||
|
def test_showssl(self):
|
||||||
|
assert "certificate chain" in self.tval(["get:/p/200"], showssl=True)
|
||||||
|
|
||||||
def test_clientcert(self):
|
def test_clientcert(self):
|
||||||
c = pathoc.Pathoc(
|
c = pathoc.Pathoc(
|
||||||
("127.0.0.1", self.d.port),
|
("127.0.0.1", self.d.port),
|
||||||
@ -65,29 +90,13 @@ class TestDaemonSSL(_TestDaemon):
|
|||||||
|
|
||||||
class TestDaemon(_TestDaemon):
|
class TestDaemon(_TestDaemon):
|
||||||
ssl = False
|
ssl = False
|
||||||
def tval(self, requests, showreq=False, showresp=False, explain=False, hexdump=False, timeout=None, ignorecodes=None, ignoretimeout=None):
|
|
||||||
c = pathoc.Pathoc(("127.0.0.1", self.d.port))
|
|
||||||
c.connect()
|
|
||||||
if timeout:
|
|
||||||
c.settimeout(timeout)
|
|
||||||
s = cStringIO.StringIO()
|
|
||||||
for i in requests:
|
|
||||||
c.print_request(
|
|
||||||
i,
|
|
||||||
showreq = showreq,
|
|
||||||
showresp = showresp,
|
|
||||||
explain = explain,
|
|
||||||
hexdump = hexdump,
|
|
||||||
ignorecodes = ignorecodes,
|
|
||||||
ignoretimeout = ignoretimeout,
|
|
||||||
fp = s
|
|
||||||
)
|
|
||||||
return s.getvalue()
|
|
||||||
|
|
||||||
def test_ssl_error(self):
|
def test_ssl_error(self):
|
||||||
c = pathoc.Pathoc(("127.0.0.1", self.d.port), ssl = True)
|
c = pathoc.Pathoc(("127.0.0.1", self.d.port), ssl = True)
|
||||||
tutils.raises("ssl handshake", c.connect)
|
tutils.raises("ssl handshake", c.connect)
|
||||||
|
|
||||||
|
def test_showssl(self):
|
||||||
|
assert not "certificate chain" in self.tval(["get:/p/200"], showssl=True)
|
||||||
|
|
||||||
def test_ignorecodes(self):
|
def test_ignorecodes(self):
|
||||||
assert "200" in self.tval(["get:'/p/200:b@1'"])
|
assert "200" in self.tval(["get:'/p/200:b@1'"])
|
||||||
assert "200" not in self.tval(["get:'/p/200:b@1'"], ignorecodes=[200])
|
assert "200" not in self.tval(["get:'/p/200:b@1'"], ignorecodes=[200])
|
||||||
|
Loading…
Reference in New Issue
Block a user