diff --git a/libs/editor/connectioneditorbase.cpp b/libs/editor/connectioneditorbase.cpp --- a/libs/editor/connectioneditorbase.cpp +++ b/libs/editor/connectioneditorbase.cpp @@ -284,7 +284,8 @@ || 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")); } diff --git a/vpn/wireguard/wireguard.cpp b/vpn/wireguard/wireguard.cpp --- a/vpn/wireguard/wireguard.cpp +++ b/vpn/wireguard/wireguard.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "wireguardwidget.h" #include "wireguardauth.h" @@ -109,11 +110,17 @@ 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 @@ -204,17 +211,36 @@ } } - // 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); } } @@ -279,6 +305,12 @@ 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; } @@ -288,6 +320,12 @@ { 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 @@ -315,8 +353,21 @@ 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))) diff --git a/vpn/wireguard/wireguard.ui b/vpn/wireguard/wireguard.ui --- a/vpn/wireguard/wireguard.ui +++ b/vpn/wireguard/wireguard.ui @@ -69,21 +69,6 @@ - - - - DNS: - - - - - - - Optional. -IPv4 or IPv6 address to set the interface's DNS server. - - - diff --git a/vpn/wireguard/wireguardwidget.h b/vpn/wireguard/wireguardwidget.h --- a/vpn/wireguard/wireguardwidget.h +++ b/vpn/wireguard/wireguardwidget.h @@ -49,7 +49,6 @@ void checkAddressValid(); void checkPrivateKeyValid(); void checkPublicKeyValid(); - void checkDnsValid(); void checkAllowedIpsValid(); void checkEndpointValid(); diff --git a/vpn/wireguard/wireguardwidget.cpp b/vpn/wireguard/wireguardwidget.cpp --- a/vpn/wireguard/wireguardwidget.cpp +++ b/vpn/wireguard/wireguardwidget.cpp @@ -45,16 +45,14 @@ 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 { @@ -85,7 +83,6 @@ 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); @@ -107,10 +104,6 @@ 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); @@ -134,7 +127,6 @@ checkAddressValid(); checkPrivateKeyValid(); checkPublicKeyValid(); - checkDnsValid(); checkAllowedIpsValid(); checkEndpointValid(); @@ -148,13 +140,13 @@ 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]); @@ -178,7 +170,6 @@ 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); @@ -220,7 +211,6 @@ return d->addressValid && d->privateKeyValid && d->publicKeyValid - && d->dnsValid && d->allowedIpsValid && d->endpointValid; } @@ -266,17 +256,6 @@ 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;