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:
Floris Bos 2023-03-10 18:37:22 +01:00
parent ebaf2ef6a1
commit 6dc2f3e58e
12 changed files with 373 additions and 197 deletions

View file

@ -4,30 +4,76 @@
*/
#include "networkmanagerapi.h"
#include <QDebug>
#include <QNetworkInterface>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/wireless.h>
#ifndef QT_NO_DBUS
#include <QDBusMetaType>
#include <QDBusInterface>
#include <QDBusReply>
#include <QDebug>
#endif
typedef QMap<QString, QVariantMap> VariantMapMap;
Q_DECLARE_METATYPE(VariantMapMap)
NetworkManagerApi::NetworkManagerApi(QObject *parent)
: QObject{parent}
NetworkManagerApi::NetworkManagerApi()
{
#ifndef QT_NO_DBUS
qDBusRegisterMetaType<VariantMapMap>();
#endif
}
QString NetworkManagerApi::getPSK()
QByteArray NetworkManagerApi::getSSID()
{
qDBusRegisterMetaType<VariantMapMap>();
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<QList<QDBusObjectPath>>();
@ -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;
}

View file

@ -6,17 +6,17 @@
* Copyright (C) 2022 Raspberry Pi Ltd
*/
#include <QObject>
#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