def test_authenticate_clean(self): ba = authentication.BasicProxyAuth(authentication.PassManNonAnon(), "test") headers = Headers() vals = ("basic", "foo", "bar") headers[ba.AUTH_HEADER] = authentication.assemble_http_basic_auth( *vals) assert ba.authenticate(headers) ba.clean(headers) assert ba.AUTH_HEADER not in headers headers[ba.AUTH_HEADER] = "" assert not ba.authenticate(headers) headers[ba.AUTH_HEADER] = "foo" assert not ba.authenticate(headers) vals = ("foo", "foo", "bar") headers[ba.AUTH_HEADER] = authentication.assemble_http_basic_auth( *vals) assert not ba.authenticate(headers) ba = authentication.BasicProxyAuth(authentication.PassMan(), "test") vals = ("basic", "foo", "bar") headers[ba.AUTH_HEADER] = authentication.assemble_http_basic_auth( *vals) assert not ba.authenticate(headers)
def test_authenticate_clean(self): ba = authentication.BasicProxyAuth(authentication.PassManNonAnon(), "test") hdrs = odict.ODictCaseless() vals = ("basic", "foo", "bar") hdrs[ba.AUTH_HEADER] = [authentication.assemble_http_basic_auth(*vals)] assert ba.authenticate(hdrs) ba.clean(hdrs) assert not ba.AUTH_HEADER in hdrs hdrs[ba.AUTH_HEADER] = [""] assert not ba.authenticate(hdrs) hdrs[ba.AUTH_HEADER] = ["foo"] assert not ba.authenticate(hdrs) vals = ("foo", "foo", "bar") hdrs[ba.AUTH_HEADER] = [authentication.assemble_http_basic_auth(*vals)] assert not ba.authenticate(hdrs) ba = authentication.BasicProxyAuth(authentication.PassMan(), "test") vals = ("basic", "foo", "bar") hdrs[ba.AUTH_HEADER] = [authentication.assemble_http_basic_auth(*vals)] assert not ba.authenticate(hdrs)
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.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, 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)
def configure(self, options, updated): # type: (mitmproxy.options.Options, Any) -> None if options.add_upstream_certs_to_client_chain and not options.ssl_insecure: raise exceptions.OptionsError( "The verify-upstream-cert requires certificate verification to be disabled. " "If upstream certificates are verified then extra upstream certificates are " "not available for inclusion to the client chain." ) if options.ssl_insecure: self.openssl_verification_mode_server = SSL.VERIFY_NONE else: self.openssl_verification_mode_server = SSL.VERIFY_PEER 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)) if options.mode == "reverse": self.authenticator = authentication.BasicWebsiteAuth( password_manager, self.upstream_server.address ) else: self.authenticator = authentication.BasicProxyAuth( password_manager, "mitmproxy" )
def test_simple(self): ba = authentication.BasicProxyAuth(authentication.PassManNonAnon(), "test") headers = Headers() assert ba.auth_challenge_headers() assert not ba.authenticate(headers)
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, )
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)