diff options
| author | Odd Stranne <odd@mullvad.net> | 2020-06-09 12:13:16 +0200 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2020-06-09 12:13:16 +0200 |
| commit | fbbc4096f7c5efcc4c7343f55f8b07eddaec1938 (patch) | |
| tree | b01d747127fee3ad5e6082c9566dc68e12e2f1cc | |
| parent | 3a35547e4c4a00755b14d05f67ae5e636138f81b (diff) | |
| parent | 1c39069982c78cda590678a6b02e2a9e94006b92 (diff) | |
| download | mullvadvpn-fbbc4096f7c5efcc4c7343f55f8b07eddaec1938.tar.xz mullvadvpn-fbbc4096f7c5efcc4c7343f55f8b07eddaec1938.zip | |
Merge branch 'win-fw-restrict-relay-access'
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 11 | ||||
| -rw-r--r-- | mullvad-setup/src/main.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/firewall/mod.rs | 5 | ||||
| -rw-r--r-- | talpid-core/src/firewall/windows.rs | 39 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/mod.rs | 11 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/fwcontext.cpp | 117 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/fwcontext.h | 11 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/rules/baseline/permitvpnrelay.h | 30 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/rules/dns/permitnontunnel.h | 11 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/rules/multi/permitvpnrelay.cpp (renamed from windows/winfw/src/winfw/rules/baseline/permitvpnrelay.cpp) | 38 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/rules/multi/permitvpnrelay.h | 47 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/winfw.cpp | 29 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/winfw.h | 13 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/winfw.vcxproj | 4 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/winfw.vcxproj.filters | 15 |
15 files changed, 276 insertions, 107 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index f4cf17a839..9b1854d4a3 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -564,6 +564,8 @@ where tunnel_state_machine_shutdown_tx, #[cfg(target_os = "android")] android_context, + #[cfg(windows)] + Self::get_approved_applications(), ) .map_err(Error::TunnelError)?; @@ -634,6 +636,15 @@ where Ok(daemon) } + #[cfg(windows)] + fn get_approved_applications() -> Vec<PathBuf> { + let resource_dir = mullvad_paths::get_resource_dir(); + vec![ + resource_dir.join("mullvad-daemon.exe"), + resource_dir.join("openvpn.exe"), + resource_dir.join("sslocal.exe"), + ] + } /// Consume the `Daemon` and run the main event loop. Blocks until an error happens or a /// shutdown event is received. diff --git a/mullvad-setup/src/main.rs b/mullvad-setup/src/main.rs index f8fda169b5..a01f832c3e 100644 --- a/mullvad-setup/src/main.rs +++ b/mullvad-setup/src/main.rs @@ -69,6 +69,8 @@ fn reset_firewall() -> Result<(), Error> { let mut firewall = Firewall::new(FirewallArguments { initialize_blocked: false, allow_lan: None, + #[cfg(windows)] + approved_applications: vec!["foobar".into()], }) .map_err(Error::FirewallError)?; diff --git a/talpid-core/src/firewall/mod.rs b/talpid-core/src/firewall/mod.rs index 110b0bb2a1..80c9b65713 100644 --- a/talpid-core/src/firewall/mod.rs +++ b/talpid-core/src/firewall/mod.rs @@ -7,6 +7,8 @@ use std::fmt; use std::net::IpAddr; #[cfg(unix)] use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +#[cfg(windows)] +use std::path::PathBuf; use talpid_types::net::Endpoint; @@ -169,6 +171,9 @@ pub struct FirewallArguments { pub initialize_blocked: bool, /// This argument is required for the blocked state to configure the firewall correctly. pub allow_lan: Option<bool>, + /// List of applications that are approved for communicating with the relay. + #[cfg(windows)] + pub approved_applications: Vec<PathBuf>, } impl Firewall { diff --git a/talpid-core/src/firewall/windows.rs b/talpid-core/src/firewall/windows.rs index 807bcd1167..d3b18c2c3a 100644 --- a/talpid-core/src/firewall/windows.rs +++ b/talpid-core/src/firewall/windows.rs @@ -52,12 +52,29 @@ impl FirewallT for Firewall { fn new(args: FirewallArguments) -> Result<Self, Self::Error> { let logging_context = b"WinFw\0".as_ptr(); + + let app_strings = args + .approved_applications + .iter() + .map(|app| Self::to_widestring(app.to_string_lossy())) + .collect::<Vec<_>>(); + let app_ptrs = app_strings + .iter() + .map(|app| app.as_ptr()) + .collect::<Vec<_>>(); + + let approved_applications = WinFwApprovedApplications { + apps: app_ptrs.as_ptr(), + num_apps: app_ptrs.len(), + }; + if args.initialize_blocked { let cfg = &WinFwSettings::new(args.allow_lan.unwrap()); unsafe { WinFw_InitializeBlocked( WINFW_TIMEOUT_SECONDS, &cfg, + &approved_applications, Some(log_sink), logging_context, ) @@ -65,8 +82,13 @@ impl FirewallT for Firewall { }; } else { unsafe { - WinFw_Initialize(WINFW_TIMEOUT_SECONDS, Some(log_sink), logging_context) - .into_result()? + WinFw_Initialize( + WINFW_TIMEOUT_SECONDS, + &approved_applications, + Some(log_sink), + logging_context, + ) + .into_result()? }; } @@ -175,6 +197,11 @@ impl Firewall { WideCString::new(buf).unwrap() } + fn to_widestring<T: AsRef<str>>(string: T) -> WideCString { + let buf = string.as_ref().encode_utf16().collect::<Vec<_>>(); + WideCString::new(buf).unwrap() + } + fn set_connected_state( &mut self, endpoint: &Endpoint, @@ -284,6 +311,12 @@ mod winfw { pub num_addresses: usize, } + #[repr(C)] + pub struct WinFwApprovedApplications { + pub apps: *const *const libc::wchar_t, + pub num_apps: usize, + } + #[allow(dead_code)] #[repr(u8)] #[derive(Clone, Copy)] @@ -303,6 +336,7 @@ mod winfw { #[link_name = "WinFw_Initialize"] pub fn WinFw_Initialize( timeout: libc::c_uint, + approved_applications: *const WinFwApprovedApplications, sink: Option<LogSink>, sink_context: *const u8, ) -> InitializationResult; @@ -311,6 +345,7 @@ mod winfw { pub fn WinFw_InitializeBlocked( timeout: libc::c_uint, settings: &WinFwSettings, + approved_applications: *const WinFwApprovedApplications, sink: Option<LogSink>, sink_context: *const u8, ) -> InitializationResult; diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs index b0222ade67..7f867fdcd0 100644 --- a/talpid-core/src/tunnel_state_machine/mod.rs +++ b/talpid-core/src/tunnel_state_machine/mod.rs @@ -87,6 +87,7 @@ pub fn spawn( state_change_listener: impl Sender<TunnelStateTransition> + Send + 'static, shutdown_tx: oneshot::Sender<()>, #[cfg(target_os = "android")] android_context: AndroidContext, + #[cfg(windows)] approved_applications: Vec<PathBuf>, ) -> Result<Arc<mpsc::UnboundedSender<TunnelCommand>>, Error> { let (command_tx, command_rx) = mpsc::unbounded(); let command_tx = Arc::new(command_tx); @@ -119,6 +120,8 @@ pub fn spawn( command_rx, state_change_listener, shutdown_tx, + #[cfg(target_os = "windows")] + approved_applications, ) { Ok((mut reactor, event_loop)) => { startup_result_tx.send(Ok(())).expect( @@ -159,6 +162,7 @@ fn create_event_loop( commands: mpsc::UnboundedReceiver<TunnelCommand>, state_change_listener: impl Sender<TunnelStateTransition>, shutdown_tx: oneshot::Sender<()>, + #[cfg(windows)] approved_applications: Vec<PathBuf>, ) -> Result<(Core, impl Future<Item = (), Error = Error>), Error> { let reactor = Core::new().map_err(Error::ReactorError)?; let state_machine = TunnelStateMachine::new( @@ -171,6 +175,8 @@ fn create_event_loop( resource_dir, cache_dir, commands, + #[cfg(windows)] + approved_applications, )?; let future = state_machine @@ -228,16 +234,21 @@ impl TunnelStateMachine { resource_dir: PathBuf, cache_dir: impl AsRef<Path>, commands: mpsc::UnboundedReceiver<TunnelCommand>, + #[cfg(windows)] approved_applications: Vec<PathBuf>, ) -> Result<Self, Error> { let args = if block_when_disconnected { FirewallArguments { initialize_blocked: true, allow_lan: Some(allow_lan), + #[cfg(windows)] + approved_applications, } } else { FirewallArguments { initialize_blocked: false, allow_lan: None, + #[cfg(windows)] + approved_applications, } }; diff --git a/windows/winfw/src/winfw/fwcontext.cpp b/windows/winfw/src/winfw/fwcontext.cpp index 4883e6f6d8..7661fe95d4 100644 --- a/windows/winfw/src/winfw/fwcontext.cpp +++ b/windows/winfw/src/winfw/fwcontext.cpp @@ -11,14 +11,13 @@ #include "rules/baseline/permitlan.h" #include "rules/baseline/permitlanservice.h" #include "rules/baseline/permitloopback.h" -#include "rules/baseline/permitvpnrelay.h" #include "rules/baseline/permitvpntunnel.h" #include "rules/baseline/permitvpntunnelservice.h" #include "rules/baseline/permitping.h" #include "rules/baseline/permitdns.h" #include "rules/dns/blockall.h" -#include "rules/dns/permitnontunnel.h" #include "rules/dns/permittunnel.h" +#include "rules/multi/permitvpnrelay.h" #include <libwfp/transaction.h> #include <libwfp/filterengine.h> #include <libcommon/error.h> @@ -30,12 +29,12 @@ using namespace rules; namespace { -baseline::PermitVpnRelay::Protocol TranslateProtocol(WinFwProtocol protocol) +multi::PermitVpnRelay::Protocol TranslateProtocol(WinFwProtocol protocol) { switch (protocol) { - case Tcp: return baseline::PermitVpnRelay::Protocol::Tcp; - case Udp: return baseline::PermitVpnRelay::Protocol::Udp; + case Tcp: return multi::PermitVpnRelay::Protocol::Tcp; + case Udp: return multi::PermitVpnRelay::Protocol::Udp; default: { THROW_ERROR("Missing case handler in switch clause"); @@ -48,16 +47,20 @@ baseline::PermitVpnRelay::Protocol TranslateProtocol(WinFwProtocol protocol) // a local resolver to leave the machine. From the local resolver the request will either be // resolved from cache, or forwarded out onto the Internet. // -// Therefore, whenever the PermitLan rule might be activated, we must also do proper DNS management -// to prevent leaks. +// Therefore, we're unconditionally lifting all DNS traffic out of the baseline sublayer and restricting +// it in the DNS sublayer instead. The PermitDNS rule in the baseline sublayer accomplishes this. +// +// This has implications for the way the relay access is configured. In the regular case there +// is no issue: The PermitVpnRelay rule can be installed in the baseline sublayer. +// +// However, if the relay is running on the DNS port (53), it would be blocked unless the DNS +// sublayer permits this traffic. For this reason, whenever the relay is on port 53, the +// PermitVpnRelay rule has to be installed to the DNS sublayer instead of the baseline sublayer. // void AppendSettingsRules ( FwContext::Ruleset &ruleset, - const WinFwSettings &settings, - std::optional<std::wstring> tunnelInterfaceAlias = std::nullopt, - std::optional<std::vector<wfp::IpAddress> > nonTunnelDnsServers = std::nullopt, - std::optional<std::vector<wfp::IpAddress> > tunnelDnsServers = std::nullopt + const WinFwSettings &settings ) { if (settings.permitDhcp) @@ -79,18 +82,32 @@ void AppendSettingsRules ruleset.emplace_back(std::make_unique<baseline::PermitDns>()); ruleset.emplace_back(std::make_unique<dns::BlockAll>()); +} - if (nonTunnelDnsServers.has_value()) - { - ruleset.emplace_back(std::make_unique<dns::PermitNonTunnel>( - tunnelInterfaceAlias, nonTunnelDnsServers.value())); - } +// +// Refer comment on `AppendSettingsRules`. +// +void AppendRelayRules +( + FwContext::Ruleset &ruleset, + const WinFwRelay &relay, + const std::vector<std::wstring> &approvedApplications +) +{ + auto sublayer = + ( + DNS_SERVER_PORT == relay.port + ? rules::multi::PermitVpnRelay::Sublayer::Dns + : rules::multi::PermitVpnRelay::Sublayer::Baseline + ); - if (tunnelInterfaceAlias.has_value() && tunnelDnsServers.has_value()) - { - ruleset.emplace_back(std::make_unique<dns::PermitTunnel>( - tunnelInterfaceAlias.value(), tunnelDnsServers.value())); - } + ruleset.emplace_back(std::make_unique<multi::PermitVpnRelay>( + wfp::IpAddress(relay.ip), + relay.port, + TranslateProtocol(relay.protocol), + approvedApplications, + sublayer + )); } void AppendNetBlockedRules(FwContext::Ruleset &ruleset) @@ -99,23 +116,15 @@ void AppendNetBlockedRules(FwContext::Ruleset &ruleset) ruleset.emplace_back(std::make_unique<baseline::PermitLoopback>()); } -std::optional<std::vector<wfp::IpAddress> > -CreateRelayDnsExclusion(const WinFwRelay &relay) -{ - if (relay.port != DNS_SERVER_PORT) - { - return std::nullopt; - } - - std::vector<wfp::IpAddress> result = { wfp::IpAddress(relay.ip) }; - - return std::move(result); -} - } // anonymous namespace -FwContext::FwContext(uint32_t timeout) - : m_baseline(0) +FwContext::FwContext +( + uint32_t timeout, + const std::vector<std::wstring> &approvedApplications +) + : m_approvedApplications(approvedApplications) + , m_baseline(0) , m_activePolicy(Policy::None) { auto engine = wfp::FilterEngine::StandardSession(timeout); @@ -134,8 +143,14 @@ FwContext::FwContext(uint32_t timeout) m_activePolicy = Policy::None; } -FwContext::FwContext(uint32_t timeout, const WinFwSettings &settings) - : m_baseline(0) +FwContext::FwContext +( + uint32_t timeout, + const WinFwSettings &settings, + const std::vector<std::wstring> &approvedApplications +) + : m_approvedApplications(approvedApplications) + , m_baseline(0) , m_activePolicy(Policy::None) { auto engine = wfp::FilterEngine::StandardSession(timeout); @@ -166,13 +181,8 @@ bool FwContext::applyPolicyConnecting Ruleset ruleset; AppendNetBlockedRules(ruleset); - AppendSettingsRules(ruleset, settings, std::nullopt, CreateRelayDnsExclusion(relay)); - - ruleset.emplace_back(std::make_unique<baseline::PermitVpnRelay>( - wfp::IpAddress(relay.ip), - relay.port, - TranslateProtocol(relay.protocol) - )); + AppendSettingsRules(ruleset, settings); + AppendRelayRules(ruleset, relay, m_approvedApplications); // // Permit pinging the gateway inside the tunnel. @@ -208,20 +218,11 @@ bool FwContext::applyPolicyConnected Ruleset ruleset; AppendNetBlockedRules(ruleset); + AppendSettingsRules(ruleset, settings); + AppendRelayRules(ruleset, relay, m_approvedApplications); - AppendSettingsRules - ( - ruleset, - settings, - std::make_optional<>(tunnelInterfaceAlias), - CreateRelayDnsExclusion(relay), - std::make_optional<>(tunnelDnsServers) - ); - - ruleset.emplace_back(std::make_unique<baseline::PermitVpnRelay>( - wfp::IpAddress(relay.ip), - relay.port, - TranslateProtocol(relay.protocol) + ruleset.emplace_back(std::make_unique<dns::PermitTunnel>( + tunnelInterfaceAlias, tunnelDnsServers )); ruleset.emplace_back(std::make_unique<baseline::PermitVpnTunnel>( diff --git a/windows/winfw/src/winfw/fwcontext.h b/windows/winfw/src/winfw/fwcontext.h index 6bdb398b16..fd8871e26b 100644 --- a/windows/winfw/src/winfw/fwcontext.h +++ b/windows/winfw/src/winfw/fwcontext.h @@ -13,10 +13,15 @@ class FwContext { public: - FwContext(uint32_t timeout); + FwContext(uint32_t timeout, const std::vector<std::wstring> &approvedApplications); // This ctor applies the "blocked" policy. - FwContext(uint32_t timeout, const WinFwSettings &settings); + FwContext + ( + uint32_t timeout, + const WinFwSettings &settings, + const std::vector<std::wstring> &approvedApplications + ); struct PingableHosts { @@ -69,6 +74,8 @@ private: bool applyRuleset(const Ruleset &ruleset); bool applyRulesetDirectly(const Ruleset &ruleset, SessionController &controller); + const std::vector<std::wstring> m_approvedApplications; + std::unique_ptr<SessionController> m_sessionController; uint32_t m_baseline; diff --git a/windows/winfw/src/winfw/rules/baseline/permitvpnrelay.h b/windows/winfw/src/winfw/rules/baseline/permitvpnrelay.h deleted file mode 100644 index 8dd2c630f4..0000000000 --- a/windows/winfw/src/winfw/rules/baseline/permitvpnrelay.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include <winfw/rules/ifirewallrule.h> -#include <libwfp/ipaddress.h> - -namespace rules::baseline -{ - -class PermitVpnRelay : public IFirewallRule -{ -public: - - enum class Protocol - { - Tcp, - Udp - }; - - PermitVpnRelay(const wfp::IpAddress &relay, uint16_t relayPort, Protocol protocol); - - bool apply(IObjectInstaller &objectInstaller) override; - -private: - - const wfp::IpAddress m_relay; - const uint16_t m_relayPort; - const Protocol m_protocol; -}; - -} diff --git a/windows/winfw/src/winfw/rules/dns/permitnontunnel.h b/windows/winfw/src/winfw/rules/dns/permitnontunnel.h index 07b67245c3..3d8fac5cf2 100644 --- a/windows/winfw/src/winfw/rules/dns/permitnontunnel.h +++ b/windows/winfw/src/winfw/rules/dns/permitnontunnel.h @@ -6,6 +6,11 @@ #include <optional> #include <string> +// +// N.B. This rule must only be used for "custom DNS". +// Connecting to a relay on port 53 is supported using a different rule. +// + namespace rules::dns { @@ -14,8 +19,10 @@ class PermitNonTunnel : public IFirewallRule public: // - // The alias argument has to be optional for when the relay is connected on port 53. - // At this point in time there's no tunnel yet. + // The tunnel alias is optional so this rule can be applied even + // when no tunnel exists. + // + // If a tunnel does exist, the alias must be provided. // PermitNonTunnel(std::optional<std::wstring> tunnelInterfaceAlias, const std::vector<wfp::IpAddress> &hosts); diff --git a/windows/winfw/src/winfw/rules/baseline/permitvpnrelay.cpp b/windows/winfw/src/winfw/rules/multi/permitvpnrelay.cpp index daa21c3e35..db14ee4852 100644 --- a/windows/winfw/src/winfw/rules/baseline/permitvpnrelay.cpp +++ b/windows/winfw/src/winfw/rules/multi/permitvpnrelay.cpp @@ -6,11 +6,12 @@ #include <libwfp/conditions/conditionprotocol.h> #include <libwfp/conditions/conditionip.h> #include <libwfp/conditions/conditionport.h> +#include <libwfp/conditions/conditionapplication.h> #include <libcommon/error.h> using namespace wfp::conditions; -namespace rules::baseline +namespace rules::multi { namespace @@ -42,13 +43,39 @@ std::unique_ptr<ConditionProtocol> CreateProtocolCondition(PermitVpnRelay::Proto }; } +const GUID &TranslateSublayer(PermitVpnRelay::Sublayer sublayer) +{ + switch (sublayer) + { + case PermitVpnRelay::Sublayer::Baseline: return MullvadGuids::SublayerBaseline(); + case PermitVpnRelay::Sublayer::Dns: return MullvadGuids::SublayerDns(); + default: + { + THROW_ERROR("Missing case handler in switch clause"); + } + }; +} + } // anonymous namespace -PermitVpnRelay::PermitVpnRelay(const wfp::IpAddress &relay, uint16_t relayPort, Protocol protocol) +PermitVpnRelay::PermitVpnRelay +( + const wfp::IpAddress &relay, + uint16_t relayPort, + Protocol protocol, + const std::vector<std::wstring> &approvedApplications, + Sublayer sublayer +) : m_relay(relay) , m_relayPort(relayPort) , m_protocol(protocol) + , m_approvedApplications(approvedApplications) + , m_sublayer(sublayer) { + if (m_approvedApplications.empty()) + { + THROW_ERROR("Cannot configure relay access without list of approved applications"); + } } bool PermitVpnRelay::apply(IObjectInstaller &objectInstaller) @@ -65,7 +92,7 @@ bool PermitVpnRelay::apply(IObjectInstaller &objectInstaller) .description(L"This filter is part of a rule that permits communication with a VPN relay") .provider(MullvadGuids::Provider()) .layer(LayerFromIp(m_relay)) - .sublayer(MullvadGuids::SublayerBaseline()) + .sublayer(TranslateSublayer(m_sublayer)) .weight(wfp::FilterBuilder::WeightClass::Max) .permit(); @@ -75,6 +102,11 @@ bool PermitVpnRelay::apply(IObjectInstaller &objectInstaller) conditionBuilder.add_condition(ConditionPort::Remote(m_relayPort)); conditionBuilder.add_condition(CreateProtocolCondition(m_protocol)); + for (const auto &app : m_approvedApplications) + { + conditionBuilder.add_condition(std::make_unique<ConditionApplication>(app)); + } + return objectInstaller.addFilter(filterBuilder, conditionBuilder); } diff --git a/windows/winfw/src/winfw/rules/multi/permitvpnrelay.h b/windows/winfw/src/winfw/rules/multi/permitvpnrelay.h new file mode 100644 index 0000000000..e40fce159d --- /dev/null +++ b/windows/winfw/src/winfw/rules/multi/permitvpnrelay.h @@ -0,0 +1,47 @@ +#pragma once + +#include <winfw/rules/ifirewallrule.h> +#include <libwfp/ipaddress.h> +#include <string> +#include <vector> + +namespace rules::multi +{ + +class PermitVpnRelay : public IFirewallRule +{ +public: + + enum class Protocol + { + Tcp, + Udp + }; + + enum class Sublayer + { + Baseline, + Dns + }; + + PermitVpnRelay + ( + const wfp::IpAddress &relay, + uint16_t relayPort, + Protocol protocol, + const std::vector<std::wstring> &approvedApplications, + Sublayer sublayer + ); + + bool apply(IObjectInstaller &objectInstaller) override; + +private: + + const wfp::IpAddress m_relay; + const uint16_t m_relayPort; + const Protocol m_protocol; + const std::vector<std::wstring> m_approvedApplications; + const Sublayer m_sublayer; +}; + +} diff --git a/windows/winfw/src/winfw/winfw.cpp b/windows/winfw/src/winfw/winfw.cpp index 6c1cc7cd5a..55587e03f9 100644 --- a/windows/winfw/src/winfw/winfw.cpp +++ b/windows/winfw/src/winfw/winfw.cpp @@ -42,6 +42,27 @@ std::optional<FwContext::PingableHosts> ConvertPingableHosts(const PingableHosts return converted; } +std::vector<std::wstring> ConvertApprovedApplications +( + WinFwApprovedApplications *approvedApplications +) +{ + if (nullptr == approvedApplications + || 0 == approvedApplications->numApps) + { + THROW_ERROR("Invalid list of approved applications (empty list)"); + } + + std::vector<std::wstring> converted; + + for (size_t i = 0; i < approvedApplications->numApps; ++i) + { + converted.emplace_back(std::wstring(approvedApplications->apps[i])); + } + + return converted; +} + } // anonymous namespace WINFW_LINKAGE @@ -49,6 +70,7 @@ bool WINFW_API WinFw_Initialize( uint32_t timeout, + WinFwApprovedApplications *approvedApplications, MullvadLogSink logSink, void *logSinkContext ) @@ -70,7 +92,8 @@ WinFw_Initialize( g_logSink = logSink; g_logSinkContext = logSinkContext; - g_fwContext = new FwContext(timeout_ms); + g_fwContext = new FwContext(timeout_ms, + ConvertApprovedApplications(approvedApplications)); } catch (std::exception &err) { @@ -96,6 +119,7 @@ WINFW_API WinFw_InitializeBlocked( uint32_t timeout, const WinFwSettings *settings, + WinFwApprovedApplications *approvedApplications, MullvadLogSink logSink, void *logSinkContext ) @@ -122,7 +146,8 @@ WinFw_InitializeBlocked( g_logSink = logSink; g_logSinkContext = logSinkContext; - g_fwContext = new FwContext(timeout_ms, *settings); + g_fwContext = new FwContext(timeout_ms, *settings, + ConvertApprovedApplications(approvedApplications)); } catch (std::exception &err) { diff --git a/windows/winfw/src/winfw/winfw.h b/windows/winfw/src/winfw/winfw.h index 8f418c333b..100c166d32 100644 --- a/windows/winfw/src/winfw/winfw.h +++ b/windows/winfw/src/winfw/winfw.h @@ -45,6 +45,17 @@ typedef struct tag_WinFwRelay } WinFwRelay; +// +// This structure is used to define the set of applications +// that are allowed to communicate with the relay. +// +typedef struct tag_WinFwApprovedApplications +{ + const wchar_t **apps; + size_t numApps; +} +WinFwApprovedApplications; + #pragma pack(pop) /////////////////////////////////////////////////////////////////////////////// @@ -67,6 +78,7 @@ bool WINFW_API WinFw_Initialize( uint32_t timeout, + WinFwApprovedApplications *approvedApplications, MullvadLogSink logSink, void *logSinkContext ); @@ -88,6 +100,7 @@ WINFW_API WinFw_InitializeBlocked( uint32_t timeout, const WinFwSettings *settings, + WinFwApprovedApplications *approvedApplications, MullvadLogSink logSink, void *logSinkContext ); diff --git a/windows/winfw/src/winfw/winfw.vcxproj b/windows/winfw/src/winfw/winfw.vcxproj index c999f5aaca..85a6e0d0b4 100644 --- a/windows/winfw/src/winfw/winfw.vcxproj +++ b/windows/winfw/src/winfw/winfw.vcxproj @@ -32,12 +32,12 @@ <ClCompile Include="rules\baseline\permitloopback.cpp" /> <ClCompile Include="rules\baseline\permitndp.cpp" /> <ClCompile Include="rules\baseline\permitping.cpp" /> - <ClCompile Include="rules\baseline\permitvpnrelay.cpp" /> <ClCompile Include="rules\baseline\permitvpntunnel.cpp" /> <ClCompile Include="rules\baseline\permitvpntunnelservice.cpp" /> <ClCompile Include="rules\dns\blockall.cpp" /> <ClCompile Include="rules\dns\permitnontunnel.cpp" /> <ClCompile Include="rules\dns\permittunnel.cpp" /> + <ClCompile Include="rules\multi\permitvpnrelay.cpp" /> <ClCompile Include="rules\shared.cpp" /> <ClCompile Include="sessioncontroller.cpp" /> <ClCompile Include="sessionrecord.cpp" /> @@ -65,12 +65,12 @@ <ClInclude Include="rules\baseline\permitloopback.h" /> <ClInclude Include="rules\baseline\permitndp.h" /> <ClInclude Include="rules\baseline\permitping.h" /> - <ClInclude Include="rules\baseline\permitvpnrelay.h" /> <ClInclude Include="rules\baseline\permitvpntunnel.h" /> <ClInclude Include="rules\baseline\permitvpntunnelservice.h" /> <ClInclude Include="rules\dns\blockall.h" /> <ClInclude Include="rules\dns\permitnontunnel.h" /> <ClInclude Include="rules\dns\permittunnel.h" /> + <ClInclude Include="rules\multi\permitvpnrelay.h" /> <ClInclude Include="rules\ports.h" /> <ClInclude Include="rules\shared.h" /> <ClInclude Include="wfpobjecttype.h" /> diff --git a/windows/winfw/src/winfw/winfw.vcxproj.filters b/windows/winfw/src/winfw/winfw.vcxproj.filters index 46c0594c10..9ac82e87fb 100644 --- a/windows/winfw/src/winfw/winfw.vcxproj.filters +++ b/windows/winfw/src/winfw/winfw.vcxproj.filters @@ -34,9 +34,6 @@ <ClCompile Include="rules\baseline\permitping.cpp"> <Filter>rules\baseline</Filter> </ClCompile> - <ClCompile Include="rules\baseline\permitvpnrelay.cpp"> - <Filter>rules\baseline</Filter> - </ClCompile> <ClCompile Include="rules\baseline\permitvpntunnel.cpp"> <Filter>rules\baseline</Filter> </ClCompile> @@ -58,6 +55,9 @@ <ClCompile Include="rules\shared.cpp"> <Filter>rules</Filter> </ClCompile> + <ClCompile Include="rules\multi\permitvpnrelay.cpp"> + <Filter>rules\multi</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="stdafx.h" /> @@ -99,9 +99,6 @@ <ClInclude Include="rules\baseline\permitping.h"> <Filter>rules\baseline</Filter> </ClInclude> - <ClInclude Include="rules\baseline\permitvpnrelay.h"> - <Filter>rules\baseline</Filter> - </ClInclude> <ClInclude Include="rules\baseline\permitvpntunnel.h"> <Filter>rules\baseline</Filter> </ClInclude> @@ -126,6 +123,9 @@ <ClInclude Include="rules\shared.h"> <Filter>rules</Filter> </ClInclude> + <ClInclude Include="rules\multi\permitvpnrelay.h"> + <Filter>rules\multi</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <Filter Include="rules"> @@ -137,6 +137,9 @@ <Filter Include="rules\dns"> <UniqueIdentifier>{9b35e8a4-84be-4ac3-9b6f-eb21cc02e065}</UniqueIdentifier> </Filter> + <Filter Include="rules\multi"> + <UniqueIdentifier>{005cce7c-ed9d-4675-8e4f-759c9682b77e}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <None Include="winfw.def" /> |
