summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2025-09-12 11:41:58 +0200
committerDavid Lönnhager <david.l@mullvad.net>2025-09-12 11:41:58 +0200
commit29ba9088210475eb179c8eefe5c9f3b8bbc92583 (patch)
tree7bf86b44db5ef2d3f0498e05f07b1b21f1767941
parent1a4554b68660cf6b1f767cc9bbc798d3ee2d994d (diff)
parent5f4dc945c9a30035989be9a02879e54072f14d48 (diff)
downloadmullvadvpn-29ba9088210475eb179c8eefe5c9f3b8bbc92583.tar.xz
mullvadvpn-29ba9088210475eb179c8eefe5c9f3b8bbc92583.zip
Merge branch 'winfw-multiple-endpoints'
m---------windows/libwfp0
-rw-r--r--windows/winfw/src/winfw/fwcontext.cpp27
-rw-r--r--windows/winfw/src/winfw/mullvadguids.cpp206
-rw-r--r--windows/winfw/src/winfw/mullvadguids.h35
-rw-r--r--windows/winfw/src/winfw/objectpurger.cpp106
-rw-r--r--windows/winfw/src/winfw/objectpurger.h1
-rw-r--r--windows/winfw/src/winfw/rules/baseline/permitendpoint.cpp81
-rw-r--r--windows/winfw/src/winfw/rules/baseline/permitendpoint.h34
-rw-r--r--windows/winfw/src/winfw/rules/multi/permitendpoint.cpp (renamed from windows/winfw/src/winfw/rules/multi/permitvpnrelay.cpp)19
-rw-r--r--windows/winfw/src/winfw/rules/multi/permitendpoint.h (renamed from windows/winfw/src/winfw/rules/multi/permitvpnrelay.h)4
-rw-r--r--windows/winfw/src/winfw/sessioncontroller.cpp6
-rw-r--r--windows/winfw/src/winfw/sessioncontroller.h3
-rw-r--r--windows/winfw/src/winfw/winfw.vcxproj6
-rw-r--r--windows/winfw/src/winfw/winfw.vcxproj.filters10
14 files changed, 108 insertions, 430 deletions
diff --git a/windows/libwfp b/windows/libwfp
-Subproject 105a27f44a1c129b751fe533aabc9938eeec1bc
+Subproject 94415c7a85ea0ef728dedc6778457395185d892
diff --git a/windows/winfw/src/winfw/fwcontext.cpp b/windows/winfw/src/winfw/fwcontext.cpp
index 7747d7c822..dc0a38b304 100644
--- a/windows/winfw/src/winfw/fwcontext.cpp
+++ b/windows/winfw/src/winfw/fwcontext.cpp
@@ -14,12 +14,11 @@
#include "rules/baseline/permitvpntunnel.h"
#include "rules/baseline/permitvpntunnelservice.h"
#include "rules/baseline/permitdns.h"
-#include "rules/baseline/permitendpoint.h"
#include "rules/dns/blockall.h"
#include "rules/dns/permitloopback.h"
#include "rules/dns/permittunnel.h"
#include "rules/dns/permitnontunnel.h"
-#include "rules/multi/permitvpnrelay.h"
+#include "rules/multi/permitendpoint.h"
#include <libwfp/transaction.h>
#include <libwfp/filterengine.h>
#include <libcommon/error.h>
@@ -40,11 +39,11 @@ namespace
// 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.
+// is no issue: The PermitEndpoint 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.
+// PermitEndpoint rule has to be installed to the DNS sublayer instead of the baseline sublayer.
//
void AppendSettingsRules
(
@@ -87,11 +86,11 @@ void AppendRelayRules
auto sublayer =
(
DNS_SERVER_PORT == relay.port
- ? rules::multi::PermitVpnRelay::Sublayer::Dns
- : rules::multi::PermitVpnRelay::Sublayer::Baseline
+ ? rules::multi::PermitEndpoint::Sublayer::Dns
+ : rules::multi::PermitEndpoint::Sublayer::Baseline
);
- ruleset.emplace_back(std::make_unique<multi::PermitVpnRelay>(
+ ruleset.emplace_back(std::make_unique<multi::PermitEndpoint>(
wfp::IpAddress(relay.ip),
relay.port,
relay.protocol,
@@ -115,11 +114,19 @@ void AppendAllowedEndpointRules
clients.push_back(endpoint.clients[i]);
}
- ruleset.emplace_back(std::make_unique<baseline::PermitEndpoint>(
+ auto sublayer =
+ (
+ DNS_SERVER_PORT == endpoint.endpoint.port
+ ? rules::multi::PermitEndpoint::Sublayer::Dns
+ : rules::multi::PermitEndpoint::Sublayer::Baseline
+ );
+
+ ruleset.emplace_back(std::make_unique<multi::PermitEndpoint>(
wfp::IpAddress(endpoint.endpoint.ip),
- clients,
endpoint.endpoint.port,
- endpoint.endpoint.protocol
+ endpoint.endpoint.protocol,
+ clients,
+ sublayer
));
}
diff --git a/windows/winfw/src/winfw/mullvadguids.cpp b/windows/winfw/src/winfw/mullvadguids.cpp
index 3029607a11..e072b59eab 100644
--- a/windows/winfw/src/winfw/mullvadguids.cpp
+++ b/windows/winfw/src/winfw/mullvadguids.cpp
@@ -1,183 +1,5 @@
#include "stdafx.h"
#include "mullvadguids.h"
-#include <algorithm>
-#include <iterator>
-
-//static
-MullvadGuids::DetailedIdentityRegistry MullvadGuids::DeprecatedIdentities()
-{
- //
- // Collect GUIDs here that were in use in previous versions of the app.
- //
- // Otherwise upgrades will fail because the upgraded daemon will fail to
- // remove sublayers etc because they contain filters that the updated code
- // doesn't know about.
- //
-
- std::multimap<WfpObjectType, GUID> registry;
-
- static const GUID sublayer_whitelist =
- {
- 0x11d1a31a,
- 0xd7fa,
- 0x469b,
- { 0xbc, 0x21, 0xcc, 0xe9, 0x2e, 0x35, 0xfe, 0x90 }
- };
-
- registry.insert(std::make_pair(WfpObjectType::Sublayer, sublayer_whitelist));
-
- static const GUID sublayer_blacklist =
- {
- 0x843b74f0,
- 0xb499,
- 0x499a,
- { 0xac, 0xe3, 0xf9, 0xee, 0xa2, 0x4, 0x89, 0xc1 }
- };
-
- registry.insert(std::make_pair(WfpObjectType::Sublayer, sublayer_blacklist));
-
- static const GUID filter_restrictdns_outbound_ipv4 =
- {
- 0xc0792b44,
- 0xfc3c,
- 0x42e8,
- { 0xa6, 0x60, 0x25, 0x4b, 0xd0, 0x4, 0xb1, 0x9d }
- };
-
- registry.insert(std::make_pair(WfpObjectType::Filter, filter_restrictdns_outbound_ipv4));
-
- static const GUID filter_restrictdns_outbound_tunnel_ipv4 =
- {
- 0x790445dc,
- 0xb23e,
- 0x4ab4,
- { 0x8e, 0x2f, 0xc7, 0x6, 0x55, 0x5f, 0x94, 0xff }
- };
-
- registry.insert(std::make_pair(WfpObjectType::Filter, filter_restrictdns_outbound_tunnel_ipv4));
-
- static const GUID filter_restrictdns_outbound_ipv6 =
- {
- 0xcde477eb,
- 0x2d8a,
- 0x45b8,
- { 0x9a, 0x3e, 0x9a, 0xa3, 0xbe, 0x4d, 0xe2, 0xb4 }
- };
-
- registry.insert(std::make_pair(WfpObjectType::Filter, filter_restrictdns_outbound_ipv6));
-
- static const GUID filter_restrictdns_outbound_tunnel_ipv6 =
- {
- 0xacc90d87,
- 0xab77,
- 0x4cf4,
- { 0x84, 0xee, 0x1d, 0x68, 0x95, 0xf0, 0x66, 0xc2 }
- };
-
- registry.insert(std::make_pair(WfpObjectType::Filter, filter_restrictdns_outbound_tunnel_ipv6));
-
- return registry;
-}
-
-//static
-MullvadGuids::IdentityRegistry MullvadGuids::Registry(IdentityQualifier qualifier)
-{
- const auto detailedRegistry = DetailedRegistry(qualifier);
- using ValueType = decltype(detailedRegistry)::const_reference;
-
- std::unordered_set<GUID> registry;
-
- std::transform(detailedRegistry.begin(), detailedRegistry.end(), std::inserter(registry, registry.end()), [](ValueType value)
- {
- return value.second;
- });
-
- return registry;
-}
-
-//static
-MullvadGuids::DetailedIdentityRegistry MullvadGuids::DetailedRegistry(IdentityQualifier qualifier)
-{
- std::multimap<WfpObjectType, GUID> registry;
-
- if (IdentityQualifier::IncludeDeprecated == (qualifier & IdentityQualifier::IncludeDeprecated))
- {
- registry = DeprecatedIdentities();
- }
-
- registry.insert(std::make_pair(WfpObjectType::Provider, Provider()));
- registry.insert(std::make_pair(WfpObjectType::Sublayer, SublayerBaseline()));
- registry.insert(std::make_pair(WfpObjectType::Sublayer, SublayerDns()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_BlockAll_Outbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_BlockAll_Inbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_BlockAll_Outbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_BlockAll_Inbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitLan_Outbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitLan_Outbound_Multicast_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitLan_Outbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitLan_Outbound_Multicast_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitLanService_Inbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitLanService_Inbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitLoopback_Outbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitLoopback_Inbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitLoopback_Outbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitLoopback_Inbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitDhcp_Outbound_Request_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitDhcp_Inbound_Response_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitDhcp_Outbound_Request_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitDhcp_Inbound_Response_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitDhcpServer_Inbound_Request_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitDhcpServer_Outbound_Response_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnRelay()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitEndpoint()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnel_Outbound_Ipv4_1()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnel_Outbound_Ipv6_1()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnel_Outbound_Ipv4_2()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnel_Outbound_Ipv6_2()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnel_ExitIp()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnel_BlockExitIp()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnelService_Ipv4_1()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnelService_Ipv6_1()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnelService_Ipv4_2()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnelService_Ipv6_2()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnelService_ExitIp()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitVpnTunnelService_BlockExitIp()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitNdp_Outbound_Router_Solicitation()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitNdp_Inbound_Router_Advertisement()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitNdp_Outbound_Neighbor_Solicitation()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitNdp_Inbound_Neighbor_Solicitation()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitNdp_Outbound_Neighbor_Advertisement()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitNdp_Inbound_Neighbor_Advertisement()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitNdp_Inbound_Redirect()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitDns_Outbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitDns_Outbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Dns_BlockAll_Outbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Dns_BlockAll_Outbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Dns_PermitLoopback_Outbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Dns_PermitLoopback_Outbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Dns_PermitNonTunnel_Outbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Dns_PermitNonTunnel_Outbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Dns_PermitTunnel_Outbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Dns_PermitTunnel_Outbound_Ipv6()));
-
- if (IdentityQualifier::IncludePersistent == (qualifier & IdentityQualifier::IncludePersistent))
- {
- registry.insert(std::make_pair(WfpObjectType::Provider, ProviderPersistent()));
- registry.insert(std::make_pair(WfpObjectType::Sublayer, SublayerPersistent()));
-
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Boottime_BlockAll_Inbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Boottime_BlockAll_Outbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Boottime_BlockAll_Inbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Boottime_BlockAll_Outbound_Ipv6()));
-
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Persistent_BlockAll_Inbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Persistent_BlockAll_Outbound_Ipv4()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Persistent_BlockAll_Inbound_Ipv6()));
- registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Persistent_BlockAll_Outbound_Ipv6()));
- }
-
- return registry;
-}
//static
const GUID &MullvadGuids::Provider()
@@ -643,34 +465,6 @@ const GUID &MullvadGuids::Filter_Baseline_PermitDhcpServer_Outbound_Response_Ipv
}
//static
-const GUID &MullvadGuids::Filter_Baseline_PermitVpnRelay()
-{
- static const GUID g =
- {
- 0x160c205d,
- 0xdb40,
- 0x4f79,
- { 0x90, 0x6d, 0xfd, 0xa1, 0xe1, 0xc1, 0x8a, 0x70 }
- };
-
- return g;
-}
-
-//static
-const GUID &MullvadGuids::Filter_Baseline_PermitEndpoint()
-{
- static const GUID g =
- {
- 0x99dc8dac,
- 0x8520,
- 0x41be,
- { 0xbf, 0xab, 0x0c, 0x9, 0xbf, 0x12, 0xeb, 0 }
- };
-
- return g;
-}
-
-//static
const GUID &MullvadGuids::Filter_Baseline_PermitVpnTunnel_Outbound_Ipv4_1()
{
static const GUID g =
diff --git a/windows/winfw/src/winfw/mullvadguids.h b/windows/winfw/src/winfw/mullvadguids.h
index e2fd7ab276..a086155a77 100644
--- a/windows/winfw/src/winfw/mullvadguids.h
+++ b/windows/winfw/src/winfw/mullvadguids.h
@@ -1,6 +1,5 @@
#pragma once
-#include "wfpobjecttype.h"
#include "guidhash.h"
#include <guiddef.h>
#include <unordered_set>
@@ -10,26 +9,6 @@ class MullvadGuids
{
public:
- using IdentityRegistry = std::unordered_set<GUID>;
- using DetailedIdentityRegistry = std::multimap<WfpObjectType, GUID>;
-
-private:
-
- static DetailedIdentityRegistry DeprecatedIdentities();
-
-public:
-
- enum class IdentityQualifier : uint32_t
- {
- OnlyCurrent = 0x00,
- IncludeDeprecated = 0x01,
- IncludePersistent = 0x02,
- IncludeAll = IncludeDeprecated | IncludePersistent,
- };
-
- static IdentityRegistry Registry(IdentityQualifier qualifier);
- static DetailedIdentityRegistry DetailedRegistry(IdentityQualifier qualifier);
-
MullvadGuids() = delete;
static const GUID &Provider();
@@ -67,10 +46,6 @@ public:
static const GUID &Filter_Baseline_PermitDhcpServer_Inbound_Request_Ipv4();
static const GUID &Filter_Baseline_PermitDhcpServer_Outbound_Response_Ipv4();
- static const GUID &Filter_Baseline_PermitVpnRelay();
-
- static const GUID &Filter_Baseline_PermitEndpoint();
-
static const GUID &Filter_Baseline_PermitVpnTunnel_Outbound_Ipv4_1();
static const GUID &Filter_Baseline_PermitVpnTunnel_Outbound_Ipv6_1();
static const GUID &Filter_Baseline_PermitVpnTunnel_Outbound_Ipv4_2();
@@ -122,13 +97,3 @@ public:
static const GUID &Filter_Persistent_BlockAll_Inbound_Ipv6();
static const GUID &Filter_Persistent_BlockAll_Outbound_Ipv6();
};
-
-inline MullvadGuids::IdentityQualifier operator|(MullvadGuids::IdentityQualifier lhs, MullvadGuids::IdentityQualifier rhs)
-{
- return static_cast<MullvadGuids::IdentityQualifier>(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs));
-}
-
-inline MullvadGuids::IdentityQualifier operator&(MullvadGuids::IdentityQualifier lhs, MullvadGuids::IdentityQualifier rhs)
-{
- return static_cast<MullvadGuids::IdentityQualifier>(static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs));
-}
diff --git a/windows/winfw/src/winfw/objectpurger.cpp b/windows/winfw/src/winfw/objectpurger.cpp
index dce36c99c8..c63ecf2cb6 100644
--- a/windows/winfw/src/winfw/objectpurger.cpp
+++ b/windows/winfw/src/winfw/objectpurger.cpp
@@ -1,10 +1,11 @@
#include "stdafx.h"
#include "objectpurger.h"
#include "mullvadguids.h"
-#include "wfpobjecttype.h"
#include "libwfp/filterengine.h"
#include "libwfp/objectdeleter.h"
#include "libwfp/transaction.h"
+#include "libwfp/objectenumerator.h"
+#include <set>
#include <algorithm>
namespace
@@ -12,45 +13,59 @@ namespace
using ObjectDeleter = std::function<void(wfp::FilterEngine &, const GUID &)>;
-template<typename TRange>
-void RemoveRange(wfp::FilterEngine &engine, ObjectDeleter deleter, TRange range)
+template<typename T>
+bool HasMullvadProvider(T obj)
{
- std::for_each(range.first, range.second, [&](const auto &record)
- {
- const GUID &objectId = record.second;
- deleter(engine, objectId);
- });
+ return nullptr != obj.providerKey && *obj.providerKey == MullvadGuids::Provider();
}
-} // anonymous namespace
-
-//static
-ObjectPurger::RemovalFunctor ObjectPurger::GetRemoveFiltersFunctor()
+template<typename T>
+bool HasPersistentMullvadProvider(const T &obj)
{
- return [](wfp::FilterEngine &engine)
- {
- const auto registry = MullvadGuids::DetailedRegistry(MullvadGuids::IdentityQualifier::IncludeAll);
-
- // Resolve correct overload.
- void (*deleter)(wfp::FilterEngine &, const GUID &) = wfp::ObjectDeleter::DeleteFilter;
-
- RemoveRange(engine, deleter, registry.equal_range(WfpObjectType::Filter));
- };
+ return nullptr != obj.providerKey && *obj.providerKey == MullvadGuids::ProviderPersistent();
}
+} // anonymous namespace
+
//static
ObjectPurger::RemovalFunctor ObjectPurger::GetRemoveAllFunctor()
{
return [](wfp::FilterEngine &engine)
{
- const auto registry = MullvadGuids::DetailedRegistry(MullvadGuids::IdentityQualifier::IncludeAll);
+ std::unordered_set<GUID> filtersToRemove;
+ wfp::ObjectEnumerator::Filters(engine, [&](const auto &filter) -> bool
+ {
+ // Delete both non-persistent and persistent filters
+ if (HasMullvadProvider(filter) || HasPersistentMullvadProvider(filter))
+ {
+ filtersToRemove.insert(filter.filterKey);
+ }
+ return true;
+ });
+
+ std::unordered_set<GUID> sublayersToRemove;
+ wfp::ObjectEnumerator::Sublayers(engine, [&](const auto &sublayer) -> bool
+ {
+ // Delete both non-persistent and persistent sublayers
+ if (HasMullvadProvider(sublayer) || HasPersistentMullvadProvider(sublayer))
+ {
+ sublayersToRemove.insert(sublayer.subLayerKey);
+ }
+ return true;
+ });
- // Resolve correct overload.
- void(*deleter)(wfp::FilterEngine &, const GUID &) = wfp::ObjectDeleter::DeleteFilter;
+ for (const auto &filter : filtersToRemove)
+ {
+ wfp::ObjectDeleter::DeleteFilter(engine, filter);
+ }
- RemoveRange(engine, deleter, registry.equal_range(WfpObjectType::Filter));
- RemoveRange(engine, wfp::ObjectDeleter::DeleteSublayer, registry.equal_range(WfpObjectType::Sublayer));
- RemoveRange(engine, wfp::ObjectDeleter::DeleteProvider, registry.equal_range(WfpObjectType::Provider));
+ for (const auto &sublayer : sublayersToRemove)
+ {
+ wfp::ObjectDeleter::DeleteSublayer(engine, sublayer);
+ }
+
+ wfp::ObjectDeleter::DeleteProvider(engine, MullvadGuids::Provider());
+ wfp::ObjectDeleter::DeleteProvider(engine, MullvadGuids::ProviderPersistent());
};
}
@@ -59,14 +74,39 @@ ObjectPurger::RemovalFunctor ObjectPurger::GetRemoveNonPersistentFunctor()
{
return [](wfp::FilterEngine &engine)
{
- const auto registry = MullvadGuids::DetailedRegistry(MullvadGuids::IdentityQualifier::IncludeDeprecated);
+ std::unordered_set<GUID> filtersToRemove;
+ wfp::ObjectEnumerator::Filters(engine, [&](const auto &filter) -> bool
+ {
+ // Delete only non-persistent filters
+ if (HasMullvadProvider(filter))
+ {
+ filtersToRemove.insert(filter.filterKey);
+ }
+ return true;
+ });
+
+ std::unordered_set<GUID> sublayersToRemove;
+ wfp::ObjectEnumerator::Sublayers(engine, [&](const auto &sublayer) -> bool
+ {
+ // Delete only non-persistent sublayers
+ if (HasMullvadProvider(sublayer))
+ {
+ sublayersToRemove.insert(sublayer.subLayerKey);
+ }
+ return true;
+ });
+
+ for (const auto &filter : filtersToRemove)
+ {
+ wfp::ObjectDeleter::DeleteFilter(engine, filter);
+ }
- // Resolve correct overload.
- void(*deleter)(wfp::FilterEngine &, const GUID &) = wfp::ObjectDeleter::DeleteFilter;
+ for (const auto &sublayer : sublayersToRemove)
+ {
+ wfp::ObjectDeleter::DeleteSublayer(engine, sublayer);
+ }
- RemoveRange(engine, deleter, registry.equal_range(WfpObjectType::Filter));
- RemoveRange(engine, wfp::ObjectDeleter::DeleteSublayer, registry.equal_range(WfpObjectType::Sublayer));
- RemoveRange(engine, wfp::ObjectDeleter::DeleteProvider, registry.equal_range(WfpObjectType::Provider));
+ wfp::ObjectDeleter::DeleteProvider(engine, MullvadGuids::Provider());
};
}
diff --git a/windows/winfw/src/winfw/objectpurger.h b/windows/winfw/src/winfw/objectpurger.h
index 7728aac694..91ed61ddaf 100644
--- a/windows/winfw/src/winfw/objectpurger.h
+++ b/windows/winfw/src/winfw/objectpurger.h
@@ -13,7 +13,6 @@ public:
using RemovalFunctor = std::function<void(wfp::FilterEngine &engine)>;
- static RemovalFunctor GetRemoveFiltersFunctor();
static RemovalFunctor GetRemoveAllFunctor();
static RemovalFunctor GetRemoveNonPersistentFunctor();
diff --git a/windows/winfw/src/winfw/rules/baseline/permitendpoint.cpp b/windows/winfw/src/winfw/rules/baseline/permitendpoint.cpp
deleted file mode 100644
index c1c74ba6ba..0000000000
--- a/windows/winfw/src/winfw/rules/baseline/permitendpoint.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-#include "stdafx.h"
-#include "permitendpoint.h"
-#include <winfw/mullvadguids.h>
-#include <winfw/rules/shared.h>
-#include <libwfp/filterbuilder.h>
-#include <libwfp/conditionbuilder.h>
-#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
-{
-
-const GUID &OutboundLayerFromIp(const wfp::IpAddress &ip)
-{
- switch (ip.type())
- {
- case wfp::IpAddress::Type::Ipv4: return FWPM_LAYER_ALE_AUTH_CONNECT_V4;
- case wfp::IpAddress::Type::Ipv6: return FWPM_LAYER_ALE_AUTH_CONNECT_V6;
- default:
- {
- THROW_ERROR("Missing case handler in switch clause");
- }
- };
-}
-
-} // anonymous namespace
-
-PermitEndpoint::PermitEndpoint
-(
- const wfp::IpAddress &address,
- const std::vector<std::wstring> &clients,
- uint16_t port,
- WinFwProtocol protocol
-)
- : m_address(address)
- , m_clients(clients)
- , m_port(port)
- , m_protocol(protocol)
-{
-}
-
-bool PermitEndpoint::apply(IObjectInstaller &objectInstaller)
-{
- wfp::FilterBuilder filterBuilder;
-
- //
- // Permit outbound connections to endpoint.
- //
-
- filterBuilder
- .key(MullvadGuids::Filter_Baseline_PermitEndpoint())
- .name(L"Permit outbound connections to a given endpoint")
- .description(L"This filter is part of a rule that permits traffic to a specific endpoint")
- .provider(MullvadGuids::Provider())
- .layer(OutboundLayerFromIp(m_address))
- .sublayer(MullvadGuids::SublayerBaseline())
- .weight(wfp::FilterBuilder::WeightClass::Max)
- .permit();
-
- wfp::ConditionBuilder conditionBuilder(OutboundLayerFromIp(m_address));
-
- conditionBuilder.add_condition(ConditionIp::Remote(m_address));
- conditionBuilder.add_condition(ConditionPort::Remote(m_port));
- conditionBuilder.add_condition(CreateProtocolCondition(m_protocol));
-
- for (const auto client : m_clients) {
- conditionBuilder.add_condition(std::make_unique<ConditionApplication>(client));
- }
-
- return objectInstaller.addFilter(filterBuilder, conditionBuilder);
-}
-
-}
diff --git a/windows/winfw/src/winfw/rules/baseline/permitendpoint.h b/windows/winfw/src/winfw/rules/baseline/permitendpoint.h
deleted file mode 100644
index 9e5e2fc923..0000000000
--- a/windows/winfw/src/winfw/rules/baseline/permitendpoint.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-
-#include <winfw/rules/ifirewallrule.h>
-#include <winfw/winfw.h>
-#include <libwfp/ipaddress.h>
-#include <vector>
-#include <string>
-
-namespace rules::baseline
-{
-
-class PermitEndpoint : public IFirewallRule
-{
-public:
-
- PermitEndpoint
- (
- const wfp::IpAddress &address,
- const std::vector<std::wstring> &clients,
- uint16_t port,
- WinFwProtocol protocol
- );
-
- bool apply(IObjectInstaller &objectInstaller) override;
-
-private:
-
- const wfp::IpAddress m_address;
- const std::vector<std::wstring> m_clients;
- const uint16_t m_port;
- const WinFwProtocol m_protocol;
-};
-
-}
diff --git a/windows/winfw/src/winfw/rules/multi/permitvpnrelay.cpp b/windows/winfw/src/winfw/rules/multi/permitendpoint.cpp
index 19ce09571b..224f7ecfc5 100644
--- a/windows/winfw/src/winfw/rules/multi/permitvpnrelay.cpp
+++ b/windows/winfw/src/winfw/rules/multi/permitendpoint.cpp
@@ -1,5 +1,5 @@
#include "stdafx.h"
-#include "permitvpnrelay.h"
+#include "permitendpoint.h"
#include <winfw/mullvadguids.h>
#include <winfw/winfw.h>
#include <winfw/rules/shared.h>
@@ -32,12 +32,12 @@ const GUID &LayerFromIp(const wfp::IpAddress &ip)
};
}
-const GUID &TranslateSublayer(PermitVpnRelay::Sublayer sublayer)
+const GUID &TranslateSublayer(PermitEndpoint::Sublayer sublayer)
{
switch (sublayer)
{
- case PermitVpnRelay::Sublayer::Baseline: return MullvadGuids::SublayerBaseline();
- case PermitVpnRelay::Sublayer::Dns: return MullvadGuids::SublayerDns();
+ case PermitEndpoint::Sublayer::Baseline: return MullvadGuids::SublayerBaseline();
+ case PermitEndpoint::Sublayer::Dns: return MullvadGuids::SublayerDns();
default:
{
THROW_ERROR("Missing case handler in switch clause");
@@ -47,7 +47,7 @@ const GUID &TranslateSublayer(PermitVpnRelay::Sublayer sublayer)
} // anonymous namespace
-PermitVpnRelay::PermitVpnRelay
+PermitEndpoint::PermitEndpoint
(
const wfp::IpAddress &relay,
uint16_t relayPort,
@@ -63,18 +63,17 @@ PermitVpnRelay::PermitVpnRelay
{
}
-bool PermitVpnRelay::apply(IObjectInstaller &objectInstaller)
+bool PermitEndpoint::apply(IObjectInstaller &objectInstaller)
{
- wfp::FilterBuilder filterBuilder;
+ wfp::FilterBuilder filterBuilder(wfp::BuilderValidation::OnlyCritical);
//
// #1 Permit outbound connections to relay.
//
filterBuilder
- .key(MullvadGuids::Filter_Baseline_PermitVpnRelay())
- .name(L"Permit outbound connections to VPN relay")
- .description(L"This filter is part of a rule that permits communication with a VPN relay")
+ .name(L"Permit outbound connections to an endpoint")
+ .description(L"This filter is part of a rule that permits communication with an endpoint")
.provider(MullvadGuids::Provider())
.layer(LayerFromIp(m_relay))
.sublayer(TranslateSublayer(m_sublayer))
diff --git a/windows/winfw/src/winfw/rules/multi/permitvpnrelay.h b/windows/winfw/src/winfw/rules/multi/permitendpoint.h
index a2bfc16384..025c3f781c 100644
--- a/windows/winfw/src/winfw/rules/multi/permitvpnrelay.h
+++ b/windows/winfw/src/winfw/rules/multi/permitendpoint.h
@@ -8,7 +8,7 @@
namespace rules::multi
{
-class PermitVpnRelay : public IFirewallRule
+class PermitEndpoint : public IFirewallRule
{
public:
@@ -18,7 +18,7 @@ public:
Dns
};
- PermitVpnRelay
+ PermitEndpoint
(
const wfp::IpAddress &relay,
uint16_t relayPort,
diff --git a/windows/winfw/src/winfw/sessioncontroller.cpp b/windows/winfw/src/winfw/sessioncontroller.cpp
index afa6cf952b..9b5e70a610 100644
--- a/windows/winfw/src/winfw/sessioncontroller.cpp
+++ b/windows/winfw/src/winfw/sessioncontroller.cpp
@@ -60,7 +60,6 @@ bool CheckpointKeyToIndex(const std::vector<SessionRecord> &container, uint32_t
SessionController::SessionController(std::unique_ptr<wfp::FilterEngine> &&engine)
: m_engine(std::move(engine))
- , m_identityRegistry(MullvadGuids::Registry(MullvadGuids::IdentityQualifier::IncludePersistent))
, m_activeTransaction(false)
{
}
@@ -259,8 +258,9 @@ void SessionController::rewindState(size_t steps)
void SessionController::validateObject(const wfp::IIdentifiable &object) const
{
- if (m_identityRegistry.end() == m_identityRegistry.find(object.id()))
+ if (object.providerId() != MullvadGuids::Provider()
+ && object.providerId() != MullvadGuids::ProviderPersistent())
{
- THROW_ERROR("Attempting to install non-registered WFP object");
+ THROW_ERROR("WFP object with unexpected provider");
}
}
diff --git a/windows/winfw/src/winfw/sessioncontroller.h b/windows/winfw/src/winfw/sessioncontroller.h
index f82563ce0d..d4aae3f9f4 100644
--- a/windows/winfw/src/winfw/sessioncontroller.h
+++ b/windows/winfw/src/winfw/sessioncontroller.h
@@ -58,9 +58,6 @@ private:
std::unique_ptr<wfp::FilterEngine> m_engine;
- // Implement cache here since the source data doesn't change.
- const MullvadGuids::IdentityRegistry m_identityRegistry;
-
std::vector<SessionRecord> m_records;
std::vector<SessionRecord> m_transactionRecords;
diff --git a/windows/winfw/src/winfw/winfw.vcxproj b/windows/winfw/src/winfw/winfw.vcxproj
index eb14e0332d..c5031efb49 100644
--- a/windows/winfw/src/winfw/winfw.vcxproj
+++ b/windows/winfw/src/winfw/winfw.vcxproj
@@ -35,7 +35,6 @@
<ClCompile Include="rules\baseline\permitdhcp.cpp" />
<ClCompile Include="rules\baseline\permitdhcpserver.cpp" />
<ClCompile Include="rules\baseline\permitdns.cpp" />
- <ClCompile Include="rules\baseline\permitendpoint.cpp" />
<ClCompile Include="rules\baseline\permitlan.cpp" />
<ClCompile Include="rules\baseline\permitlanservice.cpp" />
<ClCompile Include="rules\baseline\permitloopback.cpp" />
@@ -46,7 +45,7 @@
<ClCompile Include="rules\dns\permitloopback.cpp" />
<ClCompile Include="rules\dns\permitnontunnel.cpp" />
<ClCompile Include="rules\dns\permittunnel.cpp" />
- <ClCompile Include="rules\multi\permitvpnrelay.cpp" />
+ <ClCompile Include="rules\multi\permitendpoint.cpp" />
<ClCompile Include="rules\persistent\blockall.cpp" />
<ClCompile Include="rules\shared.cpp" />
<ClCompile Include="sessioncontroller.cpp" />
@@ -72,7 +71,6 @@
<ClInclude Include="rules\baseline\permitdhcp.h" />
<ClInclude Include="rules\baseline\permitdhcpserver.h" />
<ClInclude Include="rules\baseline\permitdns.h" />
- <ClInclude Include="rules\baseline\permitendpoint.h" />
<ClInclude Include="rules\baseline\permitlan.h" />
<ClInclude Include="rules\baseline\permitlanservice.h" />
<ClInclude Include="rules\baseline\permitloopback.h" />
@@ -83,7 +81,7 @@
<ClInclude Include="rules\dns\permitloopback.h" />
<ClInclude Include="rules\dns\permitnontunnel.h" />
<ClInclude Include="rules\dns\permittunnel.h" />
- <ClInclude Include="rules\multi\permitvpnrelay.h" />
+ <ClInclude Include="rules\multi\permitendpoint.h" />
<ClInclude Include="rules\persistent\blockall.h" />
<ClInclude Include="rules\ports.h" />
<ClInclude Include="rules\shared.h" />
diff --git a/windows/winfw/src/winfw/winfw.vcxproj.filters b/windows/winfw/src/winfw/winfw.vcxproj.filters
index daecbb03fb..89805fb4c8 100644
--- a/windows/winfw/src/winfw/winfw.vcxproj.filters
+++ b/windows/winfw/src/winfw/winfw.vcxproj.filters
@@ -55,10 +55,7 @@
<ClCompile Include="rules\persistent\blockall.cpp">
<Filter>rules\persistent</Filter>
</ClCompile>
- <ClCompile Include="rules\baseline\permitendpoint.cpp">
- <Filter>rules\baseline</Filter>
- </ClCompile>
- <ClCompile Include="rules\multi\permitvpnrelay.cpp">
+ <ClCompile Include="rules\multi\permitendpoint.cpp">
<Filter>rules\multi</Filter>
</ClCompile>
<ClCompile Include="rules\dns\permitloopback.cpp">
@@ -129,10 +126,7 @@
<ClInclude Include="rules\persistent\blockall.h">
<Filter>rules\persistent</Filter>
</ClInclude>
- <ClInclude Include="rules\baseline\permitendpoint.h">
- <Filter>rules\baseline</Filter>
- </ClInclude>
- <ClInclude Include="rules\multi\permitvpnrelay.h">
+ <ClInclude Include="rules\multi\permitendpoint.h">
<Filter>rules\multi</Filter>
</ClInclude>
<ClInclude Include="rules\dns\permitloopback.h">