Beispiel #1
0
    def configure(self, options, updated):
        conflict = all([
            options.add_upstream_certs_to_client_chain,
            options.ssl_verify_upstream_cert
        ])
        if conflict:
            raise exceptions.OptionsError(
                "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.ssl_verify_upstream_cert:
            self.openssl_verification_mode_server = SSL.VERIFY_PEER
        else:
            self.openssl_verification_mode_server = SSL.VERIFY_NONE

        self.check_ignore = HostMatcher(options.ignore_hosts)
        self.check_tcp = HostMatcher(options.tcp_hosts)

        self.openssl_method_client, self.openssl_options_client = \
            tcp.sslversion_choices[options.ssl_version_client]
        self.openssl_method_server, self.openssl_options_server = \
            tcp.sslversion_choices[options.ssl_version_server]

        certstore_path = os.path.expanduser(options.cadir)
        if not os.path.exists(os.path.dirname(certstore_path)):
            raise exceptions.OptionsError(
                "Certificate Authority parent directory does not exist: %s" %
                os.path.dirname(options.cadir))
        self.certstore = certutils.CertStore.from_store(
            certstore_path, CONF_BASENAME)

        if options.clientcerts:
            clientcerts = os.path.expanduser(options.clientcerts)
            if not os.path.exists(clientcerts):
                raise exceptions.OptionsError(
                    "Client certificate path does not exist: %s" %
                    options.clientcerts)
            self.clientcerts = clientcerts

        for spec, cert in options.certs:
            cert = os.path.expanduser(cert)
            if not os.path.exists(cert):
                raise exceptions.OptionsError(
                    "Certificate file does not exist: %s" % cert)
            try:
                self.certstore.add_cert_file(spec, cert)
            except crypto.Error:
                raise exceptions.OptionsError(
                    "Invalid certificate format: %s" % cert)

        self.upstream_server = None
        self.upstream_auth = None
        if options.upstream_server:
            self.upstream_server = parse_server_spec(options.upstream_server)
        if options.upstream_auth:
            self.upstream_auth = parse_upstream_auth(options.upstream_auth)

        self.authenticator = authentication.NullProxyAuth(None)
        needsauth = any([
            options.auth_nonanonymous, options.auth_singleuser,
            options.auth_htpasswd
        ])
        if needsauth:
            if options.mode == "transparent":
                raise exceptions.OptionsError(
                    "Proxy Authentication not supported in transparent mode.")
            elif options.mode == "socks5":
                raise exceptions.OptionsError(
                    "Proxy Authentication not supported in SOCKS mode. "
                    "https://github.com/mitmproxy/mitmproxy/issues/738")
            elif options.auth_singleuser:
                parts = options.auth_singleuser.split(':')
                if len(parts) != 2:
                    raise exceptions.OptionsError(
                        "Invalid single-user specification. "
                        "Please use the format username:password")
                password_manager = authentication.PassManSingleUser(*parts)
            elif options.auth_nonanonymous:
                password_manager = authentication.PassManNonAnon()
            elif options.auth_htpasswd:
                try:
                    password_manager = authentication.PassManHtpasswd(
                        options.auth_htpasswd)
                except ValueError as v:
                    raise exceptions.OptionsError(str(v))
            self.authenticator = authentication.BasicProxyAuth(
                password_manager, "mitmproxy")
Beispiel #2
0
 def test_simple(self):
     na = authentication.NullProxyAuth(authentication.PassManNonAnon())
     assert not na.auth_challenge_headers()
     assert na.authenticate("foo")
     na.clean({})
Beispiel #3
0
def process_proxy_options(parser, options):
    body_size_limit = utils.parse_size(options.body_size_limit)

    c = 0
    mode, upstream_server = "regular", 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
    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.clientcerts:
        options.clientcerts = os.path.expanduser(options.clientcerts)
        if not os.path.exists(options.clientcerts) or not os.path.isdir(
                options.clientcerts):
            return parser.error(
                "Client certificate directory does not exist or is not a directory: %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,
        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)
Beispiel #4
0
def process_proxy_options(parser, options):
    body_size_limit = utils.parse_size(options.body_size_limit)

    c = 0
    mode, upstream_server, spoofed_ssl_port = None, 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
    if options.spoof_mode:
        c += 1
        mode = "spoof"
    if options.ssl_spoof_mode:
        c += 1
        mode = "sslspoof"
        spoofed_ssl_port = options.spoofed_ssl_port
    if c > 1:
        return parser.error(
            "Transparent, SOCKS5, reverse and upstream proxy mode "
            "are mutually exclusive.")

    if options.clientcerts:
        options.clientcerts = os.path.expanduser(options.clientcerts)
        if not os.path.exists(options.clientcerts) or not os.path.isdir(
                options.clientcerts):
            return parser.error(
                "Client certificate directory does not exist or is not a directory: %s"
                % options.clientcerts)

    if (options.auth_nonanonymous or options.auth_singleuser
            or options.auth_htpasswd):
        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)

    ssl_ports = options.ssl_ports
    if options.ssl_ports != TRANSPARENT_SSL_PORTS:
        # arparse appends to default value by default, strip that off.
        # see http://bugs.python.org/issue16399
        ssl_ports = ssl_ports[len(TRANSPARENT_SSL_PORTS):]

    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,
        http_form_in=options.http_form_in,
        http_form_out=options.http_form_out,
        ignore_hosts=options.ignore_hosts,
        tcp_hosts=options.tcp_hosts,
        authenticator=authenticator,
        ciphers_client=options.ciphers_client,
        ciphers_server=options.ciphers_server,
        certs=certs,
        ssl_version_client=options.ssl_version_client,
        ssl_version_server=options.ssl_version_server,
        ssl_ports=ssl_ports,
        spoofed_ssl_port=spoofed_ssl_port,
        ssl_verify_upstream_cert=options.ssl_verify_upstream_cert,
        ssl_upstream_trusted_cadir=options.ssl_upstream_trusted_cadir,
        ssl_upstream_trusted_ca=options.ssl_upstream_trusted_ca)