2016-11-11 22:39:16 +00:00
|
|
|
import re
|
|
|
|
import base64
|
|
|
|
|
|
|
|
from mitmproxy import exceptions
|
2017-04-25 22:25:56 +00:00
|
|
|
from mitmproxy import ctx
|
2016-11-11 22:39:16 +00:00
|
|
|
from mitmproxy.utils import strutils
|
|
|
|
|
|
|
|
|
|
|
|
def parse_upstream_auth(auth):
|
|
|
|
pattern = re.compile(".+:")
|
|
|
|
if pattern.search(auth) is None:
|
|
|
|
raise exceptions.OptionsError(
|
|
|
|
"Invalid upstream auth specification: %s" % auth
|
|
|
|
)
|
|
|
|
return b"Basic" + b" " + base64.b64encode(strutils.always_bytes(auth))
|
|
|
|
|
|
|
|
|
2016-11-12 22:50:28 +00:00
|
|
|
class UpstreamAuth():
|
2016-11-12 22:43:27 +00:00
|
|
|
"""
|
|
|
|
This addon handles authentication to systems upstream from us for the
|
|
|
|
upstream proxy and reverse proxy mode. There are 3 cases:
|
|
|
|
|
|
|
|
- Upstream proxy CONNECT requests should have authentication added, and
|
|
|
|
subsequent already connected requests should not.
|
|
|
|
- Upstream proxy regular requests
|
|
|
|
- Reverse proxy regular requests (CONNECT is invalid in this mode)
|
|
|
|
"""
|
2016-11-11 22:39:16 +00:00
|
|
|
def __init__(self):
|
|
|
|
self.auth = None
|
|
|
|
|
2017-04-25 23:01:27 +00:00
|
|
|
def configure(self, updated):
|
2016-11-12 22:43:27 +00:00
|
|
|
# FIXME: We're doing this because our proxy core is terminally confused
|
|
|
|
# at the moment. Ideally, we should be able to check if we're in
|
|
|
|
# reverse proxy mode at the HTTP layer, so that scripts can put the
|
|
|
|
# proxy in reverse proxy mode for specific reuests.
|
2016-11-11 22:39:16 +00:00
|
|
|
if "upstream_auth" in updated:
|
2017-04-25 23:01:27 +00:00
|
|
|
if ctx.options.upstream_auth is None:
|
2016-11-11 22:39:16 +00:00
|
|
|
self.auth = None
|
|
|
|
else:
|
2017-04-25 23:01:27 +00:00
|
|
|
self.auth = parse_upstream_auth(ctx.options.upstream_auth)
|
2016-11-11 22:39:16 +00:00
|
|
|
|
2016-11-12 22:43:27 +00:00
|
|
|
def http_connect(self, f):
|
2016-11-11 22:39:16 +00:00
|
|
|
if self.auth and f.mode == "upstream":
|
|
|
|
f.request.headers["Proxy-Authorization"] = self.auth
|
2016-11-12 22:43:27 +00:00
|
|
|
|
|
|
|
def requestheaders(self, f):
|
|
|
|
if self.auth:
|
|
|
|
if f.mode == "upstream" and not f.server_conn.via:
|
|
|
|
f.request.headers["Proxy-Authorization"] = self.auth
|
2017-04-25 22:25:56 +00:00
|
|
|
elif ctx.options.mode == "reverse":
|
2016-11-12 22:43:27 +00:00
|
|
|
f.request.headers["Proxy-Authorization"] = self.auth
|