示例#1
0
def test_is_valid_host():
    assert not check.is_valid_host(b"")
    assert check.is_valid_host(b"one.two")
    assert not check.is_valid_host(b"one" * 255)
    assert check.is_valid_host(b"one.two.")
    # Allow underscore
    assert check.is_valid_host(b"one_two")
示例#2
0
文件: url.py 项目: web-trump/softmock
def parse_authority(authority: AnyStr, check: bool) -> Tuple[str, Optional[int]]:
    """Extract the host and port from host header/authority information

    Raises:
        ValueError, if check is True and the authority information is malformed.
    """
    try:
        if isinstance(authority, bytes):
            authority_str = authority.decode("idna")
        else:
            authority_str = authority
        m = _authority_re.match(authority_str)
        if not m:
            raise ValueError

        host = m.group("host")
        if host.startswith("[") and host.endswith("]"):
            host = host[1:-1]
        if not is_valid_host(host):
            raise ValueError

        if m.group("port"):
            port = int(m.group("port"))
            if not is_valid_port(port):
                raise ValueError
            return host, port
        else:
            return host, None

    except ValueError:
        if check:
            raise
        else:
            return always_str(authority, "utf-8", "surrogateescape"), None
示例#3
0
    def from_file(cls, f):
        ver, msg, rsv, atyp = struct.unpack("!BBBB", f.safe_read(4))
        if rsv != 0x00:
            raise SocksError(REP.GENERAL_SOCKS_SERVER_FAILURE,
                             "Socks Request: Invalid reserved byte: %s" % rsv)
        if atyp == ATYP.IPV4_ADDRESS:
            # We use tnoa here as ntop is not commonly available on Windows.
            host = ipaddress.IPv4Address(f.safe_read(4)).compressed
            use_ipv6 = False
        elif atyp == ATYP.IPV6_ADDRESS:
            host = ipaddress.IPv6Address(f.safe_read(16)).compressed
            use_ipv6 = True
        elif atyp == ATYP.DOMAINNAME:
            length, = struct.unpack("!B", f.safe_read(1))
            host = f.safe_read(length)
            if not check.is_valid_host(host):
                raise SocksError(REP.GENERAL_SOCKS_SERVER_FAILURE,
                                 "Invalid hostname: %s" % host)
            host = host.decode("idna")
            use_ipv6 = False
        else:
            raise SocksError(REP.ADDRESS_TYPE_NOT_SUPPORTED,
                             "Socks Request: Unknown ATYP: %s" % atyp)

        port, = struct.unpack("!H", f.safe_read(2))
        addr = tcp.Address((host, port), use_ipv6=use_ipv6)
        return cls(ver, msg, atyp, addr)
示例#4
0
文件: socks.py 项目: s4chin/mitmproxy
    def from_file(cls, f):
        ver, msg, rsv, atyp = struct.unpack("!BBBB", f.safe_read(4))
        if rsv != 0x00:
            raise SocksError(
                REP.GENERAL_SOCKS_SERVER_FAILURE,
                "Socks Request: Invalid reserved byte: %s" % rsv
            )
        if atyp == ATYP.IPV4_ADDRESS:
            # We use tnoa here as ntop is not commonly available on Windows.
            host = ipaddress.IPv4Address(f.safe_read(4)).compressed
        elif atyp == ATYP.IPV6_ADDRESS:
            host = ipaddress.IPv6Address(f.safe_read(16)).compressed
        elif atyp == ATYP.DOMAINNAME:
            length, = struct.unpack("!B", f.safe_read(1))
            host = f.safe_read(length)
            if not check.is_valid_host(host):
                raise SocksError(REP.GENERAL_SOCKS_SERVER_FAILURE, "Invalid hostname: %s" % host)
            host = host.decode("idna")
        else:
            raise SocksError(REP.ADDRESS_TYPE_NOT_SUPPORTED,
                             "Socks Request: Unknown ATYP: %s" % atyp)

        port, = struct.unpack("!H", f.safe_read(2))
        addr = (host, port)
        return cls(ver, msg, atyp, addr)
