diff options
-rw-r--r-- | mitmproxy/connections.py | 16 | ||||
-rw-r--r-- | mitmproxy/io_compat.py | 2 | ||||
-rw-r--r-- | mitmproxy/proxy/protocol/http.py | 3 | ||||
-rw-r--r-- | mitmproxy/proxy/protocol/http2.py | 7 | ||||
-rw-r--r-- | mitmproxy/proxy/protocol/http_replay.py | 6 | ||||
-rw-r--r-- | mitmproxy/proxy/server.py | 3 | ||||
-rw-r--r-- | mitmproxy/test/tflow.py | 4 | ||||
-rw-r--r-- | mitmproxy/tools/console/flowdetailview.py | 4 | ||||
-rw-r--r-- | setup.py | 2 |
9 files changed, 30 insertions, 17 deletions
diff --git a/mitmproxy/connections.py b/mitmproxy/connections.py index c7941ad9..fc637420 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 "<ClientConnection: {ssl}{address}>".format( + return "<ClientConnection: {ssl}{alpn}{address}>".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 "<ServerConnection: {ssl}{address}>".format( + return "<ServerConnection: {ssl}{alpn}{address}>".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 20ee8824..14f4928c 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/proxy/protocol/http.py b/mitmproxy/proxy/protocol/http.py index 50d64e17..59de070f 100644 --- a/mitmproxy/proxy/protocol/http.py +++ b/mitmproxy/proxy/protocol/http.py @@ -1,6 +1,5 @@ import h2.exceptions import time -import traceback import enum from mitmproxy import connections # noqa @@ -431,7 +430,7 @@ class HttpLayer(base.Layer): response = http.make_error_response(code, message, headers) self.send_response(response) except (exceptions.NetlibException, h2.exceptions.H2Error, exceptions.Http2ProtocolException): - self.log(traceback.format_exc(), "debug") + self.log("Failed to send error response to client: {}".format(message), "debug") def change_upstream_proxy_server(self, address) -> None: # Make set_upstream_proxy_server always available, diff --git a/mitmproxy/proxy/protocol/http2.py b/mitmproxy/proxy/protocol/http2.py index 41707096..b7548221 100644 --- a/mitmproxy/proxy/protocol/http2.py +++ b/mitmproxy/proxy/protocol/http2.py @@ -1,6 +1,5 @@ import threading import time -import traceback import functools from typing import Dict, Callable, Any, List # noqa @@ -328,7 +327,7 @@ class Http2Layer(base.Layer): try: while True: - r = tcp.ssl_read_select(conns, 1) + r = tcp.ssl_read_select(conns, 0.1) for conn in r: source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn @@ -358,7 +357,6 @@ class Http2Layer(base.Layer): self._cleanup_streams() except Exception as e: # pragma: no cover self.log(repr(e), "info") - self.log(traceback.format_exc(), "debug") self._kill_all_streams() @@ -580,7 +578,7 @@ class Http2SingleStreamLayer(httpbase._HttpTransmissionLayer, basethread.BaseThr def read_response_body(self, request, response): while True: try: - yield self.response_data_queue.get(timeout=1) + yield self.response_data_queue.get(timeout=0.1) except queue.Empty: # pragma: no cover pass if self.response_data_finished.is_set(): @@ -624,7 +622,6 @@ class Http2SingleStreamLayer(httpbase._HttpTransmissionLayer, basethread.BaseThr pass except exceptions.ProtocolException as e: # pragma: no cover self.log(repr(e), "info") - self.log(traceback.format_exc(), "debug") except exceptions.SetServerNotAllowedException as e: # pragma: no cover self.log("Changing the Host server for HTTP/2 connections not allowed: {}".format(e), "info") except exceptions.Kill: diff --git a/mitmproxy/proxy/protocol/http_replay.py b/mitmproxy/proxy/protocol/http_replay.py index 2e4c91b0..38f511c4 100644 --- a/mitmproxy/proxy/protocol/http_replay.py +++ b/mitmproxy/proxy/protocol/http_replay.py @@ -1,5 +1,3 @@ -import traceback - from mitmproxy import log from mitmproxy import controller from mitmproxy import exceptions @@ -107,10 +105,10 @@ class RequestReplayThread(basethread.BaseThread): "log", log.LogEntry("Connection killed", "info") ) - except Exception: + except Exception as e: self.channel.tell( "log", - log.LogEntry(traceback.format_exc(), "error") + log.LogEntry(repr(e), "error") ) finally: r.first_line_format = first_line_format_backup diff --git a/mitmproxy/proxy/server.py b/mitmproxy/proxy/server.py index fc00a633..97018dad 100644 --- a/mitmproxy/proxy/server.py +++ b/mitmproxy/proxy/server.py @@ -120,7 +120,6 @@ class ConnectionHandler: except exceptions.Kill: self.log("Connection killed", "info") except exceptions.ProtocolException as e: - if isinstance(e, exceptions.ClientHandshakeException): self.log( "Client Handshake failed. " @@ -134,7 +133,7 @@ class ConnectionHandler: else: self.log(str(e), "warn") - self.log(traceback.format_exc(), "debug") + self.log(repr(e), "debug") # If an error propagates to the topmost level, # we send an HTTP error response, which is both # understandable by HTTP clients and humans. diff --git a/mitmproxy/test/tflow.py b/mitmproxy/test/tflow.py index 281047f5..f100f62e 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 7677efe4..8c08d6ee 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) @@ -67,7 +67,7 @@ setup( "cryptography>=1.3, <1.8", "cssutils>=1.0.1, <1.1", "Flask>=0.10.1, <0.12", - "h2>=2.5.0, <3", + "h2>=2.5.1, <3", "html2text>=2016.1.8, <=2016.9.19", "hyperframe>=4.0.1, <5", "jsbeautifier>=1.6.3, <1.7", |