Ejemplo n.º 1
0
def test_parse_size():
    assert human.parse_size("0") == 0
    assert human.parse_size("0b") == 0
    assert human.parse_size("1") == 1
    assert human.parse_size("1k") == 1024
    assert human.parse_size("1m") == 1024**2
    assert human.parse_size("1g") == 1024**3
    tutils.raises(ValueError, human.parse_size, "1f")
    tutils.raises(ValueError, human.parse_size, "ak")
Ejemplo n.º 2
0
def get_common_options(options):
    stickycookie, stickyauth = None, None
    if options.stickycookie_filt:
        stickycookie = options.stickycookie_filt

    if options.stickyauth_filt:
        stickyauth = options.stickyauth_filt

    stream_large_bodies = options.stream_large_bodies
    if stream_large_bodies:
        stream_large_bodies = human.parse_size(stream_large_bodies)

    reps = []
    for i in options.replace:
        try:
            p = parse_replace_hook(i)
        except ParseException as e:
            raise configargparse.ArgumentTypeError(e.message)
        reps.append(p)
    for i in options.replace_file:
        try:
            patt, rex, path = parse_replace_hook(i)
        except ParseException as e:
            raise configargparse.ArgumentTypeError(e.message)
        try:
            v = open(path, "rb").read()
        except IOError as e:
            raise configargparse.ArgumentTypeError(
                "Could not read replace file: %s" % path
            )
        reps.append((patt, rex, v))

    setheaders = []
    for i in options.setheader:
        try:
            p = parse_setheader(i)
        except ParseException as e:
            raise configargparse.ArgumentTypeError(e.message)
        setheaders.append(p)

    if options.outfile and options.outfile[0] == options.rfile:
        if options.outfile[1] == "wb":
            raise configargparse.ArgumentTypeError(
                "Cannot use '{}' for both reading and writing flows. "
                "Are you looking for --afile?".format(options.rfile)
            )
        else:
            raise configargparse.ArgumentTypeError(
                "Cannot use '{}' for both reading and appending flows. "
                "That would trigger an infinite loop."
            )

    return dict(
        app=options.app,
        app_host=options.app_host,
        app_port=options.app_port,

        anticache=options.anticache,
        anticomp=options.anticomp,
        client_replay=options.client_replay,
        kill=options.kill,
        no_server=options.no_server,
        refresh_server_playback=not options.norefresh,
        rheaders=options.rheaders,
        rfile=options.rfile,
        replacements=reps,
        setheaders=setheaders,
        server_replay=options.server_replay,
        scripts=options.scripts,
        stickycookie=stickycookie,
        stickyauth=stickyauth,
        stream_large_bodies=stream_large_bodies,
        showhost=options.showhost,
        outfile=options.outfile,
        verbosity=options.verbose,
        nopop=options.nopop,
        replay_ignore_content=options.replay_ignore_content,
        replay_ignore_params=options.replay_ignore_params,
        replay_ignore_payload_params=options.replay_ignore_payload_params,
        replay_ignore_host=options.replay_ignore_host
    )
Ejemplo n.º 3
0
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_CRAFT_ANCHOR,
                        type=str,
                        help="""
            URL path specifying prefix for URL crafting
            commands. (%s)
        """ % pathod.DEFAULT_CRAFT_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(
        "--ssl-version",
        dest="ssl_version",
        type=str,
        default="secure",
        choices=tcp.sslversion_choices.keys(),
        help="Set supported SSL/TLS versions. "
        "SSLv2, SSLv3 and 'all' are INSECURE. Defaults to secure, which is TLS1.0+."
    )

    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")
    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:])

    args.ssl_version, args.ssl_options = tcp.sslversion_choices[
        args.ssl_version]

    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 = human.parse_size(args.sizelimit)
        except ValueError as v:
            return parser.error(v)
    args.sizelimit = sizelimit

    anchors = []
    for patt, spec in args.anchors:
        if os.path.isfile(spec):
            data = open(spec).read()
            spec = data
        try:
            arex = re.compile(patt)
        except re.error:
            return parser.error("Invalid regex in anchor: %s" % patt)
        anchors.append((arex, spec))
    args.anchors = anchors

    return args
