|
|
|
#include "connectionsettingsengine.h"
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
bool ConnectionSettingsEngine::wipeClonedMacAddress = false;
|
|
|
|
QString ConnectionSettingsEngine::targetConnUuidStr = QString();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The configuration map:
|
|
|
|
*
|
|
|
|
* connName: QString
|
|
|
|
* autoconnectEnabled: bool
|
|
|
|
* autoconnectPriority: int
|
|
|
|
* allUsersMayConnect: bool
|
|
|
|
* vpnAutoconnectEnabled: bool
|
|
|
|
* autoconnectVpn: QString
|
|
|
|
* meteredConnection: ConnectionSettingsEngine::Metered
|
|
|
|
* device: QString
|
|
|
|
* clonedMacAddress: QString
|
|
|
|
* mtu: int
|
|
|
|
*
|
|
|
|
* For Ethernet devices only:
|
|
|
|
* autoLinkNegotiation: ConnectionSettingsEngine::LinkNegotiation
|
|
|
|
* linkSpeed: ConnectionSettingsEngine::LinkSpeed
|
|
|
|
* duplexMode: ConnectionSettingsEngine::DuplexMode
|
|
|
|
*/
|
|
|
|
|
|
|
|
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::WiredSetting>();
|
|
|
|
NetworkManager::WirelessSetting::Ptr connWirelessSetting = connSettings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>();
|
|
|
|
QVariantMap result;
|
|
|
|
result.insert("connName", connSettings->id());
|
|
|
|
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()));
|
|
|
|
result.insert("mtu", connWiredSetting->mtu());
|
|
|
|
|
|
|
|
if (connWiredSetting->autoNegotiate()) {
|
|
|
|
result.insert("autoLinkNegotiation", ConnectionSettingsEngine::NegotiationAutomatic);
|
|
|
|
result.insert("linkSpeed", ConnectionSettingsEngine::SpeedUnknown);
|
|
|
|
result.insert("duplexMode", ConnectionSettingsEngine::DuplexUnknown);
|
|
|
|
} else if (connWiredSetting->speed() != 0 && connWiredSetting->duplexType() != NetworkManager::WiredSetting::UnknownDuplexType) {
|
|
|
|
result.insert("autoLinkNegotiation", ConnectionSettingsEngine::NegotiationManual);
|
|
|
|
switch (connWiredSetting->speed()) {
|
|
|
|
case 10:
|
|
|
|
result.insert("linkSpeed", ConnectionSettingsEngine::Speed10Mbps);
|
|
|
|
break;
|
|
|
|
case 100:
|
|
|
|
result.insert("linkSpeed", ConnectionSettingsEngine::Speed100Mbps);
|
|
|
|
break;
|
|
|
|
case 1000:
|
|
|
|
result.insert("linkSpeed", ConnectionSettingsEngine::Speed1Gbps);
|
|
|
|
break;
|
|
|
|
case 2500:
|
|
|
|
result.insert("linkSpeed", ConnectionSettingsEngine::Speed2_5Gbps);
|
|
|
|
break;
|
|
|
|
case 5000:
|
|
|
|
result.insert("linkSpeed", ConnectionSettingsEngine::Speed5Gbps);
|
|
|
|
break;
|
|
|
|
case 10000:
|
|
|
|
result.insert("linkSpeed", ConnectionSettingsEngine::Speed10Gbps);
|
|
|
|
break;
|
|
|
|
case 40000:
|
|
|
|
result.insert("linkSpeed", ConnectionSettingsEngine::Speed40Gbps);
|
|
|
|
break;
|
|
|
|
case 100000:
|
|
|
|
result.insert("linkSpeed", ConnectionSettingsEngine::Speed100Gbps);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (connWiredSetting->duplexType()) {
|
|
|
|
case NetworkManager::WiredSetting::UnknownDuplexType:
|
|
|
|
result.insert("duplexType", ConnectionSettingsEngine::DuplexUnknown);
|
|
|
|
break;
|
|
|
|
case NetworkManager::WiredSetting::Half:
|
|
|
|
result.insert("duplexType", ConnectionSettingsEngine::DuplexHalf);
|
|
|
|
break;
|
|
|
|
case NetworkManager::WiredSetting::Full:
|
|
|
|
result.insert("duplexType", ConnectionSettingsEngine::DuplexFull);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
result.insert("duplexMode", connWiredSetting->duplexType());
|
|
|
|
} else {
|
|
|
|
result.insert("autoLinkNegotiation", ConnectionSettingsEngine::NegotiationIgnore);
|
|
|
|
result.insert("linkSpeed", ConnectionSettingsEngine::SpeedUnknown);
|
|
|
|
result.insert("duplexMode", ConnectionSettingsEngine::DuplexUnknown);
|
|
|
|
}
|
|
|
|
} else if (!connWirelessSetting.isNull()) {
|
|
|
|
result.insert("clonedMacAddress", NetworkManager::macAddressAsString(connWirelessSetting->clonedMacAddress()));
|
|
|
|
result.insert("mtu", connWirelessSetting->mtu());
|
|
|
|
}
|
|
|
|
// TODO: pick up here
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionSettingsEngine::modifyConnectionSettings(QString connUuidStr, QVariantMap settings)
|
|
|
|
{
|
|
|
|
// Contains adapted code from plasma-nm
|
|
|
|
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::WiredSetting>();
|
|
|
|
NetworkManager::WirelessSetting::Ptr connWirelessSetting = connSettings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>();
|
|
|
|
|
|
|
|
if (settings["connName"].isValid()) {
|
|
|
|
connSettings->setId(settings["connName"].toString());
|
|
|
|
}
|
|
|
|
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<QString, QString>());
|
|
|
|
} 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());
|
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray macBin = NetworkManager::macAddressFromString(settings["clonedMacAddress"].toString());
|
|
|
|
if (settings["clonedMacAddress"].toString().length() != 17) {
|
|
|
|
wipeClonedMacAddress = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!connWiredSetting.isNull()) {
|
|
|
|
if (!wipeClonedMacAddress) {
|
|
|
|
connWiredSetting->setClonedMacAddress(macBin);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings["mtu"].isValid()) {
|
|
|
|
connWiredSetting->setMtu(settings["mtu"].toUInt());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings["autoLinkNegotiation"].isValid()) {
|
|
|
|
if (settings["autoLinkNegotiation"].toInt() == ConnectionSettingsEngine::NegotiationAutomatic) {
|
|
|
|
connWiredSetting->setAutoNegotiate(true);
|
|
|
|
connWiredSetting->setSpeed(0);
|
|
|
|
connWiredSetting->setDuplexType(NetworkManager::WiredSetting::UnknownDuplexType);
|
|
|
|
} else if (settings["autoLinkNegotiation"].toInt() == ConnectionSettingsEngine::NegotiationManual) {
|
|
|
|
connWiredSetting->setAutoNegotiate(false);
|
|
|
|
switch (settings["linkSpeed"].toInt()) {
|
|
|
|
case ConnectionSettingsEngine::Speed10Mbps:
|
|
|
|
connWiredSetting->setSpeed(10);
|
|
|
|
break;
|
|
|
|
case ConnectionSettingsEngine::Speed100Mbps:
|
|
|
|
connWiredSetting->setSpeed(100);
|
|
|
|
break;
|
|
|
|
case ConnectionSettingsEngine::Speed1Gbps:
|
|
|
|
connWiredSetting->setSpeed(1000);
|
|
|
|
break;
|
|
|
|
case ConnectionSettingsEngine::Speed2_5Gbps:
|
|
|
|
connWiredSetting->setSpeed(2500);
|
|
|
|
break;
|
|
|
|
case ConnectionSettingsEngine::Speed5Gbps:
|
|
|
|
connWiredSetting->setSpeed(5000);
|
|
|
|
break;
|
|
|
|
case ConnectionSettingsEngine::Speed10Gbps:
|
|
|
|
connWiredSetting->setSpeed(10000);
|
|
|
|
break;
|
|
|
|
case ConnectionSettingsEngine::Speed40Gbps:
|
|
|
|
connWiredSetting->setSpeed(40000);
|
|
|
|
break;
|
|
|
|
case ConnectionSettingsEngine::Speed100Gbps:
|
|
|
|
connWiredSetting->setSpeed(100000);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (settings["duplexMode"].toInt()) {
|
|
|
|
case ConnectionSettingsEngine::DuplexUnknown:
|
|
|
|
connWiredSetting->setDuplexType(NetworkManager::WiredSetting::UnknownDuplexType);
|
|
|
|
break;
|
|
|
|
case ConnectionSettingsEngine::DuplexHalf:
|
|
|
|
connWiredSetting->setDuplexType(NetworkManager::WiredSetting::Half);
|
|
|
|
break;
|
|
|
|
case ConnectionSettingsEngine::DuplexFull:
|
|
|
|
connWiredSetting->setDuplexType(NetworkManager::WiredSetting::Full);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
connWiredSetting->setAutoNegotiate(false);
|
|
|
|
connWiredSetting->setSpeed(0);
|
|
|
|
connWiredSetting->setDuplexType(NetworkManager::WiredSetting::UnknownDuplexType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (!connWirelessSetting.isNull()) {
|
|
|
|
if (!wipeClonedMacAddress) {
|
|
|
|
connWirelessSetting->setClonedMacAddress(macBin);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings["mtu"].isValid()) {
|
|
|
|
connWirelessSetting->setMtu(settings["mtu"].toUInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: pick up here
|
|
|
|
|
|
|
|
targetConnUuidStr = connUuidStr;
|
|
|
|
QDBusPendingReply<> reply = conn->update(connSettings->toMap());
|
|
|
|
auto watcher = new QDBusPendingCallWatcher(reply);
|
|
|
|
QObject::connect(watcher, &QDBusPendingCallWatcher::finished, saveReplyFinished);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionSettingsEngine::saveReplyFinished()
|
|
|
|
{
|
|
|
|
NetworkManager::Connection::Ptr conn = NetworkManager::findConnectionByUuid(targetConnUuidStr);
|
|
|
|
NetworkManager::ConnectionSettings::Ptr connSettings = conn->settings();
|
|
|
|
NetworkManager::WiredSetting::Ptr connWiredSetting = connSettings->setting(NetworkManager::Setting::Wired).dynamicCast<NetworkManager::WiredSetting>();
|
|
|
|
NetworkManager::WirelessSetting::Ptr connWirelessSetting = connSettings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>();
|
|
|
|
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());
|
|
|
|
}
|