示例#5
0
def parse(server_spec: str) -> ServerSpec:
    """
    Parses a server mode specification, e.g.:

        - http://example.com/
        - example.org
        - example.com:443

    Raises:
        ValueError, if the server specification is invalid.
    """
    m = server_spec_re.match(server_spec)
    if not m:
        raise ValueError(f"Invalid server specification: {server_spec}")

    # defaulting to https/port 443 may annoy some folks, but it's secure-by-default.
    scheme = m.group("scheme") or "https"
    if scheme not in ("http", "https"):
        raise ValueError(f"Invalid server scheme: {scheme}")

    host = m.group("host")
    # IPv6 brackets
    if host.startswith("[") and host.endswith("]"):
        host = host[1:-1]
    if not check.is_valid_host(host.encode("idna")):
        raise ValueError(f"Invalid hostname: {host}")

    if m.group("port"):
        port = int(m.group("port"))
    else:
        port = {"http": 80, "https": 443}[scheme]
    if not check.is_valid_port(port):
        raise ValueError(f"Invalid port: {port}")

    return ServerSpec(scheme, (host, port))
示例#6
0
 def sni(self):
     for extension in self._client_hello.extensions:
         is_valid_sni_extension = (extension.type == 0x00
                                   and len(extension.server_names) == 1
                                   and extension.server_names[0].type == 0
                                   and check.is_valid_host(
                                       extension.server_names[0].name))
         if is_valid_sni_extension:
             return extension.server_names[0].name.decode("idna")
示例#7
0
文件: url.py 项目: web-trump/softmock
def parse(url):
    """
        URL-parsing function that checks that
            - port is an integer 0-65535
            - host is a valid IDNA-encoded hostname with no null-bytes
            - path is valid ASCII

        Args:
            A URL (as bytes or as unicode)

        Returns:
            A (scheme, host, port, path) tuple

        Raises:
            ValueError, if the URL is not properly formatted.
    """
    # FIXME: We shouldn't rely on urllib here.

    # Size of Ascii character after encoding is 1 byte which is same as its size
    # But non-Ascii character's size after encoding will be more than its size
    def ascii_check(l):
        if len(l) == len(str(l).encode()):
            return True
        return False

    if isinstance(url, bytes):
        url = url.decode()
        if not ascii_check(url):
            url = urllib.parse.urlsplit(url)
            url = list(url)
            url[3] = urllib.parse.quote(url[3])
            url = urllib.parse.urlunsplit(url)

    parsed = urllib.parse.urlparse(url)
    if not parsed.hostname:
        raise ValueError("No hostname given")

    else:
        host = parsed.hostname.encode("idna")
        if isinstance(parsed, urllib.parse.ParseResult):
            parsed = parsed.encode("ascii")

    port = parsed.port
    if not port:
        port = 443 if parsed.scheme == b"https" else 80

    full_path = urllib.parse.urlunparse(
        (b"", b"", parsed.path, parsed.params, parsed.query, parsed.fragment)
    )
    if not full_path.startswith(b"/"):
        full_path = b"/" + full_path

    if not check.is_valid_host(host):
        raise ValueError("Invalid Host")

    return parsed.scheme, host, port, full_path
示例#8
0
文件: tls.py 项目: vhaupert/mitmproxy
 def sni(self):
     for extension in self._client_hello.extensions:
         is_valid_sni_extension = (
             extension.type == 0x00 and
             len(extension.server_names) == 1 and
             extension.server_names[0].type == 0 and
             check.is_valid_host(extension.server_names[0].name)
         )
         if is_valid_sni_extension:
             return extension.server_names[0].name.decode("idna")
 def sni(self) -> typing.Optional[bytes]:
     if self._client_hello.extensions:
         for extension in self._client_hello.extensions.extensions:
             is_valid_sni_extension = (
                 extension.type == 0x00 and
                 len(extension.body.server_names) == 1 and
                 extension.body.server_names[0].name_type == 0 and
                 check.is_valid_host(extension.body.server_names[0].host_name)
             )
             if is_valid_sni_extension:
                 return extension.body.server_names[0].host_name
     return None