Ejemplo n.º 4
0
def process_proxy_options(parser, options):
    body_size_limit = options.body_size_limit
    if body_size_limit:
        body_size_limit = human.parse_size(body_size_limit)

    c = 0
    mode, upstream_server, upstream_auth = "regular", None, None
    if options.transparent_proxy:
        c += 1
        if not platform.resolver:
            return parser.error("Transparent mode not supported on this platform.")
        mode = "transparent"
    if options.socks_proxy:
        c += 1
        mode = "socks5"
    if options.reverse_proxy:
        c += 1
        mode = "reverse"
        upstream_server = options.reverse_proxy
    if options.upstream_proxy:
        c += 1
        mode = "upstream"
        upstream_server = options.upstream_proxy
        upstream_auth = options.upstream_auth
    if c > 1:
        return parser.error(
            "Transparent, SOCKS5, reverse and upstream proxy mode "
            "are mutually exclusive. Read the docs on proxy modes to understand why."
        )
    if options.add_upstream_certs_to_client_chain and options.no_upstream_cert:
        return parser.error(
            "The no-upstream-cert and add-upstream-certs-to-client-chain "
            "options are mutually exclusive. If no-upstream-cert is enabled "
            "then the upstream certificate is not retrieved before generating "
            "the client certificate chain."
        )
    if options.add_upstream_certs_to_client_chain and options.ssl_verify_upstream_cert:
        return parser.error(
            "The verify-upstream-cert and add-upstream-certs-to-client-chain "
            "options are mutually exclusive. If upstream certificates are verified "
            "then extra upstream certificates are not available for inclusion "
            "to the client chain."
        )
    if options.clientcerts:
        options.clientcerts = os.path.expanduser(options.clientcerts)
        if not os.path.exists(options.clientcerts):
            return parser.error(
                "Client certificate path does not exist: %s" % options.clientcerts
            )
    if options.auth_nonanonymous or options.auth_singleuser or options.auth_htpasswd:

        if options.transparent_proxy:
            return parser.error("Proxy Authentication not supported in transparent mode.")

        if options.socks_proxy:
            return parser.error(
                "Proxy Authentication not supported in SOCKS mode. "
                "https://github.com/mitmproxy/mitmproxy/issues/738"
            )

        if options.auth_singleuser:
            if len(options.auth_singleuser.split(':')) != 2:
                return parser.error(
                    "Invalid single-user specification. Please use the format username:password"
                )
            username, password = options.auth_singleuser.split(':')
            password_manager = authentication.PassManSingleUser(username, password)
        elif options.auth_nonanonymous:
            password_manager = authentication.PassManNonAnon()
        elif options.auth_htpasswd:
            try:
                password_manager = authentication.PassManHtpasswd(
                    options.auth_htpasswd)
            except ValueError as v:
                return parser.error(v)
        authenticator = authentication.BasicProxyAuth(password_manager, "mitmproxy")
    else:
        authenticator = authentication.NullProxyAuth(None)

    certs = []
    for i in options.certs:
        parts = i.split("=", 1)
        if len(parts) == 1:
            parts = ["*", parts[0]]
        parts[1] = os.path.expanduser(parts[1])
        if not os.path.exists(parts[1]):
            parser.error("Certificate file does not exist: %s" % parts[1])
        certs.append(parts)

    return ProxyConfig(
        host=options.addr,
        port=options.port,
        cadir=options.cadir,
        clientcerts=options.clientcerts,
        no_upstream_cert=options.no_upstream_cert,
        body_size_limit=body_size_limit,
        mode=mode,
        upstream_server=upstream_server,
        upstream_auth=upstream_auth,
        ignore_hosts=options.ignore_hosts,
        tcp_hosts=options.tcp_hosts,
        http2=options.http2,
        rawtcp=options.rawtcp,
        authenticator=authenticator,
        ciphers_client=options.ciphers_client,
        ciphers_server=options.ciphers_server,
        certs=tuple(certs),
        ssl_version_client=options.ssl_version_client,
        ssl_version_server=options.ssl_version_server,
        ssl_verify_upstream_cert=options.ssl_verify_upstream_cert,
        ssl_verify_upstream_trusted_cadir=options.ssl_verify_upstream_trusted_cadir,
        ssl_verify_upstream_trusted_ca=options.ssl_verify_upstream_trusted_ca,
        add_upstream_certs_to_client_chain=options.add_upstream_certs_to_client_chain,
    )
