mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-30 03:14:22 +00:00
Merge pull request #988 from xhy940801/master
Add upstream proxy authentication
This commit is contained in:
commit
d7e9dda85c
@ -1,6 +1,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import base64
|
||||||
|
|
||||||
import configargparse
|
import configargparse
|
||||||
|
|
||||||
@ -117,6 +118,15 @@ def parse_server_spec(url):
|
|||||||
return config.ServerSpec(scheme, address)
|
return config.ServerSpec(scheme, address)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_upstream_auth(auth):
|
||||||
|
pattern = re.compile(".+:")
|
||||||
|
if pattern.search(auth) is None:
|
||||||
|
raise configargparse.ArgumentTypeError(
|
||||||
|
"Invalid upstream auth specification: %s" % auth
|
||||||
|
)
|
||||||
|
return "Basic" + " " + base64.b64encode(auth)
|
||||||
|
|
||||||
|
|
||||||
def get_common_options(options):
|
def get_common_options(options):
|
||||||
stickycookie, stickyauth = None, None
|
stickycookie, stickyauth = None, None
|
||||||
if options.stickycookie_filt:
|
if options.stickycookie_filt:
|
||||||
@ -370,6 +380,15 @@ def proxy_options(parser):
|
|||||||
If your OpenSSL version supports ALPN, HTTP/2 is enabled by default.
|
If your OpenSSL version supports ALPN, HTTP/2 is enabled by default.
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--upstream-auth",
|
||||||
|
action="store", dest="upstream_auth", default=None,
|
||||||
|
type=parse_upstream_auth,
|
||||||
|
help="""
|
||||||
|
Proxy Authentication:
|
||||||
|
username:password
|
||||||
|
"""
|
||||||
|
)
|
||||||
rawtcp = group.add_mutually_exclusive_group()
|
rawtcp = group.add_mutually_exclusive_group()
|
||||||
rawtcp.add_argument("--raw-tcp", action="store_true", dest="rawtcp")
|
rawtcp.add_argument("--raw-tcp", action="store_true", dest="rawtcp")
|
||||||
rawtcp.add_argument("--no-raw-tcp", action="store_false", dest="rawtcp",
|
rawtcp.add_argument("--no-raw-tcp", action="store_false", dest="rawtcp",
|
||||||
|
@ -192,6 +192,9 @@ class HTTPRequest(MessageMixin, Request):
|
|||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return id(self)
|
return id(self)
|
||||||
|
|
||||||
|
def set_auth(self, auth):
|
||||||
|
self.data.headers.set_all("Proxy-Authorization", (auth,))
|
||||||
|
|
||||||
def replace(self, pattern, repl, *args, **kwargs):
|
def replace(self, pattern, repl, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Replaces a regular expression pattern with repl in the headers, the
|
Replaces a regular expression pattern with repl in the headers, the
|
||||||
|
@ -179,6 +179,9 @@ class HttpLayer(Layer):
|
|||||||
try:
|
try:
|
||||||
flow = HTTPFlow(self.client_conn, self.server_conn, live=self)
|
flow = HTTPFlow(self.client_conn, self.server_conn, live=self)
|
||||||
flow.request = request
|
flow.request = request
|
||||||
|
# set upstream auth
|
||||||
|
if self.mode == "upstream" and self.config.upstream_auth is not None:
|
||||||
|
flow.request.set_auth(self.config.upstream_auth)
|
||||||
self.process_request_hook(flow)
|
self.process_request_hook(flow)
|
||||||
|
|
||||||
if not flow.response:
|
if not flow.response:
|
||||||
|
@ -53,6 +53,7 @@ class ProxyConfig:
|
|||||||
body_size_limit=None,
|
body_size_limit=None,
|
||||||
mode="regular",
|
mode="regular",
|
||||||
upstream_server=None,
|
upstream_server=None,
|
||||||
|
upstream_auth = None,
|
||||||
authenticator=None,
|
authenticator=None,
|
||||||
ignore_hosts=tuple(),
|
ignore_hosts=tuple(),
|
||||||
tcp_hosts=tuple(),
|
tcp_hosts=tuple(),
|
||||||
@ -77,8 +78,10 @@ class ProxyConfig:
|
|||||||
self.mode = mode
|
self.mode = mode
|
||||||
if upstream_server:
|
if upstream_server:
|
||||||
self.upstream_server = ServerSpec(upstream_server[0], Address.wrap(upstream_server[1]))
|
self.upstream_server = ServerSpec(upstream_server[0], Address.wrap(upstream_server[1]))
|
||||||
|
self.upstream_auth = upstream_auth
|
||||||
else:
|
else:
|
||||||
self.upstream_server = None
|
self.upstream_server = None
|
||||||
|
self.upstream_auth = None
|
||||||
|
|
||||||
self.check_ignore = HostMatcher(ignore_hosts)
|
self.check_ignore = HostMatcher(ignore_hosts)
|
||||||
self.check_tcp = HostMatcher(tcp_hosts)
|
self.check_tcp = HostMatcher(tcp_hosts)
|
||||||
@ -110,7 +113,7 @@ 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
|
||||||
mode, upstream_server = "regular", None
|
mode, upstream_server, upstream_auth = "regular", None, None
|
||||||
if options.transparent_proxy:
|
if options.transparent_proxy:
|
||||||
c += 1
|
c += 1
|
||||||
if not platform.resolver:
|
if not platform.resolver:
|
||||||
@ -127,6 +130,7 @@ def process_proxy_options(parser, options):
|
|||||||
c += 1
|
c += 1
|
||||||
mode = "upstream"
|
mode = "upstream"
|
||||||
upstream_server = options.upstream_proxy
|
upstream_server = options.upstream_proxy
|
||||||
|
upstream_auth = options.upstream_auth
|
||||||
if c > 1:
|
if c > 1:
|
||||||
return parser.error(
|
return parser.error(
|
||||||
"Transparent, SOCKS5, reverse and upstream proxy mode "
|
"Transparent, SOCKS5, reverse and upstream proxy mode "
|
||||||
@ -189,6 +193,7 @@ def process_proxy_options(parser, options):
|
|||||||
body_size_limit=body_size_limit,
|
body_size_limit=body_size_limit,
|
||||||
mode=mode,
|
mode=mode,
|
||||||
upstream_server=upstream_server,
|
upstream_server=upstream_server,
|
||||||
|
upstream_auth=upstream_auth,
|
||||||
ignore_hosts=options.ignore_hosts,
|
ignore_hosts=options.ignore_hosts,
|
||||||
tcp_hosts=options.tcp_hosts,
|
tcp_hosts=options.tcp_hosts,
|
||||||
http2=options.http2,
|
http2=options.http2,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
import base64
|
||||||
from mitmproxy import cmdline
|
from mitmproxy import cmdline
|
||||||
from . import tutils
|
from . import tutils
|
||||||
|
|
||||||
@ -53,6 +54,16 @@ def test_parse_server_spec():
|
|||||||
"http://")
|
"http://")
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_upstream_auth():
|
||||||
|
tutils.raises("Invalid upstream auth specification", cmdline.parse_upstream_auth, "")
|
||||||
|
tutils.raises("Invalid upstream auth specification", cmdline.parse_upstream_auth, ":")
|
||||||
|
tutils.raises("Invalid upstream auth specification", cmdline.parse_upstream_auth, ":test")
|
||||||
|
assert cmdline.parse_upstream_auth(
|
||||||
|
"test:test") == "Basic" + " " + base64.b64encode("test:test")
|
||||||
|
assert cmdline.parse_upstream_auth(
|
||||||
|
"test:") == "Basic" + " " + base64.b64encode("test:")
|
||||||
|
|
||||||
|
|
||||||
def test_parse_setheaders():
|
def test_parse_setheaders():
|
||||||
x = cmdline.parse_setheader("/foo/bar/voing")
|
x = cmdline.parse_setheader("/foo/bar/voing")
|
||||||
assert x == ("foo", "bar", "voing")
|
assert x == ("foo", "bar", "voing")
|
||||||
|
@ -92,6 +92,10 @@ class TestProcessProxyOptions:
|
|||||||
self.assert_err("expected one argument", "-U")
|
self.assert_err("expected one argument", "-U")
|
||||||
self.assert_err("Invalid server specification", "-U", "upstream")
|
self.assert_err("Invalid server specification", "-U", "upstream")
|
||||||
|
|
||||||
|
self.assert_noerr("--upstream-auth", "test:test")
|
||||||
|
self.assert_err("expected one argument", "--upstream-auth")
|
||||||
|
self.assert_err("Invalid upstream auth specification", "--upstream-auth", "test")
|
||||||
|
|
||||||
self.assert_err("not allowed with", "-R", "http://localhost", "-T")
|
self.assert_err("not allowed with", "-R", "http://localhost", "-T")
|
||||||
|
|
||||||
def test_socks_auth(self):
|
def test_socks_auth(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user