fix #318
This commit is contained in:
parent
a3c3e4e504
commit
de05484d9d
|
@ -11,14 +11,32 @@ CONF_DIR = "~/.mitmproxy"
|
||||||
|
|
||||||
class ProxyConfig:
|
class ProxyConfig:
|
||||||
def __init__(self, confdir=CONF_DIR, clientcerts=None,
|
def __init__(self, confdir=CONF_DIR, clientcerts=None,
|
||||||
no_upstream_cert=False, body_size_limit=None, get_upstream_server=None,
|
no_upstream_cert=False, body_size_limit=None,
|
||||||
http_form_in="absolute", http_form_out="relative", authenticator=None,
|
mode=None, upstream_server=None, http_form_in=None, http_form_out=None,
|
||||||
ciphers=None, certs=[], certforward = False
|
authenticator=None,
|
||||||
):
|
ciphers=None, certs=[], certforward=False):
|
||||||
self.ciphers = ciphers
|
self.ciphers = ciphers
|
||||||
self.clientcerts = clientcerts
|
self.clientcerts = clientcerts
|
||||||
self.no_upstream_cert = no_upstream_cert
|
self.no_upstream_cert = no_upstream_cert
|
||||||
self.body_size_limit = body_size_limit
|
self.body_size_limit = body_size_limit
|
||||||
|
|
||||||
|
if mode == "transparent":
|
||||||
|
get_upstream_server = TransparentUpstreamServerResolver(platform.resolver(), TRANSPARENT_SSL_PORTS)
|
||||||
|
http_form_in_default, http_form_out_default = "relative", "relative"
|
||||||
|
elif mode == "reverse":
|
||||||
|
get_upstream_server = ConstUpstreamServerResolver(upstream_server)
|
||||||
|
http_form_in_default, http_form_out_default = "relative", "relative"
|
||||||
|
elif mode == "upstream":
|
||||||
|
get_upstream_server = ConstUpstreamServerResolver(upstream_server)
|
||||||
|
http_form_in_default, http_form_out_default = "absolute", "absolute"
|
||||||
|
elif upstream_server:
|
||||||
|
get_upstream_server = ConstUpstreamServerResolver(upstream_server)
|
||||||
|
http_form_in_default, http_form_out_default = "absolute", "relative"
|
||||||
|
else:
|
||||||
|
get_upstream_server, http_form_in_default, http_form_out_default = None, "absolute", "relative"
|
||||||
|
http_form_in = http_form_in or http_form_in_default
|
||||||
|
http_form_out = http_form_out or http_form_out_default
|
||||||
|
|
||||||
self.get_upstream_server = get_upstream_server
|
self.get_upstream_server = get_upstream_server
|
||||||
self.http_form_in = http_form_in
|
self.http_form_in = http_form_in
|
||||||
self.http_form_out = http_form_out
|
self.http_form_out = http_form_out
|
||||||
|
@ -35,32 +53,27 @@ def process_proxy_options(parser, options):
|
||||||
body_size_limit = utils.parse_size(options.body_size_limit)
|
body_size_limit = utils.parse_size(options.body_size_limit)
|
||||||
|
|
||||||
c = 0
|
c = 0
|
||||||
http_form_in, http_form_out = "absolute", "relative"
|
mode, upstream_server = None, None
|
||||||
get_upstream_server = None
|
|
||||||
if options.transparent_proxy:
|
if options.transparent_proxy:
|
||||||
c += 1
|
c += 1
|
||||||
if not platform.resolver:
|
if not platform.resolver:
|
||||||
return parser.error("Transparent mode not supported on this platform.")
|
return parser.error("Transparent mode not supported on this platform.")
|
||||||
get_upstream_server = TransparentUpstreamServerResolver(platform.resolver(), TRANSPARENT_SSL_PORTS)
|
mode = "transparent"
|
||||||
http_form_in, http_form_out = "relative", "relative"
|
|
||||||
if options.reverse_proxy:
|
if options.reverse_proxy:
|
||||||
c += 1
|
c += 1
|
||||||
get_upstream_server = ConstUpstreamServerResolver(options.reverse_proxy)
|
mode = "reverse"
|
||||||
http_form_in, http_form_out = "relative", "relative"
|
upstream_server = options.reverse_proxy
|
||||||
if options.upstream_proxy:
|
if options.upstream_proxy:
|
||||||
c += 1
|
c += 1
|
||||||
get_upstream_server = ConstUpstreamServerResolver(options.upstream_proxy)
|
mode = "upstream"
|
||||||
http_form_in, http_form_out = "absolute", "absolute"
|
upstream_server = options.upstream_proxy
|
||||||
if options.manual_destination_server:
|
if options.manual_destination_server:
|
||||||
c += 1
|
c += 1
|
||||||
get_upstream_server = ConstUpstreamServerResolver(options.manual_destination_server)
|
mode = "manual"
|
||||||
|
upstream_server = options.manual_destination_server
|
||||||
if c > 1:
|
if c > 1:
|
||||||
return parser.error("Transparent mode, reverse mode, upstream proxy mode and "
|
return parser.error("Transparent mode, reverse mode, upstream proxy mode and "
|
||||||
"specification of an upstream server are mutually exclusive.")
|
"specification of an upstream server are mutually exclusive.")
|
||||||
if options.http_form_in:
|
|
||||||
http_form_in = options.http_form_in
|
|
||||||
if options.http_form_out:
|
|
||||||
http_form_out = options.http_form_out
|
|
||||||
|
|
||||||
if options.clientcerts:
|
if options.clientcerts:
|
||||||
options.clientcerts = os.path.expanduser(options.clientcerts)
|
options.clientcerts = os.path.expanduser(options.clientcerts)
|
||||||
|
@ -93,21 +106,22 @@ def process_proxy_options(parser, options):
|
||||||
parts = ["*", parts[0]]
|
parts = ["*", parts[0]]
|
||||||
parts[1] = os.path.expanduser(parts[1])
|
parts[1] = os.path.expanduser(parts[1])
|
||||||
if not os.path.exists(parts[1]):
|
if not os.path.exists(parts[1]):
|
||||||
parser.error("Certificate file does not exist: %s"%parts[1])
|
parser.error("Certificate file does not exist: %s" % parts[1])
|
||||||
certs.append(parts)
|
certs.append(parts)
|
||||||
|
|
||||||
return ProxyConfig(
|
return ProxyConfig(
|
||||||
clientcerts = options.clientcerts,
|
confdir=options.confdir,
|
||||||
body_size_limit = body_size_limit,
|
clientcerts=options.clientcerts,
|
||||||
no_upstream_cert = options.no_upstream_cert,
|
no_upstream_cert=options.no_upstream_cert,
|
||||||
get_upstream_server = get_upstream_server,
|
body_size_limit=body_size_limit,
|
||||||
confdir = options.confdir,
|
mode=mode,
|
||||||
http_form_in = http_form_in,
|
upstream_server=upstream_server,
|
||||||
http_form_out = http_form_out,
|
http_form_in=options.http_form_in,
|
||||||
authenticator = authenticator,
|
http_form_out=options.http_form_out,
|
||||||
ciphers = options.ciphers,
|
authenticator=authenticator,
|
||||||
certs = certs,
|
ciphers=options.ciphers,
|
||||||
certforward = options.certforward,
|
certs=certs,
|
||||||
|
certforward=options.certforward,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,10 +129,10 @@ def ssl_option_group(parser):
|
||||||
group = parser.add_argument_group("SSL")
|
group = parser.add_argument_group("SSL")
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--cert", dest='certs', default=[], type=str,
|
"--cert", dest='certs', default=[], type=str,
|
||||||
metavar = "SPEC", action="append",
|
metavar="SPEC", action="append",
|
||||||
help='Add an SSL certificate. SPEC is of the form "[domain=]path". '\
|
help='Add an SSL certificate. SPEC is of the form "[domain=]path". ' \
|
||||||
'The domain may include a wildcard, and is equal to "*" if not specified. '\
|
'The domain may include a wildcard, and is equal to "*" if not specified. ' \
|
||||||
'The file at path is a certificate in PEM format. If a private key is included in the PEM, '\
|
'The file at path is a certificate in PEM format. If a private key is included in the PEM, ' \
|
||||||
'it is used, else the default key in the conf dir is used. Can be passed multiple times.'
|
'it is used, else the default key in the conf dir is used. Can be passed multiple times.'
|
||||||
)
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
|
|
|
@ -2,6 +2,8 @@ import os.path
|
||||||
import threading, Queue
|
import threading, Queue
|
||||||
import shutil, tempfile
|
import shutil, tempfile
|
||||||
import flask
|
import flask
|
||||||
|
import mock
|
||||||
|
|
||||||
from libmproxy.proxy.config import ProxyConfig
|
from libmproxy.proxy.config import ProxyConfig
|
||||||
from libmproxy.proxy.server import ProxyServer
|
from libmproxy.proxy.server import ProxyServer
|
||||||
from libmproxy.proxy.primitives import TransparentUpstreamServerResolver
|
from libmproxy.proxy.primitives import TransparentUpstreamServerResolver
|
||||||
|
@ -88,28 +90,25 @@ class ProxTestBase(object):
|
||||||
cls.server2 = libpathod.test.Daemon(ssl=cls.ssl, ssloptions=cls.ssloptions)
|
cls.server2 = libpathod.test.Daemon(ssl=cls.ssl, ssloptions=cls.ssloptions)
|
||||||
pconf = cls.get_proxy_config()
|
pconf = cls.get_proxy_config()
|
||||||
cls.confdir = os.path.join(tempfile.gettempdir(), "mitmproxy")
|
cls.confdir = os.path.join(tempfile.gettempdir(), "mitmproxy")
|
||||||
config = ProxyConfig(
|
cls.config = ProxyConfig(
|
||||||
no_upstream_cert = cls.no_upstream_cert,
|
no_upstream_cert = cls.no_upstream_cert,
|
||||||
confdir = cls.confdir,
|
confdir = cls.confdir,
|
||||||
authenticator = cls.authenticator,
|
authenticator = cls.authenticator,
|
||||||
certforward = cls.certforward,
|
certforward = cls.certforward,
|
||||||
**pconf
|
**pconf
|
||||||
)
|
)
|
||||||
tmaster = cls.masterclass(config)
|
tmaster = cls.masterclass(cls.config)
|
||||||
tmaster.start_app(APP_HOST, APP_PORT, cls.externalapp)
|
tmaster.start_app(APP_HOST, APP_PORT, cls.externalapp)
|
||||||
cls.proxy = ProxyThread(tmaster)
|
cls.proxy = ProxyThread(tmaster)
|
||||||
cls.proxy.start()
|
cls.proxy.start()
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def tearDownAll(cls):
|
|
||||||
shutil.rmtree(cls.confdir)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def master(cls):
|
def master(cls):
|
||||||
return cls.proxy.tmaster
|
return cls.proxy.tmaster
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def teardownAll(cls):
|
def teardownAll(cls):
|
||||||
|
shutil.rmtree(cls.confdir)
|
||||||
cls.proxy.shutdown()
|
cls.proxy.shutdown()
|
||||||
cls.server.shutdown()
|
cls.server.shutdown()
|
||||||
cls.server2.shutdown()
|
cls.server2.shutdown()
|
||||||
|
@ -189,16 +188,21 @@ class TResolver:
|
||||||
class TransparentProxTest(ProxTestBase):
|
class TransparentProxTest(ProxTestBase):
|
||||||
ssl = None
|
ssl = None
|
||||||
resolver = TResolver
|
resolver = TResolver
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_proxy_config(cls):
|
@mock.patch("libmproxy.platform.resolver")
|
||||||
d = ProxTestBase.get_proxy_config()
|
def setupAll(cls, _):
|
||||||
|
super(TransparentProxTest, cls).setupAll()
|
||||||
if cls.ssl:
|
if cls.ssl:
|
||||||
ports = [cls.server.port, cls.server2.port]
|
ports = [cls.server.port, cls.server2.port]
|
||||||
else:
|
else:
|
||||||
ports = []
|
ports = []
|
||||||
d["get_upstream_server"] = TransparentUpstreamServerResolver(cls.resolver(cls.server.port), ports)
|
cls.config.get_upstream_server = TransparentUpstreamServerResolver(cls.resolver(cls.server.port), ports)
|
||||||
d["http_form_in"] = "relative"
|
|
||||||
d["http_form_out"] = "relative"
|
@classmethod
|
||||||
|
def get_proxy_config(cls):
|
||||||
|
d = ProxTestBase.get_proxy_config()
|
||||||
|
d["mode"] = "transparent"
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def pathod(self, spec, sni=None):
|
def pathod(self, spec, sni=None):
|
||||||
|
@ -227,7 +231,7 @@ class ReverseProxTest(ProxTestBase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_proxy_config(cls):
|
def get_proxy_config(cls):
|
||||||
d = ProxTestBase.get_proxy_config()
|
d = ProxTestBase.get_proxy_config()
|
||||||
d["get_upstream_server"] = lambda c: (
|
d["upstream_server"] = (
|
||||||
True if cls.ssl else False,
|
True if cls.ssl else False,
|
||||||
True if cls.ssl else False,
|
True if cls.ssl else False,
|
||||||
"127.0.0.1",
|
"127.0.0.1",
|
||||||
|
@ -264,7 +268,7 @@ class ChainProxTest(ProxTestBase):
|
||||||
"""
|
"""
|
||||||
n = 2
|
n = 2
|
||||||
chain_config = [lambda port: ProxyConfig(
|
chain_config = [lambda port: ProxyConfig(
|
||||||
get_upstream_server = lambda c: (False, False, "127.0.0.1", port),
|
upstream_server= (False, False, "127.0.0.1", port),
|
||||||
http_form_in = "absolute",
|
http_form_in = "absolute",
|
||||||
http_form_out = "absolute"
|
http_form_out = "absolute"
|
||||||
)] * n
|
)] * n
|
||||||
|
|
Loading…
Reference in New Issue