Unify mitmproxy and mitmdump commandline

- Extract common options into cmdline.py
- Change mitmproxy keybindings to fit command line

Some cmdline options and keybindings aren't in operation yet - just stubs
where functionality will be added in the next few commits.
This commit is contained in:
Aldo Cortesi 2011-03-12 14:30:12 +13:00
parent 9927ebad3e
commit 2f457e041e
4 changed files with 160 additions and 140 deletions

110
libmproxy/cmdline.py Normal file
View File

@ -0,0 +1,110 @@
import proxy
import optparse
def get_common_options(options):
stickycookie = None
if options.stickycookie_all:
stickycookie = ".*"
elif options.stickycookie_filt:
stickycookie = stickycookie_filt
return dict(
verbosity = options.verbose,
wfile = options.wfile,
request_script = options.request_script,
response_script = options.response_script,
server_replay = options.server_replay,
kill = options.kill,
rheaders = options.rheaders,
client_replay = options.client_replay,
stickycookie = stickycookie,
anticache = options.anticache,
refresh_server_playback = not options.norefresh,
)
def common_options(parser):
parser.add_option(
"-a",
action="store", type = "str", dest="addr", default='',
help = "Address to bind proxy to (defaults to all interfaces)"
)
parser.add_option(
"-p",
action="store", type = "int", dest="port", default=8080,
help = "Proxy service port."
)
parser.add_option(
"-q",
action="store_true", dest="quiet",
help="Quiet."
)
parser.add_option(
"--anticache",
action="store_true", dest="anticache", default=False,
help="Strip out request headers that might cause the server to return 304-not-modified."
)
parser.add_option(
"--reqscript",
action="store", dest="request_script", default=None,
help="Script to run when a request is recieved."
)
parser.add_option(
"--respscript",
action="store", dest="response_script", default=None,
help="Script to run when a response is recieved."
)
parser.add_option(
"-t",
action="store_true", dest="stickycookie_all", default=None,
help="Set sticky cookie for all requests."
)
parser.add_option(
"-T",
action="store", dest="stickycookie_filt", default=None, metavar="FILTER",
help="Set sticky cookie filter. Matched against requests."
)
parser.add_option(
"-v",
action="count", dest="verbose", default=1,
help="Increase verbosity. Can be passed multiple times."
)
parser.add_option(
"-w",
action="store", dest="wfile", default=None,
help="Write flows to file."
)
group = optparse.OptionGroup(parser, "Client Replay")
group.add_option(
"-c",
action="store", dest="client_replay", default=None, metavar="PATH",
help="Replay client requests from a saved file."
)
parser.add_option_group(group)
group = optparse.OptionGroup(parser, "Server Replay")
group.add_option(
"-s",
action="store", dest="server_replay", default=None, metavar="PATH",
help="Replay server responses from a saved file."
)
group.add_option(
"-k",
action="store_true", dest="kill", default=False,
help="Kill extra requests during replay."
)
group.add_option(
"--rheader",
action="append", dest="rheaders", type="str",
help="Request headers to be considered during replay. "
"Can be passed multiple times."
)
group.add_option(
"--norefresh",
action="store_true", dest="norefresh", default=False,
help= "Disable response refresh, "
"which updates times in cookies and headers for replayed responses."
)
parser.add_option_group(group)
proxy.certificate_option_group(parser)

View File

