From 59ec291b6cff1dfa83b316401418b6308df93aac Mon Sep 17 00:00:00 2001 From: iroiro123 Date: Thu, 18 Jun 2015 23:53:27 +0900 Subject: [PATCH] HTTP Transparent Proxy --- libmproxy/cmdline.py | 5 +++++ libmproxy/protocol/http.py | 15 ++++++++++++++- libmproxy/proxy/config.py | 7 ++++++- libmproxy/proxy/primitives.py | 8 ++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py index eb24bed7a..d0e54dfe2 100644 --- a/libmproxy/cmdline.py +++ b/libmproxy/cmdline.py @@ -362,6 +362,11 @@ def common_options(parser): action="store_true", dest="transparent_proxy", default=False, help="Set transparent proxy mode." ) + group.add_argument( + "-H", "--http-transparent", + action="store_true", dest="http_transparent_proxy", default=False, + help="Use the Host header to connect to server." + ) group.add_argument( "-U", "--upstream", action="store", diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py index 9c1433865..c7479b762 100644 --- a/libmproxy/protocol/http.py +++ b/libmproxy/protocol/http.py @@ -1328,7 +1328,20 @@ class HTTPHandler(ProtocolHandler): # value at flow.server_conn self.c.set_server_address((request.host, request.port)) flow.server_conn = self.c.server_conn - + + elif request.form_in == "relative": + if self.c.config.mode == "httptransparent": + h = request.headers.get_first("host") + if h is None: + raise http.HttpError( + 400, + "Invalid request: No Host header" + ) + p = http.parse_url("http://" + h) + request.host, request.port = p[1], p[2] + self.c.set_server_address((request.host, request.port)) + flow.server_conn = self.c.server_conn + return None raise http.HttpError( 400, "Invalid HTTP request form (expected: %s, got: %s)" % ( diff --git a/libmproxy/proxy/config.py b/libmproxy/proxy/config.py index 3f5796694..2074d0bf7 100644 --- a/libmproxy/proxy/config.py +++ b/libmproxy/proxy/config.py @@ -4,7 +4,7 @@ import re from OpenSSL import SSL from netlib import http_auth, certutils, tcp from .. import utils, platform, version -from .primitives import RegularProxyMode, TransparentProxyMode, UpstreamProxyMode, ReverseProxyMode, Socks5ProxyMode +from .primitives import RegularProxyMode, HTTPTransparentProxyMode, TransparentProxyMode, UpstreamProxyMode, ReverseProxyMode, Socks5ProxyMode TRANSPARENT_SSL_PORTS = [443, 8443] CONF_BASENAME = "mitmproxy" @@ -70,6 +70,8 @@ class ProxyConfig: self.mode = ReverseProxyMode(upstream_server) elif mode == "upstream": self.mode = UpstreamProxyMode(upstream_server) + elif mode == "httptransparent": + self.mode = HTTPTransparentProxyMode() else: self.mode = RegularProxyMode() @@ -144,6 +146,9 @@ def process_proxy_options(parser, options): c += 1 mode = "upstream" upstream_server = options.upstream_proxy + if options.http_transparent_proxy: + c += 1 + mode = "httptransparent" if c > 1: return parser.error( "Transparent, SOCKS5, reverse and upstream proxy mode " diff --git a/libmproxy/proxy/primitives.py b/libmproxy/proxy/primitives.py index 9e7dae9af..a9718051f 100644 --- a/libmproxy/proxy/primitives.py +++ b/libmproxy/proxy/primitives.py @@ -51,6 +51,14 @@ class RegularProxyMode(ProxyMode): return None +class HTTPTransparentProxyMode(ProxyMode): + http_form_in = "relative" + http_form_out = "relative" + + def get_upstream_server(self, client_conn): + return None + + class TransparentProxyMode(ProxyMode): http_form_in = "relative" http_form_out = "relative"