diff options
| author | Odd Stranne <odd@mullvad.net> | 2020-02-19 16:25:46 +0100 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2020-02-19 20:46:19 +0100 |
| commit | e1663a8c7c098e1693e6fdb1a2288e02cedc1587 (patch) | |
| tree | 79a1451d3e537201fc075795d2ca839c4323b5d5 | |
| parent | d46b18457a768e1e9571e68f1efdb81125f7b297 (diff) | |
| download | mullvadvpn-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.cpp | 101 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/mullvadguids.h | 23 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/objectpurger.cpp | 4 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/sessioncontroller.cpp | 27 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/sessioncontroller.h | 5 |
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; |
