From 18a4456397d0b4b1275ac2c8ab393d041176e949 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Mon, 8 Jun 2015 16:03:33 +0200 Subject: refactor cmdline tests --- libpathod/pathod_cmdline.py | 235 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 libpathod/pathod_cmdline.py (limited to 'libpathod/pathod_cmdline.py') diff --git a/libpathod/pathod_cmdline.py b/libpathod/pathod_cmdline.py new file mode 100644 index 00000000..c1f016c2 --- /dev/null +++ b/libpathod/pathod_cmdline.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python +import sys +import argparse +import os +import os.path +import re +from netlib import http_uastrings +from . import pathoc, pathod, version, utils, language + + +def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): + parser = argparse.ArgumentParser( + description='A pathological HTTP/S daemon.' + ) + parser.add_argument( + '--version', + action='version', + version="pathod " + version.VERSION + ) + parser.add_argument( + "-p", + dest='port', + default=9999, + type=int, + help='Port. Specify 0 to pick an arbitrary empty port. (9999)' + ) + parser.add_argument( + "-l", + dest='address', + default="127.0.0.1", + type=str, + help='Listening address. (127.0.0.1)' + ) + parser.add_argument( + "-a", + dest='anchors', + default=[], + type=str, + action="append", + metavar="ANCHOR", + help=""" + Add an anchor. Specified as a string with the form + pattern=spec or pattern=filepath, where pattern is a regular + expression. + """ + ) + parser.add_argument( + "-c", dest='craftanchor', default=pathod.DEFAULT_ANCHOR, type=str, + help=""" + Regular expression specifying anchor point for URL crafting + commands. (%s) + """%pathod.DEFAULT_ANCHOR + ) + parser.add_argument( + "--confdir", + action="store", type = str, dest="confdir", default='~/.mitmproxy', + help = "Configuration directory. (~/.mitmproxy)" + ) + parser.add_argument( + "-d", dest='staticdir', default=None, type=str, + help='Directory for static files.' + ) + parser.add_argument( + "-D", dest='daemonize', default=False, action="store_true", + help='Daemonize.' + ) + parser.add_argument( + "-t", dest="timeout", type=int, default=None, + help="Connection timeout" + ) + parser.add_argument( + "--limit-size", + dest='sizelimit', + default=None, + type=str, + help='Size limit of served responses. Understands size suffixes, i.e. 100k.') + parser.add_argument( + "--noapi", dest='noapi', default=False, action="store_true", + help='Disable API.' + ) + parser.add_argument( + "--nohang", dest='nohang', default=False, action="store_true", + help='Disable pauses during crafted response generation.' + ) + parser.add_argument( + "--noweb", dest='noweb', default=False, action="store_true", + help='Disable both web interface and API.' + ) + parser.add_argument( + "--nocraft", + dest='nocraft', + default=False, + action="store_true", + help='Disable response crafting. If anchors are specified, they still work.') + parser.add_argument( + "--webdebug", dest='webdebug', default=False, action="store_true", + help='Debugging mode for the web app (dev only).' + ) + + group = parser.add_argument_group( + 'SSL', + ) + group.add_argument( + "-s", dest='ssl', default=False, action="store_true", + help='Run in HTTPS mode.' + ) + group.add_argument( + "--cn", + dest="cn", + type=str, + default=None, + help="CN for generated SSL certs. Default: %s" % + pathod.DEFAULT_CERT_DOMAIN) + group.add_argument( + "-C", dest='ssl_not_after_connect', default=False, action="store_true", + help="Don't expect SSL after a CONNECT request." + ) + group.add_argument( + "--cert", dest='ssl_certs', default=[], type=str, + metavar = "SPEC", action="append", + help = """ + Add an SSL certificate. SPEC is of the form "[domain=]path". The domain + may include a wildcard, and is equal to "*" if not specified. The file + at path is a certificate in PEM format. If a private key is included in + the PEM, it is used, else the default key in the conf dir is used. Can + be passed multiple times. + """ + ) + group.add_argument( + "--ciphers", dest="ciphers", type=str, default=False, + help="SSL cipher specification" + ) + group.add_argument( + "--san", dest="sans", type=str, default=[], action="append", + metavar="SAN", + help=""" + Subject Altnernate Name to add to the server certificate. + May be passed multiple times. + """ + ) + group.add_argument( + "--sslversion", dest="sslversion", type=int, default=4, + choices=[1, 2, 3, 4], + help=""""Use a specified protocol - TLSv1, SSLv2, SSLv3, SSLv23. Default + to SSLv23.""" + ) + + group = parser.add_argument_group( + 'Controlling Logging', + """ + Some of these options expand generated values for logging - if + you're generating large data, use them with caution. + """ + ) + group.add_argument( + "-e", dest="explain", action="store_true", default=False, + help="Explain responses" + ) + group.add_argument( + "-f", dest='logfile', default=None, type=str, + help='Log to file.' + ) + group.add_argument( + "-q", dest="logreq", action="store_true", default=False, + help="Log full request" + ) + group.add_argument( + "-r", dest="logresp", action="store_true", default=False, + help="Log full response" + ) + group.add_argument( + "-x", dest="hexdump", action="store_true", default=False, + help="Log request/response in hexdump format" + ) + args = parser.parse_args(argv[1:]) + + certs = [] + for i in args.ssl_certs: + parts = i.split("=", 1) + if len(parts) == 1: + parts = ["*", parts[0]] + parts[1] = os.path.expanduser(parts[1]) + if not os.path.isfile(parts[1]): + return parser.error( + "Certificate file does not exist: %s" % + parts[1]) + certs.append(parts) + args.ssl_certs = certs + + alst = [] + for i in args.anchors: + parts = utils.parse_anchor_spec(i) + if not parts: + return parser.error("Invalid anchor specification: %s" % i) + alst.append(parts) + args.anchors = alst + + sizelimit = None + if args.sizelimit: + try: + sizelimit = utils.parse_size(args.sizelimit) + except ValueError as v: + return parser.error(v) + args.sizelimit = sizelimit + + try: + args.craftanchor = re.compile(args.craftanchor) + except re.error: + return parser.error( + "Invalid regex in craft anchor: %s" % args.craftanchor + ) + + anchors = [] + for patt, spec in args.anchors: + if os.path.isfile(spec): + data = open(spec).read() + spec = data + try: + req = language.parse_pathod(spec) + except language.ParseException as v: + print >> stderr, "Error parsing anchor spec: %s" % v.msg + print >> stderr, v.marked() + sys.exit(1) + try: + arex = re.compile(patt) + except re.error: + return parser.error("Invalid regex in anchor: %s" % patt) + anchors.append((arex, req)) + args.anchors = anchors + return args + + +def go_pathod(): # pragma: nocover + args = args_pathod(sys.argv) + pathod.main(args) -- cgit v1.2.3 From 22811c45dd1e6e6f1c8108e83a7be625f305c19e Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Thu, 11 Jun 2015 16:36:58 +0200 Subject: fix craft anchor The go-button in the app was broken due to an invalid string representation of the regex. A plain string used as URL prefix simplifies this drastically. --- libpathod/pathod_cmdline.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'libpathod/pathod_cmdline.py') diff --git a/libpathod/pathod_cmdline.py b/libpathod/pathod_cmdline.py index c1f016c2..68828aca 100644 --- a/libpathod/pathod_cmdline.py +++ b/libpathod/pathod_cmdline.py @@ -45,11 +45,11 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): """ ) parser.add_argument( - "-c", dest='craftanchor', default=pathod.DEFAULT_ANCHOR, type=str, + "-c", dest='craftanchor', default=pathod.DEFAULT_CRAFT_ANCHOR, type=str, help=""" - Regular expression specifying anchor point for URL crafting + URL path specifying prefix for URL crafting commands. (%s) - """%pathod.DEFAULT_ANCHOR + """%pathod.DEFAULT_CRAFT_ANCHOR ) parser.add_argument( "--confdir", @@ -203,13 +203,6 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): return parser.error(v) args.sizelimit = sizelimit - try: - args.craftanchor = re.compile(args.craftanchor) - except re.error: - return parser.error( - "Invalid regex in craft anchor: %s" % args.craftanchor - ) - anchors = [] for patt, spec in args.anchors: if os.path.isfile(spec): -- cgit v1.2.3 From 30fbf57e4b72e3947c323d98aee7b2d44663e33c Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Fri, 12 Jun 2015 13:41:04 +0200 Subject: delay pathod parsing until needed This allows us to use different languages based on runtime env. --- libpathod/pathod_cmdline.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'libpathod/pathod_cmdline.py') diff --git a/libpathod/pathod_cmdline.py b/libpathod/pathod_cmdline.py index 68828aca..f1bb6982 100644 --- a/libpathod/pathod_cmdline.py +++ b/libpathod/pathod_cmdline.py @@ -208,17 +208,11 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): if os.path.isfile(spec): data = open(spec).read() spec = data - try: - req = language.parse_pathod(spec) - except language.ParseException as v: - print >> stderr, "Error parsing anchor spec: %s" % v.msg - print >> stderr, v.marked() - sys.exit(1) try: arex = re.compile(patt) except re.error: return parser.error("Invalid regex in anchor: %s" % patt) - anchors.append((arex, req)) + anchors.append((arex, spec)) args.anchors = anchors return args -- cgit v1.2.3 From a0d8afd0fcc3c678da0dc956c5a80d4e07d5ac3e Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Thu, 11 Jun 2015 16:13:22 +0200 Subject: http2: add request-response to pathod --- libpathod/pathod_cmdline.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'libpathod/pathod_cmdline.py') diff --git a/libpathod/pathod_cmdline.py b/libpathod/pathod_cmdline.py index f1bb6982..4343401f 100644 --- a/libpathod/pathod_cmdline.py +++ b/libpathod/pathod_cmdline.py @@ -139,10 +139,11 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): """ ) group.add_argument( - "--sslversion", dest="sslversion", type=int, default=4, - choices=[1, 2, 3, 4], - help=""""Use a specified protocol - TLSv1, SSLv2, SSLv3, SSLv23. Default - to SSLv23.""" + "--sslversion", dest="sslversion", type=str, default='SSLv23', + choices=utils.SSLVERSIONS.keys(), + help="""" + Use a specified protocol - TLSv1.2, TLSv1.1, TLSv1, SSLv3, SSLv2, SSLv23. + Default to SSLv23.""" ) group = parser.add_argument_group( @@ -172,6 +173,12 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): "-x", dest="hexdump", action="store_true", default=False, help="Log request/response in hexdump format" ) + group.add_argument( + "--http2-framedump", dest="http2_framedump", action="store_true", default=False, + help="Output all received & sent HTTP/2 frames" + ) + + args = parser.parse_args(argv[1:]) certs = [] -- cgit v1.2.3