示例#10
0
def parse(url):
    """
        URL-parsing function that checks that
            - port is an integer 0-65535
            - host is a valid IDNA-encoded hostname with no null-bytes
            - path is valid ASCII

        Args:
            A URL (as bytes or as unicode)

        Returns:
            A (scheme, host, port, path) tuple

        Raises:
            ValueError, if the URL is not properly formatted.
    """
    parsed = urllib.parse.urlparse(url)

    if not parsed.hostname:
        raise ValueError("No hostname given")

    if isinstance(url, bytes):
        host = parsed.hostname

        # this should not raise a ValueError,
        # but we try to be very forgiving here and accept just everything.
        # decode_parse_result(parsed, "ascii")
    else:
        host = parsed.hostname.encode("idna")
        parsed = encode_parse_result(parsed, "ascii")

    port = parsed.port
    if not port:
        port = 443 if parsed.scheme == b"https" else 80

    full_path = urllib.parse.urlunparse(
        (b"", b"", parsed.path, parsed.params, parsed.query, parsed.fragment)
    )
    if not full_path.startswith(b"/"):
        full_path = b"/" + full_path

    if not check.is_valid_host(host):
        raise ValueError("Invalid Host")
    if not check.is_valid_port(port):
        raise ValueError("Invalid Port")

    return parsed.scheme, host, port, full_path
示例#11
0
def parse(url):
    """
        URL-parsing function that checks that
            - port is an integer 0-65535
            - host is a valid IDNA-encoded hostname with no null-bytes
            - path is valid ASCII

        Args:
            A URL (as bytes or as unicode)

        Returns:
            A (scheme, host, port, path) tuple

        Raises:
            ValueError, if the URL is not properly formatted.
    """
    parsed = urllib.parse.urlparse(url)

    if not parsed.hostname:
        raise ValueError("No hostname given")

    if isinstance(url, bytes):
        host = parsed.hostname

        # this should not raise a ValueError,
        # but we try to be very forgiving here and accept just everything.
        # decode_parse_result(parsed, "ascii")
    else:
        host = parsed.hostname.encode("idna")
        parsed = encode_parse_result(parsed, "ascii")

    port = parsed.port
    if not port:
        port = 443 if parsed.scheme == b"https" else 80

    full_path = urllib.parse.urlunparse(
        (b"", b"", parsed.path, parsed.params, parsed.query, parsed.fragment)
    )
    if not full_path.startswith(b"/"):
        full_path = b"/" + full_path

    if not check.is_valid_host(host):
        raise ValueError("Invalid Host")
    if not check.is_valid_port(port):
        raise ValueError("Invalid Port")

    return parsed.scheme, host, port, full_path
示例#12
0
 def sni(self) -> Optional[str]:
     """
     The [Server Name Indication](https://en.wikipedia.org/wiki/Server_Name_Indication),
     which indicates which hostname the client wants to connect to.
     """
     if self._client_hello.extensions:
         for extension in self._client_hello.extensions.extensions:
             is_valid_sni_extension = (
                 extension.type == 0x00
                 and len(extension.body.server_names) == 1
                 and extension.body.server_names[0].name_type == 0
                 and check.is_valid_host(
                     extension.body.server_names[0].host_name))
             if is_valid_sni_extension:
                 return extension.body.server_names[0].host_name.decode(
                     "ascii")
     return None
示例#13
0
def _parse_authority_form(hostport):
    """
        Returns (host, port) if hostport is a valid authority-form host specification.
        http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01 section 3.1

        Raises:
            ValueError, if the input is malformed
    """
    try:
        host, port = hostport.split(b":")
        port = int(port)
        if not check.is_valid_host(host) or not check.is_valid_port(port):
            raise ValueError()
    except ValueError:
        raise exceptions.HttpSyntaxException("Invalid host specification: {}".format(hostport))

    return host, port
示例#14
0
def _parse_authority_form(hostport):
    """
        Returns (host, port) if hostport is a valid authority-form host specification.
        http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01 section 3.1

        Raises:
            ValueError, if the input is malformed
    """
    try:
        host, port = hostport.split(b":")
        port = int(port)
        if not check.is_valid_host(host) or not check.is_valid_port(port):
            raise ValueError()
    except ValueError:
        raise exceptions.HttpSyntaxException(
            "Invalid host specification: {}".format(hostport))

    return host, port
