diff options
-rw-r--r-- | issue_template.md | 8 | ||||
-rw-r--r-- | mitmproxy/addons/__init__.py | 2 | ||||
-rw-r--r-- | mitmproxy/addons/allowremote.py | 29 | ||||
-rw-r--r-- | mitmproxy/addons/script.py | 17 | ||||
-rw-r--r-- | test/mitmproxy/addons/test_allowremote.py | 38 | ||||
-rw-r--r-- | test/mitmproxy/addons/test_script.py | 24 | ||||
-rw-r--r-- | test/mitmproxy/data/addonscripts/same_filename/addon.py | 1 |
7 files changed, 108 insertions, 11 deletions
diff --git a/issue_template.md b/issue_template.md index 5c5f95ed..0ac2afe9 100644 --- a/issue_template.md +++ b/issue_template.md @@ -11,10 +11,4 @@ ##### System information - -<!-- - Cut and paste the output of "mitmproxy --version". - - If you're using an older version if mitmproxy, please specify the version - and OS. ---> +<!-- Paste the output of "mitmproxy --version" here. --> diff --git a/mitmproxy/addons/__init__.py b/mitmproxy/addons/__init__.py index 783a2c94..24cf2270 100644 --- a/mitmproxy/addons/__init__.py +++ b/mitmproxy/addons/__init__.py @@ -1,3 +1,4 @@ +from mitmproxy.addons import allowremote from mitmproxy.addons import anticache from mitmproxy.addons import anticomp from mitmproxy.addons import check_alpn @@ -25,6 +26,7 @@ def default_addons(): return [ core.Core(), core_option_validation.CoreOptionValidation(), + allowremote.AllowRemote(), anticache.AntiCache(), anticomp.AntiComp(), check_alpn.CheckALPN(), diff --git a/mitmproxy/addons/allowremote.py b/mitmproxy/addons/allowremote.py new file mode 100644 index 00000000..f1d3d8fb --- /dev/null +++ b/mitmproxy/addons/allowremote.py @@ -0,0 +1,29 @@ +import ipaddress +from mitmproxy import ctx + + +class AllowRemote: + def load(self, loader): + loader.add_option( + "allow_remote", bool, False, + """ + Allow remote clients to connect to proxy. If set to false, + client will not be able to connect to proxy unless it is on the same network + or the proxyauth option is set + """ + ) + + def clientconnect(self, layer): + address = layer.client_conn.address + + accept_connection = ( + ctx.options.allow_remote or + ipaddress.ip_address(address[0]).is_private or + ctx.options.proxyauth is not None + ) + + if not accept_connection: + layer.reply.kill() + ctx.log.warn("Client connection was killed because allow_remote option is set to false, " + "client IP was not a private IP and proxyauth was not set.\n" + "To allow remote connections set allow_remote option to true or set proxyauth option.") diff --git a/mitmproxy/addons/script.py b/mitmproxy/addons/script.py index b4274f8c..3e60fe67 100644 --- a/mitmproxy/addons/script.py +++ b/mitmproxy/addons/script.py @@ -1,5 +1,6 @@ import os -import importlib +import importlib.util +import importlib.machinery import time import sys import typing @@ -16,12 +17,21 @@ def load_script(actx, path): if not os.path.exists(path): ctx.log.info("No such file: %s" % path) return - loader = importlib.machinery.SourceFileLoader(os.path.basename(path), path) + + fullname = "__mitmproxy_script__.{}".format( + os.path.splitext(os.path.basename(path))[0] + ) + # the fullname is not unique among scripts, so if there already is an existing script with said + # fullname, remove it. + sys.modules.pop(fullname, None) try: oldpath = sys.path sys.path.insert(0, os.path.dirname(path)) with addonmanager.safecall(): - m = loader.load_module() + loader = importlib.machinery.SourceFileLoader(fullname, path) + spec = importlib.util.spec_from_loader(fullname, loader=loader) + m = importlib.util.module_from_spec(spec) + loader.exec_module(m) if not getattr(m, "name", None): m.name = path return m @@ -64,7 +74,6 @@ class Script: ctx.log.info("Loading script: %s" % self.path) if self.ns: ctx.master.addons.remove(self.ns) - del sys.modules[self.ns.__name__] self.ns = load_script(ctx, self.fullpath) if self.ns: # We're already running, so we have to explicitly register and diff --git a/test/mitmproxy/addons/test_allowremote.py b/test/mitmproxy/addons/test_allowremote.py new file mode 100644 index 00000000..9fc71525 --- /dev/null +++ b/test/mitmproxy/addons/test_allowremote.py @@ -0,0 +1,38 @@ +from unittest import mock +import pytest + +from mitmproxy.addons import allowremote +from mitmproxy.test import taddons + + +@pytest.mark.parametrize("allow_remote, ip, should_be_killed", [ + (True, "192.168.1.3", False), + (True, "122.176.243.101", False), + (False, "192.168.1.3", False), + (False, "122.176.243.101", True), + (True, "::ffff:1:2", False), + (True, "fe80::", False), + (True, "2001:4860:4860::8888", False), + (False, "::ffff:1:2", False), + (False, "fe80::", False), + (False, "2001:4860:4860::8888", True), +]) +def test_allowremote(allow_remote, ip, should_be_killed): + ar = allowremote.AllowRemote() + with taddons.context() as tctx: + tctx.master.addons.register(ar) + tctx.options.allow_remote = allow_remote + + with mock.patch('mitmproxy.proxy.protocol.base.Layer') as layer: + layer.client_conn.address = (ip, 12345) + + ar.clientconnect(layer) + if should_be_killed: + assert tctx.master.has_log("Client connection was killed", "warn") + else: + assert tctx.master.logs == [] + tctx.master.clear() + + tctx.options.proxyauth = "any" + ar.clientconnect(layer) + assert tctx.master.logs == [] diff --git a/test/mitmproxy/addons/test_script.py b/test/mitmproxy/addons/test_script.py index 03b1f620..b7e6c82a 100644 --- a/test/mitmproxy/addons/test_script.py +++ b/test/mitmproxy/addons/test_script.py @@ -30,6 +30,30 @@ def test_load_script(): assert not ns +def test_load_fullname(): + """ + Test that loading two scripts at locations a/foo.py and b/foo.py works. + This only succeeds if they get assigned different basenames. + + """ + with taddons.context() as tctx: + ns = script.load_script( + tctx.ctx(), + tutils.test_data.path( + "mitmproxy/data/addonscripts/addon.py" + ) + ) + assert ns.addons + ns2 = script.load_script( + tctx.ctx(), + tutils.test_data.path( + "mitmproxy/data/addonscripts/same_filename/addon.py" + ) + ) + assert ns.name != ns2.name + assert not hasattr(ns2, "addons") + + def test_script_print_stdout(): with taddons.context() as tctx: with mock.patch('mitmproxy.ctx.log.warn') as mock_warn: diff --git a/test/mitmproxy/data/addonscripts/same_filename/addon.py b/test/mitmproxy/data/addonscripts/same_filename/addon.py new file mode 100644 index 00000000..c84a9b13 --- /dev/null +++ b/test/mitmproxy/data/addonscripts/same_filename/addon.py @@ -0,0 +1 @@ +foo = 42 |