diff --git a/libs/editor/connectioneditorbase.cpp b/libs/editor/connectioneditorbase.cpp index e5d28cc3..72f75cb4 100644 --- a/libs/editor/connectioneditorbase.cpp +++ b/libs/editor/connectioneditorbase.cpp @@ -1,485 +1,486 @@ /* Copyright 2013-2016 Jan Grulich Copyright 2013, 2014 Lukas Tinkl This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "connectioneditorbase.h" #include "debug.h" #include "settings/bondwidget.h" #include "settings/bridgewidget.h" #include "settings/btwidget.h" #include "settings/cdmawidget.h" #include "settings/connectionwidget.h" #include "settings/gsmwidget.h" #include "settings/infinibandwidget.h" #include "settings/ipv4widget.h" #include "settings/ipv6widget.h" #include "settings/pppwidget.h" #include "settings/pppoewidget.h" #include "settings/teamwidget.h" #include "settings/vlanwidget.h" #include "settings/wificonnectionwidget.h" #include "settings/wifisecurity.h" #include "settings/wiredconnectionwidget.h" #include "settings/wiredsecurity.h" #include "vpnuiplugin.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include ConnectionEditorBase::ConnectionEditorBase(const NetworkManager::ConnectionSettings::Ptr &connection, QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) , m_initialized(false) , m_valid(false) , m_pendingReplies(0) , m_connection(connection) { } ConnectionEditorBase::ConnectionEditorBase(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { } ConnectionEditorBase::~ConnectionEditorBase() { m_connection.clear(); } void ConnectionEditorBase::setConnection(const NetworkManager::ConnectionSettings::Ptr &connection) { // Set connection settings m_connection.clear(); m_connection = connection; m_initialized = false; // Reset UI setting widgets delete m_connectionWidget; m_connectionWidget = nullptr; qDeleteAll(m_settingWidgets); m_settingWidgets.clear(); initialize(); } NMVariantMapMap ConnectionEditorBase::setting() const { NMVariantMapMap settings = m_connectionWidget->setting(); for (SettingWidget *widget : m_settingWidgets) { const QString type = widget->type(); if (type != NetworkManager::Setting::typeAsString(NetworkManager::Setting::Security8021x) && type != NetworkManager::Setting::typeAsString(NetworkManager::Setting::WirelessSecurity)) { settings.insert(type, widget->setting()); } // add 802.1x security if needed QVariantMap security8021x; if (type == NetworkManager::Setting::typeAsString(NetworkManager::Setting::WirelessSecurity)) { WifiSecurity *wifiSecurity = static_cast(widget); if (wifiSecurity->enabled()) { settings.insert(type, wifiSecurity->setting()); } if (wifiSecurity->enabled8021x()) { security8021x = static_cast(widget)->setting8021x(); settings.insert(NetworkManager::Setting::typeAsString(NetworkManager::Setting::Security8021x), security8021x); } } else if (type == NetworkManager::Setting::typeAsString(NetworkManager::Setting::Security8021x)) { WiredSecurity *wiredSecurity = static_cast(widget); if (wiredSecurity->enabled8021x()) { security8021x = static_cast(widget)->setting(); settings.insert(NetworkManager::Setting::typeAsString(NetworkManager::Setting::Security8021x), security8021x); } } } // Set properties which are not returned from setting widgets NetworkManager::ConnectionSettings::Ptr connectionSettings = NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(m_connection->connectionType())); connectionSettings->fromMap(settings); connectionSettings->setId(connectionName()); connectionSettings->setUuid(m_connection->uuid()); if (connectionSettings->connectionType() == NetworkManager::ConnectionSettings::Wireless) { NetworkManager::WirelessSecuritySetting::Ptr securitySetting = connectionSettings->setting(NetworkManager::Setting::WirelessSecurity).staticCast(); NetworkManager::WirelessSetting::Ptr wirelessSetting = connectionSettings->setting(NetworkManager::Setting::Wireless).staticCast(); if (securitySetting && wirelessSetting) { if (securitySetting->keyMgmt() != NetworkManager::WirelessSecuritySetting::WirelessSecuritySetting::Unknown) { wirelessSetting->setSecurity("802-11-wireless-security"); } } } return connectionSettings->toMap(); } bool ConnectionEditorBase::isInitialized() const { return m_initialized; } bool ConnectionEditorBase::isValid() const { return m_valid; } void ConnectionEditorBase::addConnectionWidget(ConnectionWidget *widget, const QString &text) { m_connectionWidget = widget; connect(widget, &ConnectionWidget::settingChanged, this, &ConnectionEditorBase::settingChanged); addWidget(widget, text); } void ConnectionEditorBase::addSettingWidget(SettingWidget *widget, const QString &text) { m_settingWidgets << widget; connect(widget, &SettingWidget::settingChanged, this, &ConnectionEditorBase::settingChanged); addWidget(widget, text); } void ConnectionEditorBase::initialize() { const bool emptyConnection = m_connection->id().isEmpty(); const NetworkManager::ConnectionSettings::ConnectionType type = m_connection->connectionType(); if (emptyConnection) { m_connection->addToPermissions(KUser().loginName(), QString()); } // General configuration common to all connection types ConnectionWidget *connectionWidget = new ConnectionWidget(m_connection); addConnectionWidget(connectionWidget, i18nc("General", "General configuration")); // Add the rest of widgets QString serviceType; if (type == NetworkManager::ConnectionSettings::Wired) { WiredConnectionWidget *wiredWidget = new WiredConnectionWidget(m_connection->setting(NetworkManager::Setting::Wired), this); addSettingWidget(wiredWidget, i18n("Wired")); WiredSecurity *wiredSecurity = new WiredSecurity(m_connection->setting(NetworkManager::Setting::Security8021x).staticCast(), this); addSettingWidget(wiredSecurity, i18n("802.1x Security")); } else if (type == NetworkManager::ConnectionSettings::Wireless) { WifiConnectionWidget *wifiWidget = new WifiConnectionWidget(m_connection->setting(NetworkManager::Setting::Wireless), this); addSettingWidget(wifiWidget, i18n("Wi-Fi")); WifiSecurity *wifiSecurity = new WifiSecurity(m_connection->setting(NetworkManager::Setting::WirelessSecurity), m_connection->setting(NetworkManager::Setting::Security8021x).staticCast(), this); addSettingWidget(wifiSecurity, i18n("Wi-Fi Security")); connect(wifiWidget, QOverload::of(&WifiConnectionWidget::ssidChanged), wifiSecurity, &WifiSecurity::onSsidChanged); } else if (type == NetworkManager::ConnectionSettings::Pppoe) { // DSL PppoeWidget *pppoeWidget = new PppoeWidget(m_connection->setting(NetworkManager::Setting::Pppoe), this); addSettingWidget(pppoeWidget, i18n("DSL")); WiredConnectionWidget *wiredWidget = new WiredConnectionWidget(m_connection->setting(NetworkManager::Setting::Wired), this); addSettingWidget(wiredWidget, i18n("Wired")); } else if (type == NetworkManager::ConnectionSettings::Gsm) { // GSM GsmWidget *gsmWidget = new GsmWidget(m_connection->setting(NetworkManager::Setting::Gsm), this); addSettingWidget(gsmWidget, i18n("Mobile Broadband (%1)", m_connection->typeAsString(m_connection->connectionType()))); } else if (type == NetworkManager::ConnectionSettings::Cdma) { // CDMA CdmaWidget *cdmaWidget = new CdmaWidget(m_connection->setting(NetworkManager::Setting::Cdma), this); addSettingWidget(cdmaWidget, i18n("Mobile Broadband (%1)", m_connection->typeAsString(m_connection->connectionType()))); } else if (type == NetworkManager::ConnectionSettings::Bluetooth) { // Bluetooth BtWidget *btWidget = new BtWidget(m_connection->setting(NetworkManager::Setting::Bluetooth), this); addSettingWidget(btWidget, i18n("Bluetooth")); NetworkManager::BluetoothSetting::Ptr btSetting = m_connection->setting(NetworkManager::Setting::Bluetooth).staticCast(); if (btSetting->profileType() == NetworkManager::BluetoothSetting::Dun) { GsmWidget *gsmWidget = new GsmWidget(m_connection->setting(NetworkManager::Setting::Gsm), this); addSettingWidget(gsmWidget, i18n("GSM")); PPPWidget *pppWidget = new PPPWidget(m_connection->setting(NetworkManager::Setting::Ppp), this); addSettingWidget(pppWidget, i18n("PPP")); } } else if (type == NetworkManager::ConnectionSettings::Infiniband) { // Infiniband InfinibandWidget *infinibandWidget = new InfinibandWidget(m_connection->setting(NetworkManager::Setting::Infiniband), this); addSettingWidget(infinibandWidget, i18n("Infiniband")); } else if (type == NetworkManager::ConnectionSettings::Bond) { // Bond BondWidget *bondWidget = new BondWidget(m_connection->uuid(), m_connection->setting(NetworkManager::Setting::Bond), this); addSettingWidget(bondWidget, i18n("Bond")); } else if (type == NetworkManager::ConnectionSettings::Bridge) { // Bridge BridgeWidget *bridgeWidget = new BridgeWidget(m_connection->uuid(), m_connection->setting(NetworkManager::Setting::Bridge), this); addSettingWidget(bridgeWidget, i18n("Bridge")); } else if (type == NetworkManager::ConnectionSettings::Vlan) { // Vlan VlanWidget *vlanWidget = new VlanWidget(m_connection->setting(NetworkManager::Setting::Vlan), this); addSettingWidget(vlanWidget, i18n("Vlan")); } else if (type == NetworkManager::ConnectionSettings::Team) { // Team TeamWidget *teamWidget = new TeamWidget(m_connection->uuid(), m_connection->setting(NetworkManager::Setting::Team), this); addSettingWidget(teamWidget, i18n("Team")); } else if (type == NetworkManager::ConnectionSettings::Vpn) { // VPN QString error; VpnUiPlugin *vpnPlugin = nullptr; NetworkManager::VpnSetting::Ptr vpnSetting = m_connection->setting(NetworkManager::Setting::Vpn).staticCast(); if (!vpnSetting) { qCWarning(PLASMA_NM) << "Missing VPN setting!"; } else { serviceType = vpnSetting->serviceType(); vpnPlugin = KServiceTypeTrader::createInstanceFromQuery(QString::fromLatin1("PlasmaNetworkManagement/VpnUiPlugin"), QString::fromLatin1("[X-NetworkManager-Services]=='%1'").arg(serviceType), this, QVariantList(), &error); if (vpnPlugin && error.isEmpty()) { const QString shortName = serviceType.section('.', -1); SettingWidget *vpnWidget = vpnPlugin->widget(vpnSetting, this); addSettingWidget(vpnWidget, i18n("VPN (%1)", shortName)); } else { qCWarning(PLASMA_NM) << error << ", serviceType == " << serviceType; } } } // PPP widget if (type == NetworkManager::ConnectionSettings::Pppoe || type == NetworkManager::ConnectionSettings::Cdma || type == NetworkManager::ConnectionSettings::Gsm) { PPPWidget *pppWidget = new PPPWidget(m_connection->setting(NetworkManager::Setting::Ppp), this); addSettingWidget(pppWidget, i18n("PPP")); } // IPv4 widget if (!m_connection->isSlave()) { IPv4Widget *ipv4Widget = new IPv4Widget(m_connection->setting(NetworkManager::Setting::Ipv4), this); addSettingWidget(ipv4Widget, i18n("IPv4")); } // IPv6 widget if ((type == NetworkManager::ConnectionSettings::Wired || type == NetworkManager::ConnectionSettings::Wireless || type == NetworkManager::ConnectionSettings::Infiniband || type == NetworkManager::ConnectionSettings::Team || type == NetworkManager::ConnectionSettings::Cdma || type == NetworkManager::ConnectionSettings::Gsm || type == NetworkManager::ConnectionSettings::Bond || type == NetworkManager::ConnectionSettings::Bridge || type == NetworkManager::ConnectionSettings::Vlan - || (type == NetworkManager::ConnectionSettings::Vpn && serviceType == QLatin1String("org.freedesktop.NetworkManager.openvpn"))) && !m_connection->isSlave()) { + || (type == NetworkManager::ConnectionSettings::Vpn && serviceType == QLatin1String("org.freedesktop.NetworkManager.openvpn")) + || (type == NetworkManager::ConnectionSettings::Vpn && serviceType == QLatin1String("org.freedesktop.NetworkManager.wireguard"))) && !m_connection->isSlave()) { IPv6Widget *ipv6Widget = new IPv6Widget(m_connection->setting(NetworkManager::Setting::Ipv6), this); addSettingWidget(ipv6Widget, i18n("IPv6")); } // Re-check validation bool valid = true; for (SettingWidget *widget : m_settingWidgets) { valid = valid && widget->isValid(); connect(widget, &SettingWidget::validChanged, this, &ConnectionEditorBase::validChanged); } m_valid = valid; Q_EMIT validityChanged(valid); KAcceleratorManager::manage(this); // If the connection is not empty (not new) we want to load its secrets if (!emptyConnection) { NetworkManager::Connection::Ptr connection = NetworkManager::findConnectionByUuid(m_connection->uuid()); if (connection) { QStringList requiredSecrets; QString settingName; QVariantMap setting; QDBusPendingReply reply; if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Adsl) { NetworkManager::AdslSetting::Ptr adslSetting = connection->settings()->setting(NetworkManager::Setting::Adsl).staticCast(); if (adslSetting && !adslSetting->needSecrets().isEmpty()) { requiredSecrets = adslSetting->needSecrets(); setting = adslSetting->toMap(); settingName = QLatin1String("adsl"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Bluetooth) { NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).staticCast(); if (gsmSetting && !gsmSetting->needSecrets().isEmpty()) { requiredSecrets = gsmSetting->needSecrets(); setting = gsmSetting->toMap(); settingName = QLatin1String("gsm"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Cdma) { NetworkManager::CdmaSetting::Ptr cdmaSetting = connection->settings()->setting(NetworkManager::Setting::Cdma).staticCast(); if (cdmaSetting && !cdmaSetting->needSecrets().isEmpty()) { requiredSecrets = cdmaSetting->needSecrets(); setting = cdmaSetting->toMap(); settingName = QLatin1String("cdma"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Gsm) { NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).staticCast(); if (gsmSetting && !gsmSetting->needSecrets().isEmpty()) { requiredSecrets = gsmSetting->needSecrets(); setting = gsmSetting->toMap(); settingName = QLatin1String("gsm"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Pppoe) { NetworkManager::PppoeSetting::Ptr pppoeSetting = connection->settings()->setting(NetworkManager::Setting::Pppoe).staticCast(); if (pppoeSetting && !pppoeSetting->needSecrets().isEmpty()) { requiredSecrets = pppoeSetting->needSecrets(); setting = pppoeSetting->toMap(); settingName = QLatin1String("pppoe"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Wired) { NetworkManager::Security8021xSetting::Ptr securitySetting = connection->settings()->setting(NetworkManager::Setting::Security8021x).staticCast(); if (securitySetting && !securitySetting->needSecrets().isEmpty()) { requiredSecrets = securitySetting->needSecrets(); setting = securitySetting->toMap(); settingName = QLatin1String("802-1x"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Wireless) { NetworkManager::WirelessSecuritySetting::Ptr wifiSecuritySetting = connection->settings()->setting(NetworkManager::Setting::WirelessSecurity).staticCast(); if (wifiSecuritySetting && (wifiSecuritySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::WpaEap || (wifiSecuritySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::WirelessSecuritySetting::Ieee8021x && wifiSecuritySetting->authAlg() != NetworkManager::WirelessSecuritySetting::Leap))) { NetworkManager::Security8021xSetting::Ptr securitySetting = connection->settings()->setting(NetworkManager::Setting::Security8021x).staticCast(); if (securitySetting && !securitySetting->needSecrets().isEmpty()) { requiredSecrets = securitySetting->needSecrets(); setting = securitySetting->toMap(); settingName = QLatin1String("802-1x"); if (requiredSecrets.contains(NM_SETTING_802_1X_PASSWORD_RAW)) { requiredSecrets.removeAll(NM_SETTING_802_1X_PASSWORD_RAW); } } } else { if (!wifiSecuritySetting->needSecrets().isEmpty()) { requiredSecrets = wifiSecuritySetting->needSecrets(); setting = wifiSecuritySetting->toMap(); settingName = QLatin1String("802-11-wireless-security"); } } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Vpn) { settingName = QLatin1String("vpn"); } if (!requiredSecrets.isEmpty() || m_connection->connectionType() == NetworkManager::ConnectionSettings::Vpn) { bool requestSecrets = false; if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Vpn) { NetworkManager::VpnSetting::Ptr vpnSetting = connection->settings()->setting(NetworkManager::Setting::Vpn).staticCast(); for (const QString &key : vpnSetting->data().keys()) { if (key.endsWith(QStringLiteral("-flags"))) { NetworkManager::Setting::SecretFlagType secretFlag = (NetworkManager::Setting::SecretFlagType)vpnSetting->data().value(key).toInt(); if (secretFlag == NetworkManager::Setting::None || secretFlag == NetworkManager::Setting::AgentOwned) { requestSecrets = true; } } } } else { for (const QString &secret : requiredSecrets) { if (setting.contains(secret + QLatin1String("-flags"))) { NetworkManager::Setting::SecretFlagType secretFlag = (NetworkManager::Setting::SecretFlagType)setting.value(secret + QLatin1String("-flags")).toInt(); if (secretFlag == NetworkManager::Setting::None || secretFlag == NetworkManager::Setting::AgentOwned) { requestSecrets = true; } } else { requestSecrets = true; } } } if (requestSecrets) { m_pendingReplies++; reply = connection->secrets(settingName); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); watcher->setProperty("connection", connection->name()); watcher->setProperty("settingName", settingName); connect(watcher, &QDBusPendingCallWatcher::finished, this, &ConnectionEditorBase::replyFinished); m_valid = false; Q_EMIT validityChanged(false); return; } } } } // We should be now fully initialized as we don't wait for secrets if (m_pendingReplies == 0) { m_initialized = true; } } void ConnectionEditorBase::replyFinished(QDBusPendingCallWatcher *watcher) { QDBusPendingReply reply = *watcher; const QString settingName = watcher->property("settingName").toString(); if (reply.isValid()) { NMVariantMapMap secrets = reply.argumentAt<0>(); for (const QString &key : secrets.keys()) { if (key == settingName) { NetworkManager::Setting::Ptr setting = m_connection->setting(NetworkManager::Setting::typeFromString(key)); if (setting) { setting->secretsFromMap(secrets.value(key)); for (SettingWidget *widget : m_settingWidgets) { const QString type = widget->type(); if (type == settingName || (settingName == NetworkManager::Setting::typeAsString(NetworkManager::Setting::Security8021x) && type == NetworkManager::Setting::typeAsString(NetworkManager::Setting::WirelessSecurity))) { widget->loadSecrets(setting); } } } } } } else { KNotification *notification = new KNotification("FailedToGetSecrets", KNotification::CloseOnTimeout); notification->setComponentName("networkmanagement"); notification->setTitle(i18n("Failed to get secrets for %1", watcher->property("connection").toString())); notification->setText(reply.error().message()); notification->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(KIconLoader::SizeHuge)); notification->sendEvent(); } watcher->deleteLater(); validChanged(true); // We should be now fully with secrets m_pendingReplies--; m_initialized = true; } void ConnectionEditorBase::validChanged(bool valid) { if (!valid) { m_valid = false; Q_EMIT validityChanged(false); return; } else { for (SettingWidget *widget : m_settingWidgets) { if (!widget->isValid()) { m_valid = false; Q_EMIT validityChanged(false); return; } } } m_valid = true; Q_EMIT validityChanged(true); } diff --git a/vpn/wireguard/wireguard.cpp b/vpn/wireguard/wireguard.cpp index 51ef09b1..534e09ce 100644 --- a/vpn/wireguard/wireguard.cpp +++ b/vpn/wireguard/wireguard.cpp @@ -1,375 +1,426 @@ /* Copyright 2018 Bruce Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "wireguard.h" #include #include #include #include #include #include #include #include +#include #include "wireguardwidget.h" #include "wireguardauth.h" #include "simpleipv4addressvalidator.h" #include "simpleipv6addressvalidator.h" #include "simpleiplistvalidator.h" #include "wireguardkeyvalidator.h" #include "nm-wireguard-service.h" K_PLUGIN_CLASS_WITH_JSON(WireGuardUiPlugin, "plasmanetworkmanagement_wireguardui.json") #define NMV_WG_TAG_INTERFACE "Interface" #define NMV_WG_TAG_PRIVATE_KEY "PrivateKey" #define NMV_WG_TAG_LISTEN_PORT "ListenPort" #define NMV_WG_TAG_ADDRESS "Address" #define NMV_WG_TAG_DNS "DNS" #define NMV_WG_TAG_MTU "MTU" #define NMV_WG_TAG_TABLE "Table" #define NMV_WG_TAG_PRE_UP "PreUp" #define NMV_WG_TAG_POST_UP "PostUp" #define NMV_WG_TAG_PRE_DOWN "PreDown" #define NMV_WG_TAG_POST_DOWN "PostDown" #define NMV_WG_TAG_FWMARK "FwMark" #define NMV_WG_TAG_PEER "Peer" #define NMV_WG_TAG_PUBLIC_KEY "PublicKey" #define NMV_WG_TAG_ALLOWED_IPS "AllowedIPs" #define NMV_WG_TAG_ENDPOINT "Endpoint" #define NMV_WG_TAG_PRESHARED_KEY "PresharedKey" #define NMV_WG_TAG_PERSISTENT_KEEPALIVE "PersistentKeepalive" WireGuardUiPlugin::WireGuardUiPlugin(QObject *parent, const QVariantList &) : VpnUiPlugin(parent) { } WireGuardUiPlugin::~WireGuardUiPlugin() { } SettingWidget *WireGuardUiPlugin::widget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent) { return new WireGuardSettingWidget(setting, parent); } SettingWidget *WireGuardUiPlugin::askUser(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent) { return new WireGuardAuthWidget(setting, parent); } QString WireGuardUiPlugin::suggestedFileName(const NetworkManager::ConnectionSettings::Ptr &connection) const { return connection->id() + "_wireguard.conf"; } QString WireGuardUiPlugin::supportedFileExtensions() const { return "*.conf"; } NMVariantMapMap WireGuardUiPlugin::importConnectionSettings(const QString &fileName) { NMVariantMapMap result; const KConfig importFile(fileName, KConfig::NoGlobals); const KConfigGroup interfaceGroup = importFile.group(NMV_WG_TAG_INTERFACE); const KConfigGroup peerGroup = importFile.group(NMV_WG_TAG_PEER); // The config file must have both [Interface] and [Peer] sections if (!interfaceGroup.exists() || !peerGroup.exists()) { mError = VpnUiPlugin::Error; mErrorMessage = i18n("Config file needs both [Peer] and [Interface]"); return result; } const QString connectionName = QFileInfo(fileName).completeBaseName(); NMStringMap dataMap; QVariantMap ipv4Data; + QVariantMap ipv6Data; QString value; QStringList valueList; + QList ipv4List; + QList ipv6List; int intValue; + NetworkManager::Ipv4Setting ipv4Setting; + NetworkManager::Ipv6Setting ipv6Setting; + // Do the required fields first and fail (i.e. return an empty result) if not present // Addresses valueList = interfaceGroup.readEntry(NMV_WG_TAG_ADDRESS, QStringList()); if (valueList.isEmpty()) { mError = VpnUiPlugin::Error; mErrorMessage = i18n("No address in config file"); return result; } for (const QString &address : valueList) { const QPair addressIn = QHostAddress::parseSubnet(address.trimmed()); if (addressIn.first.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv4Protocol) { dataMap.insert(QLatin1String(NM_WG_KEY_ADDR_IP4), address); } else if (addressIn.first.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv6Protocol) { dataMap.insert(QLatin1String(NM_WG_KEY_ADDR_IP6), address); } else { // Error condition mError = VpnUiPlugin::Error; mErrorMessage = i18n("No valid address in config file"); return result; } } WireGuardKeyValidator keyValidator(nullptr); int pos = 0; // Private Key value = interfaceGroup.readEntry(NMV_WG_TAG_PRIVATE_KEY); if (!value.isEmpty()) { if (keyValidator.validate(value, pos) == QValidator::State::Acceptable) { dataMap.insert(QLatin1String(NM_WG_KEY_PRIVATE_KEY), value); } else { mError = VpnUiPlugin::Error; mErrorMessage = i18n("No valid Private Key in config file"); return result; } } else { mError = VpnUiPlugin::Error; mErrorMessage = i18n("No Private Key in config file"); return result; } // Public Key value = peerGroup.readEntry(NMV_WG_TAG_PUBLIC_KEY); if (!value.isEmpty()) { if (keyValidator.validate(value, pos) == QValidator::State::Acceptable) { dataMap.insert(QLatin1String(NM_WG_KEY_PUBLIC_KEY), value); } else { mError = VpnUiPlugin::Error; mErrorMessage = i18n("No valid Public Key in config file"); return result; } } else { mError = VpnUiPlugin::Error; mErrorMessage = i18n("No Public Key in config file"); return result; } // Allowed IPs value = peerGroup.readEntry(NMV_WG_TAG_ALLOWED_IPS); if (!value.isEmpty()) { SimpleIpListValidator validator(this, SimpleIpListValidator::WithCidr, SimpleIpListValidator::Both); if (validator.validate(value, pos) != QValidator::State::Invalid) { dataMap.insert(QLatin1String(NM_WG_KEY_ALLOWED_IPS), value); } else { mError = VpnUiPlugin::Error; mErrorMessage = i18n("Invalid Allowed IP in config file"); return result; } } else { mError = VpnUiPlugin::Error; mErrorMessage = i18n("No Allowed IPs in config file"); return result; } // Now the optional ones // Listen Port intValue = interfaceGroup.readEntry(NMV_WG_TAG_LISTEN_PORT, 0); if (intValue > 0) { if (intValue < 65536) { dataMap.insert(QLatin1String(NM_WG_KEY_LISTEN_PORT), QString::number(intValue)); } else { mError = VpnUiPlugin::Error; mErrorMessage = i18n("Invalid Listen Port in config file"); return result; } } - // DNS - value = interfaceGroup.readEntry(NMV_WG_TAG_DNS); - if (!value.isEmpty()) { - const QHostAddress testAddress(value); - if (testAddress.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv4Protocol - || testAddress.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv6Protocol) { - dataMap.insert(QLatin1String(NM_WG_KEY_DNS), value); - } else { - mError = VpnUiPlugin::Error; - mErrorMessage = i18n("Invalid DNS in config file"); - return result; + // DNS servers are added slightly differently in that they are not added + // to the [vpn] section of the setup but to the [ipv4] and/or [ipv6] + // sections. + valueList = interfaceGroup.readEntry(NMV_WG_TAG_DNS, QStringList()); + if (!valueList.isEmpty()) { + for (const QString &address : valueList) { + const QPair addressIn = QHostAddress::parseSubnet(address.trimmed()); + if (addressIn.first.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv4Protocol) { + ipv4List.append(addressIn.first); + } else if (addressIn.first.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv6Protocol) { + ipv6List.append(addressIn.first); + } else { // Error condition + mError = VpnUiPlugin::Error; + mErrorMessage = i18n("No valid address in config file"); + return result; + } + } + + // If there are any addresses put them on the correct tab and set the "method" to + // "Automatic (Only addresses)" by setting "ignore-auto-dns=true" + if (!ipv4List.isEmpty()) { + ipv4Setting.setMethod(NetworkManager::Ipv4Setting::Automatic); + ipv4Setting.setIgnoreAutoDns(true); + ipv4Setting.setDns(ipv4List); + } + + if (!ipv6List.isEmpty()) { + ipv6Setting.setMethod(NetworkManager::Ipv6Setting::Automatic); + ipv6Setting.setIgnoreAutoDns(true); + ipv6Setting.setDns(ipv6List); } } // MTU intValue = interfaceGroup.readEntry(NMV_WG_TAG_MTU, 0); if (intValue > 0) dataMap.insert(QLatin1String(NM_WG_KEY_LISTEN_PORT), QString::number(intValue)); // Table value = interfaceGroup.readEntry(NMV_WG_TAG_TABLE); if (!value.isEmpty()) dataMap.insert(QLatin1String(NM_WG_KEY_TABLE), value); // PreUp value = interfaceGroup.readEntry(NMV_WG_TAG_PRE_UP); if (!value.isEmpty()) dataMap.insert(QLatin1String(NM_WG_KEY_PRE_UP), value); // PostUp value = interfaceGroup.readEntry(NMV_WG_TAG_POST_UP); if (!value.isEmpty()) dataMap.insert(QLatin1String(NM_WG_KEY_POST_UP), value); // PreDown value = interfaceGroup.readEntry(NMV_WG_TAG_PRE_DOWN); if (!value.isEmpty()) dataMap.insert(QLatin1String(NM_WG_KEY_PRE_DOWN), value); // PostDown value = interfaceGroup.readEntry(NMV_WG_TAG_POST_DOWN); if (!value.isEmpty()) dataMap.insert(QLatin1String(NM_WG_KEY_POST_DOWN), value); // Endpoint value = peerGroup.readEntry(NMV_WG_TAG_ENDPOINT); if (!value.isEmpty()) dataMap.insert(QLatin1String(NM_WG_KEY_ENDPOINT), value); // Preshared Key value = peerGroup.readEntry(NMV_WG_TAG_PRESHARED_KEY); if (!value.isEmpty()) { if (keyValidator.validate(value, pos) == QValidator::State::Acceptable) { dataMap.insert(QLatin1String(NM_WG_KEY_PRESHARED_KEY), value); } else { mError = VpnUiPlugin::Error; mErrorMessage = i18n("Invalid Preshared Key in config file"); return result; } } // Persistent Keepalive intValue = peerGroup.readEntry(NMV_WG_TAG_PERSISTENT_KEEPALIVE, -1); if (intValue > -1) dataMap.insert(QLatin1String(NM_WG_KEY_PERSISTENT_KEEPALIVE), QString::number(intValue)); NetworkManager::VpnSetting setting; setting.setServiceType(QLatin1String(NM_DBUS_SERVICE_WIREGUARD)); setting.setData(dataMap); QVariantMap conn; conn.insert("id", connectionName); conn.insert("type", "vpn"); result.insert("connection", conn); result.insert("vpn", setting.toMap()); + if (!ipv4List.isEmpty()) { + result.insert("ipv4", ipv4Setting.toMap()); + } + if (!ipv6List.isEmpty()) { + result.insert("ipv6", ipv6Setting.toMap()); + } return result; } bool WireGuardUiPlugin::exportConnectionSettings(const NetworkManager::ConnectionSettings::Ptr &connection, const QString &fileName) { NetworkManager::VpnSetting::Ptr vpnSetting = connection->setting( NetworkManager::Setting::Vpn).dynamicCast(); + NetworkManager::Ipv4Setting::Ptr ipv4Setting = connection->setting( + NetworkManager::Setting::Ipv4).dynamicCast(); + NetworkManager::Ipv6Setting::Ptr ipv6Setting = connection->setting( + NetworkManager::Setting::Ipv6).dynamicCast(); + QList ipv4Dns = ipv4Setting->dns(); + QList ipv6Dns = ipv6Setting->dns(); NMStringMap dataMap = vpnSetting->data(); // Make sure all the required fields are present if (!(dataMap.contains(QLatin1String(NM_WG_KEY_ADDR_IP4)) || dataMap.contains(QLatin1String(NM_WG_KEY_ADDR_IP6))) || !dataMap.contains(QLatin1String(NM_WG_KEY_PRIVATE_KEY)) || !dataMap.contains(QLatin1String(NM_WG_KEY_PUBLIC_KEY)) || !dataMap.contains(QLatin1String(NM_WG_KEY_ALLOWED_IPS))) return false; // Open the output file KConfig exportFile(fileName, KConfig::NoGlobals); KConfigGroup interfaceGroup = exportFile.group(NMV_WG_TAG_INTERFACE); KConfigGroup peerGroup = exportFile.group(NMV_WG_TAG_PEER); QStringList outputList; if (dataMap.contains(QLatin1String(NM_WG_KEY_ADDR_IP4))) outputList.append(dataMap[NM_WG_KEY_ADDR_IP4]); if (dataMap.contains(QLatin1String(NM_WG_KEY_ADDR_IP6))) outputList.append(dataMap[NM_WG_KEY_ADDR_IP6]); interfaceGroup.writeEntry(NMV_WG_TAG_ADDRESS, outputList); // Do Private Key interfaceGroup.writeEntry(NMV_WG_TAG_PRIVATE_KEY, dataMap[NM_WG_KEY_PRIVATE_KEY]); // Do DNS (Not required) - if (dataMap.contains(QLatin1String(NM_WG_KEY_DNS))) + // DNS is a little complicated because the first version of plasma-nm-wireguard included + // the DNS key in the VPN settings but this was changed in a later version such that it + // uses DNS from the IPv4 and IPv6 tabs instead, so here we check to see if the IPv4 and/or + // the IPv6 tabs contain DNS entries and if so use those. Otherwise see if we have an + // old style VPN setting with DNS in it and if so use that. + if (ipv4Dns.count() > 0 || ipv6Dns.count() > 0) { + QStringList dnsList; + for (QHostAddress addr : ipv4Dns) + dnsList.append(addr.toString()); + for (QHostAddress addr : ipv6Dns) + dnsList.append(addr.toString()); + interfaceGroup.writeEntry(NMV_WG_TAG_DNS, dnsList); + } else if (dataMap.contains(QLatin1String(NM_WG_KEY_DNS))) { interfaceGroup.writeEntry(NMV_WG_TAG_DNS, dataMap[NM_WG_KEY_DNS]); + } // Do MTU (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_MTU))) interfaceGroup.writeEntry(NMV_WG_TAG_MTU, dataMap[NM_WG_KEY_MTU]); // Do Table number (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_TABLE))) interfaceGroup.writeEntry(NMV_WG_TAG_TABLE, dataMap[NM_WG_KEY_TABLE]); // Do Listen Port (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_LISTEN_PORT))) interfaceGroup.writeEntry(NMV_WG_TAG_LISTEN_PORT, dataMap[NM_WG_KEY_LISTEN_PORT]); // Do FwMark (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_FWMARK))) interfaceGroup.writeEntry(NMV_WG_TAG_FWMARK, dataMap[NM_WG_KEY_FWMARK]); // Do PreUp (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_PRE_UP))) interfaceGroup.writeEntry(NMV_WG_TAG_PRE_UP, dataMap[NM_WG_KEY_PRE_UP]); // Do PostUp (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_POST_UP))) interfaceGroup.writeEntry(NMV_WG_TAG_POST_UP, dataMap[NM_WG_KEY_POST_UP]); // Do PreDown (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_PRE_DOWN))) interfaceGroup.writeEntry(NMV_WG_TAG_PRE_DOWN, dataMap[NM_WG_KEY_PRE_DOWN]); // Do PostDown (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_POST_DOWN))) interfaceGroup.writeEntry(NMV_WG_TAG_POST_DOWN, dataMap[NM_WG_KEY_POST_DOWN]); // Do Public key (required) peerGroup.writeEntry(NMV_WG_TAG_PUBLIC_KEY, dataMap[NM_WG_KEY_PUBLIC_KEY]); // Do Allowed IP list (Required) peerGroup.writeEntry(NMV_WG_TAG_ALLOWED_IPS, dataMap[NM_WG_KEY_ALLOWED_IPS]); // Do Endpoint (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_ENDPOINT))) peerGroup.writeEntry(NMV_WG_TAG_ENDPOINT, dataMap[NM_WG_KEY_ENDPOINT]); // Do Preshared Key (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_PRESHARED_KEY))) peerGroup.writeEntry(NMV_WG_TAG_PRESHARED_KEY, dataMap[NM_WG_KEY_PRESHARED_KEY]); // Do Persistent Keepalive (Not required) if (dataMap.contains(QLatin1String(NM_WG_KEY_PERSISTENT_KEEPALIVE))) peerGroup.writeEntry(NMV_WG_TAG_PERSISTENT_KEEPALIVE, dataMap[NM_WG_KEY_PERSISTENT_KEEPALIVE]); exportFile.sync(); return true; } #include "wireguard.moc" diff --git a/vpn/wireguard/wireguard.ui b/vpn/wireguard/wireguard.ui index 35ae1ff4..e0c378ff 100644 --- a/vpn/wireguard/wireguard.ui +++ b/vpn/wireguard/wireguard.ui @@ -1,199 +1,184 @@ WireGuardProp 0 0 495 454 WireGuard Settings Interface Address (IPv4): IPv4 Internet address with CIDR (example: 10.22.13.123/32) assigned to the local interface. IPv4 or IPv6 address (or both) required Address (IPv6): IPv6 Internet address with CIDR assigned to the local interface. (example: fc00:aaaa:aaaa:aa03::1bc9/128) IPv4 or IPv6 address (or both) required Private key: Required. A base64 private key generated by wg genkey. - - - - DNS: - - - - - - - Optional. -IPv4 or IPv6 address to set the interface's DNS server. - - - Peer Public key: Required. A base64 public key calculated by wg pubkey from a private key, and usually transmitted out of band to the author of the configuration file. Allowed IPs: Required. A comma-separated list of IP (v4 or v6) addresses with CIDR masks from which incoming traffic for this peer is allowed and to which outgoing traffic for this peer is directed. The catch-all 0.0.0.0/0 may be specified for matching all IPv4 addresses, and ::/0 may be specified for matching all IPv6 addresses. Endpoint: Optional. An endpoint IP followed by a colon, and then a port number. Qt::Horizontal 40 20 Advanced... Qt::Vertical 20 0 PasswordField QLineEdit
passwordfield.h
diff --git a/vpn/wireguard/wireguardwidget.cpp b/vpn/wireguard/wireguardwidget.cpp index 456b299b..073add06 100644 --- a/vpn/wireguard/wireguardwidget.cpp +++ b/vpn/wireguard/wireguardwidget.cpp @@ -1,307 +1,286 @@ /* Copyright 2018 Bruce Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "debug.h" #include "wireguardwidget.h" #include "wireguardadvancedwidget.h" #include "simpleipv4addressvalidator.h" #include "simpleiplistvalidator.h" #include "wireguardkeyvalidator.h" #include #include #include #include "nm-wireguard-service.h" class WireGuardSettingWidget::Private { public: Private(); Ui_WireGuardProp ui; NetworkManager::VpnSetting::Ptr setting; KSharedConfigPtr config; QPalette warningPalette; QPalette normalPalette; WireGuardKeyValidator *keyValidator; bool addressValid; bool privateKeyValid; bool publicKeyValid; - bool dnsValid; bool allowedIpsValid; bool endpointValid; }; WireGuardSettingWidget::Private::Private(void) : addressValid(false) , privateKeyValid(false) , publicKeyValid(false) - , dnsValid(true) // optional so blank is valid , allowedIpsValid(false) , endpointValid(true) // optional so blank is valid { } WireGuardSettingWidget::WireGuardSettingWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent) : SettingWidget(setting, parent) , d(new Private) { qDBusRegisterMetaType(); d->ui.setupUi(this); d->setting = setting; d->config = KSharedConfig::openConfig(); d->warningPalette = KColorScheme::createApplicationPalette(d->config); d->normalPalette = KColorScheme::createApplicationPalette(d->config); KColorScheme::adjustBackground(d->warningPalette, KColorScheme::NegativeBackground, QPalette::Base, KColorScheme::ColorSet::View, d->config); KColorScheme::adjustBackground(d->normalPalette, KColorScheme::NormalBackground, QPalette::Base, KColorScheme::ColorSet::View, d->config); connect(d->ui.addressIPv4LineEdit, &QLineEdit::textChanged, this, &WireGuardSettingWidget::checkAddressValid); connect(d->ui.addressIPv6LineEdit, &QLineEdit::textChanged, this, &WireGuardSettingWidget::checkAddressValid); connect(d->ui.privateKeyLineEdit, &PasswordField::textChanged, this, &WireGuardSettingWidget::checkPrivateKeyValid); connect(d->ui.publicKeyLineEdit, &QLineEdit::textChanged, this, &WireGuardSettingWidget::checkPublicKeyValid); connect(d->ui.allowedIPsLineEdit, &QLineEdit::textChanged, this, &WireGuardSettingWidget::checkAllowedIpsValid); connect(d->ui.endpointLineEdit, &QLineEdit::textChanged, this, &WireGuardSettingWidget::checkEndpointValid); - connect(d->ui.dNSLineEdit, &QLineEdit::textChanged, this, &WireGuardSettingWidget::checkDnsValid); d->ui.privateKeyLineEdit->setPasswordModeEnabled(true); connect(d->ui.btnAdvanced, &QPushButton::clicked, this, &WireGuardSettingWidget::showAdvanced); SimpleIpV4AddressValidator *ip4WithCidrValidator = new SimpleIpV4AddressValidator(this, SimpleIpV4AddressValidator::AddressStyle::WithCidr); d->ui.addressIPv4LineEdit->setValidator(ip4WithCidrValidator); // Create a validator for the IPv6 address line edit // Address must be a valid IP address with a CIDR suffix SimpleIpV6AddressValidator *ip6WithCidrValidator = new SimpleIpV6AddressValidator(this, SimpleIpV6AddressValidator::AddressStyle::WithCidr); d->ui.addressIPv6LineEdit->setValidator(ip6WithCidrValidator); // This is done as a private variable rather than a local variable so it can be // used both here and to validate the private key later d->keyValidator = new WireGuardKeyValidator(this); d->ui.publicKeyLineEdit->setValidator(d->keyValidator); - // Create validator for DNS - SimpleIpV4AddressValidator *dnsValidator = new SimpleIpV4AddressValidator(this); - d->ui.dNSLineEdit->setValidator(dnsValidator); - // Create validator for Endpoint SimpleIpV4AddressValidator *endpointValidator = new SimpleIpV4AddressValidator(this, SimpleIpV4AddressValidator::AddressStyle::WithPort); d->ui.endpointLineEdit->setValidator(endpointValidator); // Create validator for AllowedIPs SimpleIpListValidator *allowedIPsValidator = new SimpleIpListValidator(this, SimpleIpListValidator::WithCidr, SimpleIpListValidator::Both); d->ui.allowedIPsLineEdit->setValidator(allowedIPsValidator); // Connect for setting check watchChangedSetting(); KAcceleratorManager::manage(this); if (setting && !setting->isNull()) { loadConfig(d->setting); } // Set the initial backgrounds on all the widgets checkAddressValid(); checkPrivateKeyValid(); checkPublicKeyValid(); - checkDnsValid(); checkAllowedIpsValid(); checkEndpointValid(); } WireGuardSettingWidget::~WireGuardSettingWidget() { delete d; } void WireGuardSettingWidget::loadConfig(const NetworkManager::Setting::Ptr &setting) { Q_UNUSED(setting) + // General settings const NMStringMap dataMap = d->setting->data(); d->ui.addressIPv4LineEdit->setText(dataMap[NM_WG_KEY_ADDR_IP4]); d->ui.addressIPv6LineEdit->setText(dataMap[NM_WG_KEY_ADDR_IP6]); d->ui.privateKeyLineEdit->setText(dataMap[NM_WG_KEY_PRIVATE_KEY]); - d->ui.dNSLineEdit->setText(dataMap[NM_WG_KEY_DNS]); d->ui.publicKeyLineEdit->setText(dataMap[NM_WG_KEY_PUBLIC_KEY]); d->ui.allowedIPsLineEdit->setText(dataMap[NM_WG_KEY_ALLOWED_IPS]); d->ui.endpointLineEdit->setText(dataMap[NM_WG_KEY_ENDPOINT]); } void WireGuardSettingWidget::loadSecrets(const NetworkManager::Setting::Ptr &setting) { // Currently WireGuard does not have any secrets Q_UNUSED(setting) } QVariantMap WireGuardSettingWidget::setting() const { NMStringMap data = d->setting->data(); NetworkManager::VpnSetting setting; setting.setServiceType(QLatin1String(NM_DBUS_SERVICE_WIREGUARD)); // required settings setProperty(data, QLatin1String(NM_WG_KEY_ADDR_IP4), d->ui.addressIPv4LineEdit->displayText()); setProperty(data, QLatin1String(NM_WG_KEY_ADDR_IP6), d->ui.addressIPv6LineEdit->displayText()); setProperty(data, QLatin1String(NM_WG_KEY_PRIVATE_KEY), d->ui.privateKeyLineEdit->text()); setProperty(data, QLatin1String(NM_WG_KEY_PUBLIC_KEY), d->ui.publicKeyLineEdit->displayText()); setProperty(data, QLatin1String(NM_WG_KEY_ALLOWED_IPS), d->ui.allowedIPsLineEdit->displayText()); - setProperty(data, QLatin1String(NM_WG_KEY_DNS), d->ui.dNSLineEdit->displayText()); setProperty(data, QLatin1String(NM_WG_KEY_ENDPOINT), d->ui.endpointLineEdit->displayText()); setting.setData(data); return setting.toMap(); } void WireGuardSettingWidget::setProperty(NMStringMap &data, const QLatin1String &key, const QString &value) const { if (!value.isEmpty()) data.insert(key, value); else data.remove(key); } void WireGuardSettingWidget::showAdvanced() { QPointer adv = new WireGuardAdvancedWidget(d->setting, this); connect(adv.data(), &WireGuardAdvancedWidget::accepted, [adv, this] () { NetworkManager::VpnSetting::Ptr advData = adv->setting(); if (!advData.isNull()) { d->setting->setData(advData->data()); } }); connect(adv.data(), &WireGuardAdvancedWidget::finished, [adv] () { if (adv) { adv->deleteLater(); } }); adv->setModal(true); adv->show(); } bool WireGuardSettingWidget::isValid() const { return d->addressValid && d->privateKeyValid && d->publicKeyValid - && d->dnsValid && d->allowedIpsValid && d->endpointValid; } void WireGuardSettingWidget::checkAddressValid() { int pos = 0; QLineEdit *widget = d->ui.addressIPv4LineEdit; QString value(widget->displayText()); bool ip4valid = (widget->validator()->validate(value, pos) == QValidator::Acceptable); bool ip4present = !widget->displayText().isEmpty(); widget = d->ui.addressIPv6LineEdit; value = widget->displayText(); bool ip6valid = QValidator::Acceptable == widget->validator()->validate(value, pos); bool ip6present = !widget->displayText().isEmpty(); d->addressValid = (ip4valid && ip6valid) || (ip4valid && !ip6present) || (!ip4present && ip6valid); setBackground(d->ui.addressIPv4LineEdit, d->addressValid); setBackground(d->ui.addressIPv6LineEdit, d->addressValid); slotWidgetChanged(); } void WireGuardSettingWidget::checkPrivateKeyValid() { int pos = 0; PasswordField *widget = d->ui.privateKeyLineEdit; QString value = widget->text(); d->privateKeyValid = QValidator::Acceptable == d->keyValidator->validate(value, pos); setBackground(widget, d->privateKeyValid); slotWidgetChanged(); } void WireGuardSettingWidget::checkPublicKeyValid() { int pos = 0; QLineEdit *widget = d->ui.publicKeyLineEdit; QString value = widget->displayText(); d->publicKeyValid = QValidator::Acceptable == widget->validator()->validate(value, pos); setBackground(widget, d->publicKeyValid); slotWidgetChanged(); } -void WireGuardSettingWidget::checkDnsValid() -{ - int pos = 0; - QLineEdit *widget = d->ui.dNSLineEdit; - QString value = widget->displayText(); - d->dnsValid = QValidator::Acceptable == widget->validator()->validate(value, pos) - || widget->displayText().isEmpty(); - setBackground(widget, d->dnsValid); - slotWidgetChanged(); -} - void WireGuardSettingWidget::checkAllowedIpsValid() { int pos = 0; QLineEdit *widget = d->ui.allowedIPsLineEdit; QString value = widget->displayText(); d->allowedIpsValid = QValidator::Acceptable == widget->validator()->validate(value, pos); setBackground(widget, d->allowedIpsValid); slotWidgetChanged(); } void WireGuardSettingWidget::checkEndpointValid() { int pos = 0; QLineEdit *widget = d->ui.endpointLineEdit; QString value = widget->displayText(); d->endpointValid = QValidator::Acceptable == widget->validator()->validate(value, pos) || value.isEmpty(); setBackground(widget, d->endpointValid); slotWidgetChanged(); } void WireGuardSettingWidget::setBackground(QWidget *w, bool result) const { if (result) w->setPalette(d->normalPalette); else w->setPalette(d->warningPalette); } diff --git a/vpn/wireguard/wireguardwidget.h b/vpn/wireguard/wireguardwidget.h index 4aee0354..e12ec9fd 100644 --- a/vpn/wireguard/wireguardwidget.h +++ b/vpn/wireguard/wireguardwidget.h @@ -1,60 +1,59 @@ /* Copyright 2018 Bruce Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef WIREGUARDWIDGET_H #define WIREGUARDWIDGET_H #include "settingwidget.h" #include "ui_wireguard.h" #include class WireGuardSettingWidget : public SettingWidget { Q_OBJECT public: explicit WireGuardSettingWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent = nullptr); ~WireGuardSettingWidget() override; void loadConfig(const NetworkManager::Setting::Ptr &setting) override; void loadSecrets(const NetworkManager::Setting::Ptr &setting) override; QVariantMap setting() const override; virtual bool isValid() const override; private Q_SLOTS: void showAdvanced(); private: void setProperty(NMStringMap &data, const QLatin1String &key, const QString &value) const; void setBackground(QWidget *w, bool result) const; void checkAddressValid(); void checkPrivateKeyValid(); void checkPublicKeyValid(); - void checkDnsValid(); void checkAllowedIpsValid(); void checkEndpointValid(); class Private; Private *d; }; #endif // WIREGUARDWIDGET_H