From ffcf0609285048ed2868548fe8e162b52cce1f25 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sat, 17 Dec 2016 13:49:18 +0100 Subject: [PATCH] display ALPN information --- mitmproxy/connections.py | 16 ++++++++++++++-- mitmproxy/io_compat.py | 2 ++ mitmproxy/test/tflow.py | 4 +++- mitmproxy/tools/console/flowdetailview.py | 4 ++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/mitmproxy/connections.py b/mitmproxy/connections.py index c7941ad9b..fc6374204 100644 --- a/mitmproxy/connections.py +++ b/mitmproxy/connections.py @@ -22,6 +22,7 @@ class ClientConnection(tcp.BaseHandler, stateobject.StateObject): timestamp_end: Connection end timestamp sni: Server Name Indication sent by client during the TLS handshake cipher_name: The current used cipher + alpn_proto_negotiated: The negotiated application protocol tls_version: TLS version """ @@ -44,14 +45,16 @@ class ClientConnection(tcp.BaseHandler, stateobject.StateObject): self.timestamp_ssl_setup = None self.sni = None self.cipher_name = None + self.alpn_proto_negotiated = None self.tls_version = None def connected(self): return bool(self.connection) and not self.finished def __repr__(self): - return "".format( + return "".format( ssl="[ssl] " if self.ssl_established else "", + alpn="[ALPN: {}] ".format(self.alpn_proto_negotiated) if self.alpn_proto_negotiated else "", address=repr(self.address) ) @@ -68,6 +71,7 @@ class ClientConnection(tcp.BaseHandler, stateobject.StateObject): timestamp_end=float, sni=str, cipher_name=str, + alpn_proto_negotiated=str, tls_version=str, ) @@ -97,6 +101,7 @@ class ClientConnection(tcp.BaseHandler, stateobject.StateObject): timestamp_ssl_setup=None, sni=None, cipher_name=None, + alpn_proto_negotiated=None, tls_version=None, )) @@ -109,6 +114,7 @@ class ClientConnection(tcp.BaseHandler, stateobject.StateObject): else: self.sni = None self.cipher_name = self.connection.get_cipher_name() + self.alpn_proto_negotiated = self.get_alpn_proto_negotiated() self.tls_version = self.connection.get_protocol_version_name() def finish(self): @@ -128,6 +134,7 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject): ssl_established: True if TLS is established, False otherwise cert: The certificate presented by the remote during the TLS handshake sni: Server Name Indication sent by the proxy during the TLS handshake + alpn_proto_negotiated: The negotiated application protocol via: The underlying server connection (e.g. the connection to the upstream proxy in upstream proxy mode) timestamp_start: Connection start timestamp timestamp_tcp_setup: TCP ACK received timestamp @@ -138,6 +145,7 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject): def __init__(self, address, source_address=None, spoof_source_address=None): tcp.TCPClient.__init__(self, address, source_address, spoof_source_address) + self.alpn_proto_negotiated = None self.via = None self.timestamp_start = None self.timestamp_end = None @@ -154,8 +162,9 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject): ssl = "[ssl] " else: ssl = "" - return "".format( + return "".format( ssl=ssl, + alpn="[ALPN: {}] ".format(self.alpn_proto_negotiated) if self.alpn_proto_negotiated else "", address=repr(self.address) ) @@ -170,6 +179,7 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject): ssl_established=bool, cert=certs.SSLCert, sni=str, + alpn_proto_negotiated=str, timestamp_start=float, timestamp_tcp_setup=float, timestamp_ssl_setup=float, @@ -189,6 +199,7 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject): ip_address=dict(address=address, use_ipv6=False), cert=None, sni=None, + alpn_proto_negotiated=None, source_address=dict(address=('', 0), use_ipv6=False), ssl_established=False, timestamp_start=None, @@ -228,6 +239,7 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject): self.convert_to_ssl(cert=clientcert, sni=sni, **kwargs) self.sni = sni + self.alpn_proto_negotiated = self.get_alpn_proto_negotiated() self.timestamp_ssl_setup = time.time() def finish(self): diff --git a/mitmproxy/io_compat.py b/mitmproxy/io_compat.py index 20ee88248..14f4928c6 100644 --- a/mitmproxy/io_compat.py +++ b/mitmproxy/io_compat.py @@ -67,8 +67,10 @@ def convert_017_018(data): def convert_018_019(data): data["version"] = (0, 19) data["client_conn"]["sni"] = None + data["client_conn"]["alpn_proto_negotiated"] = None data["client_conn"]["cipher_name"] = None data["client_conn"]["tls_version"] = None + data["server_conn"]["alpn_proto_negotiated"] = None data["mode"] = "regular" data["metadata"] = dict() return data diff --git a/mitmproxy/test/tflow.py b/mitmproxy/test/tflow.py index 281047f5d..f100f62ed 100644 --- a/mitmproxy/test/tflow.py +++ b/mitmproxy/test/tflow.py @@ -72,6 +72,7 @@ def tclient_conn(): timestamp_end=3, sni="address", cipher_name="cipher", + alpn_proto_negotiated=None, tls_version="TLSv1.2", )) c.reply = controller.DummyReply() @@ -93,7 +94,8 @@ def tserver_conn(): timestamp_end=4, ssl_established=False, sni="address", - via=None + alpn_proto_negotiated=None, + via=None, )) c.reply = controller.DummyReply() return c diff --git a/mitmproxy/tools/console/flowdetailview.py b/mitmproxy/tools/console/flowdetailview.py index 7677efe41..8c08d6eef 100644 --- a/mitmproxy/tools/console/flowdetailview.py +++ b/mitmproxy/tools/console/flowdetailview.py @@ -31,6 +31,8 @@ def flowdetails(state, flow): ["Address", repr(sc.address)], ["Resolved Address", repr(sc.ip_address)], ] + if sc.alpn_proto_negotiated: + parts.append(["ALPN", sc.alpn_proto_negotiated]) text.extend( common.format_keyvals(parts, key="key", val="text", indent=4) @@ -94,6 +96,8 @@ def flowdetails(state, flow): 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)