summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOdd Stranne <odd@mullvad.net>2020-02-19 16:25:46 +0100
committerOdd Stranne <odd@mullvad.net>2020-02-19 20:46:19 +0100
commite1663a8c7c098e1693e6fdb1a2288e02cedc1587 (patch)
tree79a1451d3e537201fc075795d2ca839c4323b5d5
parentd46b18457a768e1e9571e68f1efdb81125f7b297 (diff)
downloadmullvadvpn-e1663a8c7c098e1693e6fdb1a2288e02cedc1587.tar.xz
mullvadvpn-e1663a8c7c098e1693e6fdb1a2288e02cedc1587.zip
Track deprecated WFP object identities to enable cleaning up old objects
-rw-r--r--windows/winfw/src/winfw/mullvadguids.cpp101
-rw-r--r--windows/winfw/src/winfw/mullvadguids.h23
-rw-r--r--windows/winfw/src/winfw/objectpurger.cpp4
-rw-r--r--windows/winfw/src/winfw/sessioncontroller.cpp27
-rw-r--r--windows/winfw/src/winfw/sessioncontroller.h5
5 files changed, 119 insertions, 41 deletions
diff --git a/windows/winfw/src/winfw/mullvadguids.cpp b/windows/winfw/src/winfw/mullvadguids.cpp
index 6f826d41e1..06edc3182e 100644
--- a/windows/winfw/src/winfw/mullvadguids.cpp
+++ b/windows/winfw/src/winfw/mullvadguids.cpp
@@ -4,9 +4,85 @@
#include <iterator>
//static
-WfpObjectRegistry MullvadGuids::BuildRegistry()
+MullvadGuids::DetailedIdentityRegistry MullvadGuids::DeprecatedIdentities()
{
- const auto detailedRegistry = DetailedRegistry();
+ //
+ // 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;
@@ -20,10 +96,15 @@ WfpObjectRegistry MullvadGuids::BuildRegistry()
}
//static
-DetailedWfpObjectRegistry MullvadGuids::BuildDetailedRegistry()
+MullvadGuids::DetailedIdentityRegistry MullvadGuids::DetailedRegistry(IdentityQualifier qualifier)
{
std::multimap<WfpObjectType, GUID> registry;
+ if (IdentityQualifier::IncludeDeprecated == qualifier)
+ {
+ 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()));
@@ -70,20 +151,6 @@ DetailedWfpObjectRegistry MullvadGuids::BuildDetailedRegistry()
}
//static
-const WfpObjectRegistry &MullvadGuids::Registry()
-{
- static auto registry = BuildRegistry(); // TODO: Thread safety.
- return registry;
-}
-
-//static
-const DetailedWfpObjectRegistry &MullvadGuids::DetailedRegistry()
-{
- static auto registry = BuildDetailedRegistry(); // TODO: Thread safety.
- return registry;
-}
-
-//static
const GUID &MullvadGuids::Provider()
{
static const GUID g =
diff --git a/windows/winfw/src/winfw/mullvadguids.h b/windows/winfw/src/winfw/mullvadguids.h
index daac20fb59..8e5970698c 100644
--- a/windows/winfw/src/winfw/mullvadguids.h
+++ b/windows/winfw/src/winfw/mullvadguids.h
@@ -6,18 +6,27 @@
#include <unordered_set>
#include <map>
-using WfpObjectRegistry = std::unordered_set<GUID>;
-using DetailedWfpObjectRegistry = std::multimap<WfpObjectType, GUID>;
-
class MullvadGuids
{
- static WfpObjectRegistry BuildRegistry();
- static DetailedWfpObjectRegistry BuildDetailedRegistry();
+public:
+
+ using IdentityRegistry = std::unordered_set<GUID>;
+ using DetailedIdentityRegistry = std::multimap<WfpObjectType, GUID>;
+
+private:
+
+ static DetailedIdentityRegistry DeprecatedIdentities();
public:
- static const WfpObjectRegistry &Registry();
- static const DetailedWfpObjectRegistry &DetailedRegistry();
+ enum class IdentityQualifier
+ {
+ IncludeDeprecated,
+ OnlyCurrent,
+ };
+
+ static IdentityRegistry Registry(IdentityQualifier qualifier);
+ static DetailedIdentityRegistry DetailedRegistry(IdentityQualifier qualifier);
MullvadGuids() = delete;
diff --git a/windows/winfw/src/winfw/objectpurger.cpp b/windows/winfw/src/winfw/objectpurger.cpp
index 60c32cd53e..1db397566c 100644
--- a/windows/winfw/src/winfw/objectpurger.cpp
+++ b/windows/winfw/src/winfw/objectpurger.cpp
@@ -29,7 +29,7 @@ ObjectPurger::RemovalFunctor ObjectPurger::GetRemoveFiltersFunctor()
{
return [](wfp::FilterEngine &engine)
{
- const auto registry = MullvadGuids::DetailedRegistry();
+ const auto registry = MullvadGuids::DetailedRegistry(MullvadGuids::IdentityQualifier::IncludeDeprecated);
// Resolve correct overload.
void (*deleter)(wfp::FilterEngine &, const GUID &) = wfp::ObjectDeleter::DeleteFilter;
@@ -43,7 +43,7 @@ ObjectPurger::RemovalFunctor ObjectPurger::GetRemoveAllFunctor()
{
return [](wfp::FilterEngine &engine)
{
- const auto registry = MullvadGuids::DetailedRegistry();
+ const auto registry = MullvadGuids::DetailedRegistry(MullvadGuids::IdentityQualifier::IncludeDeprecated);
// Resolve correct overload.
void(*deleter)(wfp::FilterEngine &, const GUID &) = wfp::ObjectDeleter::DeleteFilter;
diff --git a/windows/winfw/src/winfw/sessioncontroller.cpp b/windows/winfw/src/winfw/sessioncontroller.cpp
index 3d7fcc2e1a..c5342fce78 100644
--- a/windows/winfw/src/winfw/sessioncontroller.cpp
+++ b/windows/winfw/src/winfw/sessioncontroller.cpp
@@ -1,7 +1,6 @@
#include "stdafx.h"
#include "sessioncontroller.h"
#include "wfpobjecttype.h"
-#include "mullvadguids.h"
#include "libwfp/objectinstaller.h"
#include "libwfp/objectdeleter.h"
#include "libwfp/transaction.h"
@@ -57,21 +56,11 @@ bool CheckpointKeyToIndex(const std::vector<SessionRecord> &container, uint32_t
return false;
}
-void ValidateObject(const wfp::IIdentifiable &object)
-{
- const auto registry = MullvadGuids::Registry();
-
- if (registry.end() == registry.find(object.id()))
- {
- THROW_ERROR("Attempting to install non-registered WFP object");
- }
-}
-
-
} // anonymous namespace
SessionController::SessionController(std::unique_ptr<wfp::FilterEngine> &&engine)
: m_engine(std::move(engine))
+ , m_identityRegistry(MullvadGuids::Registry(MullvadGuids::IdentityQualifier::OnlyCurrent))
, m_activeTransaction(false)
{
}
@@ -103,7 +92,7 @@ bool SessionController::addProvider(wfp::ProviderBuilder &providerBuilder)
THROW_ERROR("Cannot add provider outside transaction");
}
- ValidateObject(providerBuilder);
+ validateObject(providerBuilder);
GUID key;
@@ -124,7 +113,7 @@ bool SessionController::addSublayer(wfp::SublayerBuilder &sublayerBuilder)
THROW_ERROR("Cannot add sublayer outside transaction");
}
- ValidateObject(sublayerBuilder);
+ validateObject(sublayerBuilder);
GUID key;
@@ -145,7 +134,7 @@ bool SessionController::addFilter(wfp::FilterBuilder &filterBuilder, const wfp::
THROW_ERROR("Cannot add filter outside transaction");
}
- ValidateObject(filterBuilder);
+ validateObject(filterBuilder);
UINT64 id;
@@ -286,3 +275,11 @@ void SessionController::rewindState(size_t steps)
EraseBack(m_transactionRecords, steps);
}
+
+void SessionController::validateObject(const wfp::IIdentifiable &object) const
+{
+ if (m_identityRegistry.end() == m_identityRegistry.find(object.id()))
+ {
+ THROW_ERROR("Attempting to install non-registered WFP object");
+ }
+}
diff --git a/windows/winfw/src/winfw/sessioncontroller.h b/windows/winfw/src/winfw/sessioncontroller.h
index 243a501083..4300791660 100644
--- a/windows/winfw/src/winfw/sessioncontroller.h
+++ b/windows/winfw/src/winfw/sessioncontroller.h
@@ -2,6 +2,7 @@
#include "iobjectinstaller.h"
#include "sessionrecord.h"
+#include "mullvadguids.h"
#include "libwfp/filterengine.h"
#include "libwfp/iidentifiable.h"
#include <functional>
@@ -54,9 +55,13 @@ private:
SessionController &operator=(const SessionController &) = delete;
void rewindState(size_t steps);
+ void validateObject(const wfp::IIdentifiable &object) const;
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;