diff options
| author | David Lönnhager <david.l@mullvad.net> | 2025-09-09 16:58:18 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-09-18 17:20:42 +0200 |
| commit | 656871c71b5b5b957e6deacfef9cdd2856165408 (patch) | |
| tree | 24adb47eb80af32360f488103102ed87f8c7b9f5 | |
| parent | 38302bd84da48c51a183ab3cbe23e429bd541a13 (diff) | |
| download | mullvadvpn-656871c71b5b5b957e6deacfef9cdd2856165408.tar.xz mullvadvpn-656871c71b5b5b957e6deacfef9cdd2856165408.zip | |
Specify any number of relay endpoints in WinFw
| -rw-r--r-- | talpid-core/src/firewall/windows/winfw/mod.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/firewall/windows/winfw/sys.rs | 6 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/fwcontext.cpp | 22 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/fwcontext.h | 4 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/winfw.cpp | 64 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/winfw.h | 10 |
6 files changed, 77 insertions, 31 deletions
diff --git a/talpid-core/src/firewall/windows/winfw/mod.rs b/talpid-core/src/firewall/windows/winfw/mod.rs index 9a2d5a7c8a..adfff4e748 100644 --- a/talpid-core/src/firewall/windows/winfw/mod.rs +++ b/talpid-core/src/firewall/windows/winfw/mod.rs @@ -175,6 +175,7 @@ pub(super) fn apply_policy_connecting( let res = unsafe { WinFw_ApplyPolicyConnecting( winfw_settings, + 1, &winfw_relay, exit_endpoint_ip_ptr, relay_client_wstr_ptrs.as_ptr(), @@ -255,6 +256,7 @@ pub(super) fn apply_policy_connected( let result = unsafe { WinFw_ApplyPolicyConnected( winfw_settings, + 1, &winfw_relay, exit_endpoint_ip_ptr, relay_client_wstr_ptrs.as_ptr(), diff --git a/talpid-core/src/firewall/windows/winfw/sys.rs b/talpid-core/src/firewall/windows/winfw/sys.rs index 40bb61599c..ca36823a10 100644 --- a/talpid-core/src/firewall/windows/winfw/sys.rs +++ b/talpid-core/src/firewall/windows/winfw/sys.rs @@ -131,7 +131,8 @@ unsafe extern "system" { #[link_name = "WinFw_ApplyPolicyConnecting"] pub fn WinFw_ApplyPolicyConnecting( settings: &WinFwSettings, - relay: &WinFwEndpoint, + numRelays: usize, + relays: &WinFwEndpoint, exitEndpointIp: *const libc::wchar_t, relayClient: *const *const libc::wchar_t, relayClientLen: usize, @@ -143,7 +144,8 @@ unsafe extern "system" { #[link_name = "WinFw_ApplyPolicyConnected"] pub fn WinFw_ApplyPolicyConnected( settings: &WinFwSettings, - relay: &WinFwEndpoint, + numRelays: usize, + relays: &WinFwEndpoint, exitEndpointIp: *const libc::wchar_t, relayClient: *const *const libc::wchar_t, relayClientLen: usize, diff --git a/windows/winfw/src/winfw/fwcontext.cpp b/windows/winfw/src/winfw/fwcontext.cpp index dc0a38b304..69a79537cd 100644 --- a/windows/winfw/src/winfw/fwcontext.cpp +++ b/windows/winfw/src/winfw/fwcontext.cpp @@ -191,7 +191,7 @@ FwContext::FwContext bool FwContext::applyPolicyConnecting ( const WinFwSettings &settings, - const WinFwEndpoint &relay, + const std::vector<WinFwEndpoint> &relays, const std::optional<wfp::IpAddress> &exitEndpointIp, const std::vector<std::wstring> &relayClients, const std::optional<std::wstring> &tunnelInterfaceAlias, @@ -203,7 +203,11 @@ bool FwContext::applyPolicyConnecting AppendNetBlockedRules(ruleset); AppendSettingsRules(ruleset, settings); - AppendRelayRules(ruleset, relay, relayClients); + + for (const auto &relay : relays) + { + AppendRelayRules(ruleset, relay, relayClients); + } if (allowedEndpoint.has_value()) { @@ -299,9 +303,9 @@ bool FwContext::applyPolicyConnecting bool FwContext::applyPolicyConnected ( const WinFwSettings &settings, - const WinFwEndpoint &relay, + const std::vector<WinFwEndpoint> &relays, const std::optional<wfp::IpAddress> &exitEndpointIp, - const std::vector<std::wstring> &relayClient, + const std::vector<std::wstring> &relayClients, const std::wstring &tunnelInterfaceAlias, const std::vector<wfp::IpAddress> &tunnelDnsServers, const std::vector<wfp::IpAddress> &nonTunnelDnsServers @@ -311,7 +315,11 @@ bool FwContext::applyPolicyConnected AppendNetBlockedRules(ruleset); AppendSettingsRules(ruleset, settings); - AppendRelayRules(ruleset, relay, relayClient); + + for (const auto &relay : relays) + { + AppendRelayRules(ruleset, relay, relayClients); + } if (!tunnelDnsServers.empty()) { @@ -327,14 +335,14 @@ bool FwContext::applyPolicyConnected } ruleset.emplace_back(std::make_unique<baseline::PermitVpnTunnel>( - relayClient, + relayClients, tunnelInterfaceAlias, std::nullopt, exitEndpointIp )); ruleset.emplace_back(std::make_unique<baseline::PermitVpnTunnelService>( - relayClient, + relayClients, tunnelInterfaceAlias, std::nullopt, exitEndpointIp diff --git a/windows/winfw/src/winfw/fwcontext.h b/windows/winfw/src/winfw/fwcontext.h index 8a4e4f0301..c8f3c2b4e5 100644 --- a/windows/winfw/src/winfw/fwcontext.h +++ b/windows/winfw/src/winfw/fwcontext.h @@ -27,7 +27,7 @@ public: bool applyPolicyConnecting ( const WinFwSettings &settings, - const WinFwEndpoint &relay, + const std::vector<WinFwEndpoint> &relays, const std::optional<wfp::IpAddress> &exitEndpointIp, const std::vector<std::wstring> &relayClients, const std::optional<std::wstring> &tunnelInterfaceAlias, @@ -38,7 +38,7 @@ public: bool applyPolicyConnected ( const WinFwSettings &settings, - const WinFwEndpoint &relay, + const std::vector<WinFwEndpoint> &relays, const std::optional<wfp::IpAddress> &exitEndpointIp, const std::vector<std::wstring> &relayClients, const std::wstring &tunnelInterfaceAlias, diff --git a/windows/winfw/src/winfw/winfw.cpp b/windows/winfw/src/winfw/winfw.cpp index 064532235c..6d79bf8356 100644 --- a/windows/winfw/src/winfw/winfw.cpp +++ b/windows/winfw/src/winfw/winfw.cpp @@ -328,7 +328,8 @@ WINFW_POLICY_STATUS WINFW_API WinFw_ApplyPolicyConnecting( const WinFwSettings *settings, - const WinFwEndpoint *relay, + size_t numRelays, + const WinFwEndpoint *relays, const wchar_t *exitEndpointIp, const wchar_t **relayClients, size_t relayClientsLen, @@ -349,9 +350,14 @@ WinFw_ApplyPolicyConnecting( THROW_ERROR("Invalid argument: settings"); } - if (nullptr == relay) + if (nullptr == relays) { - THROW_ERROR("Invalid argument: relay"); + THROW_ERROR("Invalid argument: relays"); + } + + if (0 == numRelays) + { + THROW_ERROR("Invalid argument: numRelays"); } if (nullptr == allowedTunnelTraffic) @@ -359,23 +365,33 @@ WinFw_ApplyPolicyConnecting( THROW_ERROR("Invalid argument: allowedTunnelTraffic"); } + std::vector<WinFwEndpoint> relayEndpoints; + relayEndpoints.reserve(numRelays); + for (size_t i = 0; i < numRelays; i++) + { + relayEndpoints.push_back(relays[i]); + } + const auto exitIpAddr = (exitEndpointIp != nullptr) ? std::make_optional(wfp::IpAddress(exitEndpointIp)) : std::nullopt; - const auto entryIpAddr = wfp::IpAddress(relay->ip); - if (entryIpAddr == exitIpAddr) + for (const auto &entryEndpoint : relayEndpoints) { - THROW_ERROR("Invalid argument: relay IP must not equal exitEndpointIp"); + const auto ipAddr = wfp::IpAddress(entryEndpoint.ip); + if (ipAddr == exitIpAddr) + { + THROW_ERROR("Invalid argument: relay IP must not equal exitEndpointIp"); + } } std::vector<std::wstring> relayClientWstrings; relayClientWstrings.reserve(relayClientsLen); - for(int i = 0; i < relayClientsLen; i++) { + for (size_t i = 0; i < relayClientsLen; i++) { relayClientWstrings.push_back(relayClients[i]); } return g_fwContext->applyPolicyConnecting( *settings, - *relay, + relayEndpoints, exitIpAddr, relayClientWstrings, tunnelInterfaceAlias != nullptr ? std::make_optional(tunnelInterfaceAlias) : std::nullopt, @@ -407,7 +423,8 @@ WINFW_POLICY_STATUS WINFW_API WinFw_ApplyPolicyConnected( const WinFwSettings *settings, - const WinFwEndpoint *relay, + size_t numRelays, + const WinFwEndpoint *relays, const wchar_t *exitEndpointIp, const wchar_t **relayClients, size_t relayClientsLen, @@ -430,9 +447,14 @@ WinFw_ApplyPolicyConnected( THROW_ERROR("Invalid argument: settings"); } - if (nullptr == relay) + if (nullptr == relays) { - THROW_ERROR("Invalid argument: relay"); + THROW_ERROR("Invalid argument: relays"); + } + + if (0 == numRelays) + { + THROW_ERROR("Invalid argument: numRelays"); } if (nullptr == tunnelInterfaceAlias) @@ -450,12 +472,22 @@ WinFw_ApplyPolicyConnected( THROW_ERROR("Invalid argument: nonTunnelDnsServers"); } + std::vector<WinFwEndpoint> relayEndpoints; + relayEndpoints.reserve(numRelays); + for (size_t i = 0; i < numRelays; i++) + { + relayEndpoints.push_back(relays[i]); + } + const auto exitIpAddr = (exitEndpointIp != nullptr) ? std::make_optional(wfp::IpAddress(exitEndpointIp)) : std::nullopt; - const auto entryIpAddr = wfp::IpAddress(relay->ip); - if (entryIpAddr == exitIpAddr) + for (const auto &entryEndpoint : relayEndpoints) { - THROW_ERROR("Invalid argument: relay IP must not equal exitEndpointIp"); + const auto ipAddr = wfp::IpAddress(entryEndpoint.ip); + if (ipAddr == exitIpAddr) + { + THROW_ERROR("Invalid argument: relay IP must not equal exitEndpointIp"); + } } std::vector<wfp::IpAddress> convertedTunnelDnsServers; @@ -499,13 +531,13 @@ WinFw_ApplyPolicyConnected( std::vector<std::wstring> relayClientWstrings; relayClientWstrings.reserve(relayClientsLen); - for(int i = 0; i < relayClientsLen; i++) { + for (size_t i = 0; i < relayClientsLen; i++) { relayClientWstrings.push_back(relayClients[i]); } return g_fwContext->applyPolicyConnected( *settings, - *relay, + relayEndpoints, exitIpAddr, relayClientWstrings, tunnelInterfaceAlias, diff --git a/windows/winfw/src/winfw/winfw.h b/windows/winfw/src/winfw/winfw.h index f3e26ea4aa..f4cd3b4bca 100644 --- a/windows/winfw/src/winfw/winfw.h +++ b/windows/winfw/src/winfw/winfw.h @@ -159,7 +159,7 @@ enum WINFW_POLICY_STATUS // // Apply restrictions in the firewall that block all traffic, except: // - What is specified by settings -// - Communication with the relay server +// - Communication with the relay server(s) // - Specified in-tunnel traffic, except DNS. // // Parameters: @@ -174,7 +174,8 @@ WINFW_POLICY_STATUS WINFW_API WinFw_ApplyPolicyConnecting( const WinFwSettings *settings, - const WinFwEndpoint *relay, + size_t numRelays, + const WinFwEndpoint *relays, const wchar_t *exitEndpointIp, const wchar_t **relayClient, size_t relayClientLen, @@ -188,7 +189,7 @@ WinFw_ApplyPolicyConnecting( // // Apply restrictions in the firewall that block all traffic, except: // - What is specified by settings -// - Communication with the relay server +// - Communication with the relay server(s) // - Non-DNS traffic inside the VPN tunnel // - DNS requests inside the VPN tunnel to any server in 'tunnelDnsServers' // - DNS requests outside the VPN tunnel to any server in 'nonTunnelDnsServers' @@ -208,7 +209,8 @@ WINFW_POLICY_STATUS WINFW_API WinFw_ApplyPolicyConnected( const WinFwSettings *settings, - const WinFwEndpoint *relay, + size_t numRelays, + const WinFwEndpoint *relays, const wchar_t *exitEndpointIp, const wchar_t **relayClient, size_t relayClientLen, |