Ejemplo n.º 5
0
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

    stream_large_bodies = args.stream_large_bodies
    if stream_large_bodies:
        stream_large_bodies = human.parse_size(stream_large_bodies)

    reps = []
    for i in args.replace:
        try:
            p = parse_replace_hook(i)
        except ParseException as e:
            raise exceptions.OptionsError(e)
        reps.append(p)
    for i in args.replace_file:
        try:
            patt, rex, path = parse_replace_hook(i)
        except ParseException as e:
            raise exceptions.OptionsError(e)
        try:
            v = open(path, "rb").read()
        except IOError as e:
            raise exceptions.OptionsError(
                "Could not read replace file: %s" % path
            )
        reps.append((patt, rex, v))

    setheaders = []
    for i in args.setheader:
        try:
            p = parse_setheader(i)
        except ParseException as e:
            raise exceptions.OptionsError(e)
        setheaders.append(p)

    if args.outfile and args.outfile[0] == args.rfile:
        if args.outfile[1] == "wb":
            raise exceptions.OptionsError(
                "Cannot use '{}' for both reading and writing flows. "
                "Are you looking for --afile?".format(args.rfile)
            )
        else:
            raise exceptions.OptionsError(
                "Cannot use '{}' for both reading and appending flows. "
                "That would trigger an infinite loop."
            )

    # Proxy config
    certs = []
    for i in args.certs:
        parts = i.split("=", 1)
        if len(parts) == 1:
            parts = ["*", parts[0]]
        certs.append(parts)

    body_size_limit = args.body_size_limit
    if body_size_limit:
        try:
            body_size_limit = human.parse_size(body_size_limit)
        except ValueError as e:
            raise exceptions.OptionsError(
                "Invalid body size limit specification: %s" % body_size_limit
            )

    # Establish proxy mode
    c = 0
    mode, upstream_server = "regular", None
    if args.transparent_proxy:
        c += 1
        if not platform.resolver:
            raise exceptions.OptionsError(
                "Transparent mode not supported on this platform."
            )
        mode = "transparent"
    if args.socks_proxy:
        c += 1
        mode = "socks5"
    if args.reverse_proxy:
        c += 1
        mode = "reverse"
        upstream_server = args.reverse_proxy
    if args.upstream_proxy:
        c += 1
        mode = "upstream"
        upstream_server = args.upstream_proxy
    if c > 1:
        raise exceptions.OptionsError(
            "Transparent, SOCKS5, reverse and upstream proxy mode "
            "are mutually exclusive. Read the docs on proxy modes "
            "to understand why."
        )
    if args.add_upstream_certs_to_client_chain and args.no_upstream_cert:
        raise exceptions.OptionsError(
            "The no-upstream-cert and add-upstream-certs-to-client-chain "
            "options are mutually exclusive. If no-upstream-cert is enabled "
            "then the upstream certificate is not retrieved before generating "
            "the client certificate chain."
        )

    if args.quiet:
        args.verbose = 0

    return dict(
        app=args.app,
        app_host=args.app_host,
        app_port=args.app_port,

        anticache=args.anticache,
        anticomp=args.anticomp,
        client_replay=args.client_replay,
        kill=args.kill,
        no_server=args.no_server,
        refresh_server_playback=not args.norefresh,
        rheaders=args.rheaders,
        rfile=args.rfile,
        replacements=reps,
        setheaders=setheaders,
        server_replay=args.server_replay,
        scripts=args.scripts,
        stickycookie=stickycookie,
        stickyauth=stickyauth,
        stream_large_bodies=stream_large_bodies,
        showhost=args.showhost,
        outfile=args.outfile,
        verbosity=args.verbose,
        nopop=args.nopop,
        replay_ignore_content=args.replay_ignore_content,
        replay_ignore_params=args.replay_ignore_params,
        replay_ignore_payload_params=args.replay_ignore_payload_params,
        replay_ignore_host=args.replay_ignore_host,

        auth_nonanonymous = args.auth_nonanonymous,
        auth_singleuser = args.auth_singleuser,
        auth_htpasswd = args.auth_htpasswd,
        add_upstream_certs_to_client_chain = args.add_upstream_certs_to_client_chain,
        body_size_limit = body_size_limit,
        cadir = args.cadir,
        certs = certs,
        ciphers_client = args.ciphers_client,
        ciphers_server = args.ciphers_server,
        clientcerts = args.clientcerts,
        http2 = args.http2,
        ignore_hosts = args.ignore_hosts,
        listen_host = args.addr,
        listen_port = args.port,
        mode = mode,
        no_upstream_cert = args.no_upstream_cert,
        rawtcp = args.rawtcp,
        upstream_server = upstream_server,
        upstream_auth = args.upstream_auth,
        ssl_version_client = args.ssl_version_client,
        ssl_version_server = args.ssl_version_server,
        ssl_verify_upstream_cert = args.ssl_verify_upstream_cert,
        ssl_verify_upstream_trusted_cadir = args.ssl_verify_upstream_trusted_cadir,
        ssl_verify_upstream_trusted_ca = args.ssl_verify_upstream_trusted_ca,
        tcp_hosts = args.tcp_hosts,
    )