@ -164,7 +164,7 @@ class ConnectionItem(WWrap):
elif key == "R":
self.state.revert(self.flow)
self.master.sync_list_view()
elif key == "s":
elif key == "w":
self.master.prompt("Save this flow: ", self.master.save_one_flow, self.flow)
elif key == "z":
self.master.kill_connection(self.flow)
@ -515,7 +515,7 @@ class ConnectionView(WWrap):
elif key == "R":
self.state.revert(self.flow)
self.master.refresh_connection(self.flow)
elif key == "s":
elif key == "w":
self.master.prompt("Save this flow: ", self.master.save_one_flow, self.flow)
elif key == "v":
if self.state.view_flow_mode == VIEW_FLOW_REQUEST:
@ -526,7 +526,7 @@ class ConnectionView(WWrap):
t = conn.headers.get("content-type", [None])
t = t[0]
self.master.spawn_external_viewer(conn.content, t)
elif key == "w":
elif key == "b":
if self.state.view_flow_mode == VIEW_FLOW_REQUEST:
self.master.prompt("Save request body: ", self.save_body)
else:
@ -758,6 +758,33 @@ class ConsoleState(flow.State):
return ret
class Options(object):
__slots__ = [
"anticache",
"beep",
"client_replay",
"keepserving",
"kill",
"intercept",
"limit",
"refresh_server_playback",
"request_script",
"response_script",
"rheaders",
"server_replay",
"stickycookie",
"verbosity",
"wfile",
]
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
for i in self.__slots__:
if not hasattr(self, i):
setattr(self, i, None)
#begin nocover
VIEW_CONNLIST = 0
VIEW_FLOW = 1
@ -798,7 +825,7 @@ class ConsoleMaster(flow.FlowMaster):
print >> sys.stderr, "Beep error:", r
sys.exit(1)
r = self.set_stickycookie(options.sticky)
r = self.set_stickycookie(options.stickycookie)
if r:
print >> sys.stderr, "Sticky cookies error:", r
sys.exit(1)
@ -987,7 +1014,7 @@ class ConsoleMaster(flow.FlowMaster):
("A", "accept all intercepted connections"),
("a", "accept this intercepted connection"),
("B", "set beep filter pattern"),
("c", "set sticky cookie expression"),
("c", "client replay"),
("i", "set interception pattern"),
("j, k", "up, down"),
("l", "set limit filter pattern"),
@ -997,6 +1024,9 @@ class ConsoleMaster(flow.FlowMaster):
("r", "replay request"),
("R", "revert changes to request"),
("S", "save all flows matching current limit"),
("s", "server replay"),
("t", "set sticky cookie expression"),
("w", "save this flow"),
("page up/down", "page up/down"),
("enter", "view connection"),
]
@ -1006,7 +1036,6 @@ class ConsoleMaster(flow.FlowMaster):
keys = [
("C", "clear connection list"),
("d", "delete connection from view"),
("s", "save this t flow"),
("z", "kill and delete connection, even if it's mid-intercept"),
("space", "page down"),
]
@ -1014,12 +1043,11 @@ class ConsoleMaster(flow.FlowMaster):
text.extend([("head", "\n\nConnection view keys:\n")])
keys = [
("e", "edit response/request"),
("b", "save request/response body"),
("e", "edit request/response"),
("m", "change view mode (raw, indent, hex)"),
("p", "previous flow"),
("s", "save this flow"),
("v", "view contents in external viewer"),
("w", "save request or response body"),
("v", "view body in external viewer"),
("|", "run script"),
("tab", "toggle response/request view"),
("space", "next flow"),
@ -1237,7 +1265,7 @@ class ConsoleMaster(flow.FlowMaster):
self.load_flows
)
k = None
elif k == "c":
elif k == "t":
self.prompt("Sticky cookie: ", self.set_stickycookie)
k = None
if k:

114
mitmdump
View File