示例#15
0
def parse(server_spec: str) -> ServerSpec:
    """
    Parses a server mode specification, e.g.:

        - http://example.com/
        - example.org
        - example.com:443

    Raises:
        ValueError, if the server specification is invalid.
    """
    m = server_spec_re.match(server_spec)
    if not m:
        raise ValueError(f"Invalid server specification: {server_spec}")

    if m.group("scheme"):
        scheme = m.group("scheme")
    else:
        scheme = "https" if m.group("port") in ("443", None) else "http"
    if scheme not in ("http", "https"):
        raise ValueError(f"Invalid server scheme: {scheme}")

    host = m.group("host")
    # IPv6 brackets
    if host.startswith("[") and host.endswith("]"):
        host = host[1:-1]
    if not check.is_valid_host(host):
        raise ValueError(f"Invalid hostname: {host}")

    if m.group("port"):
        port = int(m.group("port"))
    else:
        port = {
            "http": 80,
            "https": 443
        }[scheme]
    if not check.is_valid_port(port):
        raise ValueError(f"Invalid port: {port}")

    return ServerSpec(scheme, (host, port))  # type: ignore
示例#16
0
def parse(server_spec: str) -> ServerSpec:
    """
    Parses a server mode specification, e.g.:

        - http://example.com/
        - example.org
        - example.com:443

    Raises:
        ValueError, if the server specification is invalid.
    """
    m = server_spec_re.match(server_spec)
    if not m:
        raise ValueError("Invalid server specification: {}".format(server_spec))

    # defaulting to https/port 443 may annoy some folks, but it's secure-by-default.
    scheme = m.group("scheme") or "https"
    if scheme not in ("http", "https"):
        raise ValueError("Invalid server scheme: {}".format(scheme))

    host = m.group("host")
    # IPv6 brackets
    if host.startswith("[") and host.endswith("]"):
        host = host[1:-1]
    if not check.is_valid_host(host.encode("idna")):
        raise ValueError("Invalid hostname: {}".format(host))

    if m.group("port"):
        port = int(m.group("port"))
    else:
        port = {
            "http": 80,
            "https": 443
        }[scheme]
    if not check.is_valid_port(port):
        raise ValueError("Invalid port: {}".format(port))

    return ServerSpec(scheme, (host, port))
示例#17
0
def _load_webpack_config() -> WebpackConfig:
	log.debug(f'Getting config from webpack config using {GET_CONFIG_SCRIPT_PATH}.')
	proc = run(['node', GET_CONFIG_SCRIPT_PATH], stdout=PIPE)
	log.debug(f'Output: {proc.stdout}.')
	config = loads(proc.stdout)

	dev_server_host = config.get('dev_server_host', None)
	assert isinstance(dev_server_host, str), f'dev_server_host must be a string, got {dev_server_host}.'
	assert is_valid_host(dev_server_host), f'dev_server_host must be a valid IP or hostname, got {dev_server_host}.'
	if dev_server_host == '0.0.0.0':
		dev_server_host = '127.0.0.1'
	log.debug(f'Local dev server will use host {dev_server_host}.')

	dev_server_port = config.get('dev_server_port', None)
	if isinstance(dev_server_port, str):
		try:
			dev_server_port = int(dev_server_port, 10)
		except ValueError:
			pass
	assert isinstance(dev_server_port, int), f'dev_server_port must be a number, got {dev_server_port}.'
	assert is_valid_port(dev_server_port), f'dev_server_port must be a valid port, got {dev_server_port}.'
	log.debug(f'Local dev server will use port {dev_server_port}.')

	build_dir = config.get('build_dir', None)
	assert isinstance(build_dir, str), f'build_dir must be a string, got {build_dir}.'
	build_dir = Path(build_dir)
	log.debug(f'Local builds will be in {build_dir}.')

	upstream_url = config.get('upstream_url', None)
	assert isinstance(upstream_url, str), f'upstream_url must be a string, got {upstream_url}.'
	try:
		parse_url(upstream_url)
	except ValueError as e:
		assert False, f'upstream_url must be a valid URL, got {upstream_url} ({e}).'
	log.debug(f'Upstream builds will be at {upstream_url}.')

	return WebpackConfig(dev_server_host, dev_server_port, build_dir, upstream_url)
