diff --git a/mitmproxy/addons/dns_resolver.py b/mitmproxy/addons/dns_resolver.py index 84ee99ae4..7426f6890 100644 --- a/mitmproxy/addons/dns_resolver.py +++ b/mitmproxy/addons/dns_resolver.py @@ -45,7 +45,10 @@ class DnsResolver: or `[]` if they cannot be determined. """ try: - return ctx.options.dns_name_servers or mitmproxy_rs.get_system_dns_servers() + return ( + ctx.options.dns_name_servers + or mitmproxy_rs.dns.get_system_dns_servers() + ) except RuntimeError as e: logger.warning( f"Failed to get system dns servers: {e}\n" @@ -54,13 +57,13 @@ class DnsResolver: return [] @cache - def resolver(self) -> mitmproxy_rs.DnsResolver: + def resolver(self) -> mitmproxy_rs.dns.DnsResolver: """ Our mitmproxy_rs DNS resolver. """ ns = self.name_servers() assert ns - return mitmproxy_rs.DnsResolver( + return mitmproxy_rs.dns.DnsResolver( name_servers=ns, use_hosts_file=ctx.options.dns_use_hosts_file, ) diff --git a/mitmproxy/proxy/mode_servers.py b/mitmproxy/proxy/mode_servers.py index 6df2f85e9..fd6f6731f 100644 --- a/mitmproxy/proxy/mode_servers.py +++ b/mitmproxy/proxy/mode_servers.py @@ -219,7 +219,7 @@ class ServerInstance(Generic[M], metaclass=ABCMeta): class AsyncioServerInstance(ServerInstance[M], metaclass=ABCMeta): - _servers: list[asyncio.Server | mitmproxy_rs.UdpServer] + _servers: list[asyncio.Server | mitmproxy_rs.udp.UdpServer] def __init__(self, *args, **kwargs) -> None: self._servers = [] @@ -233,7 +233,7 @@ class AsyncioServerInstance(ServerInstance[M], metaclass=ABCMeta): def listen_addrs(self) -> tuple[Address, ...]: addrs = [] for s in self._servers: - if isinstance(s, mitmproxy_rs.UdpServer): + if isinstance(s, mitmproxy_rs.udp.UdpServer): addrs.append(s.getsockname()) else: try: @@ -270,11 +270,11 @@ class AsyncioServerInstance(ServerInstance[M], metaclass=ABCMeta): async def listen( self, host: str, port: int - ) -> list[asyncio.Server | mitmproxy_rs.UdpServer]: + ) -> list[asyncio.Server | mitmproxy_rs.udp.UdpServer]: if self.mode.transport_protocol not in ("tcp", "udp", "both"): raise AssertionError(self.mode.transport_protocol) - servers: list[asyncio.Server | mitmproxy_rs.UdpServer] = [] + servers: list[asyncio.Server | mitmproxy_rs.udp.UdpServer] = [] if self.mode.transport_protocol in ("tcp", "both"): # workaround for https://github.com/python/cpython/issues/89856: # We want both IPv4 and IPv6 sockets to bind to the same port. @@ -305,14 +305,14 @@ class AsyncioServerInstance(ServerInstance[M], metaclass=ABCMeta): # we start two servers for dual-stack support. # On Linux, this would also be achievable by toggling IPV6_V6ONLY off, but this here works cross-platform. if host == "": - ipv4 = await mitmproxy_rs.start_udp_server( + ipv4 = await mitmproxy_rs.udp.start_udp_server( "0.0.0.0", port, self.handle_udp_stream, ) servers.append(ipv4) try: - ipv6 = await mitmproxy_rs.start_udp_server( + ipv6 = await mitmproxy_rs.udp.start_udp_server( "[::]", ipv4.getsockname()[1], self.handle_udp_stream, @@ -322,7 +322,7 @@ class AsyncioServerInstance(ServerInstance[M], metaclass=ABCMeta): logger.debug("Failed to listen on '::', listening on IPv4 only.") else: servers.append( - await mitmproxy_rs.start_udp_server( + await mitmproxy_rs.udp.start_udp_server( host, port, self.handle_udp_stream, @@ -333,7 +333,7 @@ class AsyncioServerInstance(ServerInstance[M], metaclass=ABCMeta): class WireGuardServerInstance(ServerInstance[mode_specs.WireGuardMode]): - _server: mitmproxy_rs.WireGuardServer | None = None + _server: mitmproxy_rs.wireguard.WireGuardServer | None = None server_key: str client_key: str @@ -369,8 +369,8 @@ class WireGuardServerInstance(ServerInstance[mode_specs.WireGuardMode]): conf_path.write_text( json.dumps( { - "server_key": mitmproxy_rs.genkey(), - "client_key": mitmproxy_rs.genkey(), + "server_key": mitmproxy_rs.wireguard.genkey(), + "client_key": mitmproxy_rs.wireguard.genkey(), }, indent=4, ) @@ -383,10 +383,10 @@ class WireGuardServerInstance(ServerInstance[mode_specs.WireGuardMode]): except Exception as e: raise ValueError(f"Invalid configuration file ({conf_path}): {e}") from e # error early on invalid keys - p = mitmproxy_rs.pubkey(self.client_key) - _ = mitmproxy_rs.pubkey(self.server_key) + p = mitmproxy_rs.wireguard.pubkey(self.client_key) + _ = mitmproxy_rs.wireguard.pubkey(self.server_key) - self._server = await mitmproxy_rs.start_wireguard_server( + self._server = await mitmproxy_rs.wireguard.start_wireguard_server( host or "0.0.0.0", port, self.server_key, @@ -416,7 +416,7 @@ class WireGuardServerInstance(ServerInstance[mode_specs.WireGuardMode]): DNS = 10.0.0.53 [Peer] - PublicKey = {mitmproxy_rs.pubkey(self.server_key)} + PublicKey = {mitmproxy_rs.wireguard.pubkey(self.server_key)} AllowedIPs = 0.0.0.0/0 Endpoint = {host}:{port} """ @@ -440,7 +440,7 @@ class WireGuardServerInstance(ServerInstance[mode_specs.WireGuardMode]): class LocalRedirectorInstance(ServerInstance[mode_specs.LocalMode]): - _server: ClassVar[mitmproxy_rs.LocalRedirector | None] = None + _server: ClassVar[mitmproxy_rs.local.LocalRedirector | None] = None """The local redirector daemon. Will be started once and then reused for all future instances.""" _instance: ClassVar[LocalRedirectorInstance | None] = None """The current LocalRedirectorInstance. Will be unset again if an instance is stopped.""" @@ -474,7 +474,7 @@ class LocalRedirectorInstance(ServerInstance[mode_specs.LocalMode]): cls._instance = self # assign before awaiting to avoid races if cls._server is None: try: - cls._server = await mitmproxy_rs.start_local_redirector( + cls._server = await mitmproxy_rs.local.start_local_redirector( cls.redirector_handle_stream, cls.redirector_handle_stream, ) diff --git a/mitmproxy/proxy/mode_specs.py b/mitmproxy/proxy/mode_specs.py index ff5d1c5fe..ab894abc1 100644 --- a/mitmproxy/proxy/mode_specs.py +++ b/mitmproxy/proxy/mode_specs.py @@ -298,7 +298,7 @@ class LocalMode(ProxyMode): def __post_init__(self) -> None: # should not raise - mitmproxy_rs.LocalRedirector.describe_spec(self.data) + mitmproxy_rs.local.LocalRedirector.describe_spec(self.data) class OsProxyMode(ProxyMode): # pragma: no cover diff --git a/mitmproxy/proxy/server.py b/mitmproxy/proxy/server.py index 4322f6e8e..449e5abff 100644 --- a/mitmproxy/proxy/server.py +++ b/mitmproxy/proxy/server.py @@ -215,7 +215,7 @@ class ConnectionHandler(metaclass=abc.ABCMeta): local_addr=command.connection.sockname, ) elif command.connection.transport_protocol == "udp": - reader = writer = await mitmproxy_rs.open_udp_connection( + reader = writer = await mitmproxy_rs.udp.open_udp_connection( *command.connection.address, local_addr=command.connection.sockname, ) diff --git a/mitmproxy/tools/web/app.py b/mitmproxy/tools/web/app.py index 9cb42c620..861881a39 100644 --- a/mitmproxy/tools/web/app.py +++ b/mitmproxy/tools/web/app.py @@ -664,7 +664,7 @@ class State(RequestHandler): class ProcessList(RequestHandler): @staticmethod def get_json(): - processes = mitmproxy_rs.active_executables() + processes = mitmproxy_rs.process_info.active_executables() return [ { "is_visible": process.is_visible, @@ -687,7 +687,7 @@ class ProcessImage(RequestHandler): raise APIError(400, "Missing 'path' parameter.") try: - icon_bytes = mitmproxy_rs.executable_icon(path) + icon_bytes = mitmproxy_rs.process_info.executable_icon(path) except Exception: icon_bytes = TRANSPARENT_PNG diff --git a/pyproject.toml b/pyproject.toml index 8e7c62078..7ea5b9a56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ dependencies = [ "hyperframe>=6.0,<=6.0.1", "kaitaistruct>=0.10,<=0.10", "ldap3>=2.8,<=2.9.1", - "mitmproxy_rs>=0.7.2,<0.8", # relaxed upper bound here: we control this + "mitmproxy_rs>=0.8.1,<0.9", # relaxed upper bound here: we control this "msgpack>=1.0.0,<=1.0.8", "passlib>=1.6.5,<=1.7.4", "protobuf>=5.27.2,<=5.28.0", diff --git a/test/mitmproxy/addons/test_dns_resolver.py b/test/mitmproxy/addons/test_dns_resolver.py index 9101b1c5c..22230df9a 100644 --- a/test/mitmproxy/addons/test_dns_resolver.py +++ b/test/mitmproxy/addons/test_dns_resolver.py @@ -37,12 +37,12 @@ def _err(): async def test_name_servers(caplog, monkeypatch): dr = dns_resolver.DnsResolver() with taddons.context(dr) as tctx: - assert dr.name_servers() == mitmproxy_rs.get_system_dns_servers() + assert dr.name_servers() == mitmproxy_rs.dns.get_system_dns_servers() tctx.options.dns_name_servers = ["1.1.1.1"] assert dr.name_servers() == ["1.1.1.1"] - monkeypatch.setattr(mitmproxy_rs, "get_system_dns_servers", _err) + monkeypatch.setattr(mitmproxy_rs.dns, "get_system_dns_servers", _err) tctx.options.dns_name_servers = [] assert dr.name_servers() == [] assert "Failed to get system dns servers" in caplog.text @@ -86,15 +86,17 @@ async def test_lookup( domain: Domain, hosts_file: HostsFile, name_servers: NameServers, monkeypatch ): if name_servers == "nameservers": - monkeypatch.setattr(mitmproxy_rs, "get_system_dns_servers", lambda: ["8.8.8.8"]) monkeypatch.setattr( - mitmproxy_rs.DnsResolver, "lookup_ipv4", lambda _, name: lookup(name) + mitmproxy_rs.dns, "get_system_dns_servers", lambda: ["8.8.8.8"] ) monkeypatch.setattr( - mitmproxy_rs.DnsResolver, "lookup_ipv6", lambda _, name: lookup(name) + mitmproxy_rs.dns.DnsResolver, "lookup_ipv4", lambda _, name: lookup(name) + ) + monkeypatch.setattr( + mitmproxy_rs.dns.DnsResolver, "lookup_ipv6", lambda _, name: lookup(name) ) else: - monkeypatch.setattr(mitmproxy_rs, "get_system_dns_servers", lambda: []) + monkeypatch.setattr(mitmproxy_rs.dns, "get_system_dns_servers", lambda: []) monkeypatch.setattr(asyncio.get_running_loop(), "getaddrinfo", getaddrinfo) dr = dns_resolver.DnsResolver() diff --git a/test/mitmproxy/addons/test_proxyserver.py b/test/mitmproxy/addons/test_proxyserver.py index 346167878..a78c7a3a2 100644 --- a/test/mitmproxy/addons/test_proxyserver.py +++ b/test/mitmproxy/addons/test_proxyserver.py @@ -271,7 +271,7 @@ async def lookup_ipv4(): async def test_dns(caplog_async, monkeypatch) -> None: monkeypatch.setattr( - mitmproxy_rs.DnsResolver, "lookup_ipv4", lambda _, __: lookup_ipv4() + mitmproxy_rs.dns.DnsResolver, "lookup_ipv4", lambda _, __: lookup_ipv4() ) caplog_async.set_level("INFO") @@ -286,7 +286,7 @@ async def test_dns(caplog_async, monkeypatch) -> None: await caplog_async.await_log("DNS server listening at") assert ps.servers dns_addr = ps.servers["dns@127.0.0.1:0"].listen_addrs[0] - s = await mitmproxy_rs.open_udp_connection(*dns_addr) + s = await mitmproxy_rs.udp.open_udp_connection(*dns_addr) req = tdnsreq() s.write(req.packed) resp = dns.Message.unpack(await s.read(65535)) @@ -384,7 +384,7 @@ async def test_udp(caplog_async) -> None: ) assert ps.servers addr = ps.servers[mode].listen_addrs[0] - stream = await mitmproxy_rs.open_udp_connection(*addr) + stream = await mitmproxy_rs.udp.open_udp_connection(*addr) stream.write(b"\x16") assert b"\x01" == await stream.read(65535) assert repr(ps) == "Proxyserver(1 active conns)" @@ -847,7 +847,7 @@ async def test_regular_http3(caplog_async, monkeypatch) -> None: with taddons.context(ps, nl, ta) as tctx: ta.configure(["confdir"]) async with quic_server(H3EchoServer, alpn=["h3"]) as server_addr: - orig_open_connection = mitmproxy_rs.open_udp_connection + orig_open_connection = mitmproxy_rs.udp.open_udp_connection async def open_connection_path( host: str, port: int, *args, **kwargs @@ -858,7 +858,7 @@ async def test_regular_http3(caplog_async, monkeypatch) -> None: return orig_open_connection(host, port, *args, **kwargs) monkeypatch.setattr( - mitmproxy_rs, "open_udp_connection", open_connection_path + mitmproxy_rs.udp, "open_udp_connection", open_connection_path ) mode = f"http3@127.0.0.1:0" tctx.configure( diff --git a/test/mitmproxy/proxy/test_mode_servers.py b/test/mitmproxy/proxy/test_mode_servers.py index b97a31c7c..e98933cef 100644 --- a/test/mitmproxy/proxy/test_mode_servers.py +++ b/test/mitmproxy/proxy/test_mode_servers.py @@ -261,7 +261,7 @@ async def test_udp_start_stop(caplog_async): assert await caplog_async.await_log("server listening") host, port, *_ = inst.listen_addrs[0] - stream = await mitmproxy_rs.open_udp_connection(host, port) + stream = await mitmproxy_rs.udp.open_udp_connection(host, port) stream.write(b"\x00\x00\x01") assert await caplog_async.await_log("sent an invalid message") @@ -316,7 +316,7 @@ async def test_dual_stack(ip_version, protocol, caplog_async): if protocol == "tcp": _, stream = await asyncio.open_connection(addr, port) else: - stream = await mitmproxy_rs.open_udp_connection(addr, port) + stream = await mitmproxy_rs.udp.open_udp_connection(addr, port) stream.write(b"\x00\x00\x01") assert await caplog_async.await_log("sent an invalid message") stream.close() @@ -341,7 +341,7 @@ async def test_dns_start_stop(caplog_async, transport_protocol): if transport_protocol == "tcp": _, stream = await asyncio.open_connection("127.0.0.1", port) elif transport_protocol == "udp": - stream = await mitmproxy_rs.open_udp_connection("127.0.0.1", port) + stream = await mitmproxy_rs.udp.open_udp_connection("127.0.0.1", port) stream.write(b"\x00\x00\x01") assert await caplog_async.await_log("sent an invalid message") @@ -356,7 +356,9 @@ async def test_dns_start_stop(caplog_async, transport_protocol): @pytest.fixture() def patched_local_redirector(monkeypatch): start_local_redirector = AsyncMock(return_value=Mock()) - monkeypatch.setattr(mitmproxy_rs, "start_local_redirector", start_local_redirector) + monkeypatch.setattr( + mitmproxy_rs.local, "start_local_redirector", start_local_redirector + ) # make sure _server and _instance are restored after this test monkeypatch.setattr(LocalRedirectorInstance, "_server", None) monkeypatch.setattr(LocalRedirectorInstance, "_instance", None) diff --git a/test/mitmproxy/tools/web/test_app.py b/test/mitmproxy/tools/web/test_app.py index f5677e404..aed224e68 100644 --- a/test/mitmproxy/tools/web/test_app.py +++ b/test/mitmproxy/tools/web/test_app.py @@ -407,10 +407,10 @@ class TestApp(tornado.testing.AsyncHTTPTestCase): def test_process_list(self): try: - mitmproxy_rs.active_executables() + mitmproxy_rs.process_info.active_executables() except NotImplementedError: pytest.skip( - "mitmproxy_rs.active_executables not available on this platform." + "mitmproxy_rs.process_info.active_executables not available on this platform." ) resp = self.fetch("/processes") assert resp.code == 200 @@ -418,9 +418,11 @@ class TestApp(tornado.testing.AsyncHTTPTestCase): def test_process_icon(self): try: - mitmproxy_rs.executable_icon("invalid") + mitmproxy_rs.process_info.executable_icon("invalid") except NotImplementedError: - pytest.skip("mitmproxy_rs.executable_icon not available on this platform.") + pytest.skip( + "mitmproxy_rs.process_info.executable_icon not available on this platform." + ) except Exception: pass resp = self.fetch("/executable-icon")