Options unification: simple strings

Move all simple string options to the new scheme. Also regularise some names.
This commit is contained in:
Aldo Cortesi 2017-03-06 11:39:19 +13:00
parent 201c65960e
commit 18a6b66ba4
8 changed files with 126 additions and 163 deletions

View File

@ -27,7 +27,14 @@ class Options(optmanager.OptManager):
"onboarding", True, bool,
"Toggle the mitmproxy onboarding app."
)
self.add_option("onboarding_host", APP_HOST, str)
self.add_option(
"onboarding_host", APP_HOST, str,
"""
Domain to serve the onboarding app from. For transparent mode, use
an IP when a DNS entry for the app domain is not present. Default:
%s
""" % APP_HOST
)
self.add_option(
"onboarding_port", APP_PORT, int,
help="Port to serve the onboarding app from."
@ -64,7 +71,10 @@ class Options(optmanager.OptManager):
self.add_option(
"refresh_server_playback", True, bool,
)
self.add_option("rfile", None, Optional[str])
self.add_option(
"rfile", None, Optional[str],
"Read flows from file."
)
self.add_option("scripts", [], Sequence[str])
self.add_option(
"showhost", False, bool,
@ -75,8 +85,14 @@ class Options(optmanager.OptManager):
self.add_option("server_replay_use_headers", [], Sequence[str])
self.add_option("setheaders", [], Sequence[Union[Tuple[str, str, str], str]])
self.add_option("server_replay", [], Sequence[str])
self.add_option("stickycookie", None, Optional[str])
self.add_option("stickyauth", None, Optional[str])
self.add_option(
"stickycookie", None, Optional[str],
"Set sticky cookie filter. Matched against requests."
)
self.add_option(
"stickyauth", None, Optional[str],
"Set sticky auth filter. Matched against requests."
)
self.add_option(
"stream_large_bodies", None, Optional[str],
"""
@ -109,8 +125,17 @@ class Options(optmanager.OptManager):
"auth_nonanonymous", False, bool,
"Allow access to any user long as a credentials are specified."
)
self.add_option("auth_singleuser", None, Optional[str])
self.add_option("auth_htpasswd", None, Optional[str])
self.add_option(
"auth_singleuser", None, Optional[str],
"""
Allows access to a a single user, specified in the form
username:password.
"""
)
self.add_option(
"auth_htpasswd", None, Optional[str],
"Allow access to users specified in an Apache htpasswd file."
)
self.add_option(
"add_upstream_certs_to_client_chain", False, bool,
"Add all certificates of the upstream server to the certificate chain "
@ -121,18 +146,36 @@ class Options(optmanager.OptManager):
"Byte size limit of HTTP request and response bodies."
" Understands k/m/g suffixes, i.e. 3m for 3 megabytes."
)
self.add_option("cadir", CA_DIR, str)
self.add_option(
"cadir", CA_DIR, str,
"Location of the default mitmproxy CA files. (%s)" % CA_DIR
)
self.add_option("certs", [], Sequence[Tuple[str, str]])
self.add_option("ciphers_client", DEFAULT_CLIENT_CIPHERS, str)
self.add_option("ciphers_server", None, Optional[str])
self.add_option("clientcerts", None, Optional[str])
self.add_option(
"ciphers_client", DEFAULT_CLIENT_CIPHERS, str,
"Set supported ciphers for client connections. (OpenSSL Syntax)"
)
self.add_option(
"ciphers_server", None, Optional[str],
"Set supported ciphers for server connections. (OpenSSL Syntax)"
)
self.add_option(
"client_certs", None, Optional[str],
"Client certificate file or directory."
)
self.add_option("ignore_hosts", [], Sequence[str])
self.add_option("listen_host", "", str)
self.add_option(
"listen_host", "", str,
"Address to bind proxy to (defaults to all interfaces)"
)
self.add_option(
"listen_port", LISTEN_PORT, int,
"Proxy service port."
)
self.add_option("upstream_bind_address", "", str)
self.add_option(
"upstream_bind_address", "", str,
"Address to bind upstream requests to (defaults to none)"
)
self.add_option("mode", "regular", str)
self.add_option(
"upstream_cert", True, bool,
@ -172,23 +215,39 @@ class Options(optmanager.OptManager):
"Combine with --upstream-bind-address to spoof a fixed source address."
)
self.add_option("upstream_server", None, Optional[str])
self.add_option("upstream_auth", None, Optional[str])
self.add_option(
"upstream_auth", None, Optional[str],
"""
Add HTTP Basic authentcation to upstream proxy and reverse proxy
requests. Format: username:password
"""
)
self.add_option("ssl_version_client", "secure", str)
self.add_option("ssl_version_server", "secure", str)
self.add_option(
"ssl_insecure", False, bool,
"Do not verify upstream server SSL/TLS certificates."
)
self.add_option("ssl_verify_upstream_trusted_cadir", None, Optional[str])
self.add_option("ssl_verify_upstream_trusted_ca", None, Optional[str])
self.add_option(
"ssl_verify_upstream_trusted_cadir", None, Optional[str],
"Path to a directory of trusted CA certificates for upstream "
"server verification prepared using the c_rehash tool."
)
self.add_option(
"ssl_verify_upstream_trusted_ca", None, Optional[str],
"Path to a PEM formatted trusted CA certificate."
)
self.add_option("tcp_hosts", [], Sequence[str])
self.add_option("intercept", None, Optional[str])
self.add_option(
"intercept", None, Optional[str],
"Intercept filter expression."
)
# Console options
self.add_option(
"console_eventlog", False, bool,
help="Show event log."
"Show event log."
)
self.add_option(
"console_focus_follow", False, bool,
@ -208,7 +267,10 @@ class Options(optmanager.OptManager):
"console_order_reversed", False, bool,
)
self.add_option("filter", None, Optional[str])
self.add_option(
"filter", None, Optional[str],
"Filter view expression."
)
# Web options
self.add_option(
@ -223,7 +285,10 @@ class Options(optmanager.OptManager):
"web_port", 8081, int,
"Mitmweb port."
)
self.add_option("web_iface", "127.0.0.1", str)
self.add_option(
"web_iface", "127.0.0.1", str,
"Mitmweb interface."
)
# Dump options
self.add_option("filtstr", None, Optional[str])

View File

@ -59,7 +59,7 @@ class ProxyConfig:
self.check_ignore = None
self.check_tcp = None
self.certstore = None
self.clientcerts = None
self.client_certs = None
self.openssl_verification_mode_server = None
self.configure(options, set(options.keys()))
options.changed.connect(self.configure)
@ -96,14 +96,14 @@ class ProxyConfig:
CONF_BASENAME
)
if options.clientcerts:
clientcerts = os.path.expanduser(options.clientcerts)
if not os.path.exists(clientcerts):
if options.client_certs:
client_certs = os.path.expanduser(options.client_certs)
if not os.path.exists(client_certs):
raise exceptions.OptionsError(
"Client certificate path does not exist: %s" %
options.clientcerts
options.client_certs
)
self.clientcerts = clientcerts
self.client_certs = client_certs
for spec, cert in options.certs:
cert = os.path.expanduser(cert)

View File

@ -61,7 +61,7 @@ class RequestReplayThread(basethread.BaseThread):
if resp.status_code != 200:
raise exceptions.ReplayException("Upstream server refuses CONNECT request")
server.establish_ssl(
self.config.clientcerts,
self.config.client_certs,
sni=self.f.server_conn.sni
)
r.first_line_format = "relative"
@ -76,7 +76,7 @@ class RequestReplayThread(basethread.BaseThread):
server.connect()
if r.scheme == "https":
server.establish_ssl(
self.config.clientcerts,
self.config.client_certs,
sni=self.f.server_conn.sni
)
r.first_line_format = "relative"

View File

@ -527,7 +527,7 @@ class TlsLayer(base.Layer):
ciphers_server = ':'.join(ciphers_server)
self.server_conn.establish_ssl(
self.config.clientcerts,
self.config.client_certs,
self.server_sni,
method=self.config.openssl_method_server,
options=self.config.openssl_options_server,

View File

@ -17,13 +17,6 @@ class ParseException(Exception):
def get_common_options(args):
stickycookie, stickyauth = None, None
if args.stickycookie_filt:
stickycookie = args.stickycookie_filt
if args.stickyauth_filt:
stickyauth = args.stickyauth_filt
if args.streamfile and args.streamfile[0] == args.rfile:
if args.streamfile[1] == "wb":
raise exceptions.OptionsError(
@ -101,8 +94,8 @@ def get_common_options(args):
keep_host_header=args.keep_host_header,
server_replay=args.server_replay,
scripts=args.scripts,
stickycookie=stickycookie,
stickyauth=stickyauth,
stickycookie=args.stickycookie,
stickyauth=args.stickyauth,
stream_large_bodies=args.stream_large_bodies,
showhost=args.showhost,
streamfile=args.streamfile[0] if args.streamfile else None,
@ -123,9 +116,9 @@ def get_common_options(args):
certs = certs,
ciphers_client = args.ciphers_client,
ciphers_server = args.ciphers_server,
clientcerts = args.clientcerts,
client_certs = args.client_certs,
ignore_hosts = args.ignore_hosts,
listen_host = args.listen_addr,
listen_host = args.listen_host,
listen_port = args.listen_port,
upstream_bind_address = args.upstream_bind_address,
mode = mode,
@ -161,22 +154,14 @@ def basic_options(parser, opts):
version=version.VERSION
)
opts.make_parser(parser, "anticache")
parser.add_argument(
"--cadir",
action="store", type=str, dest="cadir",
help="Location of the default mitmproxy CA files. (%s)" % options.CA_DIR
)
opts.make_parser(parser, "cadir")
opts.make_parser(parser, "showhost")
parser.add_argument(
"-q", "--quiet",
action="store_true", dest="quiet",
help="Quiet."
)
parser.add_argument(
"-r", "--read-flows",
action="store", dest="rfile",
help="Read flows from file."
)
opts.make_parser(parser, "rfile")
parser.add_argument(
"-s", "--script",
action="append", type=str, dest="scripts",
@ -186,18 +171,8 @@ def basic_options(parser, opts):
passed multiple times.
"""
)
parser.add_argument(
"-t", "--stickycookie",
action="store",
dest="stickycookie_filt",
metavar="FILTER",
help="Set sticky cookie filter. Matched against requests."
)
parser.add_argument(
"-u", "--stickyauth",
action="store", dest="stickyauth_filt", metavar="FILTER",
help="Set sticky auth filter. Matched against requests."
)
opts.make_parser(parser, "stickycookie", metavar="FILTER")
opts.make_parser(parser, "stickyauth", metavar="FILTER")
parser.add_argument(
"-v", "--verbose",
action="store_const", dest="verbose", const=3,
@ -254,11 +229,7 @@ def proxy_modes(parser, opts):
def proxy_options(parser, opts):
group = parser.add_argument_group("Proxy Options")
group.add_argument(
"-b", "--bind-address",
action="store", type=str, dest="listen_addr",
help="Address to bind proxy to (defaults to all interfaces)"
)
opts.make_parser(group, "listen_host")
group.add_argument(
"-I", "--ignore",
action="append", type=str, dest="ignore_hosts",
@ -292,24 +263,10 @@ def proxy_options(parser, opts):
websocket = group.add_mutually_exclusive_group()
opts.make_parser(websocket, "websocket")
parser.add_argument(
"--upstream-auth",
action="store", dest="upstream_auth",
type=str,
help="""
Add HTTP Basic authentcation to upstream proxy and reverse proxy
requests. Format: username:password
"""
)
opts.make_parser(group, "upstream_auth", metavar="USER:PASS")
opts.make_parser(group, "rawtcp")
opts.make_parser(group, "spoof_source_address")
group.add_argument(
"--upstream-bind-address",
action="store", type=str, dest="upstream_bind_address",
help="Address to bind upstream requests to (defaults to none)"
)
opts.make_parser(group, "upstream_bind_address", metavar="ADDR")
opts.make_parser(group, "keep_host_header")
@ -328,35 +285,14 @@ def proxy_ssl_options(parser, opts):
'in the PEM, it is used, else the default key in the conf dir is used. '
'The PEM file should contain the full certificate chain, with the leaf certificate '
'as the first entry. Can be passed multiple times.')
group.add_argument(
"--ciphers-client", action="store",
type=str, dest="ciphers_client",
help="Set supported ciphers for client connections. (OpenSSL Syntax)"
)
group.add_argument(
"--ciphers-server", action="store",
type=str, dest="ciphers_server",
help="Set supported ciphers for server connections. (OpenSSL Syntax)"
)
group.add_argument(
"--client-certs", action="store",
type=str, dest="clientcerts",
help="Client certificate file or directory."
)
opts.make_parser(group, "ciphers_server", metavar="CIPHERS")
opts.make_parser(group, "ciphers_client", metavar="CIPHERS")
opts.make_parser(group, "client_certs")
opts.make_parser(group, "upstream_cert")
opts.make_parser(group, "add_upstream_certs_to_client_chain")
opts.make_parser(group, "ssl_insecure")
group.add_argument(
"--upstream-trusted-cadir", action="store",
dest="ssl_verify_upstream_trusted_cadir",
help="Path to a directory of trusted CA certificates for upstream "
"server verification prepared using the c_rehash tool."
)
group.add_argument(
"--upstream-trusted-ca", action="store",
dest="ssl_verify_upstream_trusted_ca",
help="Path to a PEM formatted trusted CA certificate."
)
opts.make_parser(group, "ssl_verify_upstream_trusted_cadir", metavar="PATH")
opts.make_parser(group, "ssl_verify_upstream_trusted_ca", metavar="PATH")
group.add_argument(
"--ssl-version-client", dest="ssl_version_client",
action="store",
@ -375,16 +311,8 @@ def proxy_ssl_options(parser, opts):
def onboarding_app(parser, opts):
group = parser.add_argument_group("Onboarding App")
opts.make_parser(parser, "onboarding")
group.add_argument(
"--onboarding-host",
action="store", dest="onboarding_host",
help="""
Domain to serve the onboarding app from. For transparent mode, use
an IP when a DNS entry for the app domain is not present. Default:
%s
""" % options.APP_HOST
)
opts.make_parser(group, "onboarding")
opts.make_parser(group, "onboarding_host", metavar="HOST")
opts.make_parser(group, "onboarding_port", metavar="PORT")
@ -488,21 +416,8 @@ def proxy_authentication(parser, opts):
"""
).add_mutually_exclusive_group()
opts.make_parser(group, "auth_nonanonymous")
group.add_argument(
"--singleuser",
action="store", dest="auth_singleuser", type=str,
metavar="USER",
help="""
Allows access to a a single user, specified in the form
username:password.
"""
)
group.add_argument(
"--htpasswd",
action="store", dest="auth_htpasswd", type=str,
metavar="PATH",
help="Allow access to users specified in an Apache htpasswd file."
)
opts.make_parser(group, "auth_singleuser", metavar="USER:PASS")
opts.make_parser(group, "auth_htpasswd", metavar="PATH")
def common_options(parser, opts):
@ -553,16 +468,8 @@ def mitmproxy(opts):
"Filters",
"See help in mitmproxy for filter expression syntax."
)
group.add_argument(
"-i", "--intercept", action="store",
type=str, dest="intercept",
help="Intercept filter expression."
)
group.add_argument(
"-f", "--filter", action="store",
type=str, dest="filter",
help="Filter view expression."
)
opts.make_parser(group, "intercept", metavar="FILTER")
opts.make_parser(group, "filter", metavar="FILTER")
return parser
@ -588,13 +495,8 @@ def mitmweb(opts):
group = parser.add_argument_group("Mitmweb")
opts.make_parser(group, "web_open_browser")
opts.make_parser(parser, "web_port", metavar="PORT")
group.add_argument(
"--web-iface",
action="store", dest="web_iface",
metavar="IFACE",
help="Mitmweb interface."
)
opts.make_parser(group, "web_port", metavar="PORT")
opts.make_parser(group, "web_iface", metavar="INTERFACE")
opts.make_parser(group, "web_debug")
common_options(parser, opts)
@ -602,9 +504,5 @@ def mitmweb(opts):
"Filters",
"See help in mitmproxy for filter expression syntax."
)
group.add_argument(
"-i", "--intercept", action="store",
type=str, dest="intercept",
help="Intercept filter expression."
)
opts.make_parser(group, "intercept", metavar="FILTER")
return parser

View File

@ -342,22 +342,22 @@ class TestHTTPS(tservers.HTTPProxyTest, CommonMixin, TcpMixin):
def test_clientcert_file(self):
try:
self.config.clientcerts = os.path.join(
self.config.client_certs = os.path.join(
tutils.test_data.path("mitmproxy/data/clientcert"), "client.pem")
f = self.pathod("304")
assert f.status_code == 304
assert self.server.last_log()["request"]["clientcert"]["keyinfo"]
finally:
self.config.clientcerts = None
self.config.client_certs = None
def test_clientcert_dir(self):
try:
self.config.clientcerts = tutils.test_data.path("mitmproxy/data/clientcert")
self.config.client_certs = tutils.test_data.path("mitmproxy/data/clientcert")
f = self.pathod("304")
assert f.status_code == 304
assert self.server.last_log()["request"]["clientcert"]["keyinfo"]
finally:
self.config.clientcerts = None
self.config.client_certs = None
def test_error_post_connect(self):
p = self.pathoc()

View File

@ -96,12 +96,12 @@ class TestProcessProxyOptions:
def test_upstream_trusted_cadir(self):
expected_dir = "/path/to/a/ca/dir"
p = self.assert_noerr("--upstream-trusted-cadir", expected_dir)
p = self.assert_noerr("--ssl-verify-upstream-trusted-cadir", expected_dir)
assert p.options.ssl_verify_upstream_trusted_cadir == expected_dir
def test_upstream_trusted_ca(self):
expected_file = "/path/to/a/cert/file"
p = self.assert_noerr("--upstream-trusted-ca", expected_file)
p = self.assert_noerr("--ssl-verify-upstream-trusted-ca", expected_file)
assert p.options.ssl_verify_upstream_trusted_ca == expected_file

View File

@ -11,8 +11,8 @@ def test_common():
assert cmdline.get_common_options(args)
args.stickycookie_filt = "foo"
args.stickyauth_filt = "foo"
args.stickycookie = "foo"
args.stickyauth = "foo"
v = cmdline.get_common_options(args)
assert v["stickycookie"] == "foo"
assert v["stickyauth"] == "foo"