aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/protocol2
diff options
context:
space:
mode:
Diffstat (limited to 'libmproxy/protocol2')
-rw-r--r--libmproxy/protocol2/__init__.py7
-rw-r--r--libmproxy/protocol2/reverse_proxy.py5
-rw-r--r--libmproxy/protocol2/root_context.py10
-rw-r--r--libmproxy/protocol2/socks_proxy.py2
-rw-r--r--libmproxy/protocol2/tls.py38
5 files changed, 42 insertions, 20 deletions
diff --git a/libmproxy/protocol2/__init__.py b/libmproxy/protocol2/__init__.py
index d5dafaae..61b9a77e 100644
--- a/libmproxy/protocol2/__init__.py
+++ b/libmproxy/protocol2/__init__.py
@@ -3,8 +3,11 @@ from .root_context import RootContext
from .socks_proxy import Socks5Proxy
from .reverse_proxy import ReverseProxy
from .http_proxy import HttpProxy, HttpUpstreamProxy
-from .rawtcp import RawTcpLayer
+from .transparent_proxy import TransparentProxy
+from .http import make_error_response
__all__ = [
- "Socks5Proxy", "RawTcpLayer", "RootContext", "ReverseProxy", "HttpProxy", "HttpUpstreamProxy"
+ "RootContext",
+ "Socks5Proxy", "ReverseProxy", "HttpProxy", "HttpUpstreamProxy", "TransparentProxy",
+ "make_error_response"
]
diff --git a/libmproxy/protocol2/reverse_proxy.py b/libmproxy/protocol2/reverse_proxy.py
index 9d5a4beb..76163c71 100644
--- a/libmproxy/protocol2/reverse_proxy.py
+++ b/libmproxy/protocol2/reverse_proxy.py
@@ -12,10 +12,7 @@ class ReverseProxy(Layer, ServerConnectionMixin):
self._server_tls = server_tls
def __call__(self):
- if self._client_tls or self._server_tls:
- layer = TlsLayer(self, self._client_tls, self._server_tls)
- else:
- layer = self.ctx.next_layer(self)
+ layer = TlsLayer(self, self._client_tls, self._server_tls)
try:
layer()
diff --git a/libmproxy/protocol2/root_context.py b/libmproxy/protocol2/root_context.py
index 78d48453..af0e7a37 100644
--- a/libmproxy/protocol2/root_context.py
+++ b/libmproxy/protocol2/root_context.py
@@ -4,7 +4,7 @@ from netlib.http.http1 import HTTP1Protocol
from netlib.http.http2 import HTTP2Protocol
from .rawtcp import RawTcpLayer
-from .tls import TlsLayer
+from .tls import TlsLayer, is_tls_record_magic
from .http import Http1Layer, Http2Layer
@@ -38,13 +38,7 @@ class RootContext(object):
# 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)
- is_tls_client_hello = (
- len(d) == 3 and
- d[0] == '\x16' and
- d[1] == '\x03' and
- d[2] in ('\x00', '\x01', '\x02', '\x03')
- )
- if is_tls_client_hello:
+ if is_tls_record_magic(d):
return TlsLayer(top_layer, True, True)
# 3. Check for --tcp
diff --git a/libmproxy/protocol2/socks_proxy.py b/libmproxy/protocol2/socks_proxy.py
index 18b363d5..91935d24 100644
--- a/libmproxy/protocol2/socks_proxy.py
+++ b/libmproxy/protocol2/socks_proxy.py
@@ -8,7 +8,7 @@ from .layer import Layer, ServerConnectionMixin
class Socks5Proxy(Layer, ServerConnectionMixin):
def __call__(self):
try:
- s5mode = Socks5ProxyMode(self.config.ssl_ports)
+ s5mode = Socks5ProxyMode([])
address = s5mode.get_upstream_server(self.client_conn)[2:]
except ProxyError as e:
# TODO: Unmonkeypatch
diff --git a/libmproxy/protocol2/tls.py b/libmproxy/protocol2/tls.py
index b1b80034..850bf5dc 100644
--- a/libmproxy/protocol2/tls.py
+++ b/libmproxy/protocol2/tls.py
@@ -11,6 +11,21 @@ from ..exceptions import ProtocolException
from .layer import Layer
+def is_tls_record_magic(d):
+ """
+ Returns:
+ True, if the passed bytes start with the TLS record magic bytes.
+ False, otherwise.
+ """
+ d = d[:3]
+ return (
+ len(d) == 3 and
+ d[0] == '\x16' and
+ d[1] == '\x03' and
+ d[2] in ('\x00', '\x01', '\x02', '\x03')
+ )
+
+
class TlsLayer(Layer):
def __init__(self, ctx, client_tls, server_tls):
self.client_sni = None
@@ -69,9 +84,13 @@ class TlsLayer(Layer):
client_hello_size = 1
offset = 0
while len(client_hello) < client_hello_size:
- record_header = self.client_conn.rfile.peek(offset+5)[offset:]
+ record_header = self.client_conn.rfile.peek(offset + 5)[offset:]
+ if not is_tls_record_magic(record_header) or len(record_header) != 5:
+ raise ProtocolException('Expected TLS record, got "%s" instead.' % record_header)
record_size = struct.unpack("!H", record_header[3:])[0] + 5
- record_body = self.client_conn.rfile.peek(offset+record_size)[offset+5:]
+ record_body = self.client_conn.rfile.peek(offset + record_size)[offset + 5:]
+ if len(record_body) != record_size - 5:
+ raise ProtocolException("Unexpected EOF in TLS handshake: %s" % record_body)
client_hello += record_body
offset += record_size
client_hello_size = struct.unpack("!I", '\x00' + client_hello[1:4])[0] + 4
@@ -81,7 +100,12 @@ class TlsLayer(Layer):
"""
Peek into the connection, read the initial client hello and parse it to obtain ALPN values.
"""
- raw_client_hello = self._get_client_hello()[4:] # exclude handshake header.
+ try:
+ raw_client_hello = self._get_client_hello()[4:] # exclude handshake header.
+ except ProtocolException as e:
+ self.log("Cannot parse Client Hello: %s" % repr(e), "error")
+ return
+
try:
client_hello = ClientHello.parse(raw_client_hello)
except ConstructError as e:
@@ -97,7 +121,10 @@ class TlsLayer(Layer):
elif extension.type == 0x10:
self.client_alpn_protocols = list(extension.alpn_protocols)
- self.log("Parsed Client Hello: sni=%s, alpn=%s" % (self.client_sni, self.client_alpn_protocols), "debug")
+ self.log(
+ "Parsed Client Hello: sni=%s, alpn=%s" % (self.client_sni, self.client_alpn_protocols),
+ "debug"
+ )
def connect(self):
if not self.server_conn:
@@ -226,7 +253,8 @@ class TlsLayer(Layer):
host = self.server_conn.address.host
sans = set()
# Incorporate upstream certificate
- if self.server_conn and self.server_conn.tls_established and (not self.config.no_upstream_cert):
+ if self.server_conn and self.server_conn.tls_established and (
+ not self.config.no_upstream_cert):
upstream_cert = self.server_conn.cert
sans.update(upstream_cert.altnames)
if upstream_cert.cn: