diff options
author | Maximilian Hils <git@maximilianhils.com> | 2015-08-30 02:27:38 +0200 |
---|---|---|
committer | Maximilian Hils <git@maximilianhils.com> | 2015-08-30 02:27:38 +0200 |
commit | 1dd09a5509219e7390abbb8c0b6818c7e792daa1 (patch) | |
tree | ef1f433ebbcb05003b7648f8cabdfce7f2f00de5 /libmproxy/protocol2 | |
parent | dd7f50d64bef38fa67b4cace91913d03691dde26 (diff) | |
download | mitmproxy-1dd09a5509219e7390abbb8c0b6818c7e792daa1.tar.gz mitmproxy-1dd09a5509219e7390abbb8c0b6818c7e792daa1.tar.bz2 mitmproxy-1dd09a5509219e7390abbb8c0b6818c7e792daa1.zip |
always insert tls layer for inline script upgrades
Diffstat (limited to 'libmproxy/protocol2')
-rw-r--r-- | libmproxy/protocol2/http_proxy.py | 5 | ||||
-rw-r--r-- | libmproxy/protocol2/reverse_proxy.py | 10 | ||||
-rw-r--r-- | libmproxy/protocol2/root_context.py | 33 | ||||
-rw-r--r-- | libmproxy/protocol2/tls.py | 13 |
4 files changed, 43 insertions, 18 deletions
diff --git a/libmproxy/protocol2/http_proxy.py b/libmproxy/protocol2/http_proxy.py index b3389eb7..2876c022 100644 --- a/libmproxy/protocol2/http_proxy.py +++ b/libmproxy/protocol2/http_proxy.py @@ -1,12 +1,11 @@ from __future__ import (absolute_import, print_function, division) from .layer import Layer, ServerConnectionMixin -from .http import Http1Layer class HttpProxy(Layer, ServerConnectionMixin): def __call__(self): - layer = Http1Layer(self, "regular") + layer = self.ctx.next_layer(self) try: layer() finally: @@ -19,7 +18,7 @@ class HttpUpstreamProxy(Layer, ServerConnectionMixin): super(HttpUpstreamProxy, self).__init__(ctx, server_address=server_address) def __call__(self): - layer = Http1Layer(self, "upstream") + layer = self.ctx.next_layer(self) try: layer() finally: diff --git a/libmproxy/protocol2/reverse_proxy.py b/libmproxy/protocol2/reverse_proxy.py index e959db86..c4cabccc 100644 --- a/libmproxy/protocol2/reverse_proxy.py +++ b/libmproxy/protocol2/reverse_proxy.py @@ -5,16 +5,12 @@ from .tls import TlsLayer class ReverseProxy(Layer, ServerConnectionMixin): - def __init__(self, ctx, server_address, client_tls, server_tls): + def __init__(self, ctx, server_address, server_tls): super(ReverseProxy, self).__init__(ctx, server_address=server_address) - self._client_tls = client_tls - self._server_tls = server_tls + self.server_tls = server_tls def __call__(self): - # Always use a TLS layer here; if someone changes the scheme, there needs to be a - # TLS layer underneath. - layer = TlsLayer(self, self._client_tls, self._server_tls) - + layer = self.ctx.next_layer(self) try: layer() finally: diff --git a/libmproxy/protocol2/root_context.py b/libmproxy/protocol2/root_context.py index 4d69204f..210ba6ab 100644 --- a/libmproxy/protocol2/root_context.py +++ b/libmproxy/protocol2/root_context.py @@ -6,7 +6,9 @@ from netlib.http.http2 import HTTP2Protocol from .rawtcp import RawTcpLayer from .tls import TlsLayer, is_tls_record_magic from .http import Http1Layer, Http2Layer - +from .layer import ServerConnectionMixin +from .http_proxy import HttpProxy, HttpUpstreamProxy +from .reverse_proxy import ReverseProxy class RootContext(object): """ @@ -34,18 +36,33 @@ class RootContext(object): if self.config.check_ignore(top_layer.server_conn.address): return RawTcpLayer(top_layer, logging=False) - # 2. Check for TLS - # TLS ClientHello magic, works for SSLv3, TLSv1.0, TLSv1.1, TLSv1.2 - # http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html#client-hello d = top_layer.client_conn.rfile.peek(3) - if is_tls_record_magic(d): + client_tls = is_tls_record_magic(d) + + # 2. Always insert a TLS layer, even if there's neither client nor server tls. + # An inline script may upgrade from http to https, + # in which case we need some form of TLS layer. + if isinstance(top_layer, ReverseProxy): + return TlsLayer(top_layer, client_tls, top_layer.server_tls) + if isinstance(top_layer, ServerConnectionMixin): + return TlsLayer(top_layer, client_tls, client_tls) + + # 3. In Http Proxy mode and Upstream Proxy mode, the next layer is fixed. + if isinstance(top_layer, TlsLayer): + if isinstance(top_layer.ctx, HttpProxy): + return Http1Layer(top_layer, "regular") + if isinstance(top_layer.ctx, HttpUpstreamProxy): + return Http1Layer(top_layer, "upstream") + + # 4. Check for other TLS cases (e.g. after CONNECT). + if client_tls: return TlsLayer(top_layer, True, True) - # 3. Check for --tcp + # 4. Check for --tcp if self.config.check_tcp(top_layer.server_conn.address): return RawTcpLayer(top_layer) - # 4. Check for TLS ALPN (HTTP1/HTTP2) + # 5. Check for TLS ALPN (HTTP1/HTTP2) if isinstance(top_layer, TlsLayer): alpn = top_layer.client_conn.get_alpn_proto_negotiated() if alpn == HTTP2Protocol.ALPN_PROTO_H2: @@ -53,7 +70,7 @@ class RootContext(object): if alpn == HTTP1Protocol.ALPN_PROTO_HTTP1: return Http1Layer(top_layer, 'transparent') - # 5. Assume HTTP1 by default + # 6. Assume HTTP1 by default return Http1Layer(top_layer, 'transparent') # In a future version, we want to implement TCP passthrough as the last fallback, diff --git a/libmproxy/protocol2/tls.py b/libmproxy/protocol2/tls.py index 0c02b0ea..041adaaa 100644 --- a/libmproxy/protocol2/tls.py +++ b/libmproxy/protocol2/tls.py @@ -18,6 +18,9 @@ def is_tls_record_magic(d): False, otherwise. """ d = d[:3] + + # TLS ClientHello magic, works for SSLv3, TLSv1.0, TLSv1.1, TLSv1.2 + # http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html#client-hello return ( len(d) == 3 and d[0] == '\x16' and @@ -73,6 +76,16 @@ class TlsLayer(Layer): layer = self.ctx.next_layer(self) layer() + def __repr__(self): + if self._client_tls and self._server_tls: + return "TlsLayer(client and server)" + elif self._client_tls: + return "TlsLayer(client)" + elif self._server_tls: + return "TlsLayer(server)" + else: + return "TlsLayer(inactive)" + def _get_client_hello(self): """ Peek into the socket and read all records that contain the initial client hello message. |