@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys, os.path
from libmproxy import proxy, dump, utils
from libmproxy import proxy, dump, utils, cmdline
from libmproxy.version import VERSION
from optparse import OptionParser, OptionGroup
@ -26,109 +26,18 @@ if __name__ == '__main__':
usage = "%prog [options] [filter]",
version="%%prog %s"%VERSION,
)
parser.add_option(
"-a",
action="store", type = "str", dest="addr", default='',
help = "Address to bind proxy to (defaults to all interfaces)"
)
parser.add_option(
"-i",
action="store_true", dest="stickycookie_all", default=None,
help="Set sticky cookie for all requests."
)
parser.add_option(
"-I",
action="store", dest="stickycookie_filt", default=None, metavar="FILTER",
help="Set sticky cookie filter. Matched against requests."
)
cmdline.common_options(parser)
parser.add_option(
"--keepserving",
action="store_true", dest="keepserving", default=False,
help="Continue serving after playback."
help="Continue serving after playback. We exit by default."
)
parser.add_option(
"-p",
action="store", type = "int", dest="port", default=8080,
help = "Proxy service port."
)
parser.add_option(
"-q",
action="store_true", dest="quiet",
help="Quiet."
)
parser.add_option(
"--anticache",
action="store_true", dest="anticache", default=False,
help="Strip out request headers that might cause the server to return 304-not-modified."
)
parser.add_option(
"--reqscript",
action="store", dest="request_script", default=None,
help="Script to run when a request is recieved."
)
parser.add_option(
"--respscript",
action="store", dest="response_script", default=None,
help="Script to run when a response is recieved."
)
parser.add_option(
"-v",
action="count", dest="verbose", default=1,
help="Increase verbosity. Can be passed multiple times."
)
parser.add_option(
"-w",
action="store", dest="wfile", default=None,
help="Write flows to file."
)
group = OptionGroup(parser, "Client Replay")
group.add_option(
"-c",
action="store", dest="client_replay", default=None, metavar="PATH",
help="Replay client requests from a saved file."
)
parser.add_option_group(group)
group = OptionGroup(parser, "Server Replay")
group.add_option(
"-s",
action="store", dest="server_replay", default=None, metavar="PATH",
help="Replay server responses from a saved file."
)
group.add_option(
"-k",
action="store_true", dest="kill", default=False,
help="Kill extra requests during replay."
)
group.add_option(
"--rheader",
action="append", dest="rheaders", type="str",
help="Request headers to be considered during replay. "
"Can be passed multiple times."
)
group.add_option(
"--norefresh",
action="store_true", dest="norefresh", default=False,
help= "Disable response refresh, "
"which updates times in cookies and headers for replayed responses."
)
parser.add_option_group(group)
proxy.certificate_option_group(parser)
options, args = parser.parse_args()
if options.quiet:
options.verbose = 0
stickycookie = None
if options.stickycookie_all:
stickycookie = ".*"
elif options.stickycookie_filt:
stickycookie = stickycookie_filt
config = proxy.process_certificate_option_group(parser, options)
try:
server = proxy.ProxyServer(config, options.port, options.addr)
@ -136,20 +45,9 @@ if __name__ == '__main__':
print >> sys.stderr, "mitmdump:", v.args[0]
sys.exit(1)
dumpopts = dump.Options(
verbosity = options.verbose,
wfile = options.wfile,
request_script = options.request_script,
response_script = options.response_script,
server_replay = options.server_replay,
kill = options.kill,
rheaders = options.rheaders,
client_replay = options.client_replay,
keepserving = options.keepserving,
stickycookie = stickycookie,
anticache = options.anticache,
refresh_server_playback = not options.norefresh,
)
dumpopts = dump.Options(**cmdline.get_common_options(options))
dumpopts.keepserving = options.keepserving
if args:
filt = " ".join(args)
else:

View File

@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys, os.path
from libmproxy import proxy, controller, console, utils, flow
from libmproxy import proxy, controller, console, utils, flow, cmdline
from libmproxy.version import VERSION
from optparse import OptionParser, OptionGroup
@ -26,18 +26,8 @@ if __name__ == '__main__':
usage = "%prog [options] [flowdump path]",
version="%%prog %s"%VERSION,
)
proxy.certificate_option_group(parser)
parser.add_option(
"-a", "--addr", action="store",
type = "str", dest="addr", default='',
help = "Address to bind proxy to (defaults to all interfaces)"
)
cmdline.common_options(parser)
parser.add_option(
"-p", "--port", action="store",
type = "int", dest="port", default=8080,
help = "Proxy service port."
)
group = OptionGroup(
parser,
@ -59,24 +49,18 @@ if __name__ == '__main__':
type = "str", dest="intercept", default=None,
help = "Intercept filter expression."
)
group.add_option(
"-s", "--sticky", action="store",
type = "str", dest="sticky", default=None,
help = "Sticky cookie filter expression."
)
parser.add_option_group(group)
options, args = parser.parse_args()
config = proxy.process_certificate_option_group(parser, options)
try:
server = proxy.ProxyServer(config, options.port, options.addr)
except proxy.ProxyServerError, v:
print >> sys.stderr, "mitmproxy:", v.args[0]
sys.exit(1)
m = console.ConsoleMaster(server, options)
opts = console.Options(**cmdline.get_common_options(options))
m = console.ConsoleMaster(server, opts)
for i in args:
try: