Changeset View
Changeset View
Standalone View
Standalone View
vpn/wireguard/wireguard.cpp
Show All 23 Lines | |||||
24 | #include <QFileInfo> | 24 | #include <QFileInfo> | ||
25 | #include <KPluginFactory> | 25 | #include <KPluginFactory> | ||
26 | #include <KConfig> | 26 | #include <KConfig> | ||
27 | #include <KConfigGroup> | 27 | #include <KConfigGroup> | ||
28 | 28 | | |||
29 | #include <NetworkManagerQt/Connection> | 29 | #include <NetworkManagerQt/Connection> | ||
30 | #include <NetworkManagerQt/VpnSetting> | 30 | #include <NetworkManagerQt/VpnSetting> | ||
31 | #include <NetworkManagerQt/Ipv4Setting> | 31 | #include <NetworkManagerQt/Ipv4Setting> | ||
32 | #include <NetworkManagerQt/Ipv6Setting> | ||||
32 | 33 | | |||
33 | #include "wireguardwidget.h" | 34 | #include "wireguardwidget.h" | ||
34 | #include "wireguardauth.h" | 35 | #include "wireguardauth.h" | ||
35 | #include "simpleipv4addressvalidator.h" | 36 | #include "simpleipv4addressvalidator.h" | ||
36 | #include "simpleipv6addressvalidator.h" | 37 | #include "simpleipv6addressvalidator.h" | ||
37 | #include "simpleiplistvalidator.h" | 38 | #include "simpleiplistvalidator.h" | ||
38 | #include "wireguardkeyvalidator.h" | 39 | #include "wireguardkeyvalidator.h" | ||
39 | 40 | | |||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Line(s) | 104 | if (!interfaceGroup.exists() || !peerGroup.exists()) { | |||
104 | mError = VpnUiPlugin::Error; | 105 | mError = VpnUiPlugin::Error; | ||
105 | mErrorMessage = i18n("Config file needs both [Peer] and [Interface]"); | 106 | mErrorMessage = i18n("Config file needs both [Peer] and [Interface]"); | ||
106 | return result; | 107 | return result; | ||
107 | } | 108 | } | ||
108 | 109 | | |||
109 | const QString connectionName = QFileInfo(fileName).completeBaseName(); | 110 | const QString connectionName = QFileInfo(fileName).completeBaseName(); | ||
110 | NMStringMap dataMap; | 111 | NMStringMap dataMap; | ||
111 | QVariantMap ipv4Data; | 112 | QVariantMap ipv4Data; | ||
113 | QVariantMap ipv6Data; | ||||
112 | 114 | | |||
113 | QString value; | 115 | QString value; | ||
114 | QStringList valueList; | 116 | QStringList valueList; | ||
117 | QList<QHostAddress> ipv4List; | ||||
118 | QList<QHostAddress> ipv6List; | ||||
115 | int intValue; | 119 | int intValue; | ||
116 | 120 | | |||
121 | NetworkManager::Ipv4Setting ipv4Setting; | ||||
122 | NetworkManager::Ipv6Setting ipv6Setting; | ||||
123 | | ||||
117 | // Do the required fields first and fail (i.e. return an empty result) if not present | 124 | // Do the required fields first and fail (i.e. return an empty result) if not present | ||
118 | 125 | | |||
119 | // Addresses | 126 | // Addresses | ||
120 | valueList = interfaceGroup.readEntry(NMV_WG_TAG_ADDRESS, QStringList()); | 127 | valueList = interfaceGroup.readEntry(NMV_WG_TAG_ADDRESS, QStringList()); | ||
121 | if (valueList.isEmpty()) { | 128 | if (valueList.isEmpty()) { | ||
122 | mError = VpnUiPlugin::Error; | 129 | mError = VpnUiPlugin::Error; | ||
123 | mErrorMessage = i18n("No address in config file"); | 130 | mErrorMessage = i18n("No address in config file"); | ||
124 | return result; | 131 | return result; | ||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Line(s) | 205 | if (intValue < 65536) { | |||
199 | dataMap.insert(QLatin1String(NM_WG_KEY_LISTEN_PORT), QString::number(intValue)); | 206 | dataMap.insert(QLatin1String(NM_WG_KEY_LISTEN_PORT), QString::number(intValue)); | ||
200 | } else { | 207 | } else { | ||
201 | mError = VpnUiPlugin::Error; | 208 | mError = VpnUiPlugin::Error; | ||
202 | mErrorMessage = i18n("Invalid Listen Port in config file"); | 209 | mErrorMessage = i18n("Invalid Listen Port in config file"); | ||
203 | return result; | 210 | return result; | ||
204 | } | 211 | } | ||
205 | } | 212 | } | ||
206 | 213 | | |||
207 | // DNS | 214 | // DNS servers are added slightly differently in that they are not added | ||
208 | value = interfaceGroup.readEntry(NMV_WG_TAG_DNS); | 215 | // to the [vpn] section of the setup but to the [ipv4] and/or [ipv6] | ||
209 | if (!value.isEmpty()) { | 216 | // sections. | ||
210 | const QHostAddress testAddress(value); | 217 | valueList = interfaceGroup.readEntry(NMV_WG_TAG_DNS, QStringList()); | ||
211 | if (testAddress.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv4Protocol | 218 | if (!valueList.isEmpty()) { | ||
212 | || testAddress.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv6Protocol) { | 219 | for (const QString &address : valueList) { | ||
213 | dataMap.insert(QLatin1String(NM_WG_KEY_DNS), value); | 220 | const QPair<QHostAddress, int> addressIn = QHostAddress::parseSubnet(address.trimmed()); | ||
214 | } else { | 221 | if (addressIn.first.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv4Protocol) { | ||
222 | ipv4List.append(addressIn.first); | ||||
223 | } else if (addressIn.first.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv6Protocol) { | ||||
224 | ipv6List.append(addressIn.first); | ||||
225 | } else { // Error condition | ||||
215 | mError = VpnUiPlugin::Error; | 226 | mError = VpnUiPlugin::Error; | ||
216 | mErrorMessage = i18n("Invalid DNS in config file"); | 227 | mErrorMessage = i18n("No valid address in config file"); | ||
217 | return result; | 228 | return result; | ||
218 | } | 229 | } | ||
219 | } | 230 | } | ||
220 | 231 | | |||
232 | // If there are any addresses put them on the correct tab and set the "method" to | ||||
233 | // "Automatic (Only addresses)" by setting "ignore-auto-dns=true" | ||||
234 | if (!ipv4List.isEmpty()) { | ||||
235 | ipv4Setting.setMethod(NetworkManager::Ipv4Setting::Automatic); | ||||
236 | ipv4Setting.setIgnoreAutoDns(true); | ||||
237 | ipv4Setting.setDns(ipv4List); | ||||
238 | } | ||||
239 | | ||||
240 | if (!ipv6List.isEmpty()) { | ||||
241 | ipv6Setting.setMethod(NetworkManager::Ipv6Setting::Automatic); | ||||
242 | ipv6Setting.setIgnoreAutoDns(true); | ||||
243 | ipv6Setting.setDns(ipv6List); | ||||
244 | } | ||||
245 | } | ||||
246 | | ||||
221 | // MTU | 247 | // MTU | ||
222 | intValue = interfaceGroup.readEntry(NMV_WG_TAG_MTU, 0); | 248 | intValue = interfaceGroup.readEntry(NMV_WG_TAG_MTU, 0); | ||
223 | if (intValue > 0) | 249 | if (intValue > 0) | ||
224 | dataMap.insert(QLatin1String(NM_WG_KEY_LISTEN_PORT), QString::number(intValue)); | 250 | dataMap.insert(QLatin1String(NM_WG_KEY_LISTEN_PORT), QString::number(intValue)); | ||
225 | 251 | | |||
226 | // Table | 252 | // Table | ||
227 | value = interfaceGroup.readEntry(NMV_WG_TAG_TABLE); | 253 | value = interfaceGroup.readEntry(NMV_WG_TAG_TABLE); | ||
228 | if (!value.isEmpty()) | 254 | if (!value.isEmpty()) | ||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Line(s) | |||||
274 | setting.setServiceType(QLatin1String(NM_DBUS_SERVICE_WIREGUARD)); | 300 | setting.setServiceType(QLatin1String(NM_DBUS_SERVICE_WIREGUARD)); | ||
275 | setting.setData(dataMap); | 301 | setting.setData(dataMap); | ||
276 | 302 | | |||
277 | QVariantMap conn; | 303 | QVariantMap conn; | ||
278 | conn.insert("id", connectionName); | 304 | conn.insert("id", connectionName); | ||
279 | conn.insert("type", "vpn"); | 305 | conn.insert("type", "vpn"); | ||
280 | result.insert("connection", conn); | 306 | result.insert("connection", conn); | ||
281 | result.insert("vpn", setting.toMap()); | 307 | result.insert("vpn", setting.toMap()); | ||
308 | if (!ipv4List.isEmpty()) { | ||||
309 | result.insert("ipv4", ipv4Setting.toMap()); | ||||
310 | } | ||||
311 | if (!ipv6List.isEmpty()) { | ||||
312 | result.insert("ipv6", ipv6Setting.toMap()); | ||||
313 | } | ||||
282 | 314 | | |||
283 | return result; | 315 | return result; | ||
284 | } | 316 | } | ||
285 | 317 | | |||
286 | bool WireGuardUiPlugin::exportConnectionSettings(const NetworkManager::ConnectionSettings::Ptr &connection, | 318 | bool WireGuardUiPlugin::exportConnectionSettings(const NetworkManager::ConnectionSettings::Ptr &connection, | ||
287 | const QString &fileName) | 319 | const QString &fileName) | ||
288 | { | 320 | { | ||
289 | NetworkManager::VpnSetting::Ptr vpnSetting = connection->setting( | 321 | NetworkManager::VpnSetting::Ptr vpnSetting = connection->setting( | ||
290 | NetworkManager::Setting::Vpn).dynamicCast<NetworkManager::VpnSetting>(); | 322 | NetworkManager::Setting::Vpn).dynamicCast<NetworkManager::VpnSetting>(); | ||
323 | NetworkManager::Ipv4Setting::Ptr ipv4Setting = connection->setting( | ||||
324 | NetworkManager::Setting::Ipv4).dynamicCast<NetworkManager::Ipv4Setting>(); | ||||
325 | NetworkManager::Ipv6Setting::Ptr ipv6Setting = connection->setting( | ||||
326 | NetworkManager::Setting::Ipv6).dynamicCast<NetworkManager::Ipv6Setting>(); | ||||
327 | QList<QHostAddress> ipv4Dns = ipv4Setting->dns(); | ||||
328 | QList<QHostAddress> ipv6Dns = ipv6Setting->dns(); | ||||
291 | NMStringMap dataMap = vpnSetting->data(); | 329 | NMStringMap dataMap = vpnSetting->data(); | ||
292 | 330 | | |||
293 | // Make sure all the required fields are present | 331 | // Make sure all the required fields are present | ||
294 | if (!(dataMap.contains(QLatin1String(NM_WG_KEY_ADDR_IP4)) | 332 | if (!(dataMap.contains(QLatin1String(NM_WG_KEY_ADDR_IP4)) | ||
295 | || dataMap.contains(QLatin1String(NM_WG_KEY_ADDR_IP6))) | 333 | || dataMap.contains(QLatin1String(NM_WG_KEY_ADDR_IP6))) | ||
296 | || !dataMap.contains(QLatin1String(NM_WG_KEY_PRIVATE_KEY)) | 334 | || !dataMap.contains(QLatin1String(NM_WG_KEY_PRIVATE_KEY)) | ||
297 | || !dataMap.contains(QLatin1String(NM_WG_KEY_PUBLIC_KEY)) | 335 | || !dataMap.contains(QLatin1String(NM_WG_KEY_PUBLIC_KEY)) | ||
298 | || !dataMap.contains(QLatin1String(NM_WG_KEY_ALLOWED_IPS))) | 336 | || !dataMap.contains(QLatin1String(NM_WG_KEY_ALLOWED_IPS))) | ||
Show All 11 Lines | |||||
310 | if (dataMap.contains(QLatin1String(NM_WG_KEY_ADDR_IP6))) | 348 | if (dataMap.contains(QLatin1String(NM_WG_KEY_ADDR_IP6))) | ||
311 | outputList.append(dataMap[NM_WG_KEY_ADDR_IP6]); | 349 | outputList.append(dataMap[NM_WG_KEY_ADDR_IP6]); | ||
312 | interfaceGroup.writeEntry(NMV_WG_TAG_ADDRESS, outputList); | 350 | interfaceGroup.writeEntry(NMV_WG_TAG_ADDRESS, outputList); | ||
313 | 351 | | |||
314 | // Do Private Key | 352 | // Do Private Key | ||
315 | interfaceGroup.writeEntry(NMV_WG_TAG_PRIVATE_KEY, dataMap[NM_WG_KEY_PRIVATE_KEY]); | 353 | interfaceGroup.writeEntry(NMV_WG_TAG_PRIVATE_KEY, dataMap[NM_WG_KEY_PRIVATE_KEY]); | ||
316 | 354 | | |||
317 | // Do DNS (Not required) | 355 | // Do DNS (Not required) | ||
318 | if (dataMap.contains(QLatin1String(NM_WG_KEY_DNS))) | 356 | // DNS is a little complicated because the first version of plasma-nm-wireguard included | ||
357 | // the DNS key in the VPN settings but this was changed in a later version such that it | ||||
358 | // uses DNS from the IPv4 and IPv6 tabs instead, so here we check to see if the IPv4 and/or | ||||
359 | // the IPv6 tabs contain DNS entries and if so use those. Otherwise see if we have an | ||||
360 | // old style VPN setting with DNS in it and if so use that. | ||||
361 | if (ipv4Dns.count() > 0 || ipv6Dns.count() > 0) { | ||||
362 | QStringList dnsList; | ||||
363 | for (QHostAddress addr : ipv4Dns) | ||||
364 | dnsList.append(addr.toString()); | ||||
365 | for (QHostAddress addr : ipv6Dns) | ||||
366 | dnsList.append(addr.toString()); | ||||
367 | interfaceGroup.writeEntry(NMV_WG_TAG_DNS, dnsList); | ||||
368 | } else if (dataMap.contains(QLatin1String(NM_WG_KEY_DNS))) { | ||||
319 | interfaceGroup.writeEntry(NMV_WG_TAG_DNS, dataMap[NM_WG_KEY_DNS]); | 369 | interfaceGroup.writeEntry(NMV_WG_TAG_DNS, dataMap[NM_WG_KEY_DNS]); | ||
370 | } | ||||
320 | 371 | | |||
321 | // Do MTU (Not required) | 372 | // Do MTU (Not required) | ||
322 | if (dataMap.contains(QLatin1String(NM_WG_KEY_MTU))) | 373 | if (dataMap.contains(QLatin1String(NM_WG_KEY_MTU))) | ||
323 | interfaceGroup.writeEntry(NMV_WG_TAG_MTU, dataMap[NM_WG_KEY_MTU]); | 374 | interfaceGroup.writeEntry(NMV_WG_TAG_MTU, dataMap[NM_WG_KEY_MTU]); | ||
324 | 375 | | |||
325 | // Do Table number (Not required) | 376 | // Do Table number (Not required) | ||
326 | if (dataMap.contains(QLatin1String(NM_WG_KEY_TABLE))) | 377 | if (dataMap.contains(QLatin1String(NM_WG_KEY_TABLE))) | ||
327 | interfaceGroup.writeEntry(NMV_WG_TAG_TABLE, dataMap[NM_WG_KEY_TABLE]); | 378 | interfaceGroup.writeEntry(NMV_WG_TAG_TABLE, dataMap[NM_WG_KEY_TABLE]); | ||
▲ Show 20 Lines • Show All 48 Lines • Show Last 20 Lines |