mirror of
https://github.com/cmclark00/retro-imager.git
synced 2025-05-19 08:25:21 +01:00
Refactor WLAN PSK retrieval code
- Reduce platform specific code in ImageWriter class, and move that to seperate classes. - Use API calls to get current SSID on Windows and Linux instead of launching command line utilities.
This commit is contained in:
parent
ebaf2ef6a1
commit
6dc2f3e58e
12 changed files with 373 additions and 197 deletions
140
src/windows/winwlancredentials.cpp
Normal file
140
src/windows/winwlancredentials.cpp
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2023 Raspberry Pi Ltd
|
||||
*/
|
||||
|
||||
#include "winwlancredentials.h"
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
#include <wlanapi.h>
|
||||
#include <Windot11.h>
|
||||
#include <QDebug>
|
||||
#include <QRegularExpression>
|
||||
#ifndef WLAN_PROFILE_GET_PLAINTEXT_KEY
|
||||
#define WLAN_PROFILE_GET_PLAINTEXT_KEY 4
|
||||
#endif
|
||||
|
||||
inline QString unescapeXml(QString str)
|
||||
{
|
||||
static const char *table[] = {
|
||||
"<", "<",
|
||||
">", ">",
|
||||
""", "\"",
|
||||
"'", "'",
|
||||
"&", "&"
|
||||
};
|
||||
int tableLen = sizeof(table) / sizeof(table[0]);
|
||||
|
||||
for (int i=0; i < tableLen; i+=2)
|
||||
{
|
||||
str.replace(table[i], table[i+1]);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
WinWlanCredentials::WinWlanCredentials()
|
||||
{
|
||||
/* Get both SSID and PSK in one go, and store it in variables */
|
||||
HANDLE h;
|
||||
DWORD supportedVersion = 0;
|
||||
DWORD clientVersion = 2;
|
||||
|
||||
if (WlanOpenHandle(clientVersion, NULL, &supportedVersion, &h) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
PWLAN_INTERFACE_INFO_LIST ifList = NULL;
|
||||
|
||||
if (WlanEnumInterfaces(h, NULL, &ifList) == ERROR_SUCCESS)
|
||||
{
|
||||
for (DWORD i=0; i < ifList->dwNumberOfItems; i++)
|
||||
{
|
||||
PWLAN_PROFILE_INFO_LIST profileList = NULL;
|
||||
|
||||
if (ifList->InterfaceInfo[i].isState != wlan_interface_state_connected)
|
||||
continue; /* Wlan adapter not connected */
|
||||
|
||||
/* Get current connection info for SSID */
|
||||
PWLAN_CONNECTION_ATTRIBUTES pConnectInfo = NULL;
|
||||
DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES);
|
||||
WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid;
|
||||
|
||||
if (WlanQueryInterface(h, &ifList->InterfaceInfo[i].InterfaceGuid,
|
||||
wlan_intf_opcode_current_connection, NULL,
|
||||
&connectInfoSize, (PVOID *) &pConnectInfo, &opCode) != ERROR_SUCCESS || !pConnectInfo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pConnectInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength)
|
||||
{
|
||||
_ssid = QByteArray((const char *) pConnectInfo->wlanAssociationAttributes.dot11Ssid.ucSSID,
|
||||
pConnectInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength);
|
||||
}
|
||||
WlanFreeMemory(pConnectInfo);
|
||||
|
||||
if (_ssid.isEmpty())
|
||||
continue;
|
||||
|
||||
if (WlanGetProfileList(h, &ifList->InterfaceInfo[i].InterfaceGuid,
|
||||
NULL, &profileList) == ERROR_SUCCESS)
|
||||
{
|
||||
for (DWORD j=0; j < profileList->dwNumberOfItems; j++)
|
||||
{
|
||||
QString s = QString::fromWCharArray(profileList->ProfileInfo[j].strProfileName);
|
||||
qDebug() << "Enumerating wlan profiles, SSID found:" << s << " looking for:" << _ssid;
|
||||
|
||||
if (s == _ssid) {
|
||||
DWORD flags = WLAN_PROFILE_GET_PLAINTEXT_KEY;
|
||||
DWORD access = 0;
|
||||
DWORD ret = 0;
|
||||
LPWSTR xmlstr = NULL;
|
||||
|
||||
if ( (ret = WlanGetProfile(h, &ifList->InterfaceInfo[i].InterfaceGuid, profileList->ProfileInfo[j].strProfileName,
|
||||
NULL, &xmlstr, &flags, &access)) == ERROR_SUCCESS && xmlstr)
|
||||
{
|
||||
QString xml = QString::fromWCharArray(xmlstr);
|
||||
qDebug() << "XML wlan profile:" << xml;
|
||||
QRegularExpression rx("<keyMaterial>(.+)</keyMaterial>");
|
||||
QRegularExpressionMatch match = rx.match(xml);
|
||||
|
||||
if (match.hasMatch()) {
|
||||
_psk = unescapeXml(match.captured(1)).toLatin1();
|
||||
}
|
||||
|
||||
WlanFreeMemory(xmlstr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (profileList) {
|
||||
WlanFreeMemory(profileList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ifList)
|
||||
WlanFreeMemory(ifList);
|
||||
WlanCloseHandle(h, NULL);
|
||||
}
|
||||
|
||||
QByteArray WinWlanCredentials::getSSID()
|
||||
{
|
||||
return _ssid;
|
||||
}
|
||||
|
||||
QByteArray WinWlanCredentials::getPSK()
|
||||
{
|
||||
return _psk;
|
||||
}
|
||||
|
||||
WlanCredentials *WlanCredentials::_instance = NULL;
|
||||
WlanCredentials *WlanCredentials::instance()
|
||||
{
|
||||
if (!_instance)
|
||||
_instance = new WinWlanCredentials();
|
||||
|
||||
return _instance;
|
||||
}
|
22
src/windows/winwlancredentials.h
Normal file
22
src/windows/winwlancredentials.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef WINWLANCREDENTIALS_H
|
||||
#define WINWLANCREDENTIALS_H
|
||||
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2023 Raspberry Pi Ltd
|
||||
*/
|
||||
|
||||
#include "wlancredentials.h"
|
||||
|
||||
class WinWlanCredentials : public WlanCredentials
|
||||
{
|
||||
public:
|
||||
WinWlanCredentials();
|
||||
virtual QByteArray getSSID();
|
||||
virtual QByteArray getPSK();
|
||||
|
||||
protected:
|
||||
QByteArray _ssid, _psk;
|
||||
};
|
||||
|
||||
#endif // WINWLANCREDENTIALS_H
|
Loading…
Add table
Add a link
Reference in a new issue