summaryrefslogtreecommitdiffhomepage
path: root/windows/nsis-plugins/src/driverlogic/context.cpp
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-01-21 15:24:07 +0100
committerDavid Lönnhager <david.l@mullvad.net>2020-01-31 16:24:48 +0100
commit60d01c3525f4d3c133d517702997d83c463df3ba (patch)
tree56fb5ec432fdca3ffc9194dfe9b6e6020760576c /windows/nsis-plugins/src/driverlogic/context.cpp
parentddf28d3a7599ebeed20a4b425630aa4a8bf7e9b4 (diff)
downloadmullvadvpn-60d01c3525f4d3c133d517702997d83c463df3ba.tar.xz
mullvadvpn-60d01c3525f4d3c133d517702997d83c463df3ba.zip
Refactor driverlogic
Diffstat (limited to 'windows/nsis-plugins/src/driverlogic/context.cpp')
-rw-r--r--windows/nsis-plugins/src/driverlogic/context.cpp530
1 files changed, 0 insertions, 530 deletions
diff --git a/windows/nsis-plugins/src/driverlogic/context.cpp b/windows/nsis-plugins/src/driverlogic/context.cpp
deleted file mode 100644
index 1718182768..0000000000
--- a/windows/nsis-plugins/src/driverlogic/context.cpp
+++ /dev/null
@@ -1,530 +0,0 @@
-#include "stdafx.h"
-#include "context.h"
-
-#include <libcommon/guid.h>
-#include <libcommon/string.h>
-#include <libcommon/error.h>
-#include <libcommon/memory.h>
-#include <libcommon/network/nci.h>
-#include <log/log.h>
-
-#include <winsock2.h>
-#include <ws2ipdef.h>
-#include <iphlpapi.h>
-#include <windows.h>
-
-#include <vector>
-#include <list>
-#include <sstream>
-#include <algorithm>
-
-#include <setupapi.h>
-#include <devguid.h>
-#include <combaseapi.h>
-#include <initguid.h>
-#include <devpkey.h>
-
-namespace
-{
-
-const wchar_t TAP_HARDWARE_ID[] = L"tapmullvad0901";
-const wchar_t DEPRECATED_TAP_HARDWARE_ID[] = L"tap0901";
-
-template<typename T>
-void LogAdapters(const std::wstring &description, const T &adapters)
-{
- //
- // Flatten the information so we can log it more easily.
- //
-
- std::vector<std::wstring> details;
-
- for (const auto &adapter : adapters)
- {
- details.emplace_back(L"Adapter");
-
- details.emplace_back(std::wstring(L" Guid: ").append(adapter.guid));
- details.emplace_back(std::wstring(L" Name: ").append(adapter.name));
- details.emplace_back(std::wstring(L" Alias: ").append(adapter.alias));
- }
-
- PluginLogWithDetails(description, details);
-}
-
-std::wstring GetNetCfgInstanceId(HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData)
-{
- HKEY hNet = SetupDiOpenDevRegKey(
- devInfo,
- const_cast<SP_DEVINFO_DATA *>(&devInfoData),
- DICS_FLAG_GLOBAL,
- 0,
- DIREG_DRV,
- KEY_READ
- );
-
- if (hNet == INVALID_HANDLE_VALUE)
- {
- THROW_WINDOWS_ERROR(GetLastError(), "SetupDiOpenDevRegKey");
- }
-
- std::vector<wchar_t> instanceId(MAX_PATH + sizeof(L'\0'));
- DWORD strSize = instanceId.size() * sizeof(wchar_t);
-
- const auto status = RegGetValueW(
- hNet,
- nullptr,
- L"NetCfgInstanceId",
- RRF_RT_REG_SZ,
- nullptr,
- instanceId.data(),
- &strSize
- );
-
- RegCloseKey(hNet);
-
- if (ERROR_SUCCESS != status)
- {
- THROW_WINDOWS_ERROR(status, "RegGetValueW");
- }
-
- instanceId[strSize / sizeof(wchar_t)] = L'\0';
-
- return instanceId.data();
-}
-
-std::wstring GetDeviceInstanceId(
- HDEVINFO devInfo,
- SP_DEVINFO_DATA* devInfoData
-)
-{
- DWORD requiredSize = 0;
-
- SetupDiGetDeviceInstanceIdW(
- devInfo,
- devInfoData,
- nullptr,
- 0,
- &requiredSize
- );
-
- std::vector<wchar_t> deviceInstanceId;
- deviceInstanceId.resize(1 + requiredSize * sizeof(wchar_t));
-
- const auto status = SetupDiGetDeviceInstanceIdW(
- devInfo,
- devInfoData,
- &deviceInstanceId[0],
- deviceInstanceId.size(),
- nullptr
- );
-
- if (FALSE == status)
- {
- THROW_WINDOWS_ERROR(GetLastError(), "SetupDiGetDeviceInstanceIdW() failed");
- }
-
- return deviceInstanceId.data();
-}
-
-std::wstring GetDeviceStringProperty(
- HDEVINFO devInfo,
- SP_DEVINFO_DATA *devInfoData,
- const DEVPROPKEY *property
-)
-{
- //
- // Obtain required buffer size
- //
-
- DWORD requiredSize = 0;
- DEVPROPTYPE type;
-
- const auto sizeStatus = SetupDiGetDevicePropertyW(
- devInfo,
- devInfoData,
- property,
- &type,
- nullptr,
- 0,
- &requiredSize,
- 0
- );
-
- if (FALSE == sizeStatus)
- {
- const auto lastError = GetLastError();
-
- if (ERROR_INSUFFICIENT_BUFFER != lastError)
- {
- THROW_WINDOWS_ERROR(lastError, "SetupDiGetDevicePropertyW");
- }
- }
-
- std::vector<wchar_t> buffer;
- buffer.resize(1 + requiredSize / sizeof(wchar_t));
-
- //
- // Read property
- //
-
- const auto status = SetupDiGetDevicePropertyW(
- devInfo,
- devInfoData,
- property,
- &type,
- reinterpret_cast<PBYTE>(&buffer[0]),
- buffer.size() * sizeof(wchar_t),
- nullptr,
- 0
- );
-
- if (FALSE == status)
- {
- THROW_WINDOWS_ERROR(GetLastError(), "Failed to read device property");
- }
-
- return buffer.data();
-}
-
-std::optional<std::wstring> GetDeviceRegistryStringProperty(
- HDEVINFO devInfo,
- SP_DEVINFO_DATA *devInfoData,
- DWORD property
-)
-{
- //
- // Obtain required buffer size
- //
-
- DWORD requiredSize = 0;
-
- const auto sizeStatus = SetupDiGetDeviceRegistryPropertyW(
- devInfo,
- devInfoData,
- property,
- nullptr,
- nullptr,
- 0,
- &requiredSize
- );
-
- const DWORD lastError = GetLastError();
- if (FALSE == sizeStatus && ERROR_INSUFFICIENT_BUFFER != lastError)
- {
- // ERROR_INVALID_DATA may mean that the property does not exist
- // TODO: Check if there may be other causes.
- if (ERROR_INVALID_DATA != lastError)
- {
- THROW_WINDOWS_ERROR(lastError, "SetupDiGetDeviceRegistryPropertyW");
- }
-
- return std::nullopt;
- }
-
- //
- // Read property
- //
-
- std::vector<wchar_t> buffer;
- buffer.resize(1 + requiredSize / sizeof(wchar_t));
-
- const auto status = SetupDiGetDeviceRegistryPropertyW(
- devInfo,
- devInfoData,
- property,
- nullptr,
- reinterpret_cast<PBYTE>(&buffer[0]),
- buffer.size() * sizeof(wchar_t),
- nullptr
- );
-
- if (FALSE == status)
- {
- THROW_WINDOWS_ERROR(GetLastError(), "Failed to read device property");
- }
-
- return { buffer.data() };
-}
-
-std::set<Context::NetworkAdapter> GetTapAdapters(const std::wstring &tapHardwareId)
-{
- std::set<Context::NetworkAdapter> adapters;
-
- HDEVINFO devInfo = SetupDiGetClassDevs(
- &GUID_DEVCLASS_NET,
- nullptr,
- nullptr,
- DIGCF_PRESENT
- );
-
- if (INVALID_HANDLE_VALUE == devInfo)
- {
- THROW_WINDOWS_ERROR(GetLastError(), "SetupDiGetClassDevs() failed");
- }
-
- common::memory::ScopeDestructor scopeDestructor;
- scopeDestructor += [devInfo]()
- {
- SetupDiDestroyDeviceInfoList(devInfo);
- };
-
- common::network::Nci nci;
-
- for (int memberIndex = 0; ; memberIndex++)
- {
- SP_DEVINFO_DATA devInfoData = { 0 };
- devInfoData.cbSize = sizeof(devInfoData);
-
- if (FALSE == SetupDiEnumDeviceInfo(devInfo, memberIndex, &devInfoData))
- {
- const auto lastError = GetLastError();
-
- if (ERROR_NO_MORE_ITEMS == lastError)
- {
- // Done
- break;
- }
-
- THROW_WINDOWS_ERROR(lastError, "SetupDiEnumDeviceInfo() failed while enumerating network adapters");
- }
-
- //
- // Check whether this is a TAP adapter
- //
-
- const auto hardwareId = GetDeviceRegistryStringProperty(devInfo, &devInfoData, SPDRP_HARDWAREID);
- if (!hardwareId.has_value()
- || wcscmp(hardwareId.value().c_str(), tapHardwareId.c_str()) != 0)
- {
- continue;
- }
-
- //
- // Construct NetworkAdapter
- //
-
- try
- {
- const std::wstring guid = GetNetCfgInstanceId(devInfo, devInfoData);
- GUID guidObj = common::Guid::FromString(guid);
-
- adapters.emplace(Context::NetworkAdapter(
- guid,
- GetDeviceStringProperty(devInfo, &devInfoData, &DEVPKEY_Device_DriverDesc),
- nci.getConnectionName(guidObj),
- GetDeviceInstanceId(devInfo, &devInfoData)
- ));
- }
- catch (const std::exception &e)
- {
- //
- // Log exception and skip this adapter
- //
-
- std::string msg = "Skipping TAP adapter due to exception caught while iterating: ";
- msg.append(e.what());
- PluginLog(std::wstring(msg.begin(), msg.end()));
- }
- }
-
- return adapters;
-}
-
-} // anonymous namespace
-
-//static
-std::optional<Context::NetworkAdapter> Context::FindMullvadAdapter(const std::set<Context::NetworkAdapter> &tapAdapters)
-{
- if (tapAdapters.empty())
- {
- return std::nullopt;
- }
-
- //
- // Look for TAP adapter with alias "Mullvad".
- //
-
- auto findByAlias = [](const std::set<NetworkAdapter> &adapters, const std::wstring &alias)
- {
- const auto it = std::find_if(adapters.begin(), adapters.end(), [&alias](const NetworkAdapter &candidate)
- {
- return 0 == _wcsicmp(candidate.alias.c_str(), alias.c_str());
- });
-
- return it;
- };
-
- static const wchar_t baseAlias[] = L"Mullvad";
-
- const auto mullvadAdapter = findByAlias(tapAdapters, baseAlias);
-
- if (tapAdapters.end() != mullvadAdapter)
- {
- return { *mullvadAdapter };
- }
-
- //
- // Look for TAP adapter with alias "Mullvad-1", "Mullvad-2", etc.
- //
-
- for (auto i = 0; i < 10; ++i)
- {
- std::wstringstream ss;
-
- ss << baseAlias << L"-" << i;
-
- const auto alias = ss.str();
-
- const auto mullvadAdapter = findByAlias(tapAdapters, alias);
-
- if (tapAdapters.end() != mullvadAdapter)
- {
- return { *mullvadAdapter };
- }
- }
-
- return std::nullopt;
-}
-
-Context::BaselineStatus Context::establishBaseline()
-{
- m_baseline = GetTapAdapters(TAP_HARDWARE_ID);
-
- if (m_baseline.empty())
- {
- return BaselineStatus::NO_TAP_ADAPTERS_PRESENT;
- }
-
- if (FindMullvadAdapter(m_baseline).has_value())
- {
- return BaselineStatus::MULLVAD_ADAPTER_PRESENT;
- }
-
- return BaselineStatus::SOME_TAP_ADAPTERS_PRESENT;
-}
-
-void Context::recordCurrentState()
-{
- m_currentState = GetTapAdapters(TAP_HARDWARE_ID);
-}
-
-void Context::rollbackTapAliases()
-{
- common::network::Nci nci;
-
- for (const auto &adapter : m_currentState)
- {
- const auto oldInfo = m_baseline.find(adapter);
- if (m_baseline.end() != oldInfo)
- {
- GUID guidObj = common::Guid::FromString(&adapter.guid[0]);
-
- nci.setConnectionName(guidObj, oldInfo->alias.c_str());
- }
- }
-}
-
-Context::NetworkAdapter Context::getNewAdapter()
-{
- std::list<NetworkAdapter> added;
-
- for (const auto &adapter : m_currentState)
- {
- if (m_baseline.end() == m_baseline.find(adapter))
- {
- added.push_back(adapter);
- }
- }
-
- if (added.size() == 0)
- {
- LogAdapters(L"Enumerable network TAP adapters", m_currentState);
-
- THROW_ERROR("Unable to identify recently added TAP adapter");
- }
- else if (added.size() > 1)
- {
- LogAdapters(L"Enumerable network TAP adapters", m_currentState);
- LogAdapters(L"New TAP adapters:", added);
-
- THROW_ERROR("Identified more TAP adapters than expected");
- }
-
- return *added.begin();
-}
-
-//static
-Context::DeletionResult Context::DeleteOldMullvadAdapter()
-{
- auto tapAdapters = GetTapAdapters(DEPRECATED_TAP_HARDWARE_ID);
- std::optional<NetworkAdapter> mullvadAdapter = FindMullvadAdapter(tapAdapters);
-
- if (!mullvadAdapter.has_value())
- {
- THROW_ERROR("Mullvad TAP adapter not found");
- }
-
- const auto mullvadGuid = mullvadAdapter.value().guid;
-
- HDEVINFO devInfo = SetupDiGetClassDevsW(
- &GUID_DEVCLASS_NET,
- nullptr,
- nullptr,
- DIGCF_PRESENT
- );
-
- if (INVALID_HANDLE_VALUE == devInfo)
- {
- THROW_WINDOWS_ERROR(GetLastError(), "SetupDiGetClassDevs() failed");
- }
-
- common::memory::ScopeDestructor cleanupDevList;
- cleanupDevList += [&devInfo]()
- {
- SetupDiDestroyDeviceInfoList(devInfo);
- };
-
- int numRemainingAdapters = 0;
-
- for (int memberIndex = 0; ; memberIndex++)
- {
- SP_DEVINFO_DATA devInfoData = { 0 };
- devInfoData.cbSize = sizeof(devInfoData);
-
- if (FALSE == SetupDiEnumDeviceInfo(devInfo, memberIndex, &devInfoData))
- {
- const auto lastError = GetLastError();
-
- if (ERROR_NO_MORE_ITEMS == lastError)
- {
- break;
- }
-
- THROW_WINDOWS_ERROR(lastError, "Error enumerating network adapters");
- }
-
- const auto hardwareId = GetDeviceRegistryStringProperty(devInfo, &devInfoData, SPDRP_HARDWAREID);
-
- if (hardwareId.has_value()
- && wcscmp(DEPRECATED_TAP_HARDWARE_ID, hardwareId.value().data()) == 0)
- {
- if (0 != GetNetCfgInstanceId(devInfo, devInfoData).compare(mullvadGuid))
- {
- numRemainingAdapters++;
- continue;
- }
-
- if (FALSE == SetupDiRemoveDevice(
- devInfo,
- &devInfoData
- ))
- {
- THROW_WINDOWS_ERROR(GetLastError(), "Error removing Mullvad TAP device");
- }
- }
- }
-
- return (numRemainingAdapters > 0)
- ? DeletionResult::SOME_REMAINING_TAP_ADAPTERS
- : DeletionResult::NO_REMAINING_TAP_ADAPTERS;
-}