From 77320c140f6ebbf16deeae6afceaa68aaaddadeb Mon Sep 17 00:00:00 2001 From: Aaron Rainbolt Date: Wed, 25 Oct 2023 19:01:43 -0500 Subject: [PATCH] More functionality, get cloned MAC address management working --- connectionsettingsengine.cpp | 54 +++++++++++++++- connectionsettingsengine.h | 4 ++ ethernetsettings.cpp | 2 + ethernetsettingstab.cpp | 5 +- ethernetsettingstab.ui | 120 +++++++++++++++++------------------ networkselector.cpp | 1 + 6 files changed, 119 insertions(+), 67 deletions(-) diff --git a/connectionsettingsengine.cpp b/connectionsettingsengine.cpp index bd89f93..0b8fb8b 100644 --- a/connectionsettingsengine.cpp +++ b/connectionsettingsengine.cpp @@ -1,4 +1,5 @@ #include "connectionsettingsengine.h" +#include /* * The configuration map: @@ -9,8 +10,8 @@ * vpnAutoconnectEnabled: bool * autoconnectVpn: QString * meteredConnection: ConnectionSettingsEngine::Metered - * !device: QString - * !clonedMacAddress: QString + * device: QString + * clonedMacAddress: QString * !mtu: int * * For Ethernet devices only: @@ -28,6 +29,8 @@ QVariantMap ConnectionSettingsEngine::readConnectionSettings(QString connUuidStr // Contains adapted code from plasma-nm NetworkManager::Connection::Ptr conn = NetworkManager::findConnectionByUuid(connUuidStr); NetworkManager::ConnectionSettings::Ptr connSettings = conn->settings(); + NetworkManager::WiredSetting::Ptr connWiredSetting = connSettings->setting(NetworkManager::Setting::Wired).dynamicCast(); + NetworkManager::WirelessSetting::Ptr connWirelessSetting = connSettings->setting(NetworkManager::Setting::Wireless).dynamicCast(); QVariantMap result; result.insert("autoconnectEnabled", connSettings->autoconnect()); result.insert("autoconnectPriority", connSettings->autoconnectPriority()); @@ -73,6 +76,13 @@ QVariantMap ConnectionSettingsEngine::readConnectionSettings(QString connUuidStr break; } + result.insert("device", connSettings->interfaceName()); + + if (!connWiredSetting.isNull()) { + result.insert("clonedMacAddress", NetworkManager::macAddressAsString(connWiredSetting->clonedMacAddress())); + } else if (!connWirelessSetting.isNull()) { + result.insert("clonedMacAddress", NetworkManager::macAddressAsString(connWirelessSetting->clonedMacAddress())); + } // TODO: pick up here return result; @@ -81,8 +91,12 @@ QVariantMap ConnectionSettingsEngine::readConnectionSettings(QString connUuidStr void ConnectionSettingsEngine::modifyConnectionSettings(QString connUuidStr, QVariantMap settings) { // Contains adapted code from plasma-nm + bool wipeClonedMacAddress = false; + NetworkManager::Connection::Ptr conn = NetworkManager::findConnectionByUuid(connUuidStr); NetworkManager::ConnectionSettings::Ptr connSettings = conn->settings(); + NetworkManager::WiredSetting::Ptr connWiredSetting = connSettings->setting(NetworkManager::Setting::Wired).dynamicCast(); + NetworkManager::WirelessSetting::Ptr connWirelessSetting = connSettings->setting(NetworkManager::Setting::Wireless).dynamicCast(); if (settings["autoconnectEnabled"].isValid()) { connSettings->setAutoconnect(settings["autoconnectEnabled"].toBool()); @@ -95,7 +109,7 @@ void ConnectionSettingsEngine::modifyConnectionSettings(QString connUuidStr, QVa connSettings->setPermissions(QHash()); } else { if (connSettings->permissions().isEmpty()) { - connSettings->addToPermissions(ConnectionSettingsEngine::userName(), QString()); + connSettings->addToPermissions(userName(), QString()); } // Otherwise we just leave the permissions as-is } } @@ -120,7 +134,41 @@ void ConnectionSettingsEngine::modifyConnectionSettings(QString connUuidStr, QVa } } + if (settings["device"].isValid()) { + connSettings->setInterfaceName(settings["device"].toString()); + } + + if (settings["clonedMacAddress"].isValid()) { + QByteArray macBin = NetworkManager::macAddressFromString(settings["clonedMacAddress"].toString()); + if (settings["clonedMacAddress"].toString().length() != 17) { + wipeClonedMacAddress = true; + } else { + if (!connWiredSetting.isNull()) { + connWiredSetting->setClonedMacAddress(macBin); + } else if (!connWirelessSetting.isNull()) { + connWirelessSetting->setClonedMacAddress(macBin); + } + } + } + + // TODO: pick up here + conn->update(connSettings->toMap()); + + if (wipeClonedMacAddress) { + // Wiping a MAC address with NetworkManagerQt is surprisingly difficult, so we do it with nmcli instead. + QProcess clonedMacWiper; + clonedMacWiper.setProgram("bash"); + if (!connWiredSetting.isNull()) { + clonedMacWiper.setArguments(QStringList() << QString("-c") << QString("nmcli connection modify %1 ethernet.cloned-mac-address \"\"").arg(conn->uuid())); + clonedMacWiper.start(); + clonedMacWiper.waitForFinished(); + } else if (!connWirelessSetting.isNull()) { + clonedMacWiper.setArguments(QStringList() << QString("-c") << QString("nmcli connection modify %1 wifi.cloned-mac-address \"\"").arg(conn->uuid())); + clonedMacWiper.start(); + clonedMacWiper.waitForFinished(); + } + } } QString ConnectionSettingsEngine::userName() diff --git a/connectionsettingsengine.h b/connectionsettingsengine.h index 5043209..f931c53 100644 --- a/connectionsettingsengine.h +++ b/connectionsettingsengine.h @@ -9,6 +9,10 @@ #include #include #include +#include +#include +#include +#include class ConnectionSettingsEngine { diff --git a/ethernetsettings.cpp b/ethernetsettings.cpp index 611150e..e3502ae 100644 --- a/ethernetsettings.cpp +++ b/ethernetsettings.cpp @@ -15,6 +15,7 @@ EthernetSettings::EthernetSettings(QString title, QString connUuidStr, QWidget * ui->tabWidget->addTab(ethernetSettingsTab, "Ethernet"); QVariantMap connSettings = ConnectionSettingsEngine::readConnectionSettings(connUuidStr); generalSettingsTab->loadSettings(connSettings); + ethernetSettingsTab->loadSettings(connSettings); connect(ui->cancelButton, &QPushButton::clicked, this, &EthernetSettings::onCancelButtonClicked); connect(ui->saveButton, &QPushButton::clicked, this, &EthernetSettings::onSaveButtonClicked); } @@ -34,6 +35,7 @@ void EthernetSettings::onCancelButtonClicked() void EthernetSettings::onSaveButtonClicked() { QVariantMap settings = generalSettingsTab->readSettings(); + settings.insert(ethernetSettingsTab->readSettings()); ConnectionSettingsEngine::modifyConnectionSettings(targetConnUuidStr, settings); this->done(0); } diff --git a/ethernetsettingstab.cpp b/ethernetsettingstab.cpp index de27df7..6fb793f 100644 --- a/ethernetsettingstab.cpp +++ b/ethernetsettingstab.cpp @@ -6,6 +6,7 @@ EthernetSettingsTab::EthernetSettingsTab(QWidget *parent) : ui(new Ui::EthernetSettingsTab) { ui->setupUi(this); + ui->clonedMacAddressLineEdit->setInputMask("HH:HH:HH:HH:HH:HH;_"); ui->speedComboBox->addItems(QStringList() << tr("10 Mb/s") << tr("100 Mb/s") << tr("1 Gb/s") << tr("2.5 Gb/s") << tr("10 Gb/s") << tr("40 Gb/s") << tr("100 Gb/s")); ui->linkNegotiationComboBox->addItems(QStringList() << tr("Ignore") << tr("Automatic") << tr("Manual")); } @@ -21,7 +22,7 @@ QVariantMap EthernetSettingsTab::readSettings() { QVariantMap output; output.insert("device", QVariant(ui->deviceComboBox->currentText())); - output.insert("clonedMacAddress", QVariant(ui->clonedMacAddressComboBox->currentText())); + output.insert("clonedMacAddress", QVariant(ui->clonedMacAddressLineEdit->text())); output.insert("mtu", QVariant(ui->mtuSpinBox->value())); output.insert("linkNegotiation", QVariant(ui->linkNegotiationComboBox->currentText())); switch(ui->speedComboBox->currentIndex()) { @@ -61,7 +62,7 @@ void EthernetSettingsTab::loadSettings(QVariantMap settings) ui->deviceComboBox->setCurrentText(settings["device"].toString()); } if (settings["clonedMacAddress"].isValid()) { - ui->clonedMacAddressComboBox->setCurrentText(settings["clonedMacAddress"].toString()); + ui->clonedMacAddressLineEdit->setText(settings["clonedMacAddress"].toString()); } if (settings["mtu"].isValid()) { ui->mtuSpinBox->setValue(settings["mtu"].toInt()); diff --git a/ethernetsettingstab.ui b/ethernetsettingstab.ui index 1f04506..ad8c307 100644 --- a/ethernetsettingstab.ui +++ b/ethernetsettingstab.ui @@ -14,18 +14,24 @@ Form - - + + - + 0 0 + + Link negotiation + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + - - + + 0 @@ -34,49 +40,36 @@ - - + + - + 0 0 - Cloned MAC address + MTU Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + 0 0 - - - - - - - 0 - 0 - - - - Link negotiation - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + true - + @@ -86,8 +79,8 @@ - - + + 0 @@ -95,15 +88,15 @@ - Device + Cloned MAC address Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + 0 @@ -111,56 +104,69 @@ - Duplex + Device Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - + 0 0 + + Speed + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + - - + + - + 0 0 - MTU + Duplex Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - + 0 0 - - Speed - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + @@ -187,18 +193,8 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - + + diff --git a/networkselector.cpp b/networkselector.cpp index 4f74979..8a63316 100644 --- a/networkselector.cpp +++ b/networkselector.cpp @@ -7,6 +7,7 @@ NetworkSelector::NetworkSelector(QWidget *parent) , ui(new Ui::NetworkSelector) { ui->setupUi(this); + this->setWindowTitle(tr("Connection Editor")); regenConnTree(); connect(ui->connTree, &QTreeView::clicked, this, &NetworkSelector::onTreeSingleClicked); connect(ui->connTree, &QTreeView::doubleClicked, this, &NetworkSelector::onTreeDoubleClicked);