Ejemplo n.º 6
0
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_CRAFT_ANCHOR, type=str,
        help="""
            URL path specifying prefix for URL crafting
            commands. (%s)
        """ % pathod.DEFAULT_CRAFT_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(
        "--nohang", dest='nohang', default=False, action="store_true",
        help='Disable pauses during crafted response generation.'
    )
    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(
        "--ssl-version", dest="ssl_version", type=str, default="secure",
        choices=tcp.sslversion_choices.keys(),
        help="Set supported SSL/TLS versions. "
             "SSLv2, SSLv3 and 'all' are INSECURE. Defaults to secure, which is TLS1.0+."
    )

    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"
    )
    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:])

    args.ssl_version, args.ssl_options = tcp.sslversion_choices[args.ssl_version]

    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 = 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 = human.parse_size(args.sizelimit)
        except ValueError as v:
            return parser.error(v)
    args.sizelimit = sizelimit

    anchors = []
    for patt, spec in args.anchors:
        if os.path.isfile(spec):
            data = open(spec).read()
            spec = data
        try:
            arex = re.compile(patt)
        except re.error:
            return parser.error("Invalid regex in anchor: %s" % patt)
        anchors.append((arex, spec))
    args.anchors = anchors

    return args
Ejemplo n.º 7
0
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

    stream_large_bodies = args.stream_large_bodies
    if stream_large_bodies:
        stream_large_bodies = human.parse_size(stream_large_bodies)

    reps = []
    for i in args.replace:
        try:
            p = parse_replace_hook(i)
        except ParseException as e:
            raise exceptions.OptionsError(e)
        reps.append(p)
    for i in args.replace_file:
        try:
            patt, rex, path = parse_replace_hook(i)
        except ParseException as e:
            raise exceptions.OptionsError(e)
        try:
            v = open(path, "rb").read()
        except IOError as e:
            raise exceptions.OptionsError("Could not read replace file: %s" %
                                          path)
        reps.append((patt, rex, v))

    setheaders = []
    for i in args.setheader:
        try:
            p = parse_setheader(i)
        except ParseException as e:
            raise exceptions.OptionsError(e)
        setheaders.append(p)

    if args.outfile and args.outfile[0] == args.rfile:
        if args.outfile[1] == "wb":
            raise exceptions.OptionsError(
                "Cannot use '{}' for both reading and writing flows. "
                "Are you looking for --afile?".format(args.rfile))
        else:
            raise exceptions.OptionsError(
                "Cannot use '{}' for both reading and appending flows. "
                "That would trigger an infinite loop.")

    # Proxy config
    certs = []
    for i in args.certs:
        parts = i.split("=", 1)
        if len(parts) == 1:
            parts = ["*", parts[0]]
        certs.append(parts)

    body_size_limit = args.body_size_limit
    if body_size_limit:
        try:
            body_size_limit = human.parse_size(body_size_limit)
        except ValueError as e:
            raise exceptions.OptionsError(
                "Invalid body size limit specification: %s" % body_size_limit)

    # Establish proxy mode
    c = 0
    mode, upstream_server = "regular", None
    if args.transparent_proxy:
        c += 1
        if not platform.resolver:
            raise exceptions.OptionsError(
                "Transparent mode not supported on this platform.")
        mode = "transparent"
    if args.socks_proxy:
        c += 1
        mode = "socks5"
    if args.reverse_proxy:
        c += 1
        mode = "reverse"
        upstream_server = args.reverse_proxy
    if args.upstream_proxy:
        c += 1
        mode = "upstream"
        upstream_server = args.upstream_proxy
    if c > 1:
        raise exceptions.OptionsError(
            "Transparent, SOCKS5, reverse and upstream proxy mode "
            "are mutually exclusive. Read the docs on proxy modes "
            "to understand why.")
    if args.add_upstream_certs_to_client_chain and args.no_upstream_cert:
        raise exceptions.OptionsError(
            "The no-upstream-cert and add-upstream-certs-to-client-chain "
            "options are mutually exclusive. If no-upstream-cert is enabled "
            "then the upstream certificate is not retrieved before generating "
            "the client certificate chain.")

    if args.quiet:
        args.verbose = 0

    return dict(
        app=args.app,
        app_host=args.app_host,
        app_port=args.app_port,
        anticache=args.anticache,
        anticomp=args.anticomp,
        client_replay=args.client_replay,
        kill=args.kill,
        no_server=args.no_server,
        refresh_server_playback=not args.norefresh,
        rheaders=args.rheaders,
        rfile=args.rfile,
        replacements=reps,
        setheaders=setheaders,
        server_replay=args.server_replay,
        scripts=args.scripts,
        stickycookie=stickycookie,
        stickyauth=stickyauth,
        stream_large_bodies=stream_large_bodies,
        showhost=args.showhost,
        outfile=args.outfile,
        verbosity=args.verbose,
        nopop=args.nopop,
        replay_ignore_content=args.replay_ignore_content,
        replay_ignore_params=args.replay_ignore_params,
        replay_ignore_payload_params=args.replay_ignore_payload_params,
        replay_ignore_host=args.replay_ignore_host,
        auth_nonanonymous=args.auth_nonanonymous,
        auth_singleuser=args.auth_singleuser,
        auth_htpasswd=args.auth_htpasswd,
        add_upstream_certs_to_client_chain=args.
        add_upstream_certs_to_client_chain,
        body_size_limit=body_size_limit,
        cadir=args.cadir,
        certs=certs,
        ciphers_client=args.ciphers_client,
        ciphers_server=args.ciphers_server,
        clientcerts=args.clientcerts,
        http2=args.http2,
        ignore_hosts=args.ignore_hosts,
        listen_host=args.addr,
        listen_port=args.port,
        mode=mode,
        no_upstream_cert=args.no_upstream_cert,
        rawtcp=args.rawtcp,
        upstream_server=upstream_server,
        upstream_auth=args.upstream_auth,
        ssl_version_client=args.ssl_version_client,
        ssl_version_server=args.ssl_version_server,
        ssl_verify_upstream_cert=args.ssl_verify_upstream_cert,
        ssl_verify_upstream_trusted_cadir=args.
        ssl_verify_upstream_trusted_cadir,
        ssl_verify_upstream_trusted_ca=args.ssl_verify_upstream_trusted_ca,
        tcp_hosts=args.tcp_hosts,
    )
