#include "connectionsettingsengine.h" #include /* * The configuration map: * * autoconnectEnabled: bool * autoconnectPriority: int * allUsersMayConnect: bool * vpnAutoconnectEnabled: bool * autoconnectVpn: QString * meteredConnection: ConnectionSettingsEngine::Metered * device: QString * clonedMacAddress: QString * !mtu: int * * For Ethernet devices only: * !linkNegotiation: QString * !linkSpeed: ConnectionSettingsEngine::LinkSpeed * !duplexMode: QString */ ConnectionSettingsEngine::ConnectionSettingsEngine() { } 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()); result.insert("allUsersMayConnect", connSettings->permissions().isEmpty() ? true : false); QStringList secondaryConns = connSettings->secondaries(); NetworkManager::Connection::List list = NetworkManager::listConnections(); QStringList vpnList; for (const NetworkManager::Connection::Ptr &conn : list) { NetworkManager::ConnectionSettings::Ptr conSet = conn->settings(); if (conSet->connectionType() == NetworkManager::ConnectionSettings::Vpn || conSet->connectionType() == NetworkManager::ConnectionSettings::WireGuard) { vpnList.append(conSet->uuid()); } } if (secondaryConns.isEmpty() || vpnList.isEmpty()) { result.insert("vpnAutoconnectEnabled", false); result.insert("autoconnectVpn", ""); } else { for (const QString &vpnKey : vpnList) { if (secondaryConns.contains(vpnKey)) { result.insert("vpnAutoconnectEnabled", true); result.insert("autoconnectVpn", vpnKey); break; } } } switch(connSettings->metered()) { case NetworkManager::ConnectionSettings::MeteredUnknown: case NetworkManager::ConnectionSettings::MeteredGuessYes: case NetworkManager::ConnectionSettings::MeteredGuessNo: result.insert("meteredConnection", ConnectionSettingsEngine::MeteredAutomatic); break; case NetworkManager::ConnectionSettings::MeteredYes: result.insert("meteredConnection", ConnectionSettingsEngine::MeteredYes); break; case NetworkManager::ConnectionSettings::MeteredNo: result.insert("meteredConnection", ConnectionSettingsEngine::MeteredNo); 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; } 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()); } if (settings["autoconnectPriority"].isValid()) { connSettings->setAutoconnectPriority(settings["autoconnectPriority"].toInt()); } if (settings["allUsersMayConnect"].isValid()) { if (settings["allUsersMayConnect"].toBool()) { connSettings->setPermissions(QHash()); } else { if (connSettings->permissions().isEmpty()) { connSettings->addToPermissions(userName(), QString()); } // Otherwise we just leave the permissions as-is } } if (settings["vpnAutoconnectEnabled"].isValid()) { if (settings["vpnAutoconnectEnabled"].toBool()) { connSettings->setSecondaries(QStringList() << settings["autoconnectVpn"].toString()); } } if (settings["meteredConnection"].isValid()) { switch (settings["meteredConnection"].toInt()) { case ConnectionSettingsEngine::MeteredAutomatic: connSettings->setMetered(NetworkManager::ConnectionSettings::MeteredUnknown); break; case ConnectionSettingsEngine::MeteredYes: connSettings->setMetered(NetworkManager::ConnectionSettings::MeteredYes); break; case ConnectionSettingsEngine::MeteredNo: connSettings->setMetered(NetworkManager::ConnectionSettings::MeteredNo); break; } } 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() { QProcess userNameGetter; userNameGetter.setProgram("whoami"); userNameGetter.start(); userNameGetter.waitForFinished(); return QString(userNameGetter.readAllStandardOutput()); }