From 6dc2f3e58ee1e7b87f81072c067b09b8703c34d4 Mon Sep 17 00:00:00 2001 From: Floris Bos Date: Fri, 10 Mar 2023 18:37:22 +0100 Subject: [PATCH] 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. --- src/CMakeLists.txt | 14 +-- src/OptionsPopup.qml | 2 +- src/imagewriter.cpp | 182 ++--------------------------- src/imagewriter.h | 2 +- src/linux/networkmanagerapi.cpp | 74 ++++++++++-- src/linux/networkmanagerapi.h | 14 +-- src/mac/macwlancredentials.cpp | 73 ++++++++++++ src/mac/macwlancredentials.h | 21 ++++ src/windows/winwlancredentials.cpp | 140 ++++++++++++++++++++++ src/windows/winwlancredentials.h | 22 ++++ src/wlancredentials.cpp | 0 src/wlancredentials.h | 26 +++++ 12 files changed, 373 insertions(+), 197 deletions(-) create mode 100644 src/mac/macwlancredentials.cpp create mode 100644 src/mac/macwlancredentials.h create mode 100644 src/windows/winwlancredentials.cpp create mode 100644 src/windows/winwlancredentials.h create mode 100644 src/wlancredentials.cpp create mode 100644 src/wlancredentials.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4cda133..63c2503 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,8 +12,8 @@ OPTION (ENABLE_TELEMETRY "Enable sending telemetry" ON) project(rpi-imager LANGUAGES CXX C) set(IMAGER_VERSION_MAJOR 1) set(IMAGER_VERSION_MINOR 7) -set(IMAGER_VERSION_STR "${IMAGER_VERSION_MAJOR}.${IMAGER_VERSION_MINOR}.4") -set(IMAGER_VERSION_CSV "${IMAGER_VERSION_MAJOR},${IMAGER_VERSION_MINOR},4,0") +set(IMAGER_VERSION_STR "${IMAGER_VERSION_MAJOR}.${IMAGER_VERSION_MINOR}.4.1") +set(IMAGER_VERSION_CSV "${IMAGER_VERSION_MAJOR},${IMAGER_VERSION_MINOR},4,1") add_definitions(-DIMAGER_VERSION_STR="${IMAGER_VERSION_STR}") add_definitions(-DIMAGER_VERSION_CSV=${IMAGER_VERSION_CSV}) @@ -23,21 +23,21 @@ set(CMAKE_AUTORCC ON) # Adding headers explicity so they are displayed in Qt Creator set(HEADERS config.h imagewriter.h networkaccessmanagerfactory.h nan.h drivelistitem.h drivelistmodel.h drivelistmodelpollthread.h driveformatthread.h powersaveblocker.h cli.h - devicewrapper.h devicewrapperblockcacheentry.h devicewrapperpartition.h devicewrapperstructs.h devicewrapperfatpartition.h + devicewrapper.h devicewrapperblockcacheentry.h devicewrapperpartition.h devicewrapperstructs.h devicewrapperfatpartition.h wlancredentials.h downloadthread.h downloadextractthread.h localfileextractthread.h downloadstatstelemetry.h dependencies/mountutils/src/mountutils.hpp dependencies/sha256crypt/sha256crypt.h) # Add dependencies if (APPLE) set_source_files_properties("icons/rpi-imager.icns" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") set(DEPENDENCIES acceleratedcryptographichash.cpp mac/macfile.cpp mac/macfile.h dependencies/mountutils/src/darwin/functions.cpp + mac/macwlancredentials.h mac/macwlancredentials.cpp dependencies/drivelist/src/darwin/list.mm dependencies/drivelist/src/darwin/REDiskList.m icons/rpi-imager.icns) enable_language(OBJC C) elseif (UNIX) - set(DEPENDENCIES dependencies/mountutils/src/linux/functions.cpp linux/linuxdrivelist.cpp) + set(DEPENDENCIES dependencies/mountutils/src/linux/functions.cpp linux/linuxdrivelist.cpp linux/networkmanagerapi.h linux/networkmanagerapi.cpp) find_package(Qt5DBus) if(Qt5DBus_FOUND) - set(DEPENDENCIES ${DEPENDENCIES} linux/udisks2api.cpp linux/udisks2api.h - linux/networkmanagerapi.h linux/networkmanagerapi.cpp) + set(DEPENDENCIES ${DEPENDENCIES} linux/udisks2api.cpp linux/udisks2api.h) set(EXTRALIBS Qt5::DBus) message("udisks2 support enabled") else() @@ -62,7 +62,7 @@ elseif (UNIX) endif() elseif (WIN32) set(DEPENDENCIES acceleratedcryptographichash.cpp dependencies/mountutils/src/windows/functions.cpp dependencies/drivelist/src/windows/list.cpp - windows/winfile.cpp windows/winfile.h + windows/winfile.cpp windows/winfile.h windows/winwlancredentials.h windows/winwlancredentials.cpp windows/rpi-imager.rc) find_package(Qt5WinExtras REQUIRED) set(EXTRALIBS setupapi wlanapi Qt5::WinExtras) diff --git a/src/OptionsPopup.qml b/src/OptionsPopup.qml index 97f775f..da0272d 100644 --- a/src/OptionsPopup.qml +++ b/src/OptionsPopup.qml @@ -499,7 +499,7 @@ Popup { fieldWifiCountry.currentIndex = fieldWifiCountry.find("GB") fieldWifiSSID.text = imageWriter.getSSID() if (fieldWifiSSID.text.length) { - fieldWifiPassword.text = imageWriter.getPSK(fieldWifiSSID.text) + fieldWifiPassword.text = imageWriter.getPSK() if (fieldWifiPassword.text.length) { chkShowPassword.checked = false if (Qt.platform.os == "osx") { diff --git a/src/imagewriter.cpp b/src/imagewriter.cpp index 1a757d7..1d815ac 100644 --- a/src/imagewriter.cpp +++ b/src/imagewriter.cpp @@ -11,6 +11,7 @@ #include "driveformatthread.h" #include "localfileextractthread.h" #include "downloadstatstelemetry.h" +#include "wlancredentials.h" #include #include #include @@ -38,17 +39,10 @@ #endif #ifdef Q_OS_DARWIN #include -#include #endif #ifdef Q_OS_WIN #include -#include -#include -#ifndef WLAN_PROFILE_GET_PLAINTEXT_KEY -#define WLAN_PROFILE_GET_PLAINTEXT_KEY 4 -#endif - #include #include #endif @@ -57,12 +51,6 @@ #include #endif -#ifdef Q_OS_LINUX -#ifndef QT_NO_DBUS -#include "linux/networkmanagerapi.h" -#endif -#endif - ImageWriter::ImageWriter(QObject *parent) : QObject(parent), _repo(QUrl(QString(OSLIST_URL))), _dlnow(0), _verifynow(0), _engine(nullptr), _thread(nullptr), _verifyEnabled(false), _cachingEnabled(false), @@ -863,173 +851,23 @@ QStringList ImageWriter::getKeymapLayoutList() QString ImageWriter::getSSID() { - /* Qt used to have proper bearer management that was able to provide a list of - SSIDs, but since they retired it, resort to calling platform specific tools for now. - Minimal implementation that only gets the currently connected SSID */ - - QString program, regexpstr, ssid; - QStringList args; - QProcess proc; - -#ifdef Q_OS_WIN - program = "netsh"; - args << "wlan" << "show" << "interfaces"; - regexpstr = "[ \t]+SSID[ \t]*: (.+)"; -#else -#ifdef Q_OS_DARWIN - program = "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport"; - args << "-I"; - regexpstr = "[ \t]+SSID: (.+)"; -#else - program = "iwgetid"; - args << "-r"; -#endif -#endif - - proc.start(program, args); - if (proc.waitForStarted(2000) && proc.waitForFinished(2000)) - { - if (regexpstr.isEmpty()) - { - ssid = proc.readAll().trimmed(); - } - else - { - QRegularExpression rx(regexpstr); - const QList outputlines = proc.readAll().replace('\r', "").split('\n'); - - for (const QByteArray &line : outputlines) { - QRegularExpressionMatch match = rx.match(line); - if (match.hasMatch()) - { - ssid = match.captured(1); - break; - } - } - } - } - - return ssid; + return WlanCredentials::instance()->getSSID(); } -inline QString unescapeXml(QString str) +QString ImageWriter::getPSK() { - 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; -} - -QString ImageWriter::getPSK(const QString &ssid) -{ -#ifdef Q_OS_WIN - /* Windows allows retrieving wifi PSK */ - HANDLE h; - DWORD ret = 0; - DWORD supportedVersion = 0; - DWORD clientVersion = 2; - QString psk; - - if (WlanOpenHandle(clientVersion, NULL, &supportedVersion, &h) != ERROR_SUCCESS) - return QString(); - - PWLAN_INTERFACE_INFO_LIST ifList = NULL; - - if (WlanEnumInterfaces(h, NULL, &ifList) == ERROR_SUCCESS) - { - for (int i=0; i < ifList->dwNumberOfItems; i++) - { - PWLAN_PROFILE_INFO_LIST profileList = NULL; - - if (WlanGetProfileList(h, &ifList->InterfaceInfo[i].InterfaceGuid, - NULL, &profileList) == ERROR_SUCCESS) - { - for (int j=0; j < profileList->dwNumberOfItems; j++) - { - QString s = QString::fromWCharArray(profileList->ProfileInfo[j].strProfileName); - qDebug() << "Enumerating wifi 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 wifi profile:" << xml; - QRegularExpression rx("(.+)"); - QRegularExpressionMatch match = rx.match(xml); - - if (match.hasMatch()) { - psk = unescapeXml(match.captured(1)); - } - - WlanFreeMemory(xmlstr); - break; - } - } - } - } - - if (profileList) { - WlanFreeMemory(profileList); - } - } - } - - if (ifList) - WlanFreeMemory(ifList); - WlanCloseHandle(h, NULL); - - return psk; - -#else #ifdef Q_OS_DARWIN - SecKeychainRef keychainRef; - QString psk; - QByteArray ssidAscii = ssid.toLatin1(); - + /* On OSX the user is presented with a prompt for the admin password when opening the system key chain. + * Ask if user wants to obtain the wlan password first to make sure this is desired and + * to provide the user with context. */ if (QMessageBox::question(nullptr, "", - tr("Would you like to prefill the wifi password from the system keychain?")) == QMessageBox::Yes) + tr("Would you like to prefill the wifi password from the system keychain?")) != QMessageBox::Yes) { - if (SecKeychainOpen("/Library/Keychains/System.keychain", &keychainRef) == errSecSuccess) - { - UInt32 resultLen; - void *result; - if (SecKeychainFindGenericPassword(keychainRef, 0, NULL, ssidAscii.length(), ssidAscii.constData(), &resultLen, &result, NULL) == errSecSuccess) - { - psk = QByteArray((char *) result, resultLen); - SecKeychainItemFreeContent(NULL, result); - } - CFRelease(keychainRef); - } + return QString(); } +#endif - return psk; -#else -#ifndef QT_NO_DBUS - NetworkManagerApi nm; - return nm.getPSK(); -#else - Q_UNUSED(ssid) - return QString(); -#endif -#endif -#endif + return WlanCredentials::instance()->getPSK(); } bool ImageWriter::getBoolSetting(const QString &key) diff --git a/src/imagewriter.h b/src/imagewriter.h index 2ad8390..d606752 100644 --- a/src/imagewriter.h +++ b/src/imagewriter.h @@ -103,7 +103,7 @@ public: Q_INVOKABLE QStringList getCountryList(); Q_INVOKABLE QStringList getKeymapLayoutList(); Q_INVOKABLE QString getSSID(); - Q_INVOKABLE QString getPSK(const QString &ssid); + Q_INVOKABLE QString getPSK(); Q_INVOKABLE bool getBoolSetting(const QString &key); Q_INVOKABLE void setSetting(const QString &key, const QVariant &value); diff --git a/src/linux/networkmanagerapi.cpp b/src/linux/networkmanagerapi.cpp index 3750eae..7409073 100644 --- a/src/linux/networkmanagerapi.cpp +++ b/src/linux/networkmanagerapi.cpp @@ -4,30 +4,76 @@ */ #include "networkmanagerapi.h" +#include +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_DBUS #include #include #include -#include +#endif typedef QMap VariantMapMap; Q_DECLARE_METATYPE(VariantMapMap) -NetworkManagerApi::NetworkManagerApi(QObject *parent) - : QObject{parent} +NetworkManagerApi::NetworkManagerApi() { - +#ifndef QT_NO_DBUS + qDBusRegisterMetaType(); +#endif } -QString NetworkManagerApi::getPSK() +QByteArray NetworkManagerApi::getSSID() { - qDBusRegisterMetaType(); + QByteArray ssid; + const auto interfaces = QNetworkInterface::allInterfaces(); + + for (const auto &interface : interfaces) + { + if (interface.type() == interface.Wifi) + { + ssid = _getSSIDofInterface(interface.name().toLatin1()); + if (!ssid.isEmpty()) + break; + } + } + + return ssid; +} + +QByteArray NetworkManagerApi::_getSSIDofInterface(const QByteArray &iface) +{ + char ssid[IW_ESSID_MAX_SIZE+1] = {0}; + struct iwreq iw = {0}; + int s = ::socket(AF_INET, SOCK_DGRAM, 0); + + if (s == -1) + return QByteArray(); + + strncpy(iw.ifr_ifrn.ifrn_name, iface.data(), sizeof(iw.ifr_ifrn.ifrn_name)); + iw.u.essid.pointer = ssid; + iw.u.essid.length = IW_ESSID_MAX_SIZE; + ::ioctl(s, SIOCGIWESSID, &iw); + ::close(s); + + return QByteArray(ssid); +} + +QByteArray NetworkManagerApi::getPSK() +{ +#ifndef QT_NO_DBUS QDBusInterface nm("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager", QDBusConnection::systemBus()); if (!nm.isValid()) { qDebug() << "NetworkManager not available"; - return QString(); + return QByteArray(); } const auto activeConnections = nm.property("ActiveConnections").value>(); @@ -52,8 +98,18 @@ QString NetworkManagerApi::getPSK() continue; QVariantMap secrets = reply.value().value("802-11-wireless-security"); if (secrets.contains("psk")) - return secrets.value("psk").toString(); + return secrets.value("psk").toByteArray(); } +#endif - return QString(); + return QByteArray(); +} + +WlanCredentials *WlanCredentials::_instance = NULL; +WlanCredentials *WlanCredentials::instance() +{ + if (!_instance) + _instance = new NetworkManagerApi(); + + return _instance; } diff --git a/src/linux/networkmanagerapi.h b/src/linux/networkmanagerapi.h index e3387a2..cb5346d 100644 --- a/src/linux/networkmanagerapi.h +++ b/src/linux/networkmanagerapi.h @@ -6,17 +6,17 @@ * Copyright (C) 2022 Raspberry Pi Ltd */ -#include +#include "wlancredentials.h" -class NetworkManagerApi : public QObject +class NetworkManagerApi : public WlanCredentials { - Q_OBJECT public: - explicit NetworkManagerApi(QObject *parent = nullptr); - QString getPSK(); - -signals: + NetworkManagerApi(); + virtual QByteArray getSSID(); + virtual QByteArray getPSK(); +protected: + QByteArray _getSSIDofInterface(const QByteArray &iface); }; #endif // NETWORKMANAGERAPI_H diff --git a/src/mac/macwlancredentials.cpp b/src/mac/macwlancredentials.cpp new file mode 100644 index 0000000..13f689b --- /dev/null +++ b/src/mac/macwlancredentials.cpp @@ -0,0 +1,73 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2023 Raspberry Pi Ltd + */ + +#include "macwlancredentials.h" +#include +#include +#include + +QByteArray MacWlanCredentials::getSSID() +{ + /* FIXME: find out the proper API call to get SSID instead of calling command line utilities */ + QString program, regexpstr; + QStringList args; + QProcess proc; + program = "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport"; + args << "-I"; + regexpstr = "[ \t]+SSID: (.+)"; + + proc.start(program, args); + if (proc.waitForStarted(2000) && proc.waitForFinished(2000)) + { + QRegularExpression rx(regexpstr); + const QList outputlines = proc.readAll().replace('\r', "").split('\n'); + + for (const QByteArray &line : outputlines) { + QRegularExpressionMatch match = rx.match(line); + if (match.hasMatch()) + { + _ssid = match.captured(1).toLatin1(); + break; + } + } + } + + return _ssid; +} + +QByteArray MacWlanCredentials::getPSK() +{ + SecKeychainRef keychainRef; + QByteArray psk; + + if (_ssid.isEmpty()) + getSSID(); + if (_ssid.isEmpty()) + return psk; + + if (SecKeychainOpen("/Library/Keychains/System.keychain", &keychainRef) == errSecSuccess) + { + UInt32 resultLen; + void *result; + if (SecKeychainFindGenericPassword(keychainRef, 0, NULL, _ssid.length(), _ssid.constData(), &resultLen, &result, NULL) == errSecSuccess) + { + psk = QByteArray((char *) result, resultLen); + SecKeychainItemFreeContent(NULL, result); + } + CFRelease(keychainRef); + } + + return psk; +} + +WlanCredentials *WlanCredentials::_instance = NULL; +WlanCredentials *WlanCredentials::instance() +{ + if (!_instance) + _instance = new MacWlanCredentials(); + + return _instance; +} + diff --git a/src/mac/macwlancredentials.h b/src/mac/macwlancredentials.h new file mode 100644 index 0000000..37d96c1 --- /dev/null +++ b/src/mac/macwlancredentials.h @@ -0,0 +1,21 @@ +#ifndef MACWLANCREDENTIALS_H +#define MACWLANCREDENTIALS_H + +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2023 Raspberry Pi Ltd + */ + +#include "wlancredentials.h" + +class MacWlanCredentials : public WlanCredentials +{ +public: + virtual QByteArray getSSID(); + virtual QByteArray getPSK(); + +protected: + QByteArray _ssid; +}; + +#endif // MACWLANCREDENTIALS_H diff --git a/src/windows/winwlancredentials.cpp b/src/windows/winwlancredentials.cpp new file mode 100644 index 0000000..3a80d50 --- /dev/null +++ b/src/windows/winwlancredentials.cpp @@ -0,0 +1,140 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2023 Raspberry Pi Ltd + */ + +#include "winwlancredentials.h" +#include +#include +#include +#include +#include +#include +#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("(.+)"); + 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; +} diff --git a/src/windows/winwlancredentials.h b/src/windows/winwlancredentials.h new file mode 100644 index 0000000..b7e06e1 --- /dev/null +++ b/src/windows/winwlancredentials.h @@ -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 diff --git a/src/wlancredentials.cpp b/src/wlancredentials.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/wlancredentials.h b/src/wlancredentials.h new file mode 100644 index 0000000..841b973 --- /dev/null +++ b/src/wlancredentials.h @@ -0,0 +1,26 @@ +#ifndef WLANCREDENTIALS_H +#define WLANCREDENTIALS_H + +/* + * Interface for wlan credential detection + * Use WlanCredentials::instance() to get platform + * specific implementation + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2023 Raspberry Pi Ltd + */ + +#include + +class WlanCredentials +{ +public: + static WlanCredentials *instance(); + virtual QByteArray getSSID() = 0; + virtual QByteArray getPSK() = 0; + +protected: + static WlanCredentials *_instance; +}; + +#endif // WLANCREDENTIALS_H