amnezia-client/client/platforms/windows/windowsnetworkwatcher.cpp
Mykola Baibuz 5bd8c33a6d
Update Mozilla upstream (#790)
* Update Mozilla upstream
2024-05-08 22:02:02 +01:00

140 lines
No EOL
4.2 KiB
C++

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "windowsnetworkwatcher.h"
#include <QNetworkInformation>
#include <QScopeGuard>
#include "leakdetector.h"
#include "logger.h"
#include "networkwatcherimpl.h"
#include "platforms/windows/windowsutils.h"
#pragma comment(lib, "Wlanapi.lib")
#pragma comment(lib, "windowsapp.lib")
namespace {
Logger logger("WindowsNetworkWatcher");
}
WindowsNetworkWatcher::WindowsNetworkWatcher(QObject* parent)
: NetworkWatcherImpl(parent) {
MZ_COUNT_CTOR(WindowsNetworkWatcher);
}
WindowsNetworkWatcher::~WindowsNetworkWatcher() {
MZ_COUNT_DTOR(WindowsNetworkWatcher);
if (m_wlanHandle) {
WlanCloseHandle(m_wlanHandle, nullptr);
}
}
void WindowsNetworkWatcher::initialize() {
logger.debug() << "initialize";
DWORD negotiatedVersion;
if (WlanOpenHandle(2, nullptr, &negotiatedVersion, &m_wlanHandle) !=
ERROR_SUCCESS) {
WindowsUtils::windowsLog("Failed to open the WLAN handle");
return;
}
DWORD prefNotifSource;
if (WlanRegisterNotification(m_wlanHandle, WLAN_NOTIFICATION_SOURCE_MSM,
true /* ignore duplicates */,
(WLAN_NOTIFICATION_CALLBACK)wlanCallback, this,
nullptr, &prefNotifSource) != ERROR_SUCCESS) {
WindowsUtils::windowsLog("Failed to register a wlan callback");
return;
}
logger.debug() << "callback registered";
}
// static
void WindowsNetworkWatcher::wlanCallback(PWLAN_NOTIFICATION_DATA data,
PVOID context) {
logger.debug() << "Callback";
WindowsNetworkWatcher* that = static_cast<WindowsNetworkWatcher*>(context);
Q_ASSERT(that);
that->processWlan(data);
}
void WindowsNetworkWatcher::processWlan(PWLAN_NOTIFICATION_DATA data) {
logger.debug() << "Processing wlan data";
if (!isActive()) {
logger.debug() << "The watcher is off";
return;
}
if (data->NotificationSource != WLAN_NOTIFICATION_SOURCE_MSM) {
logger.debug() << "The wlan source is not MSM";
return;
}
if (data->NotificationCode != wlan_notification_msm_connected) {
logger.debug() << "Wlan unprocessed code: " << data->NotificationCode;
return;
}
PWLAN_CONNECTION_ATTRIBUTES connectionInfo = nullptr;
DWORD connectionInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES);
WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid;
DWORD result = WlanQueryInterface(
m_wlanHandle, &data->InterfaceGuid, wlan_intf_opcode_current_connection,
nullptr, &connectionInfoSize, (PVOID*)&connectionInfo, &opCode);
if (result != ERROR_SUCCESS) {
WindowsUtils::windowsLog("Failed to query the interface");
return;
}
auto guard = qScopeGuard([&] { WlanFreeMemory(connectionInfo); });
QString bssid;
for (size_t i = 0;
i < sizeof(connectionInfo->wlanAssociationAttributes.dot11Bssid); ++i) {
if (i == 5) {
bssid.append(QString::asprintf(
"%.2X\n", connectionInfo->wlanAssociationAttributes.dot11Bssid[i]));
} else {
bssid.append(QString::asprintf(
"%.2X-", connectionInfo->wlanAssociationAttributes.dot11Bssid[i]));
}
}
if (bssid != m_lastBSSID) {
emit networkChanged(bssid);
m_lastBSSID = bssid;
}
if (connectionInfo->wlanSecurityAttributes.dot11AuthAlgorithm !=
DOT11_AUTH_ALGO_80211_OPEN &&
connectionInfo->wlanSecurityAttributes.dot11CipherAlgorithm !=
DOT11_CIPHER_ALGO_WEP &&
connectionInfo->wlanSecurityAttributes.dot11CipherAlgorithm !=
DOT11_CIPHER_ALGO_WEP40 &&
connectionInfo->wlanSecurityAttributes.dot11CipherAlgorithm !=
DOT11_CIPHER_ALGO_WEP104) {
logger.debug() << "The network is secure enough";
return;
}
QString ssid;
for (size_t i = 0;
i < connectionInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength;
++i) {
ssid.append(QString::asprintf(
"%c",
(char)connectionInfo->wlanAssociationAttributes.dot11Ssid.ucSSID[i]));
}
logger.debug() << "Unsecure network:" << logger.sensitive(ssid)
<< "id:" << logger.sensitive(bssid);
emit unsecuredNetwork(ssid, bssid);
}