diff options
Diffstat (limited to 'mitmproxy/libmproxy/proxy/modes')
-rw-r--r-- | mitmproxy/libmproxy/proxy/modes/__init__.py | 12 | ||||
-rw-r--r-- | mitmproxy/libmproxy/proxy/modes/http_proxy.py | 28 | ||||
-rw-r--r-- | mitmproxy/libmproxy/proxy/modes/reverse_proxy.py | 18 | ||||
-rw-r--r-- | mitmproxy/libmproxy/proxy/modes/socks_proxy.py | 66 | ||||
-rw-r--r-- | mitmproxy/libmproxy/proxy/modes/transparent_proxy.py | 25 |
5 files changed, 149 insertions, 0 deletions
diff --git a/mitmproxy/libmproxy/proxy/modes/__init__.py b/mitmproxy/libmproxy/proxy/modes/__init__.py new file mode 100644 index 00000000..f014ed98 --- /dev/null +++ b/mitmproxy/libmproxy/proxy/modes/__init__.py @@ -0,0 +1,12 @@ +from __future__ import (absolute_import, print_function, division) +from .http_proxy import HttpProxy, HttpUpstreamProxy +from .reverse_proxy import ReverseProxy +from .socks_proxy import Socks5Proxy +from .transparent_proxy import TransparentProxy + +__all__ = [ + "HttpProxy", "HttpUpstreamProxy", + "ReverseProxy", + "Socks5Proxy", + "TransparentProxy" +] diff --git a/mitmproxy/libmproxy/proxy/modes/http_proxy.py b/mitmproxy/libmproxy/proxy/modes/http_proxy.py new file mode 100644 index 00000000..e19062b9 --- /dev/null +++ b/mitmproxy/libmproxy/proxy/modes/http_proxy.py @@ -0,0 +1,28 @@ +from __future__ import (absolute_import, print_function, division) + +from ...protocol import Layer, ServerConnectionMixin + + +class HttpProxy(Layer, ServerConnectionMixin): + + def __call__(self): + layer = self.ctx.next_layer(self) + try: + layer() + finally: + if self.server_conn: + self.disconnect() + + +class HttpUpstreamProxy(Layer, ServerConnectionMixin): + + def __init__(self, ctx, server_address): + super(HttpUpstreamProxy, self).__init__(ctx, server_address=server_address) + + def __call__(self): + layer = self.ctx.next_layer(self) + try: + layer() + finally: + if self.server_conn: + self.disconnect() diff --git a/mitmproxy/libmproxy/proxy/modes/reverse_proxy.py b/mitmproxy/libmproxy/proxy/modes/reverse_proxy.py new file mode 100644 index 00000000..c8e80a10 --- /dev/null +++ b/mitmproxy/libmproxy/proxy/modes/reverse_proxy.py @@ -0,0 +1,18 @@ +from __future__ import (absolute_import, print_function, division) + +from ...protocol import Layer, ServerConnectionMixin + + +class ReverseProxy(Layer, ServerConnectionMixin): + + def __init__(self, ctx, server_address, server_tls): + super(ReverseProxy, self).__init__(ctx, server_address=server_address) + self.server_tls = server_tls + + def __call__(self): + layer = self.ctx.next_layer(self) + try: + layer() + finally: + if self.server_conn: + self.disconnect() diff --git a/mitmproxy/libmproxy/proxy/modes/socks_proxy.py b/mitmproxy/libmproxy/proxy/modes/socks_proxy.py new file mode 100644 index 00000000..e2ce44ae --- /dev/null +++ b/mitmproxy/libmproxy/proxy/modes/socks_proxy.py @@ -0,0 +1,66 @@ +from __future__ import (absolute_import, print_function, division) + +from netlib import socks, tcp +from netlib.exceptions import TcpException + +from ...exceptions import Socks5ProtocolException +from ...protocol import Layer, ServerConnectionMixin + + +class Socks5Proxy(Layer, ServerConnectionMixin): + + def __init__(self, ctx): + super(Socks5Proxy, self).__init__(ctx) + + def __call__(self): + try: + # Parse Client Greeting + client_greet = socks.ClientGreeting.from_file(self.client_conn.rfile, fail_early=True) + client_greet.assert_socks5() + if socks.METHOD.NO_AUTHENTICATION_REQUIRED not in client_greet.methods: + raise socks.SocksError( + socks.METHOD.NO_ACCEPTABLE_METHODS, + "mitmproxy only supports SOCKS without authentication" + ) + + # Send Server Greeting + server_greet = socks.ServerGreeting( + socks.VERSION.SOCKS5, + socks.METHOD.NO_AUTHENTICATION_REQUIRED + ) + server_greet.to_file(self.client_conn.wfile) + self.client_conn.wfile.flush() + + # Parse Connect Request + connect_request = socks.Message.from_file(self.client_conn.rfile) + connect_request.assert_socks5() + if connect_request.msg != socks.CMD.CONNECT: + raise socks.SocksError( + socks.REP.COMMAND_NOT_SUPPORTED, + "mitmproxy only supports SOCKS5 CONNECT." + ) + + # We always connect lazily, but we need to pretend to the client that we connected. + connect_reply = socks.Message( + socks.VERSION.SOCKS5, + socks.REP.SUCCEEDED, + connect_request.atyp, + # dummy value, we don't have an upstream connection yet. + connect_request.addr + ) + connect_reply.to_file(self.client_conn.wfile) + self.client_conn.wfile.flush() + + except (socks.SocksError, TcpException) as e: + raise Socks5ProtocolException("SOCKS5 mode failure: %s" % repr(e)) + + # https://github.com/mitmproxy/mitmproxy/issues/839 + address_bytes = (connect_request.addr.host.encode("idna"), connect_request.addr.port) + self.server_conn.address = tcp.Address(address_bytes, connect_request.addr.use_ipv6) + + layer = self.ctx.next_layer(self) + try: + layer() + finally: + if self.server_conn: + self.disconnect() diff --git a/mitmproxy/libmproxy/proxy/modes/transparent_proxy.py b/mitmproxy/libmproxy/proxy/modes/transparent_proxy.py new file mode 100644 index 00000000..3fdda656 --- /dev/null +++ b/mitmproxy/libmproxy/proxy/modes/transparent_proxy.py @@ -0,0 +1,25 @@ +from __future__ import (absolute_import, print_function, division) + +from ... import platform +from ...exceptions import ProtocolException +from ...protocol import Layer, ServerConnectionMixin + + +class TransparentProxy(Layer, ServerConnectionMixin): + + def __init__(self, ctx): + super(TransparentProxy, self).__init__(ctx) + self.resolver = platform.resolver() + + def __call__(self): + try: + self.server_conn.address = self.resolver.original_addr(self.client_conn.connection) + except Exception as e: + raise ProtocolException("Transparent mode failure: %s" % repr(e)) + + layer = self.ctx.next_layer(self) + try: + layer() + finally: + if self.server_conn: + self.disconnect() |