Ejemplo n.º 8
0
def process_proxy_options(parser, options):
    body_size_limit = options.body_size_limit
    if body_size_limit:
        body_size_limit = human.parse_size(body_size_limit)

    c = 0
    mode, upstream_server, upstream_auth = "regular", None, None
    if options.transparent_proxy:
        c += 1
        if not platform.resolver:
            return parser.error(
                "Transparent mode not supported on this platform.")
        mode = "transparent"
    if options.socks_proxy:
        c += 1
        mode = "socks5"
    if options.reverse_proxy:
        c += 1
        mode = "reverse"
        upstream_server = options.reverse_proxy
    if options.upstream_proxy:
        c += 1
        mode = "upstream"
        upstream_server = options.upstream_proxy
        upstream_auth = options.upstream_auth
    if c > 1:
        return parser.error(
            "Transparent, SOCKS5, reverse and upstream proxy mode "
            "are mutually exclusive. Read the docs on proxy modes to understand why."
        )
    if options.add_upstream_certs_to_client_chain and options.no_upstream_cert:
        return parser.error(
            "The no-upstream-cert and add-upstream-certs-to-client-chain "
            "options are mutually exclusive. If no-upstream-cert is enabled "
            "then the upstream certificate is not retrieved before generating "
            "the client certificate chain.")
    if options.add_upstream_certs_to_client_chain and options.ssl_verify_upstream_cert:
        return parser.error(
            "The verify-upstream-cert and add-upstream-certs-to-client-chain "
            "options are mutually exclusive. If upstream certificates are verified "
            "then extra upstream certificates are not available for inclusion "
            "to the client chain.")
    if options.clientcerts:
        options.clientcerts = os.path.expanduser(options.clientcerts)
        if not os.path.exists(options.clientcerts):
            return parser.error("Client certificate path does not exist: %s" %
                                options.clientcerts)
    if options.auth_nonanonymous or options.auth_singleuser or options.auth_htpasswd:

        if options.transparent_proxy:
            return parser.error(
                "Proxy Authentication not supported in transparent mode.")

        if options.socks_proxy:
            return parser.error(
                "Proxy Authentication not supported in SOCKS mode. "
                "https://github.com/mitmproxy/mitmproxy/issues/738")

        if options.auth_singleuser:
            if len(options.auth_singleuser.split(':')) != 2:
                return parser.error(
                    "Invalid single-user specification. Please use the format username:password"
                )
            username, password = options.auth_singleuser.split(':')
            password_manager = authentication.PassManSingleUser(
                username, password)
        elif options.auth_nonanonymous:
            password_manager = authentication.PassManNonAnon()
        elif options.auth_htpasswd:
            try:
                password_manager = authentication.PassManHtpasswd(
                    options.auth_htpasswd)
            except ValueError as v:
                return parser.error(v.message)
        authenticator = authentication.BasicProxyAuth(password_manager,
                                                      "mitmproxy")
    else:
        authenticator = authentication.NullProxyAuth(None)

    certs = []
    for i in options.certs:
        parts = i.split("=", 1)
        if len(parts) == 1:
            parts = ["*", parts[0]]
        parts[1] = os.path.expanduser(parts[1])
        if not os.path.exists(parts[1]):
            parser.error("Certificate file does not exist: %s" % parts[1])
        certs.append(parts)

    return ProxyConfig(
        host=options.addr,
        port=options.port,
        cadir=options.cadir,
        clientcerts=options.clientcerts,
        no_upstream_cert=options.no_upstream_cert,
        body_size_limit=body_size_limit,
        mode=mode,
        upstream_server=upstream_server,
        upstream_auth=upstream_auth,
        ignore_hosts=options.ignore_hosts,
        tcp_hosts=options.tcp_hosts,
        http2=options.http2,
        rawtcp=options.rawtcp,
        authenticator=authenticator,
        ciphers_client=options.ciphers_client,
        ciphers_server=options.ciphers_server,
        certs=tuple(certs),
        ssl_version_client=options.ssl_version_client,
        ssl_version_server=options.ssl_version_server,
        ssl_verify_upstream_cert=options.ssl_verify_upstream_cert,
        ssl_verify_upstream_trusted_cadir=options.
        ssl_verify_upstream_trusted_cadir,
        ssl_verify_upstream_trusted_ca=options.ssl_verify_upstream_trusted_ca,
        add_upstream_certs_to_client_chain=options.
        add_upstream_certs_to_client_chain,
    )
