aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmproxy/cmdline.py16
-rw-r--r--libmproxy/protocol/tcp.py5
-rw-r--r--libmproxy/proxy/config.py5
-rw-r--r--libmproxy/proxy/server.py39
4 files changed, 42 insertions, 23 deletions
diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py
index c9c0c75e..500337a7 100644
--- a/libmproxy/cmdline.py
+++ b/libmproxy/cmdline.py
@@ -262,9 +262,14 @@ def common_options(parser):
help="Address to bind proxy to (defaults to all interfaces)"
)
group.add_argument(
- "-U",
- action="store", type=parse_server_spec, dest="upstream_proxy", default=None,
- help="Forward all requests to upstream proxy server: http[s]://host[:port]"
+ "-I", "--ignore",
+ action="append", type=str, dest="ignore", default=[],
+ metavar="HOST",
+ help="Ignore host and forward all traffic without processing it. "
+ "In transparent mode, it is recommended to use an IP address (range), not the hostname. "
+ "In regular mode, only SSL traffic is ignored and the hostname should be used. "
+ "The supplied value is interpreted as a regular expression and matched on the ip or the hostname. "
+ "Can be passed multiple times. "
)
group.add_argument(
"-n",
@@ -286,6 +291,11 @@ def common_options(parser):
action="store_true", dest="transparent_proxy", default=False,
help="Set transparent proxy mode."
)
+ group.add_argument(
+ "-U",
+ action="store", type=parse_server_spec, dest="upstream_proxy", default=None,
+ help="Forward all requests to upstream proxy server: http://host[:port]"
+ )
group = parser.add_argument_group(
"Advanced Proxy Options",
diff --git a/libmproxy/protocol/tcp.py b/libmproxy/protocol/tcp.py
index 33c9ff05..a77a9096 100644
--- a/libmproxy/protocol/tcp.py
+++ b/libmproxy/protocol/tcp.py
@@ -1,6 +1,7 @@
from __future__ import absolute_import
import select, socket
from .primitives import ProtocolHandler
+from netlib.utils import cleanBin
class TCPHandler(ProtocolHandler):
"""
@@ -57,9 +58,9 @@ class TCPHandler(ProtocolHandler):
# if one of the peers is over SSL, we need to send bytes/strings
if not src.ssl_established: # only ssl to dst, i.e. we revc'd into buf but need bytes/string now.
contents = buf[:size].tobytes()
- self.c.log("%s %s\r\n%s" % (direction, dst_str, contents[:100]), "debug")
+ self.c.log("%s %s\r\n%s" % (direction, dst_str, cleanBin(contents)), "debug")
dst.connection.send(contents)
else:
# socket.socket.send supports raw bytearrays/memoryviews
- self.c.log("%s %s\r\n%s" % (direction, dst_str, buf[:100]), "debug")
+ self.c.log("%s %s\r\n%s" % (direction, dst_str, cleanBin(buf.tobytes())), "debug")
dst.connection.send(buf[:size]) \ No newline at end of file
diff --git a/libmproxy/proxy/config.py b/libmproxy/proxy/config.py
index a6a962ea..afa7440c 100644
--- a/libmproxy/proxy/config.py
+++ b/libmproxy/proxy/config.py
@@ -1,6 +1,7 @@
from __future__ import absolute_import
import os
from .. import utils, platform
+import re
from netlib import http_auth, certutils
from .primitives import ConstUpstreamServerResolver, TransparentUpstreamServerResolver
@@ -13,7 +14,7 @@ class ProxyConfig:
def __init__(self, confdir=CONF_DIR, clientcerts=None,
no_upstream_cert=False, body_size_limit=None,
mode=None, upstream_server=None, http_form_in=None, http_form_out=None,
- authenticator=None,
+ authenticator=None, ignore=[],
ciphers=None, certs=[], certforward=False):
self.ciphers = ciphers
self.clientcerts = clientcerts
@@ -40,6 +41,7 @@ class ProxyConfig:
self.get_upstream_server = get_upstream_server
self.http_form_in = http_form_in
self.http_form_out = http_form_out
+ self.ignore = [re.compile(i, re.IGNORECASE) for i in ignore]
self.authenticator = authenticator
self.confdir = os.path.expanduser(confdir)
self.ca_file = os.path.join(self.confdir, CONF_BASENAME + "-ca.pem")
@@ -118,6 +120,7 @@ def process_proxy_options(parser, options):
upstream_server=upstream_server,
http_form_in=options.http_form_in,
http_form_out=options.http_form_out,
+ ignore=options.ignore,
authenticator=authenticator,
ciphers=options.ciphers,
certs=certs,
diff --git a/libmproxy/proxy/server.py b/libmproxy/proxy/server.py
index 345e1507..d4a97e6a 100644
--- a/libmproxy/proxy/server.py
+++ b/libmproxy/proxy/server.py
@@ -1,4 +1,5 @@
from __future__ import absolute_import
+import re
import socket
from OpenSSL import SSL
@@ -66,31 +67,34 @@ class ConnectionHandler:
self.channel, self.server_version = channel, server_version
self.close = False
- self.conntype = None
+ self.conntype = "http"
self.sni = None
def handle(self):
self.log("clientconnect", "info")
- self.channel.ask("clientconnect", self)
-
- self.determine_conntype()
try:
# Can we already identify the target server and connect to it?
+ client_ssl, server_ssl = False, False
if self.config.get_upstream_server:
upstream_info = self.config.get_upstream_server(
self.client_conn.connection)
self.set_server_address(upstream_info[2:], AddressPriority.FROM_SETTINGS)
client_ssl, server_ssl = upstream_info[:2]
+
+ self.determine_conntype()
+ self.channel.ask("clientconnect", self)
+
+ if self.server_conn:
+ self.establish_server_connection()
if client_ssl or server_ssl:
- self.establish_server_connection()
self.establish_ssl(client=client_ssl, server=server_ssl)
while not self.close:
try:
handle_messages(self.conntype, self)
except ConnectionTypeChange:
- self.log("Connection Type Changed: %s" % self.conntype, "info")
+ self.log("Connection type changed: %s" % self.conntype, "info")
continue
except (ProxyError, tcp.NetLibError), e:
@@ -121,8 +125,11 @@ class ConnectionHandler:
self.sni = None
def determine_conntype(self):
- #TODO: Add ruleset to select correct protocol depending on mode/target port etc.
- self.conntype = "http"
+ if self.server_conn and any(rex.search(self.server_conn.address.host) for rex in self.config.ignore):
+ self.log("Ignore host: %s" % self.server_conn.address.host, "info")
+ self.conntype = "tcp"
+ else:
+ self.conntype = "http"
def set_server_address(self, address, priority):
"""
@@ -135,7 +142,7 @@ class ConnectionHandler:
if self.server_conn.priority > priority:
self.log("Attempt to change server address, "
"but priority is too low (is: %s, got: %s)" % (
- self.server_conn.priority, priority), "info")
+ self.server_conn.priority, priority), "debug")
return
if self.server_conn.address == address:
self.server_conn.priority = priority # Possibly increase priority
@@ -171,14 +178,12 @@ class ConnectionHandler:
as specified by the parameters. If the target server is on the pass-through list,
the conntype attribute will be changed and a ConnTypeChanged exception will be raised.
"""
- # TODO: Implement SSL pass-through handling and change conntype
- passthrough = [
- # "echo.websocket.org",
- # "174.129.224.73" # echo.websocket.org, transparent mode
- ]
- if self.server_conn.address.host in passthrough or self.sni in passthrough:
- self.conntype = "tcp"
- raise ConnectionTypeChange
+ # If the host is on our ignore list, change to passthrough/ignore mode.
+ for host in (self.server_conn.address.host, self.sni):
+ if host and any(rex.search(host) for rex in self.config.ignore):
+ self.log("Ignore host: %s" % host, "info")
+ self.conntype = "tcp"
+ raise ConnectionTypeChange()
# Logging
if client or server: