From 6bd95d230a5628f36590256ec9be8c5d41a47c9a Mon Sep 17 00:00:00 2001 From: Santtu Lakkala Date: Mon, 7 Dec 2020 14:21:12 +0200 Subject: [PATCH] [settings-vpn] Add support for vpnc provisioning files. Contributes to JB#51525 --- src/settingsvpnmodel.cpp | 84 ++++++++++++++++++++++++++++++++++++++++ src/settingsvpnmodel.h | 1 + 2 files changed, 85 insertions(+) diff --git a/src/settingsvpnmodel.cpp b/src/settingsvpnmodel.cpp index 0872260..dcb375c 100644 --- a/src/settingsvpnmodel.cpp +++ b/src/settingsvpnmodel.cpp @@ -613,6 +613,8 @@ QVariantMap SettingsVpnModel::processProvisioningFile(const QString &path, const rv = processOpenconnectProvisioningFile(provisioningFile); } else if (type == QStringLiteral("openfortivpn")) { rv = processOpenfortivpnProvisioningFile(provisioningFile); + } else if (type == QStringLiteral("vpnc")) { + rv = processVpncProvisioningFile(provisioningFile); } else { qWarning() << "Provisioning not currently supported for VPN type:" << type; } @@ -861,6 +863,88 @@ QVariantMap SettingsVpnModel::processOpenVpnProvisioningFile(QFile &provisioning return rv; } +QVariantMap SettingsVpnModel::processVpncProvisioningFile(QFile &provisioningFile) +{ + QVariantMap rv; + + QTextStream is(&provisioningFile); +#define ENTRY(x, y, z) { QStringLiteral(x), QStringLiteral(y), z } + static const struct { + QString key; + QString targetProperty; + bool hasValue; + } options[] = { + ENTRY("IPSec gateway", "Host", true), + ENTRY("IPSec ID", "VPNC.IPSec.ID", true), + ENTRY("Domain", "VPNC.Domain", true), + ENTRY("Vendor", "VPNC.Vendor", true), + ENTRY("IKE DH Group", "VPNC.IKE.DHGroup", true), + ENTRY("Perfect Forward Secrecy", "VPNC.PFS", true), + ENTRY("NAT Traversal Mode", "VPNC.NATTMode", true), + ENTRY("Enable Single DES", "VPNC.SingleDES", false), + ENTRY("Enable no encryption", "VPNC.NoEncryption", false), + ENTRY("Application version", "VPNC.AppVersion", true), + ENTRY("Local Port", "VPNC.LocalPort", true), + ENTRY("Cisco UDP Encapsulation Port", "VPNC.CiscoPort", true), + ENTRY("DPD idle timeout (our side)", "VPNC.DPDTimeout", true), + ENTRY("IKE Authmode", "VPNC.IKE.AuthMode", true), + /* Unhandled config options + ENTRY("IPSec secret", "VPNC.IPSec.Secret", true), + ENTRY("IPSec obfuscated secret", "?", true), + ENTRY("Xauth username", "VPNC.XAuth.Username", true), + ENTRY("Xauth password", "VPNC.XAuth.Password", true), + ENTRY("Xauth obfuscated password", "?", true), + ENTRY("Xauth interactive", "?", false), + ENTRY("Script", "?", true), + ENTRY("Interface name", "?", true), + ENTRY("Interface mode", "?", true), + ENTRY("Interface MTU", "?", true), + ENTRY("Debug", "?", true), + ENTRY("No Detach", "?", false), + ENTRY("Pidfile", "?", true), + ENTRY("Local Addr", "?", true), + ENTRY("Noninteractive", "?", false), + ENTRY("CA-File", "?", true), + ENTRY("CA-Dir", "?", true), + ENTRY("IPSEC target network", "?", true), + ENTRY("Password helper", "?", true), + */ + }; +#undef ENTRY + while (!is.atEnd()) { + QString line(is.readLine()); + + for (size_t i = 0; i < sizeof(options) / sizeof(*options); i++) { + if (!line.startsWith(options[i].key, Qt::CaseInsensitive)) { + continue; + } + if (!options[i].hasValue) { + rv[options[i].targetProperty] = true; + } else { + int pos = options[i].key.length(); + if (line.length() == pos + || (line[pos] != ' ' + && line[pos] != '\t')) { + continue; + } + rv[options[i].targetProperty] = line.mid(pos + 1); + } + } + } + + if (rv.contains("VPNC.IPSec.ID")) { + if (rv.contains("Host")) { + rv["Name"] = QStringLiteral("%1 %2").arg(rv["Host"].value()).arg(rv["VPNC.IPSec.ID"].value()); + } else { + rv["Name"] = rv["VPNC.IPSec.ID"]; + } + } else { + rv["Name"] = QFileInfo(provisioningFile).baseName(); + } + + return rv; +} + QVariantMap SettingsVpnModel::processOpenconnectProvisioningFile(QFile &provisioningFile) { char first; diff --git a/src/settingsvpnmodel.h b/src/settingsvpnmodel.h index 8f65d50..d97fcfa 100644 --- a/src/settingsvpnmodel.h +++ b/src/settingsvpnmodel.h @@ -100,6 +100,7 @@ class SYSTEMSETTINGS_EXPORT SettingsVpnModel : public VpnModel QVariantMap processOpenVpnProvisioningFile(QFile &provisioningFile); QVariantMap processOpenconnectProvisioningFile(QFile &provisioningFile); QVariantMap processOpenfortivpnProvisioningFile(QFile &provisioningFile); + QVariantMap processVpncProvisioningFile(QFile &provisioningFile); void updateBestState(VpnConnection::ConnectionState maxState); private Q_SLOTS: