File indexing completed on 2024-05-05 17:42:56
0001 /* 0002 SPDX-FileCopyrightText: 2008 Will Stephenson <wstephenson@kde.org> 0003 SPDX-FileCopyrightText: 2011-2012 Rajeesh K Nambiar <rajeeshknambiar@gmail.com> 0004 SPDX-FileCopyrightText: 2011-2012 Lamarque V. Souza <lamarque@kde.org> 0005 SPDX-FileCopyrightText: 2013 Lukas Tinkl <ltinkl@redhat.com> 0006 0007 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0008 */ 0009 0010 #include "vpnc.h" 0011 #include "plasma_nm_vpnc.h" 0012 0013 #include <QFile> 0014 #include <QFileInfo> 0015 #include <QStandardPaths> 0016 0017 #include "nm-vpnc-service.h" 0018 #include <KLocalizedString> 0019 #include <KMessageBox> 0020 #include <KPluginFactory> 0021 #include <KSharedConfig> 0022 0023 #include <NetworkManagerQt/Connection> 0024 #include <NetworkManagerQt/Ipv4Setting> 0025 #include <NetworkManagerQt/VpnSetting> 0026 0027 #include <arpa/inet.h> 0028 0029 #include "vpncauth.h" 0030 #include "vpncwidget.h" 0031 0032 VpncUiPluginPrivate::VpncUiPluginPrivate() 0033 { 0034 decryptedPasswd.clear(); 0035 ciscoDecrypt = nullptr; 0036 } 0037 0038 VpncUiPluginPrivate::~VpncUiPluginPrivate() = default; 0039 0040 QString VpncUiPluginPrivate::readStringKeyValue(const KConfigGroup &configGroup, const QString &key) 0041 { 0042 const QString retValue = configGroup.readEntry(key); 0043 if (retValue.isEmpty()) { 0044 // String key can also start with "!" in CISCO pcf file. 0045 return configGroup.readEntry('!' + key); 0046 } else { 0047 return retValue; 0048 } 0049 } 0050 0051 void VpncUiPluginPrivate::gotCiscoDecryptOutput() 0052 { 0053 QByteArray output = ciscoDecrypt->readAll(); 0054 if (!output.isEmpty()) { 0055 const QList<QByteArray> lines = output.split('\n'); 0056 if (!lines.isEmpty()) { 0057 decryptedPasswd = QString::fromUtf8(lines.first()); 0058 } 0059 } 0060 } 0061 0062 void VpncUiPluginPrivate::ciscoDecryptFinished(int exitCode, QProcess::ExitStatus exitStatus) 0063 { 0064 if (exitCode || exitStatus != QProcess::NormalExit) { 0065 decryptedPasswd.clear(); 0066 } 0067 } 0068 0069 void VpncUiPluginPrivate::ciscoDecryptError(QProcess::ProcessError pError) 0070 { 0071 if (!pError) { 0072 qCWarning(PLASMA_NM_VPNC_LOG) << "Error in executing cisco-decrypt"; 0073 KMessageBox::error(nullptr, i18n("Error decrypting the obfuscated password"), i18n("Error"), KMessageBox::Notify); 0074 } 0075 decryptedPasswd.clear(); 0076 } 0077 0078 #define NM_VPNC_LOCAL_PORT_DEFAULT 500 0079 0080 K_PLUGIN_CLASS_WITH_JSON(VpncUiPlugin, "plasmanetworkmanagement_vpncui.json") 0081 0082 VpncUiPlugin::VpncUiPlugin(QObject *parent, const QVariantList &) 0083 : VpnUiPlugin(parent) 0084 { 0085 } 0086 0087 VpncUiPlugin::~VpncUiPlugin() = default; 0088 0089 SettingWidget *VpncUiPlugin::widget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent) 0090 { 0091 return new VpncWidget(setting, parent); 0092 } 0093 0094 SettingWidget *VpncUiPlugin::askUser(const NetworkManager::VpnSetting::Ptr &setting, const QStringList &hints, QWidget *parent) 0095 { 0096 return new VpncAuthDialog(setting, hints, parent); 0097 } 0098 0099 QString VpncUiPlugin::suggestedFileName(const NetworkManager::ConnectionSettings::Ptr &connection) const 0100 { 0101 return connection->id() + QStringLiteral(".pcf"); 0102 } 0103 0104 QStringList VpncUiPlugin::supportedFileExtensions() const 0105 { 0106 return {QStringLiteral("*.pcf")}; 0107 } 0108 0109 VpnUiPlugin::ImportResult VpncUiPlugin::importConnectionSettings(const QString &fileName) 0110 { 0111 GError *error = nullptr; 0112 0113 GSList *plugins = nm_vpn_plugin_info_list_load(); 0114 0115 NMVpnPluginInfo *plugin_info = nm_vpn_plugin_info_list_find_by_service(plugins, "org.freedesktop.NetworkManager.vpnc"); 0116 0117 if (!plugin_info) { 0118 return VpnUiPlugin::ImportResult::fail(i18n("NetworkManager is missing support for Cisco Compatible VPN")); 0119 } 0120 0121 NMVpnEditorPlugin *plugin = nm_vpn_plugin_info_load_editor_plugin(plugin_info, &error); 0122 0123 NMConnection *connection = nm_vpn_editor_plugin_import(plugin, fileName.toUtf8().constData(), &error); 0124 0125 if (!connection) { 0126 const QString errorMessage = QString::fromUtf8(error->message); 0127 g_error_free(error); 0128 0129 return VpnUiPlugin::ImportResult::fail(errorMessage); 0130 } 0131 0132 return VpnUiPlugin::ImportResult::pass(connection); 0133 } 0134 0135 VpncUiPlugin::ExportResult VpncUiPlugin::exportConnectionSettings(const NetworkManager::ConnectionSettings::Ptr &connection, const QString &fileName) 0136 { 0137 NMStringMap data; 0138 NMStringMap secretData; 0139 0140 NetworkManager::VpnSetting::Ptr vpnSetting = connection->setting(NetworkManager::Setting::Vpn).dynamicCast<NetworkManager::VpnSetting>(); 0141 data = vpnSetting->data(); 0142 secretData = vpnSetting->secrets(); 0143 0144 KSharedConfig::Ptr config = KSharedConfig::openConfig(fileName); 0145 if (!config) { 0146 return VpnUiPlugin::ExportResult::fail(i18n("%1: file could not be created", fileName)); 0147 } 0148 KConfigGroup cg(config, "main"); 0149 0150 cg.writeEntry("Description", connection->id()); 0151 cg.writeEntry("Host", data.value(NM_VPNC_KEY_GATEWAY)); 0152 if (data.value(NM_VPNC_KEY_AUTHMODE) == QLatin1String("hybrid")) { 0153 cg.writeEntry("AuthType", "5"); 0154 } else { 0155 cg.writeEntry("AuthType", "1"); 0156 } 0157 cg.writeEntry("GroupName", data.value(NM_VPNC_KEY_ID)); 0158 cg.writeEntry("GroupPwd", secretData.value(NM_VPNC_KEY_SECRET)); 0159 cg.writeEntry("UserPassword", secretData.value(NM_VPNC_KEY_XAUTH_PASSWORD)); 0160 cg.writeEntry("enc_GroupPwd", ""); 0161 cg.writeEntry("enc_UserPassword", ""); 0162 if ((NetworkManager::Setting::SecretFlags)data.value(NM_VPNC_KEY_XAUTH_PASSWORD "-flags").toInt() & NetworkManager::Setting::NotSaved) { 0163 cg.writeEntry("SaveUserPassword", "0"); 0164 } 0165 if ((NetworkManager::Setting::SecretFlags)data.value(NM_VPNC_KEY_XAUTH_PASSWORD "-flags").toInt() & NetworkManager::Setting::AgentOwned) { 0166 cg.writeEntry("SaveUserPassword", "1"); 0167 } 0168 if ((NetworkManager::Setting::SecretFlags)data.value(NM_VPNC_KEY_XAUTH_PASSWORD "-flags").toInt() & NetworkManager::Setting::NotRequired) { 0169 cg.writeEntry("SaveUserPassword", "2"); 0170 } 0171 cg.writeEntry("Username", data.value(NM_VPNC_KEY_XAUTH_USER)); 0172 cg.writeEntry("EnableISPConnect", "0"); 0173 cg.writeEntry("ISPConnectType", "0"); 0174 cg.writeEntry("ISPConnect", ""); 0175 cg.writeEntry("ISPCommand", ""); 0176 cg.writeEntry("EnableBackup", "0"); 0177 cg.writeEntry("BackupServer", ""); 0178 cg.writeEntry("CertStore", "0"); 0179 cg.writeEntry("CertName", ""); 0180 cg.writeEntry("CertPath", ""); 0181 cg.writeEntry("CertSubjectName", ""); 0182 cg.writeEntry("CertSerialHash", ""); 0183 cg.writeEntry("DHGroup", data.value(NM_VPNC_KEY_DHGROUP)); 0184 cg.writeEntry("ForceKeepAlives", "0"); 0185 cg.writeEntry("NTDomain", data.value(NM_VPNC_KEY_DOMAIN)); 0186 cg.writeEntry("EnableMSLogon", "0"); 0187 cg.writeEntry("MSLogonType", "0"); 0188 cg.writeEntry("TunnelingMode", "0"); 0189 cg.writeEntry("TcpTunnelingPort", "10000"); 0190 cg.writeEntry("PeerTimeout", data.value(NM_VPNC_KEY_DPD_IDLE_TIMEOUT)); 0191 cg.writeEntry("EnableLocalLAN", "1"); 0192 cg.writeEntry("SendCertChain", "0"); 0193 cg.writeEntry("VerifyCertDN", ""); 0194 cg.writeEntry("EnableSplitDNS", "1"); 0195 cg.writeEntry("SPPhonebook", ""); 0196 if (data.value(NM_VPNC_KEY_SINGLE_DES) == "yes") { 0197 cg.writeEntry("SingleDES", "1"); 0198 } 0199 if (data.value(NM_VPNC_KEY_NAT_TRAVERSAL_MODE) == NM_VPNC_NATT_MODE_CISCO) { 0200 cg.writeEntry("EnableNat", "1"); 0201 } 0202 if (data.value(NM_VPNC_KEY_NAT_TRAVERSAL_MODE) == NM_VPNC_NATT_MODE_NATT) { 0203 cg.writeEntry("EnableNat", "1"); 0204 cg.writeEntry("X-NM-Use-NAT-T", "1"); 0205 } 0206 if (data.value(NM_VPNC_KEY_NAT_TRAVERSAL_MODE) == NM_VPNC_NATT_MODE_NATT_ALWAYS) { 0207 cg.writeEntry("EnableNat", "1"); 0208 cg.writeEntry("X-NM-Force-NAT-T", "1"); 0209 } 0210 // Export X-NM-Routes 0211 NetworkManager::Ipv4Setting::Ptr ipv4Setting = connection->setting(NetworkManager::Setting::Ipv4).dynamicCast<NetworkManager::Ipv4Setting>(); 0212 if (!ipv4Setting->routes().isEmpty()) { 0213 QString routes; 0214 for (const NetworkManager::IpRoute &route : ipv4Setting->routes()) { 0215 routes += route.ip().toString() + QLatin1Char('/') + QString::number(route.prefixLength()) + QLatin1Char(' '); 0216 } 0217 cg.writeEntry("X-NM-Routes", routes.trimmed()); 0218 } 0219 0220 cg.sync(); 0221 0222 return VpnUiPlugin::ExportResult::pass(); 0223 } 0224 0225 #include "vpnc.moc"