ProxyConf: auth_* into Options

This commit is contained in:
Aldo Cortesi 2016-07-19 14:51:12 +12:00
parent 5cfe783b6c
commit be081a24bc
7 changed files with 72 additions and 60 deletions

View File

@ -251,6 +251,9 @@ def get_common_options(args):
replay_ignore_payload_params=args.replay_ignore_payload_params,
replay_ignore_host=args.replay_ignore_host,
auth_nonanonymous = args.auth_nonanonymous,
auth_singleuser = args.auth_singleuser,
auth_htpasswd = args.auth_htpasswd,
add_upstream_certs_to_client_chain = args.add_upstream_certs_to_client_chain,
body_size_limit = body_size_limit,
cadir = args.cadir,

View File

@ -39,6 +39,9 @@ class Options(options.Options):
replay_ignore_host=False, # type: bool
# Proxy options
auth_nonanonymous=False, # type: bool
auth_singleuser=None, # type: Optional[str]
auth_htpasswd=None, # type: Optional[str]
add_upstream_certs_to_client_chain=False, # type: bool
body_size_limit=None, # type: Optional[int]
cadir = cmdline.CA_DIR, # type: str
@ -93,6 +96,9 @@ class Options(options.Options):
self.replay_ignore_host = replay_ignore_host
# Proxy options
self.auth_nonanonymous = auth_nonanonymous
self.auth_singleuser = auth_singleuser
self.auth_htpasswd = auth_htpasswd
self.add_upstream_certs_to_client_chain = add_upstream_certs_to_client_chain
self.body_size_limit = body_size_limit
self.cadir = cadir

View File

@ -70,15 +70,10 @@ def parse_upstream_auth(auth):
class ProxyConfig:
def __init__(
self,
options,
authenticator=None,
):
def __init__(self, options):
self.options = options
self.authenticator = authenticator
self.authenticator = None
self.check_ignore = None
self.check_tcp = None
self.certstore = None
@ -88,6 +83,20 @@ class ProxyConfig:
options.changed.connect(self.configure)
def configure(self, options):
conflict = all(
[
options.add_upstream_certs_to_client_chain,
options.ssl_verify_upstream_cert
]
)
if conflict:
raise exceptions.OptionsError(
"The verify-upstream-cert and add-upstream-certs-to-client-chain "
"options are mutually exclusive. If upstream certificates are verified "
"then extra upstream certificates are not available for inclusion "
"to the client chain."
)
if options.ssl_verify_upstream_cert:
self.openssl_verification_mode_server = SSL.VERIFY_PEER
else:
@ -141,46 +150,46 @@ class ProxyConfig:
if options.upstream_auth:
self.upstream_auth = parse_upstream_auth(options.upstream_auth)
def process_proxy_options(parser, options, args):
if args.add_upstream_certs_to_client_chain and args.ssl_verify_upstream_cert:
return parser.error(
"The verify-upstream-cert and add-upstream-certs-to-client-chain "
"options are mutually exclusive. If upstream certificates are verified "
"then extra upstream certificates are not available for inclusion "
"to the client chain."
self.authenticator = authentication.NullProxyAuth(None)
needsauth = any(
[
options.auth_nonanonymous,
options.auth_singleuser,
options.auth_htpasswd
]
)
if args.auth_nonanonymous or args.auth_singleuser or args.auth_htpasswd:
if args.transparent_proxy:
return parser.error("Proxy Authentication not supported in transparent mode.")
if args.socks_proxy:
return parser.error(
"Proxy Authentication not supported in SOCKS mode. "
"https://github.com/mitmproxy/mitmproxy/issues/738"
if needsauth:
if options.mode == "transparent":
raise exceptions.OptionsError(
"Proxy Authentication not supported in transparent mode."
)
elif options.mode == "socks5":
raise exceptions.OptionsError(
"Proxy Authentication not supported in SOCKS mode. "
"https://github.com/mitmproxy/mitmproxy/issues/738"
)
elif options.auth_singleuser:
parts = options.auth_singleuser.split(':')
if len(parts) != 2:
raise exceptions.OptionsError(
"Invalid single-user specification. "
"Please use the format username:password"
)
password_manager = authentication.PassManSingleUser(*parts)
elif options.auth_nonanonymous:
password_manager = authentication.PassManNonAnon()
elif options.auth_htpasswd:
try:
password_manager = authentication.PassManHtpasswd(
options.auth_htpasswd
)
except ValueError as v:
raise exceptions.OptionsError(str(v))
self.authenticator = authentication.BasicProxyAuth(
password_manager,
"mitmproxy"
)
if args.auth_singleuser:
if len(args.auth_singleuser.split(':')) != 2:
return parser.error(
"Invalid single-user specification. Please use the format username:password"
)
username, password = args.auth_singleuser.split(':')
password_manager = authentication.PassManSingleUser(username, password)
elif args.auth_nonanonymous:
password_manager = authentication.PassManNonAnon()
elif args.auth_htpasswd:
try:
password_manager = authentication.PassManHtpasswd(
args.auth_htpasswd
)
except ValueError as v:
return parser.error(v)
authenticator = authentication.BasicProxyAuth(password_manager, "mitmproxy")
else:
authenticator = authentication.NullProxyAuth(None)
return ProxyConfig(
options,
authenticator=authenticator,
)
def process_proxy_options(parser, options, args):
return ProxyConfig(options)

View File

@ -106,9 +106,7 @@ class _Http2TestBase(object):
def get_proxy_config(cls):
opts = options.Options(listen_port=0, no_upstream_cert=False)
opts.cadir = os.path.join(tempfile.gettempdir(), "mitmproxy")
d = dict(
authenticator=None,
)
d = dict()
return d, opts
@property

View File

@ -103,7 +103,11 @@ class TestProcessProxyOptions:
# self.assert_err("mutually exclusive", "-R", "http://localhost", "-T")
def test_socks_auth(self):
self.assert_err("Proxy Authentication not supported in SOCKS mode.", "--socks", "--nonanonymous")
self.assert_err(
"Proxy Authentication not supported in SOCKS mode.",
"--socks",
"--nonanonymous"
)
def test_client_certs(self):
with tutils.tmpdir() as cadir:

View File

@ -298,13 +298,8 @@ class TestHTTP(tservers.HTTPProxyTest, CommonMixin, AppMixin):
class TestHTTPAuth(tservers.HTTPProxyTest):
authenticator = http.authentication.BasicProxyAuth(
http.authentication.PassManSingleUser(
"test",
"test"),
"realm")
def test_auth(self):
self.master.options.auth_singleuser = "test:test"
assert self.pathod("202").status_code == 407
p = self.pathoc()
ret = p.request("""

View File

@ -78,7 +78,6 @@ class ProxyTestBase(object):
ssl = None
ssloptions = False
no_upstream_cert = False
authenticator = None
masterclass = TestMaster
add_upstream_certs_to_client_chain = False
@ -120,9 +119,7 @@ class ProxyTestBase(object):
@classmethod
def get_proxy_config(cls):
cls.cadir = os.path.join(tempfile.gettempdir(), "mitmproxy")
cnf = dict(
authenticator = cls.authenticator,
)
cnf = dict()
return cnf, options.Options(
listen_port=0,
cadir=cls.cadir,