示例#18
0
def test_is_valid_host():
    assert not check.is_valid_host(b"")
    assert not check.is_valid_host(b"xn--ke.ws")
    assert check.is_valid_host(b"one.two")
    assert not check.is_valid_host(b"one" * 255)
    assert check.is_valid_host(b"one.two.")
    # Allow underscore
    assert check.is_valid_host(b"one_two")
    assert check.is_valid_host(b"::1")

    # IP Address Validations
    assert check.is_valid_host(b'127.0.0.1')
    assert check.is_valid_host(b'2001:0db8:85a3:0000:0000:8a2e:0370:7334')
    assert check.is_valid_host(b'2001:db8:85a3:0:0:8a2e:370:7334')
    assert check.is_valid_host(b'2001:db8:85a3::8a2e:370:7334')
    assert not check.is_valid_host(b'2001:db8::85a3::7334')
    assert check.is_valid_host(b'2001-db8-85a3-8d3-1319-8a2e-370-7348.ipv6-literal.net')

    # TLD must be between 2 and 63 chars
    assert check.is_valid_host(b'example.tl')
    assert check.is_valid_host(b'example.tld')
    assert check.is_valid_host(b'example.' + b"x" * 63)
    assert not check.is_valid_host(b'example.' + b"x" * 64)

    # misc characters test
    assert not check.is_valid_host(b'ex@mple')
    assert not check.is_valid_host(b'*****@*****.**')
    assert not check.is_valid_host(b'example..com')
    assert not check.is_valid_host(b'.example.com')
    assert not check.is_valid_host(b'@.example.com')
    assert not check.is_valid_host(b'!.example.com')

    # Every label must be between 1 and 63 chars
    assert not check.is_valid_host(b'.tld')
    assert check.is_valid_host(b'x' * 1 + b'.tld')
    assert check.is_valid_host(b'x' * 30 + b'.tld')
    assert not check.is_valid_host(b'x' * 64 + b'.tld')
    assert check.is_valid_host(b'x' * 1 + b'.example.tld')
    assert check.is_valid_host(b'x' * 30 + b'.example.tld')
    assert not check.is_valid_host(b'x' * 64 + b'.example.tld')

    # Misc Underscore Test Cases
    assert check.is_valid_host(b'_example')
    assert check.is_valid_host(b'_example_')
    assert check.is_valid_host(b'example_')
    assert check.is_valid_host(b'_a.example.tld')
    assert check.is_valid_host(b'a_.example.tld')
    assert check.is_valid_host(b'_a_.example.tld')

    # Misc Dash/Hyphen/Minus Test Cases
    assert check.is_valid_host(b'-example')
    assert check.is_valid_host(b'-example_')
    assert check.is_valid_host(b'example-')
    assert check.is_valid_host(b'-a.example.tld')
    assert check.is_valid_host(b'a-.example.tld')
    assert check.is_valid_host(b'-a-.example.tld')

    # Misc Combo Test Cases
    assert check.is_valid_host(b'api-.example.com')
    assert check.is_valid_host(b'__a.example-site.com')
    assert check.is_valid_host(b'_-a.example-site.com')
    assert check.is_valid_host(b'_a_.example-site.com')
    assert check.is_valid_host(b'-a-.example-site.com')
    assert check.is_valid_host(b'api-.a.example.com')
    assert check.is_valid_host(b'api-._a.example.com')
    assert check.is_valid_host(b'api-.a_.example.com')
    assert check.is_valid_host(b'api-.ab.example.com')

    # Test str
    assert check.is_valid_host('example.tld')
    assert not check.is_valid_host("foo..bar")  # cannot be idna-encoded.
示例#19
0
def test_is_valid_host():
    assert not check.is_valid_host(b"")
    assert check.is_valid_host(b"one.two")
    assert not check.is_valid_host(b"one" * 255)
    assert check.is_valid_host(b"one.two.")