Ejemplo n.º 9
0
def get_common_options(options):
    stickycookie, stickyauth = None, None
    if options.stickycookie_filt:
        stickycookie = options.stickycookie_filt

    if options.stickyauth_filt:
        stickyauth = options.stickyauth_filt

    stream_large_bodies = options.stream_large_bodies
    if stream_large_bodies:
        stream_large_bodies = human.parse_size(stream_large_bodies)

    reps = []
    for i in options.replace:
        try:
            p = parse_replace_hook(i)
        except ParseException as e:
            raise configargparse.ArgumentTypeError(e.message)
        reps.append(p)
    for i in options.replace_file:
        try:
            patt, rex, path = parse_replace_hook(i)
        except ParseException as e:
            raise configargparse.ArgumentTypeError(e.message)
        try:
            v = open(path, "rb").read()
        except IOError as e:
            raise configargparse.ArgumentTypeError(
                "Could not read replace file: %s" % path)
        reps.append((patt, rex, v))

    setheaders = []
    for i in options.setheader:
        try:
            p = parse_setheader(i)
        except ParseException as e:
            raise configargparse.ArgumentTypeError(e.message)
        setheaders.append(p)

    if options.outfile and options.outfile[0] == options.rfile:
        if options.outfile[1] == "wb":
            raise configargparse.ArgumentTypeError(
                "Cannot use '{}' for both reading and writing flows. "
                "Are you looking for --afile?".format(options.rfile))
        else:
            raise configargparse.ArgumentTypeError(
                "Cannot use '{}' for both reading and appending flows. "
                "That would trigger an infinite loop.")

    return dict(
        app=options.app,
        app_host=options.app_host,
        app_port=options.app_port,
        anticache=options.anticache,
        anticomp=options.anticomp,
        client_replay=options.client_replay,
        kill=options.kill,
        no_server=options.no_server,
        refresh_server_playback=not options.norefresh,
        rheaders=options.rheaders,
        rfile=options.rfile,
        replacements=reps,
        setheaders=setheaders,
        server_replay=options.server_replay,
        scripts=options.scripts,
        stickycookie=stickycookie,
        stickyauth=stickyauth,
        stream_large_bodies=stream_large_bodies,
        showhost=options.showhost,
        outfile=options.outfile,
        verbosity=options.verbose,
        nopop=options.nopop,
        replay_ignore_content=options.replay_ignore_content,
        replay_ignore_params=options.replay_ignore_params,
        replay_ignore_payload_params=options.replay_ignore_payload_params,
        replay_ignore_host=options.replay_ignore_host)