diff --git a/vpn/l2tp/CMakeLists.txt b/vpn/l2tp/CMakeLists.txt index 7a0bc43e..03d7992b 100644 --- a/vpn/l2tp/CMakeLists.txt +++ b/vpn/l2tp/CMakeLists.txt @@ -1,28 +1,28 @@ add_definitions(-DTRANSLATION_DOMAIN=\"plasmanetworkmanagement_l2tpui\") set(l2tp_SRCS l2tp.cpp l2tpwidget.cpp l2tpauth.cpp l2tpipsecwidget.cpp l2tppppwidget.cpp ) -ki18n_wrap_ui(l2tp_SRCS l2tp.ui l2tpipsec.ui l2tpauth.ui l2tpppp.ui) +ki18n_wrap_ui(l2tp_SRCS l2tp.ui l2tpipsec.ui l2tpppp.ui) add_library(plasmanetworkmanagement_l2tpui ${l2tp_SRCS}) kcoreaddons_desktop_to_json(plasmanetworkmanagement_l2tpui plasmanetworkmanagement_l2tpui.desktop) target_link_libraries(plasmanetworkmanagement_l2tpui plasmanm_internal plasmanm_editor KF5::CoreAddons KF5::I18n KF5::KIOWidgets KF5::WidgetsAddons ) install(TARGETS plasmanetworkmanagement_l2tpui DESTINATION ${KDE_INSTALL_PLUGINDIR}) install(FILES plasmanetworkmanagement_l2tpui.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) diff --git a/vpn/l2tp/l2tp.cpp b/vpn/l2tp/l2tp.cpp index 89d026d9..08d0e508 100644 --- a/vpn/l2tp/l2tp.cpp +++ b/vpn/l2tp/l2tp.cpp @@ -1,77 +1,76 @@ /* Copyright 2013 Jan Grulich 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 #include -#include "nm-l2tp-service.h" #include "l2tp.h" #include "l2tpwidget.h" #include "l2tpauth.h" K_PLUGIN_CLASS_WITH_JSON(L2tpUiPlugin, "plasmanetworkmanagement_l2tpui.json") L2tpUiPlugin::L2tpUiPlugin(QObject * parent, const QVariantList &) : VpnUiPlugin(parent) { } L2tpUiPlugin::~L2tpUiPlugin() { } SettingWidget * L2tpUiPlugin::widget(const NetworkManager::VpnSetting::Ptr &setting, QWidget * parent) { return new L2tpWidget(setting, parent); } SettingWidget *L2tpUiPlugin::askUser(const NetworkManager::VpnSetting::Ptr &setting, QWidget * parent) { - return new L2tpAuthDialog(setting, parent); + return new L2tpAuthWidget(setting, parent); } QString L2tpUiPlugin::suggestedFileName(const NetworkManager::ConnectionSettings::Ptr &connection) const { Q_UNUSED(connection); return QString(); } QString L2tpUiPlugin::supportedFileExtensions() const { return QString(); } NMVariantMapMap L2tpUiPlugin::importConnectionSettings(const QString &fileName) { Q_UNUSED(fileName); mError = VpnUiPlugin::NotImplemented; return NMVariantMapMap(); } bool L2tpUiPlugin::exportConnectionSettings(const NetworkManager::ConnectionSettings::Ptr &connection, const QString &fileName) { Q_UNUSED(connection); Q_UNUSED(fileName); mError = VpnUiPlugin::NotImplemented; return false; } #include "l2tp.moc" diff --git a/vpn/l2tp/l2tp.ui b/vpn/l2tp/l2tp.ui index 6f541997..9deb16a3 100644 --- a/vpn/l2tp/l2tp.ui +++ b/vpn/l2tp/l2tp.ui @@ -1,221 +1,346 @@ L2tpWidget 0 0 - 450 - 388 + 495 + 422 - - - 6 - - - - - Gateway: - - - - - - - L2TP server IP or name. - - - true - - - - - - - User name: - - - - - - - Set the name used for authenticating the local system to the peer to <name>. - - - true - - - - - - - Password: - - - - - - - + + + + + + + Gateway: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + gateway + + + + + - Password passed to PPPD when prompted for it. + L2TP server IP or name. - + true + + + + Authentication type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + cmbAuthType + + + + + + + + 0 + 0 + + + + Select an authentication mode. + + + + Password + + + + + Certificates (TLS) + + + + - - - - NT Domain: - + + + + + + + + Username: + + + false + + + username + + + + + + + <html><head/><body><p>Set the name used for authenticating the local system to the peer to &lt;name&gt;.</p></body></html> + + + true + + + + + + + Password: + + + password + + + + + + + + + true + + + <html><head/><body><p>Password passed to PPPD when prompted for it.</p></body></html> + + + true + + + + + + + + + NT Domain: + + + domain + + + + + + + <html><head/><body><p>Append the domain name &lt;domain&gt; to the local host name for</p><p>authentication purposes.</p></body></html> + + + + + + + Qt::Vertical + + + + 347 + 200 + + + + + + + + + + + + CA Certificate: + + + false + + + userCA + + + + + + + <html><head/><body><p>Certificate authority (CA) file in .pem, .der, .crt, .crt or .p12 formats.</p></body></html> + + + *.pem *.der *.crt *.cer *.p12 + + + + + + + User Certificate: + + + false + + + userCert + + + + + + + <html><head/><body><p>Certificate in .pem, .der, .crt, .cer or .p12 formats.</p></body></html> + + + *.pem *.der *.crt *.cer *.p12 + + + + + + + Private Key: + + + false + + + userKey + + + + + + + <html><head/><body><p>Private key in .pem, .der, .key, .pk8 or .p12 formats.</p></body></html> + + + *.pem *der *.key *.pk8 *.p12 + + + + + + + Private Key Password: + + + userKeyPassword + + + + + + + + + <html><head/><body><p>Password for private key or PKCS#12 certificate.</p></body></html> + + + true + + + + + + + - - - - Append the domain name <domain> to the local host name for -authentication purposes. - - - true - - - - - - - Qt::Horizontal - - - - - - - - - - - - - - CA Certificate: - - - - - - - Certificate: - - - - - - - Private Key: - - - - - - - Qt::Vertical - - - - 20 - 216 - - - - - - + + Qt::Horizontal - 188 - 22 + 40 + 20 IPsec Settings... PPP Settings... - - - - false - - - - - - - false - - - - - - - false - - - - - - - Use Certificate - - - + KUrlRequester QWidget
kurlrequester.h
PasswordField QLineEdit
passwordfield.h
gateway + cmbAuthType username password domain + userCA + userCert + userKey + userKeyPassword btnIPSecSettings btnPPPSettings - + + + cmbAuthType + currentIndexChanged(int) + stackedWidget + setCurrentIndex(int) + + + 345 + 76 + + + 488 + 234 + + + +
diff --git a/vpn/l2tp/l2tpauth.cpp b/vpn/l2tp/l2tpauth.cpp index 3d14de92..e69f657b 100644 --- a/vpn/l2tp/l2tpauth.cpp +++ b/vpn/l2tp/l2tpauth.cpp @@ -1,92 +1,130 @@ /* - Copyright 2013 Jan Grulich - - 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, + Copyright 2011 Ilia Kats + Copyright 2013 Lukáš Tinkl + Copyright 2020 Douglas Kosovic + + 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 - Lesser General Public License for more details. + 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 Lesser General Public - License along with this library. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "l2tpauth.h" -#include "ui_l2tpauth.h" -#include "nm-l2tp-service.h" +#include "passwordfield.h" #include +#include +#include +#include + +#include -class L2tpAuthDialogPrivate +#include "nm-l2tp-service.h" + +class L2tpAuthWidgetPrivate { public: - Ui_L2tpAuth ui; NetworkManager::VpnSetting::Ptr setting; + QFormLayout *layout; }; -L2tpAuthDialog::L2tpAuthDialog(const NetworkManager::VpnSetting::Ptr &setting, QWidget * parent) +L2tpAuthWidget::L2tpAuthWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget * parent) : SettingWidget(setting, parent) - , d_ptr(new L2tpAuthDialogPrivate) + , d_ptr(new L2tpAuthWidgetPrivate) { - Q_D(L2tpAuthDialog); - d->ui.setupUi(this); + Q_D(L2tpAuthWidget); d->setting = setting; - - KAcceleratorManager::manage(this); + d->layout = new QFormLayout(this); + setLayout(d->layout); readSecrets(); + + KAcceleratorManager::manage(this); } -L2tpAuthDialog::~L2tpAuthDialog() +L2tpAuthWidget::~L2tpAuthWidget() { delete d_ptr; } -void L2tpAuthDialog::readSecrets() +void L2tpAuthWidget::readSecrets() { - Q_D(L2tpAuthDialog); - const NMStringMap data = d->setting->data(); + Q_D(L2tpAuthWidget); const NMStringMap secrets = d->setting->secrets(); - - QString user = data.value(NM_L2TP_KEY_USER); - if (!user.isEmpty()) { - d->ui.leUserName->setText(user); + const NMStringMap dataMap = d->setting->data(); + const QString userAType = dataMap[NM_L2TP_KEY_USER_AUTH_TYPE]; + const QString machineAType = dataMap[NM_L2TP_KEY_MACHINE_AUTH_TYPE]; + QLabel *label; + PasswordField *lineEdit; + + NetworkManager::Setting::SecretFlags passType = (NetworkManager::Setting::SecretFlags)dataMap[NM_L2TP_KEY_PASSWORD"-flags"].toInt(); + NetworkManager::Setting::SecretFlags userCertType = (NetworkManager::Setting::SecretFlags)dataMap[NM_L2TP_KEY_USER_CERTPASS"-flags"].toInt(); + NetworkManager::Setting::SecretFlags machineCertType = (NetworkManager::Setting::SecretFlags)dataMap[NM_L2TP_KEY_MACHINE_CERTPASS"-flags"].toInt(); + + if ((userAType.isEmpty() || userAType == QLatin1String(NM_L2TP_AUTHTYPE_PASSWORD)) && !(passType.testFlag(NetworkManager::Setting::NotRequired))) { + label = new QLabel(this); + label->setText(i18n("User Password:")); + lineEdit = new PasswordField(this); + lineEdit->setPasswordModeEnabled(true); + lineEdit->setProperty("nm_secrets_key", QLatin1String(NM_L2TP_KEY_PASSWORD)); + lineEdit->setText(secrets.value(QLatin1String(NM_L2TP_KEY_PASSWORD))); + d->layout->addRow(label, lineEdit); + } else if (userAType == QLatin1String(NM_L2TP_AUTHTYPE_TLS) && !(userCertType.testFlag(NetworkManager::Setting::NotRequired))) { + label = new QLabel(this); + label->setText(i18n("User Certificate Password:")); + lineEdit = new PasswordField(this); + lineEdit->setPasswordModeEnabled(true); + lineEdit->setProperty("nm_secrets_key", QLatin1String(NM_L2TP_KEY_USER_CERTPASS)); + lineEdit->setText(secrets.value(QLatin1String(NM_L2TP_KEY_USER_CERTPASS))); + d->layout->addRow(label, lineEdit); } - bool haveUserPassword = true; - if (!((NetworkManager::Setting::SecretFlags)data.value(NM_L2TP_KEY_PASSWORD"-flags").toInt()).testFlag(NetworkManager::Setting::NotRequired)) { - d->ui.leUserPassword->setText(secrets.value(QLatin1String(NM_L2TP_KEY_PASSWORD))); - } else { - d->ui.userNameLabel->setVisible(false); - d->ui.leUserName->setVisible(false); - d->ui.userPasswordLabel->setVisible(false); - d->ui.leUserPassword->setVisible(false); - haveUserPassword = false; + + if (machineAType == QLatin1String(NM_L2TP_AUTHTYPE_TLS)) { + if (!(machineCertType.testFlag(NetworkManager::Setting::NotRequired))) { + label = new QLabel(this); + label->setText(i18n("Machine Certificate Password:")); + lineEdit = new PasswordField(this); + lineEdit->setPasswordModeEnabled(true); + lineEdit->setProperty("nm_secrets_key", QLatin1String(NM_L2TP_KEY_MACHINE_CERTPASS)); + lineEdit->setText(secrets.value(QLatin1String(NM_L2TP_KEY_MACHINE_CERTPASS))); + d->layout->addRow(label, lineEdit); + } } - if (haveUserPassword && d->ui.leUserPassword->text().isEmpty()) { - d->ui.leUserPassword->setFocus(Qt::OtherFocusReason); + for (int i = 0; i < d->layout->rowCount(); i++) { + PasswordField *le = qobject_cast(d->layout->itemAt(i, QFormLayout::FieldRole)->widget()); + if (le && le->text().isEmpty()) { + le->setFocus(Qt::OtherFocusReason); + break; + } } } -QVariantMap L2tpAuthDialog::setting() const +QVariantMap L2tpAuthWidget::setting() const { - Q_D(const L2tpAuthDialog); + Q_D(const L2tpAuthWidget); NMStringMap secrets; - QVariantMap result; - - if (!d->ui.leUserPassword->text().isEmpty()) { - secrets.insert(NM_L2TP_KEY_PASSWORD, d->ui.leUserPassword->text()); + QVariantMap secretData; + for (int i = 0; i < d->layout->rowCount(); i++) { + PasswordField *le = qobject_cast(d->layout->itemAt(i, QFormLayout::FieldRole)->widget()); + if (le && !le->text().isEmpty()) { + const QString key = le->property("nm_secrets_key").toString(); + secrets.insert(key, le->text()); + } } - result.insert("secrets", QVariant::fromValue(secrets)); - - return result; + secretData.insert("secrets", QVariant::fromValue(secrets)); + return secretData; } diff --git a/vpn/l2tp/l2tpauth.h b/vpn/l2tp/l2tpauth.h index c0f3c91f..bff5bd4d 100644 --- a/vpn/l2tp/l2tpauth.h +++ b/vpn/l2tp/l2tpauth.h @@ -1,44 +1,45 @@ /* - Copyright 2013 Jan Grulich - - 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, + Copyright 2011 Ilia Kats + Copyright 2013 Lukáš Tinkl + + 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 - Lesser General Public License for more details. + 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 Lesser General Public - License along with this library. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef PLASMA_NM_L2TP_AUTH_H #define PLASMA_NM_L2TP_AUTH_H #include #include "settingwidget.h" -class L2tpAuthDialogPrivate; +class L2tpAuthWidgetPrivate; -class L2tpAuthDialog : public SettingWidget +class L2tpAuthWidget : public SettingWidget { Q_OBJECT - Q_DECLARE_PRIVATE(L2tpAuthDialog) + Q_DECLARE_PRIVATE(L2tpAuthWidget) public: - explicit L2tpAuthDialog(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent = nullptr); - ~L2tpAuthDialog() override; + explicit L2tpAuthWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent = nullptr); + ~L2tpAuthWidget() override; virtual void readSecrets(); QVariantMap setting() const override; private: - L2tpAuthDialogPrivate *const d_ptr; + L2tpAuthWidgetPrivate *const d_ptr; }; #endif // PLASMA_NM_L2TP_AUTH_H diff --git a/vpn/l2tp/l2tpauth.ui b/vpn/l2tp/l2tpauth.ui deleted file mode 100644 index 041e5231..00000000 --- a/vpn/l2tp/l2tpauth.ui +++ /dev/null @@ -1,71 +0,0 @@ - - - L2tpAuth - - - - 0 - 0 - 378 - 133 - - - - - 6 - - - - - Username: - - - leUserName - - - - - - - false - - - Set the name used for authenticating the local system to the peer to <name>. - - - - - - - User Password: - - - false - - - leUserPassword - - - - - - - Password passed to PPPD when prompted for it. - - - true - - - - - - - - PasswordField - QLineEdit -
passwordfield.h
-
-
- - -
diff --git a/vpn/l2tp/l2tpipsec.ui b/vpn/l2tp/l2tpipsec.ui index 112d1d36..41eb587f 100644 --- a/vpn/l2tp/l2tpipsec.ui +++ b/vpn/l2tp/l2tpipsec.ui @@ -1,303 +1,480 @@ L2tpIpsecWidget 0 0 - 382 - 254 + 538 + 660 - - - 6 - - - - - Enable IPsec tunnel to L2TP host - - - - - - - false - - - Gateway ID: - - - - - - - false - - - - - - - false - - - Pre-shared Key: - - - - - + + + - false - - true - - - - - - false - - - Phase1 algorithms: - - - - - - - false - - - - - - - false - - - Phase2 algorithms: - - - - - - - false - - - - - - - false + + Enable IPsec tunnel to L2TP host - - Enforce UDP encapsulation + + true true + + + + + + 0 + 0 + + + + Machine Authentication + + + + + + + + Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + cmbAuthType + + + + + + + + 0 + 0 + + + + Select an authentication mode. + + + + Pre-shared Key (PSK) + + + + + Certificates (TLS) + + + + + + + + + + + + + + Pre-shared Key: + + + presharedKey + + + + + + + + + <html><head/><body><p>Pre-shared key (PSK) secret.</p></body></html> + + + true + + + + + + + + + + + + + <html><head/><body><p>Certificate authority (CA) file in .pem, .der, .crt, .crt or .p12 formats.</p></body></html> + + + *.pem *.der *.crt *.cer *.p12 + + + + + + + Machine Certificate: + + + false + + + machineCert + + + + + + + <html><head/><body><p>Certificate in .pem, .der or .p12 formats.</p></body></html> + + + *.pem *.der *.crt *.cer *.p12 + + + + + + + Private Key: + + + false + + + machineKey + + + + + + + <html><head/><body><p>Private key in .pem, .der, .key, .pk8 or .p12 formats.</p></body></html> + + + *.pem *der *.key *.pk8 *.p12 + + + + + + + Private Key Password: + + + machineKeyPassword + + + + + + + + + <html><head/><body><p>Password for private key or PKCS#12 certificate.</p></body></html> + + + true + + + + + + + + + CA Certificate: + + + false + + + machineCA + + + + + + + + + + + + + + Advanced + + + + + + Phase1 Algorithms: + + + ike + + + + + + + Phase2 Algorithms: + + + esp + + + + + + + <html><head/><body><p>Optional. A list of proposals for ESP - Quick Mode. The format is “enc-integ,enc-integ, …”.</p></body></html> + + + + + + + false + + + <html><head/><body><p>How long the keying channel of a connection should last before being renegotiated.</p></body></html> + + + hh:mm:ss + + + + + + + Phase1 Lifetime: + + + + + + + <html><head/><body><p>Optional. A list of proposals for IKE - Main Mode. The format is “enc-integ-group,enc-integ-group, …”.</p></body></html> + + + + + + + Phase2 Lifetime: + + + + + + + false + + + <html><head/><body><p>How long a particular instance of a connection (a set of encryption/authentication keys for user packets) should last, from successful negotiation to expiry.</p></body></html> + + + hh:mm:ss + + + + + + + <html><head/><body><p>Optional. How the IPsec server should be identified for authentication. Sometimes referred to as Peer ID or Gateway ID, also referred to as rightid by strongSwan, Libreswan, Openswan and FreeS/WAN. See strongSwan or Libreswan documentation for leftid/rightid syntax and identity parsing.</p></body></html> + + + + + + + <html><head/><body><p>IPComp compresses raw IP packets before they get encrypted. This saves some bandwidth, but uses more processing power.</p></body></html> + + + Use IP compression + + + + + + + <html><head/><body><p>Disable perfect forward security. Enable this option only if the server doesn’t support PFS.</p></body></html> + + + Disable PFS + + + + + + + <html><head/><body><p>Some firewalls block ESP traffic. Enforcing UDP encapsulation even if no NAT situation is detected might help in such cases.</p></body></html> + + + Enforce UDP encapsulation + + + false + + + + + + + Remote ID: + + + remoteId + + + + + + + + + + Qt::Vertical + + + + 510 + 0 + + + + + - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + buttonBox + gbEnableTunnelToHost + + + KUrlRequester + QWidget +
kurlrequester.h
+
PasswordField QLineEdit
passwordfield.h
+ + cmbAuthType + presharedKey + machineCA + machineCert + machineKey + machineKeyPassword + - cbEnableTunnelToHost - toggled(bool) - gatewayId - setEnabled(bool) - - - 159 - 14 - - - 209 - 65 - - - - - cbEnableTunnelToHost - toggled(bool) - presharedKey - setEnabled(bool) + cmbAuthType + currentIndexChanged(int) + stackedWidget + setCurrentIndex(int) - 159 - 14 + 345 + 76 - 209 - 91 + 488 + 234 - cbEnableTunnelToHost - toggled(bool) - ike - setEnabled(bool) + buttonBox + accepted() + L2tpIpsecWidget + accept() 190 - 16 + 119 - 209 - 65 - - - - - cbEnableTunnelToHost - toggled(bool) - esp - setEnabled(bool) - - 190 - 16 - - - 209 - 65 + 68 - cbEnableTunnelToHost - toggled(bool) - cbForceEncaps - setEnabled(bool) + buttonBox + rejected() + L2tpIpsecWidget + reject() 190 - 16 + 119 - 209 - 65 - - - - - cbEnableTunnelToHost - toggled(bool) - label_2 - setEnabled(bool) - - 190 - 16 - - - 75 - 87 + 68 - cbEnableTunnelToHost + cbIkelifetime toggled(bool) - label + ikelifetime setEnabled(bool) - 190 - 16 - - 86 - 49 - - - - - cbEnableTunnelToHost - toggled(bool) - label_3 - setEnabled(bool) - - - 190 - 16 + 393 - 64 - 125 + 314 + 393 - cbEnableTunnelToHost + cbSalifetime toggled(bool) - label_4 + salifetime setEnabled(bool) - 190 - 16 - - - 64 - 163 - - - - - buttonBox - accepted() - L2tpIpsecWidget - accept() - - - 190 - 119 - - - 190 - 68 - - - - - buttonBox - rejected() - L2tpIpsecWidget - reject() - - - 190 - 119 + 86 + 418 - 190 - 68 + 314 + 418
diff --git a/vpn/l2tp/l2tpipsecwidget.cpp b/vpn/l2tp/l2tpipsecwidget.cpp index f42a5951..3f4748ae 100644 --- a/vpn/l2tp/l2tpipsecwidget.cpp +++ b/vpn/l2tp/l2tpipsecwidget.cpp @@ -1,93 +1,396 @@ /* Copyright 2013 Jan Grulich + Copyright 2020 Douglas Kosovic 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 +#include #include "l2tpipsecwidget.h" #include "ui_l2tpipsec.h" #include "nm-l2tp-service.h" #include #include +#define DEFAULT_IPSEC_STRONGSWAN_IKELIFETIME_HOURS 3 +#define DEFAULT_IPSEC_STRONGSWAN_LIFETIME_HOURS 1 + +#define DEFAULT_IPSEC_LIBRESWAN_IKELIFETIME_HOURS 1 +#define DEFAULT_IPSEC_LIBRESWAN_SALIFETIME_HOURS 8 + L2tpIpsecWidget::L2tpIpsecWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent) : QDialog(parent) , m_ui(new Ui::L2tpIpsecWidget) { m_ui->setupUi(this); + m_ui->machineKeyPassword->setPasswordOptionsEnabled(true); + m_ui->machineKeyPassword->setPasswordNotRequiredEnabled(true); + + // use requesters' urlSelected signals to set other requester's startDirs to save clicking + // around the filesystem, also if it is a .p12 file, set the other URLs to that .p12 file. + QList requesters; + requesters << m_ui->machineCA << m_ui->machineCert << m_ui->machineKey; + for (const KUrlRequester *requester : requesters) { + connect(requester, &KUrlRequester::urlSelected, this, &L2tpIpsecWidget::updateStartDirUrl); + } + + connect(m_ui->cbIkelifetime, &QCheckBox::toggled, this, &L2tpIpsecWidget::setDefaultIkelifetime); + connect(m_ui->cbSalifetime, &QCheckBox::toggled, this, &L2tpIpsecWidget::setDefaultSalifetime); + connect(m_ui->cmbAuthType, QOverload::of(&QComboBox::currentIndexChanged), this, &L2tpIpsecWidget::resizeStackedWidget); setWindowTitle(i18n("L2TP IPsec Options")); KAcceleratorManager::manage(this); loadConfig(setting); + + resizeStackedWidget(m_ui->cmbAuthType->currentIndex()); } L2tpIpsecWidget::~L2tpIpsecWidget() { delete m_ui; } void L2tpIpsecWidget::loadConfig(const NetworkManager::VpnSetting::Ptr &setting) { - if (setting->data().value(NM_L2TP_KEY_IPSEC_ENABLE) == "yes") { - m_ui->cbEnableTunnelToHost->setChecked(true); - m_ui->gatewayId->setText(setting->data().value(NM_L2TP_KEY_IPSEC_GATEWAY_ID)); - m_ui->presharedKey->setText(setting->data().value(NM_L2TP_KEY_IPSEC_PSK)); - m_ui->ike->setText(setting->data().value(NM_L2TP_KEY_IPSEC_IKE)); - m_ui->esp->setText(setting->data().value(NM_L2TP_KEY_IPSEC_ESP)); - if (setting->data().value(NM_L2TP_KEY_IPSEC_FORCEENCAPS) == "yes" ) { - m_ui->cbForceEncaps->setChecked(true); + const QString yesString = QLatin1String("yes"); + const QString noString = QLatin1String("no"); + + // General settings + const NMStringMap dataMap = setting->data(); + + if (!hasIpsecDaemon()) { + m_ui->gbEnableTunnelToHost->setChecked(false); + m_ui->gbEnableTunnelToHost->setDisabled(true); + } else if (dataMap[NM_L2TP_KEY_IPSEC_ENABLE] == yesString) { + m_ui->gbEnableTunnelToHost->setChecked(true); + + if (dataMap[NM_L2TP_KEY_MACHINE_AUTH_TYPE].isEmpty() + || dataMap[NM_L2TP_KEY_MACHINE_AUTH_TYPE] == QLatin1String(NM_L2TP_AUTHTYPE_PSK)) { + m_ui->cmbAuthType->setCurrentIndex(AuthType::PSK); + m_ui->stackedWidget->setCurrentIndex(AuthType::PSK); + + // *SWAN support Base64 encoded PSKs that are prefixed with "0s" + QString psk = dataMap[NM_L2TP_KEY_IPSEC_PSK]; + if (psk.length() > 2 && psk.startsWith(QLatin1String("0s"))) { + m_ui->presharedKey->setText(QByteArray::fromBase64(psk.mid(2).toUtf8())); + } else { + m_ui->presharedKey->setText(psk); + } + + } else { // NM_L2TP_AUTHTYPE_TLS + m_ui->cmbAuthType->setCurrentIndex(AuthType::TLS); + m_ui->stackedWidget->setCurrentIndex(AuthType::TLS); + + m_ui->machineCA->setUrl(QUrl::fromLocalFile(dataMap[NM_L2TP_KEY_MACHINE_CA])); + m_ui->machineCert->setUrl(QUrl::fromLocalFile(dataMap[NM_L2TP_KEY_MACHINE_CERT])); + m_ui->machineKey->setUrl(QUrl::fromLocalFile(dataMap[NM_L2TP_KEY_MACHINE_KEY])); + + const NetworkManager::Setting::SecretFlags machineKeyPassType = static_cast(dataMap[NM_L2TP_KEY_MACHINE_CERTPASS"-flags"].toInt()); + if (machineKeyPassType.testFlag(NetworkManager::Setting::None)) { + m_ui->machineKeyPassword->setPasswordOption(PasswordField::StoreForAllUsers); + } else if (machineKeyPassType.testFlag(NetworkManager::Setting::AgentOwned)) { + m_ui->machineKeyPassword->setPasswordOption(PasswordField::StoreForUser); + } else if (machineKeyPassType.testFlag(NetworkManager::Setting::NotSaved)) { + m_ui->machineKeyPassword->setPasswordOption(PasswordField::AlwaysAsk); + } else if (machineKeyPassType.testFlag(NetworkManager::Setting::NotRequired)) { + m_ui->machineKeyPassword->setPasswordOption(PasswordField::NotRequired); + } + } + + if (!dataMap[NM_L2TP_KEY_IPSEC_GATEWAY_ID].isEmpty()) { + m_ui->remoteId->setText(dataMap[NM_L2TP_KEY_IPSEC_GATEWAY_ID]); + } else { + m_ui->remoteId->setText(dataMap[NM_L2TP_KEY_IPSEC_REMOTE_ID]); + } + m_ui->ike->setText(dataMap[NM_L2TP_KEY_IPSEC_IKE]); + m_ui->esp->setText(dataMap[NM_L2TP_KEY_IPSEC_ESP]); + + if (!dataMap[NM_L2TP_KEY_IPSEC_IKELIFETIME].isEmpty()) { + const int totalSeconds = dataMap[NM_L2TP_KEY_IPSEC_IKELIFETIME].toInt(); + const int hours = totalSeconds / 3600; + const int minutes = (totalSeconds % 3600) / 60; + const int seconds = totalSeconds % 60; + const QTime lifetime = QTime(hours, minutes, seconds); + + m_ui->ikelifetime->setTime(lifetime); + m_ui->ikelifetime->setEnabled(true); + m_ui->cbIkelifetime->setChecked(true); + } else { + setDefaultIkelifetime(false); + m_ui->ikelifetime->setEnabled(false); + m_ui->cbIkelifetime->setChecked(false); + } + + if (!dataMap[NM_L2TP_KEY_IPSEC_SALIFETIME].isEmpty()) { + const int totalSeconds = dataMap[NM_L2TP_KEY_IPSEC_SALIFETIME].toInt(); + const int hours = totalSeconds / 3600; + const int minutes = (totalSeconds % 3600) / 60; + const int seconds = totalSeconds % 60; + const QTime lifetime = QTime(hours, minutes, seconds); + + m_ui->salifetime->setTime(lifetime); + m_ui->salifetime->setEnabled(true); + m_ui->cbSalifetime->setChecked(true); } else { - m_ui->cbForceEncaps->setChecked(false); + setDefaultSalifetime(false); + m_ui->salifetime->setEnabled(false); + m_ui->cbSalifetime->setChecked(false); + } + + m_ui->cbForceEncaps->setChecked(dataMap[NM_L2TP_KEY_IPSEC_FORCEENCAPS] == yesString); + m_ui->cbIPComp->setChecked(dataMap[NM_L2TP_KEY_IPSEC_IPCOMP] == yesString); + + if (m_ipsecDaemonType == IpsecDaemonType::Libreswan) { + m_ui->cbPFS->setChecked(dataMap[NM_L2TP_KEY_IPSEC_PFS] == noString); + } else { + m_ui->cbPFS->setChecked(false); + m_ui->cbPFS->setDisabled(true); + m_ui->cbPFS->setToolTip(""); } } else { - m_ui->cbEnableTunnelToHost->setChecked(false); + m_ui->gbEnableTunnelToHost->setChecked(false); + setDefaultIkelifetime(false); + setDefaultSalifetime(false); + if (m_ipsecDaemonType == IpsecDaemonType::Strongswan) { + m_ui->cbPFS->setDisabled(true); + m_ui->cbPFS->setToolTip(""); + } } } NMStringMap L2tpIpsecWidget::setting() const { NMStringMap result; + const QString yesString = QLatin1String("yes"); + const QString noString = QLatin1String("no"); + + if (m_ui->gbEnableTunnelToHost->isChecked()) { + result.insert(NM_L2TP_KEY_IPSEC_ENABLE, yesString); + + if (m_ui->cmbAuthType->currentIndex() == AuthType::PSK) { + // NetworkManager-l2tp < 1.2.12 does not support Base64 PSK + // For backwards compatibilty don't use Base64 PSK for now. + if (!m_ui->presharedKey->text().isEmpty()) { + result.insert(NM_L2TP_KEY_IPSEC_PSK, m_ui->presharedKey->text()); + // *SWAN support Base64 encoded PSKs that are prefixed with "0s" + /* + QString psk = QLatin1String("0s"); + psk.append(m_ui->presharedKey->text().toUtf8().toBase64()); + result.insert(NM_L2TP_KEY_IPSEC_PSK, psk); + */ + } + } else { // AuthType::TLS - if (m_ui->cbEnableTunnelToHost->isChecked()) { - result.insert(NM_L2TP_KEY_IPSEC_ENABLE, "yes"); + result.insert(NM_L2TP_KEY_MACHINE_AUTH_TYPE, NM_L2TP_AUTHTYPE_TLS); - if (!m_ui->gatewayId->text().isEmpty()) { - result.insert(NM_L2TP_KEY_IPSEC_GATEWAY_ID, m_ui->gatewayId->text()); + result.insert(NM_L2TP_KEY_MACHINE_CA, m_ui->machineCA->url().toLocalFile()); + result.insert(NM_L2TP_KEY_MACHINE_CERT, m_ui->machineCert->url().toLocalFile()); + result.insert(NM_L2TP_KEY_MACHINE_KEY, m_ui->machineKey->url().toLocalFile()); + + switch (m_ui->machineKeyPassword->passwordOption()) { + case PasswordField::StoreForAllUsers: + result.insert(NM_L2TP_KEY_MACHINE_CERTPASS"-flags", + QString::number(NetworkManager::Setting::None)); + break; + case PasswordField::StoreForUser: + result.insert(NM_L2TP_KEY_MACHINE_CERTPASS"-flags", + QString::number(NetworkManager::Setting::AgentOwned)); + break; + case PasswordField::AlwaysAsk: + result.insert(NM_L2TP_KEY_MACHINE_CERTPASS"-flags", + QString::number(NetworkManager::Setting::NotSaved)); + break; + case PasswordField::NotRequired: + result.insert(NM_L2TP_KEY_MACHINE_CERTPASS"-flags", + QString::number(NetworkManager::Setting::NotRequired)); + break; + }; } - if (!m_ui->presharedKey->text().isEmpty()) { - result.insert(NM_L2TP_KEY_IPSEC_PSK, m_ui->presharedKey->text()); + // NetworkManager-l2tp 1.2.12 recommends NM_L2TP_KEY_IPSEC_REMOTE_ID + // instead of deprecated NM_L2TP_KEY_IPSEC_GATEWAY_ID + // For backwards compatibilty use NM_L2TP_KEY_IPSEC_GATEWAY_ID for now. + if (!m_ui->remoteId->text().isEmpty()) { + result.insert(NM_L2TP_KEY_IPSEC_GATEWAY_ID, m_ui->remoteId->text()); } if (!m_ui->ike->text().isEmpty()) { result.insert(NM_L2TP_KEY_IPSEC_IKE, m_ui->ike->text()); } if (!m_ui->esp->text().isEmpty()) { result.insert(NM_L2TP_KEY_IPSEC_ESP, m_ui->esp->text()); } if (m_ui->cbForceEncaps->isChecked()) { - result.insert(NM_L2TP_KEY_IPSEC_FORCEENCAPS, "yes"); + result.insert(NM_L2TP_KEY_IPSEC_FORCEENCAPS, yesString); + } + + if (m_ui->cbIkelifetime->isChecked()) { + const int totalSeconds = m_ui->ikelifetime->time().hour() * 3600 + m_ui->ikelifetime->time().minute() * 60 + m_ui->ikelifetime->time().second(); + + result.insert(NM_L2TP_KEY_IPSEC_IKELIFETIME, QString::number(totalSeconds)); + } + + if (m_ui->cbSalifetime->isChecked()) { + const int totalSeconds = m_ui->salifetime->time().hour() * 3600 + m_ui->salifetime->time().minute() * 60 + m_ui->salifetime->time().second(); + + result.insert(NM_L2TP_KEY_IPSEC_SALIFETIME, QString::number(totalSeconds)); + } + + if (m_ui->cbIPComp->isChecked()) { + result.insert(NM_L2TP_KEY_IPSEC_IPCOMP, yesString); + } + + if (m_ipsecDaemonType == IpsecDaemonType::Libreswan) { + if (m_ui->cbPFS->isChecked()) { + result.insert(NM_L2TP_KEY_IPSEC_PFS, noString); + } + } + } + + return result; +} + +NMStringMap L2tpIpsecWidget::secrets() const +{ + NMStringMap result; + + if (m_ui->gbEnableTunnelToHost->isChecked()) { + if (m_ui->cmbAuthType->currentIndex() == AuthType::TLS) { + + // private key password + if (!m_ui->machineKeyPassword->text().isEmpty()) { + result.insert(NM_L2TP_KEY_MACHINE_CERTPASS, m_ui->machineKeyPassword->text()); + } } } return result; } + +void L2tpIpsecWidget::updateStartDirUrl(const QUrl &url) +{ + QList requesters; + requesters << m_ui->machineCA << m_ui->machineCert << m_ui->machineKey; + const bool isP12 = url.toString().endsWith(QLatin1String(".p12")); + + for (KUrlRequester *requester : requesters) { + requester->setStartDir(url.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash)); + if (isP12) { + requester->setUrl(url); + } + } +} + +void L2tpIpsecWidget::setDefaultIkelifetime(bool isChecked) +{ + if (!isChecked) { + QTime lifetime; + if (m_ipsecDaemonType == IpsecDaemonType::Libreswan) { + lifetime = QTime(DEFAULT_IPSEC_LIBRESWAN_IKELIFETIME_HOURS, 0, 0); + } else { + lifetime = QTime(DEFAULT_IPSEC_STRONGSWAN_IKELIFETIME_HOURS, 0, 0); + } + m_ui->ikelifetime->setTime(lifetime); + } +} + +void L2tpIpsecWidget::setDefaultSalifetime(bool isChecked) +{ + if (!isChecked) { + QTime lifetime; + if (m_ipsecDaemonType == IpsecDaemonType::Libreswan) { + lifetime = QTime(DEFAULT_IPSEC_LIBRESWAN_SALIFETIME_HOURS, 0, 0); + } else { + lifetime = QTime(DEFAULT_IPSEC_STRONGSWAN_LIFETIME_HOURS, 0, 0); + } + m_ui->salifetime->setTime(lifetime); + } +} + +void L2tpIpsecWidget::resizeStackedWidget(int currentIndex) +{ + m_ui->stackedWidget->setCurrentIndex(currentIndex); + for (int i = 0; i < m_ui->stackedWidget->count(); ++i) { + QSizePolicy::Policy policy; + + if (i == currentIndex) { + policy = QSizePolicy::Preferred; + } else { + policy = QSizePolicy::Ignored; + } + m_ui->stackedWidget->widget(i)->setSizePolicy(QSizePolicy::Preferred, policy); + } + QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + resize(width(), sizeHint().height()); +} + +L2tpIpsecWidget::IpsecDaemonType L2tpIpsecWidget::m_ipsecDaemonType = IpsecDaemonType::NoIpsecDaemon; + +bool L2tpIpsecWidget::hasIpsecDaemon() +{ + // NetworkManager-l2tp currently only supports libreswan and strongswan + if (m_ipsecDaemonType == IpsecDaemonType::Libreswan + || m_ipsecDaemonType == IpsecDaemonType::Strongswan) { + return true; + } + + QString ipsecBinary = QStandardPaths::findExecutable("ipsec", + QStringList() << "/sbin" << "/usr/sbin"); + + // On some Linux distributions, ipsec executable has been renamed strongswan + if (ipsecBinary.isEmpty()) { + ipsecBinary = QStandardPaths::findExecutable("strongswan", + QStringList() << "/sbin" << "/usr/sbin"); + } + + if (ipsecBinary.isEmpty()) { + m_ipsecDaemonType = IpsecDaemonType::NoIpsecDaemon; + return false; + } + + QProcess ipsecVersionProcess; + ipsecVersionProcess.setProgram(ipsecBinary); + ipsecVersionProcess.setArguments(QStringList() << "--version"); + ipsecVersionProcess.start(); + ipsecVersionProcess.waitForFinished(-1); + + if (ipsecVersionProcess.exitStatus() == QProcess::NormalExit) { + QString ipsecStdout = ipsecVersionProcess.readAllStandardOutput(); + + if (ipsecStdout.contains(" strongSwan ", Qt::CaseSensitive)) { + L2tpIpsecWidget::m_ipsecDaemonType = IpsecDaemonType::Strongswan; + } else if (ipsecStdout.contains(" Libreswan ", Qt::CaseSensitive)) { + L2tpIpsecWidget::m_ipsecDaemonType = IpsecDaemonType::Libreswan; + } else if (ipsecStdout.contains(" Openswan ", Qt::CaseSensitive)) { + L2tpIpsecWidget::m_ipsecDaemonType = IpsecDaemonType::Openswan; + } else { + L2tpIpsecWidget::m_ipsecDaemonType = IpsecDaemonType::UnknownIpsecDaemon; + } + } + + if (m_ipsecDaemonType == IpsecDaemonType::Libreswan + || m_ipsecDaemonType == IpsecDaemonType::Strongswan) { + return true; + } + return false; +} diff --git a/vpn/l2tp/l2tpipsecwidget.h b/vpn/l2tp/l2tpipsecwidget.h index d7db8efd..533f3e1a 100644 --- a/vpn/l2tp/l2tpipsecwidget.h +++ b/vpn/l2tp/l2tpipsecwidget.h @@ -1,47 +1,62 @@ /* Copyright 2013 Jan Grulich + Copyright 2020 Douglas Kosovic 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 . */ #ifndef PLASMA_NM_L2TP_IPSEC_WIDGET_H #define PLASMA_NM_L2TP_IPSEC_WIDGET_H #include #include namespace Ui { class L2tpIpsecWidget; } class L2tpIpsecWidget : public QDialog { Q_OBJECT + + enum AuthType {PSK = 0, TLS}; + enum IpsecDaemonType {NoIpsecDaemon, Libreswan, Strongswan, Openswan, UnknownIpsecDaemon}; + public: explicit L2tpIpsecWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent = nullptr); ~L2tpIpsecWidget() override; NMStringMap setting() const; + NMStringMap secrets() const; + + static bool hasIpsecDaemon(); + +private Q_SLOTS: + void updateStartDirUrl(const QUrl &); + void setDefaultIkelifetime(bool isChecked); + void setDefaultSalifetime(bool isChecked); + void resizeStackedWidget(int currentIndex); private: void loadConfig(const NetworkManager::VpnSetting::Ptr &setting); Ui::L2tpIpsecWidget * m_ui; + static IpsecDaemonType m_ipsecDaemonType; }; #endif // PLASMA_NM_L2TP_IPSEC_WIDGET_H diff --git a/vpn/l2tp/l2tppppwidget.cpp b/vpn/l2tp/l2tppppwidget.cpp index f047a6ef..d19512d4 100644 --- a/vpn/l2tp/l2tppppwidget.cpp +++ b/vpn/l2tp/l2tppppwidget.cpp @@ -1,201 +1,210 @@ /* Copyright 2013 Jan Grulich + Copyright 2020 Douglas Kosovic 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 "l2tppppwidget.h" #include "ui_l2tpppp.h" #include "nm-l2tp-service.h" #include #include -L2tpPPPWidget::L2tpPPPWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent) +L2tpPPPWidget::L2tpPPPWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent, bool need_peer_eap) : QDialog(parent) , m_ui(new Ui::L2tpPppWidget) + , m_need_peer_eap(need_peer_eap) { m_ui->setupUi(this); setWindowTitle(i18n("L2TP PPP Options")); KAcceleratorManager::manage(this); loadConfig(setting); } L2tpPPPWidget::~L2tpPPPWidget() { delete m_ui; } void L2tpPPPWidget::loadConfig(const NetworkManager::VpnSetting::Ptr &setting) { + const QString yesString = QLatin1String("yes"); + // General settings const NMStringMap dataMap = setting->data(); - // Authentication options - const QString yesString = QLatin1String("yes"); - bool refuse_pap = (dataMap[NM_L2TP_KEY_REFUSE_PAP] == yesString); - bool refuse_chap = (dataMap[NM_L2TP_KEY_REFUSE_CHAP] == yesString); - bool refuse_mschap = (dataMap[NM_L2TP_KEY_REFUSE_MSCHAP] == yesString); - bool refuse_mschapv2 = (dataMap[NM_L2TP_KEY_REFUSE_MSCHAPV2] == yesString); - bool refuse_eap = (dataMap[NM_L2TP_KEY_REFUSE_EAP] == yesString); - - QListWidgetItem * item = nullptr; - item = m_ui->listWidget->item(0); // PAP - item->setCheckState(refuse_pap ? Qt::Unchecked : Qt::Checked); - item = m_ui->listWidget->item(1); // CHAP - item->setCheckState(refuse_chap ? Qt::Unchecked : Qt::Checked); - item = m_ui->listWidget->item(2); // MSCHAP - item->setCheckState(refuse_mschap ? Qt::Unchecked : Qt::Checked); - item = m_ui->listWidget->item(3); // MSCHAPv2 - item->setCheckState(refuse_mschapv2 ? Qt::Unchecked : Qt::Checked); - item = m_ui->listWidget->item(4); // EAP - item->setCheckState(refuse_eap ? Qt::Unchecked : Qt::Checked); + if (m_need_peer_eap) { + m_ui->grp_authenfication->setVisible(false); + resize(width(), sizeHint().height()); + } else { + // Authentication options + const bool refuse_pap = (dataMap[NM_L2TP_KEY_REFUSE_PAP] == yesString); + const bool refuse_chap = (dataMap[NM_L2TP_KEY_REFUSE_CHAP] == yesString); + const bool refuse_mschap = (dataMap[NM_L2TP_KEY_REFUSE_MSCHAP] == yesString); + const bool refuse_mschapv2 = (dataMap[NM_L2TP_KEY_REFUSE_MSCHAPV2] == yesString); + const bool refuse_eap = (dataMap[NM_L2TP_KEY_REFUSE_EAP] == yesString); + + QListWidgetItem * item = nullptr; + item = m_ui->listWidget->item(0); // PAP + item->setCheckState(refuse_pap ? Qt::Unchecked : Qt::Checked); + item = m_ui->listWidget->item(1); // CHAP + item->setCheckState(refuse_chap ? Qt::Unchecked : Qt::Checked); + item = m_ui->listWidget->item(2); // MSCHAP + item->setCheckState(refuse_mschap ? Qt::Unchecked : Qt::Checked); + item = m_ui->listWidget->item(3); // MSCHAPv2 + item->setCheckState(refuse_mschapv2 ? Qt::Unchecked : Qt::Checked); + item = m_ui->listWidget->item(4); // EAP + item->setCheckState(refuse_eap ? Qt::Unchecked : Qt::Checked); + } // Cryptography and compression const bool mppe = (dataMap[NM_L2TP_KEY_REQUIRE_MPPE] == yesString); const bool mppe40 = (dataMap[NM_L2TP_KEY_REQUIRE_MPPE_40] == yesString); const bool mppe128 = (dataMap[NM_L2TP_KEY_REQUIRE_MPPE_128] == yesString); const bool mppe_stateful = (dataMap[NM_L2TP_KEY_MPPE_STATEFUL] == yesString); if (mppe || mppe40 || mppe128) { // If MPPE is use m_ui->gbMPPE->setChecked(mppe || mppe40 || mppe128); if (mppe128) { m_ui->cbMPPECrypto->setCurrentIndex(1); // 128 bit } else if (mppe40) { m_ui->cbMPPECrypto->setCurrentIndex(2); // 40 bit } else { m_ui->cbMPPECrypto->setCurrentIndex(0); // Any } m_ui->cbstatefulEncryption->setChecked(mppe_stateful); } const bool nobsd = (dataMap[NM_L2TP_KEY_NOBSDCOMP] == yesString); m_ui->cbBSD->setChecked(!nobsd); const bool nodeflate = (dataMap[NM_L2TP_KEY_NODEFLATE] == yesString); m_ui->cbdeflate->setChecked(!nodeflate); const bool novjcomp = (dataMap[NM_L2TP_KEY_NO_VJ_COMP] == yesString); m_ui->cbTCPheaders->setChecked(!novjcomp); const bool nopcomp = (dataMap[NM_L2TP_KEY_NO_PCOMP] == yesString); m_ui->cbCompressionNegotiation->setChecked(!nopcomp); const bool noaccomp = (dataMap[NM_L2TP_KEY_NO_ACCOMP] == yesString); m_ui->cbAddressControlCompression->setChecked(!noaccomp); // Echo const int lcp_echo_interval = QString(dataMap[NM_L2TP_KEY_LCP_ECHO_INTERVAL]).toInt(); m_ui->cbsendEcho->setChecked(lcp_echo_interval > 0); if (dataMap.contains(QLatin1String(NM_L2TP_KEY_MTU))) { m_ui->sbMTU->setValue(QString(dataMap[NM_L2TP_KEY_MTU]).toInt()); } if (dataMap.contains(QLatin1String(NM_L2TP_KEY_MTU))) { m_ui->sbMRU->setValue(QString(dataMap[NM_L2TP_KEY_MRU]).toInt()); } } NMStringMap L2tpPPPWidget::setting() const { NMStringMap result; - - QListWidgetItem * item = nullptr; - item = m_ui->listWidget->item(0); // PAP const QString yesString = QLatin1String("yes"); - if (item->checkState() == Qt::Unchecked) { - result.insert(NM_L2TP_KEY_REFUSE_PAP, yesString); - } - item = m_ui->listWidget->item(1); // CHAP - if (item->checkState() == Qt::Unchecked) { - result.insert(NM_L2TP_KEY_REFUSE_CHAP, yesString); - } - item = m_ui->listWidget->item(2); // MSCHAP - if (item->checkState() == Qt::Unchecked) { - result.insert(NM_L2TP_KEY_REFUSE_MSCHAP, yesString); - } - item = m_ui->listWidget->item(3); // MSCHAPv2 - if (item->checkState() == Qt::Unchecked) { - result.insert(NM_L2TP_KEY_REFUSE_MSCHAPV2, yesString); - } - item = m_ui->listWidget->item(4); // EAP - if (item->checkState() == Qt::Unchecked) { - result.insert(NM_L2TP_KEY_REFUSE_EAP, yesString); + if (!m_need_peer_eap) { + QListWidgetItem * item = nullptr; + item = m_ui->listWidget->item(0); // PAP + if (item->checkState() == Qt::Unchecked) { + result.insert(NM_L2TP_KEY_REFUSE_PAP, yesString); + } + item = m_ui->listWidget->item(1); // CHAP + if (item->checkState() == Qt::Unchecked) { + result.insert(NM_L2TP_KEY_REFUSE_CHAP, yesString); + } + item = m_ui->listWidget->item(2); // MSCHAP + if (item->checkState() == Qt::Unchecked) { + result.insert(NM_L2TP_KEY_REFUSE_MSCHAP, yesString); + } + item = m_ui->listWidget->item(3); // MSCHAPv2 + if (item->checkState() == Qt::Unchecked) { + result.insert(NM_L2TP_KEY_REFUSE_MSCHAPV2, yesString); + } + item = m_ui->listWidget->item(4); // EAP + if (item->checkState() == Qt::Unchecked) { + result.insert(NM_L2TP_KEY_REFUSE_EAP, yesString); + } } // Cryptography and compression if (m_ui->gbMPPE->isChecked()) { int index = m_ui->cbMPPECrypto->currentIndex(); switch (index) { case 0: // "Any" result.insert(NM_L2TP_KEY_REQUIRE_MPPE, yesString); break; case 1: // "128 bit" result.insert(NM_L2TP_KEY_REQUIRE_MPPE_128, yesString); break; case 2: // "40 bit" result.insert(NM_L2TP_KEY_REQUIRE_MPPE_40, yesString); break; } if (m_ui->cbstatefulEncryption->isChecked()) { result.insert(NM_L2TP_KEY_MPPE_STATEFUL, yesString); } } if (!m_ui->cbBSD->isChecked()) { result.insert(NM_L2TP_KEY_NOBSDCOMP, yesString); } if (!m_ui->cbdeflate->isChecked()) { result.insert(NM_L2TP_KEY_NODEFLATE, yesString); } if (!m_ui->cbTCPheaders->isChecked()) { result.insert(NM_L2TP_KEY_NO_VJ_COMP, yesString); } if (!m_ui->cbCompressionNegotiation->isChecked()) { result.insert(NM_L2TP_KEY_NO_PCOMP, yesString); } if (!m_ui->cbAddressControlCompression->isChecked()) { result.insert(NM_L2TP_KEY_NO_ACCOMP, yesString); } // Echo if (m_ui->cbsendEcho->isChecked()) { result.insert(NM_L2TP_KEY_LCP_ECHO_FAILURE, "5"); result.insert(NM_L2TP_KEY_LCP_ECHO_INTERVAL, "30"); } if (m_ui->sbMTU->value() != 0) { result.insert(NM_L2TP_KEY_MTU, QString::number(m_ui->sbMTU->value())); } if (m_ui->sbMRU->value() != 0) { result.insert(NM_L2TP_KEY_MRU, QString::number(m_ui->sbMRU->value())); } return result; } diff --git a/vpn/l2tp/l2tppppwidget.h b/vpn/l2tp/l2tppppwidget.h index 76c7ac07..cb21f93a 100644 --- a/vpn/l2tp/l2tppppwidget.h +++ b/vpn/l2tp/l2tppppwidget.h @@ -1,47 +1,49 @@ /* Copyright 2013 Jan Grulich + Copyright 2020 Douglas Kosovic 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 . */ #ifndef PLASMA_NM_L2TP_PPP_WIDGET_H #define PLASMA_NM_L2TP_PPP_WIDGET_H #include #include namespace Ui { class L2tpPppWidget; } class L2tpPPPWidget : public QDialog { Q_OBJECT public: - explicit L2tpPPPWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent = nullptr); + explicit L2tpPPPWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent = nullptr, bool need_peer_eap = false); ~L2tpPPPWidget() override; NMStringMap setting() const; private: void loadConfig(const NetworkManager::VpnSetting::Ptr &setting); Ui::L2tpPppWidget * m_ui; + bool m_need_peer_eap; }; #endif // PLASMA_NM_L2TP_PPP_WIDGET_H diff --git a/vpn/l2tp/l2tpwidget.cpp b/vpn/l2tp/l2tpwidget.cpp index 23eb65a4..fc17e2bf 100644 --- a/vpn/l2tp/l2tpwidget.cpp +++ b/vpn/l2tp/l2tpwidget.cpp @@ -1,285 +1,311 @@ /* Copyright 2013 Jan Grulich + Copyright 2020 Douglas Kosovic 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 "l2tpwidget.h" #include "l2tpipsecwidget.h" #include "l2tppppwidget.h" #include "ui_l2tp.h" #include "nm-l2tp-service.h" #include #include #include L2tpWidget::L2tpWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget* parent, Qt::WindowFlags f) : SettingWidget(setting, parent, f) , m_ui(new Ui::L2tpWidget) , m_setting(setting) { qDBusRegisterMetaType(); m_ui->setupUi(this); m_ui->password->setPasswordOptionsEnabled(true); + m_ui->userKeyPassword->setPasswordOptionsEnabled(true); + m_ui->userKeyPassword->setPasswordNotRequiredEnabled(true); + + // use requesters' urlSelected signals to set other requester's startDirs to save clicking + // around the filesystem, also if it is a .p12 file, set the other URLs to that .p12 file. + QList requesters; + requesters << m_ui->userCA << m_ui->userCert << m_ui->userKey; + for (const KUrlRequester *requester : requesters) { + connect(requester, &KUrlRequester::urlSelected, this, &L2tpWidget::updateStartDirUrl); + } - connect(m_ui->btnIPSecSettings, &QPushButton::clicked, this, &L2tpWidget::showIpsec); + if (L2tpIpsecWidget::hasIpsecDaemon()) { + connect(m_ui->btnIPSecSettings, &QPushButton::clicked, this, &L2tpWidget::showIpsec); + } else { + m_ui->btnIPSecSettings->setDisabled(true); + } connect(m_ui->btnPPPSettings, &QPushButton::clicked, this, &L2tpWidget::showPpp); // Connect for setting check watchChangedSetting(); // Connect for validity check connect(m_ui->gateway, &QLineEdit::textChanged, this, &L2tpWidget::slotWidgetChanged); - connect(m_ui->cbUseCertificate, &QCheckBox::stateChanged, this, &L2tpWidget::certStateChanged); KAcceleratorManager::manage(this); if (setting && !setting->isNull()) { loadConfig(setting); } } L2tpWidget::~L2tpWidget() { m_tmpIpsecSetting.clear(); m_tmpPppSetting.clear(); delete m_ui; } void L2tpWidget::loadConfig(const NetworkManager::Setting::Ptr &setting) { Q_UNUSED(setting); - const NMStringMap data = m_setting->data(); - - if (data.contains(NM_L2TP_KEY_GATEWAY)) { - m_ui->gateway->setText(data.value(NM_L2TP_KEY_GATEWAY)); - } - - if (data.contains(NM_L2TP_KEY_USER)) { - m_ui->username->setText(data.value(NM_L2TP_KEY_USER)); - } - - const NetworkManager::Setting::SecretFlags userPassType = static_cast(data.value(NM_L2TP_KEY_PASSWORD"-flags").toInt()); - if (userPassType.testFlag(NetworkManager::Setting::None)) { - m_ui->password->setPasswordOption(PasswordField::StoreForAllUsers); - } else if (userPassType.testFlag(NetworkManager::Setting::AgentOwned)) { - m_ui->password->setPasswordOption(PasswordField::StoreForUser); - } else { - m_ui->password->setPasswordOption(PasswordField::AlwaysAsk); - } + const NMStringMap dataMap = m_setting->data(); - if (data.contains(NM_L2TP_KEY_DOMAIN)) { - m_ui->domain->setText(data.value(NM_L2TP_KEY_DOMAIN)); - } + m_ui->gateway->setText(dataMap[NM_L2TP_KEY_GATEWAY]); - if (data.contains(NM_L2TP_KEY_CERT_CA)) { - m_ui->urCACertificate->setText(data.value(NM_L2TP_KEY_CERT_CA)); - } - - if (data.contains(NM_L2TP_KEY_CERT_PUB)) { - m_ui->urCertificate->setText(data.value(NM_L2TP_KEY_CERT_PUB)); - } + if (dataMap[NM_L2TP_KEY_USER_AUTH_TYPE].isEmpty() || dataMap[NM_L2TP_KEY_USER_AUTH_TYPE] == QLatin1String(NM_L2TP_AUTHTYPE_PASSWORD)) { + m_ui->cmbAuthType->setCurrentIndex(AuthType::Password); + m_ui->stackedWidget->setCurrentIndex(AuthType::Password); + m_ui->username->setText(dataMap[NM_L2TP_KEY_USER]); - if (data.contains(NM_L2TP_KEY_CERT_KEY)) { - m_ui->urPrivateKey->setText(data.value(NM_L2TP_KEY_CERT_KEY)); - } + const NetworkManager::Setting::SecretFlags userPassType = static_cast(dataMap[NM_L2TP_KEY_PASSWORD"-flags"].toInt()); + if (userPassType.testFlag(NetworkManager::Setting::None)) { + m_ui->password->setPasswordOption(PasswordField::StoreForAllUsers); + } else if (userPassType.testFlag(NetworkManager::Setting::AgentOwned)) { + m_ui->password->setPasswordOption(PasswordField::StoreForUser); + } else { + m_ui->password->setPasswordOption(PasswordField::AlwaysAsk); + } - if (data.value(NM_L2TP_KEY_USE_CERT) == QLatin1String("yes")) { - m_ui->cbUseCertificate->setChecked(true); + m_ui->domain->setText(dataMap[NM_L2TP_KEY_DOMAIN]); + + } else { // NM_L2TP_AUTHTYPE_TLS + m_ui->cmbAuthType->setCurrentIndex(AuthType::TLS); + m_ui->stackedWidget->setCurrentIndex(AuthType::TLS); + + m_ui->userCA->setUrl(QUrl::fromLocalFile(dataMap[NM_L2TP_KEY_USER_CA])); + m_ui->userCert->setUrl(QUrl::fromLocalFile(dataMap[NM_L2TP_KEY_USER_CERT])); + m_ui->userKey->setUrl(QUrl::fromLocalFile(dataMap[NM_L2TP_KEY_USER_KEY])); + + const NetworkManager::Setting::SecretFlags userKeyPassType = static_cast(dataMap[NM_L2TP_KEY_USER_CERTPASS"-flags"].toInt()); + if (userKeyPassType.testFlag(NetworkManager::Setting::None)) { + m_ui->userKeyPassword->setPasswordOption(PasswordField::StoreForAllUsers); + } else if (userKeyPassType.testFlag(NetworkManager::Setting::AgentOwned)) { + m_ui->userKeyPassword->setPasswordOption(PasswordField::StoreForUser); + } else if (userKeyPassType.testFlag(NetworkManager::Setting::NotSaved)) { + m_ui->userKeyPassword->setPasswordOption(PasswordField::AlwaysAsk); + } else if (userKeyPassType.testFlag(NetworkManager::Setting::NotRequired)) { + m_ui->userKeyPassword->setPasswordOption(PasswordField::NotRequired); + } } loadSecrets(setting); } void L2tpWidget::loadSecrets(const NetworkManager::Setting::Ptr &setting) { NetworkManager::VpnSetting::Ptr vpnSetting = setting.staticCast(); if (vpnSetting) { + const QString authType = m_setting->data().value(NM_L2TP_KEY_USER_AUTH_TYPE); const NMStringMap secrets = vpnSetting->secrets(); - const QString userPassword = secrets.value(NM_L2TP_KEY_PASSWORD); - if (!userPassword.isEmpty()) { - m_ui->password->setText(userPassword); + + if (authType == QLatin1String(NM_L2TP_AUTHTYPE_TLS)) { + m_ui->userKeyPassword->setText(secrets.value(NM_L2TP_KEY_USER_CERTPASS)); + } else { // NM_L2TP_AUTHTYPE_PASSWORD + m_ui->password->setText(secrets.value(NM_L2TP_KEY_PASSWORD)); } } } QVariantMap L2tpWidget::setting() const { NetworkManager::VpnSetting setting; setting.setServiceType(QLatin1String(NM_DBUS_SERVICE_L2TP)); NMStringMap data; + NMStringMap secrets; + if (!m_tmpIpsecSetting.isNull()) { data = m_tmpIpsecSetting->data(); + secrets = m_tmpIpsecSetting->secrets(); } else { // retrieve the settings if the dialog has not been opened QScopedPointer ipsec(new L2tpIpsecWidget(m_setting, nullptr)); data = ipsec->setting(); + secrets = ipsec->secrets(); } if (!m_tmpPppSetting.isNull()) { data.unite(m_tmpPppSetting->data()); } else { + const bool need_peer_eap = m_ui->cmbAuthType->currentIndex() != AuthType::Password; + // retrieve the settings if the dialog has not been opened - QScopedPointer ppp(new L2tpPPPWidget(m_setting, nullptr)); + QScopedPointer ppp(new L2tpPPPWidget(m_setting, nullptr, need_peer_eap)); data.unite(ppp->setting()); } - NMStringMap secrets; - if (!m_ui->gateway->text().isEmpty()) { data.insert(NM_L2TP_KEY_GATEWAY, m_ui->gateway->text()); } - if (m_ui->cbUseCertificate->isChecked()) { - data.insert(NM_L2TP_KEY_USE_CERT, "yes"); - - if (!m_ui->urCACertificate->text().isEmpty()) { - data.insert(NM_L2TP_KEY_CERT_CA, m_ui->urCACertificate->text()); - } - - if (!m_ui->urCertificate->text().isEmpty()) { - data.insert(NM_L2TP_KEY_CERT_PUB, m_ui->urCertificate->text()); - } - - if (!m_ui->urPrivateKey->text().isEmpty()) { - data.insert(NM_L2TP_KEY_CERT_KEY, m_ui->urPrivateKey->text()); - } - - data.insert(NM_L2TP_KEY_PASSWORD"-flags", QString::number(NetworkManager::Setting::NotRequired)); - - } else { - + if (m_ui->cmbAuthType->currentIndex() == AuthType::Password) { if (!m_ui->username->text().isEmpty()) { data.insert(NM_L2TP_KEY_USER, m_ui->username->text()); } - if (m_ui->password->isEnabled() && !m_ui->password->text().isEmpty()) { + if (!m_ui->password->text().isEmpty()) { secrets.insert(NM_L2TP_KEY_PASSWORD, m_ui->password->text()); + } else { + secrets.remove(NM_L2TP_KEY_PASSWORD); } switch (m_ui->password->passwordOption()) { case PasswordField::StoreForAllUsers: data.insert(NM_L2TP_KEY_PASSWORD"-flags", QString::number(NetworkManager::Setting::None)); break; case PasswordField::StoreForUser: data.insert(NM_L2TP_KEY_PASSWORD"-flags", QString::number(NetworkManager::Setting::AgentOwned)); break; default: data.insert(NM_L2TP_KEY_PASSWORD"-flags", QString::number(NetworkManager::Setting::NotSaved)); }; if (!m_ui->domain->text().isEmpty()) { data.insert(NM_L2TP_KEY_DOMAIN, m_ui->domain->text()); } + + } else { // EnumAuthType::TLS + + data.insert(NM_L2TP_KEY_USER_AUTH_TYPE, NM_L2TP_AUTHTYPE_TLS); + + data.insert(NM_L2TP_KEY_USER_CA, m_ui->userCA->url().toLocalFile()); + data.insert(NM_L2TP_KEY_USER_CERT, m_ui->userCert->url().toLocalFile()); + data.insert(NM_L2TP_KEY_USER_KEY, m_ui->userKey->url().toLocalFile()); + + // key password + if (!m_ui->userKeyPassword->text().isEmpty()) { + secrets.insert(NM_L2TP_KEY_USER_CERTPASS, m_ui->userKeyPassword->text()); + } else { + secrets.remove(NM_L2TP_KEY_USER_CERTPASS); + } + + switch (m_ui->userKeyPassword->passwordOption()) { + case PasswordField::StoreForAllUsers: + data.insert(NM_L2TP_KEY_USER_CERTPASS"-flags", QString::number(NetworkManager::Setting::None)); + break; + case PasswordField::StoreForUser: + data.insert(NM_L2TP_KEY_USER_CERTPASS"-flags", QString::number(NetworkManager::Setting::AgentOwned)); + break; + case PasswordField::AlwaysAsk: + data.insert(NM_L2TP_KEY_USER_CERTPASS"-flags", QString::number(NetworkManager::Setting::NotSaved)); + break; + case PasswordField::NotRequired: + data.insert(NM_L2TP_KEY_USER_CERTPASS"-flags", QString::number(NetworkManager::Setting::NotRequired)); + break; + }; } setting.setData(data); setting.setSecrets(secrets); return setting.toMap(); } - -void L2tpWidget::userPasswordTypeChanged(int index) +void L2tpWidget::updateStartDirUrl(const QUrl &url) { - m_ui->password->setEnabled(index == SettingWidget::EnumPasswordStorageType::Store); + QList requesters; + requesters << m_ui->userCA << m_ui->userCert << m_ui->userKey; + bool isP12 = url.toString().endsWith(QLatin1String(".p12")); + + for (KUrlRequester *requester : requesters) { + requester->setStartDir(url.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash)); + if (isP12) { + requester->setUrl(url); + } + } } void L2tpWidget::showIpsec() { QPointer ipsec; if (m_tmpIpsecSetting.isNull()) { ipsec = new L2tpIpsecWidget(m_setting, this); } else { ipsec = new L2tpIpsecWidget(m_tmpIpsecSetting, this); } connect(ipsec.data(), &L2tpIpsecWidget::accepted, [ipsec, this] () { NMStringMap ipsecData = ipsec->setting(); if (!ipsecData.isEmpty()) { if (m_tmpIpsecSetting.isNull()) { m_tmpIpsecSetting = NetworkManager::VpnSetting::Ptr(new NetworkManager::VpnSetting); } m_tmpIpsecSetting->setData(ipsecData); } }); connect(ipsec.data(), &L2tpIpsecWidget::finished, [ipsec] () { if (ipsec) { ipsec->deleteLater(); } }); ipsec->setModal(true); ipsec->show(); } void L2tpWidget::showPpp() { QPointer ipsec; + bool need_peer_eap = m_ui->cmbAuthType->currentIndex() != AuthType::Password; if (m_tmpPppSetting.isNull()) { - ipsec = new L2tpPPPWidget(m_setting, this); + ipsec = new L2tpPPPWidget(m_setting, this, need_peer_eap); } else { - ipsec = new L2tpPPPWidget(m_tmpPppSetting, this); + ipsec = new L2tpPPPWidget(m_tmpPppSetting, this, need_peer_eap); } connect(ipsec.data(), &L2tpPPPWidget::accepted, [ipsec, this] () { NMStringMap ipsecData = ipsec->setting(); if (!ipsecData.isEmpty()) { if (m_tmpPppSetting.isNull()) { m_tmpPppSetting = NetworkManager::VpnSetting::Ptr(new NetworkManager::VpnSetting); } m_tmpPppSetting->setData(ipsecData); } }); connect(ipsec.data(), &L2tpPPPWidget::finished, [ipsec] () { if (ipsec) { ipsec->deleteLater(); } }); ipsec->setModal(true); ipsec->show(); } bool L2tpWidget::isValid() const { return !m_ui->gateway->text().isEmpty(); } - -void L2tpWidget::certStateChanged() -{ - if (m_ui->cbUseCertificate->isChecked()) { - m_ui->urCACertificate->setEnabled(true); - m_ui->urCertificate->setEnabled(true); - m_ui->urPrivateKey->setEnabled(true); - m_ui->username->setEnabled(false); - m_ui->password->setEnabled(false); - m_ui->domain->setEnabled(false); - } else { - m_ui->urCACertificate->setEnabled(false); - m_ui->urCertificate->setEnabled(false); - m_ui->urPrivateKey->setEnabled(false); - m_ui->username->setEnabled(true); - m_ui->password->setEnabled(true); - m_ui->domain->setEnabled(true); - } -} diff --git a/vpn/l2tp/l2tpwidget.h b/vpn/l2tp/l2tpwidget.h index e69d25a9..652bfbc0 100644 --- a/vpn/l2tp/l2tpwidget.h +++ b/vpn/l2tp/l2tpwidget.h @@ -1,60 +1,63 @@ /* Copyright 2013 Jan Grulich + Copyright 2020 Douglas Kosovic 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 . */ #ifndef PLASMA_NM_L2TP_WIDGET_H #define PLASMA_NM_L2TP_WIDGET_H #include #include "settingwidget.h" namespace Ui { class L2tpWidget; } class L2tpWidget : public SettingWidget { Q_OBJECT + + enum AuthType {Password = 0, TLS}; + public: explicit L2tpWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget* parent = nullptr, Qt::WindowFlags f = {}); ~L2tpWidget() override; void loadConfig(const NetworkManager::Setting::Ptr &setting) override; void loadSecrets(const NetworkManager::Setting::Ptr &setting) override; QVariantMap setting() const override; bool isValid() const override; private Q_SLOTS: - void userPasswordTypeChanged(int index); + void updateStartDirUrl(const QUrl &); void showIpsec(); void showPpp(); - void certStateChanged(); private: Ui::L2tpWidget * m_ui; NetworkManager::VpnSetting::Ptr m_setting; NetworkManager::VpnSetting::Ptr m_tmpIpsecSetting; NetworkManager::VpnSetting::Ptr m_tmpPppSetting; }; #endif // PLASMA_NM_L2TP_WIDGET_H diff --git a/vpn/l2tp/nm-l2tp-service.h b/vpn/l2tp/nm-l2tp-service.h index d42bd623..994abbf5 100644 --- a/vpn/l2tp/nm-l2tp-service.h +++ b/vpn/l2tp/nm-l2tp-service.h @@ -1,72 +1,76 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +// SPDX-License-Identifier: GPL-2.0+ /* nm-l2tp-service - L2TP VPN integration with NetworkManager * * Dan Williams * - * 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) any later version. - * - * 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Copyright 2008, 2014 Red Hat, Inc. */ #ifndef NM_L2TP_SERVICE_DEFINES_H #define NM_L2TP_SERVICE_DEFINES_H #define NM_DBUS_SERVICE_L2TP "org.freedesktop.NetworkManager.l2tp" /* For the NM <-> VPN plugin service */ #define NM_DBUS_INTERFACE_L2TP "org.freedesktop.NetworkManager.l2tp" #define NM_DBUS_PATH_L2TP "/org/freedesktop/NetworkManager/l2tp" /* For the VPN plugin service <-> PPP plugin */ #define NM_DBUS_INTERFACE_L2TP_PPP "org.freedesktop.NetworkManager.l2tp.ppp" #define NM_DBUS_PATH_L2TP_PPP "/org/freedesktop/NetworkManager/l2tp/ppp" #define NM_L2TP_KEY_GATEWAY "gateway" +#define NM_L2TP_KEY_USER_AUTH_TYPE "user-auth-type" #define NM_L2TP_KEY_USER "user" #define NM_L2TP_KEY_PASSWORD "password" -#define NM_L2TP_KEY_USE_CERT "use-cert" -#define NM_L2TP_KEY_CERT_PUB "cert-pub" -#define NM_L2TP_KEY_CERT_CA "cert-ca" -#define NM_L2TP_KEY_CERT_KEY "cert-key" +#define NM_L2TP_KEY_DOMAIN "domain" +#define NM_L2TP_KEY_USER_CA "user-ca" +#define NM_L2TP_KEY_USER_CERT "user-cert" +#define NM_L2TP_KEY_USER_KEY "user-key" +#define NM_L2TP_KEY_USER_CERTPASS "user-certpass" #define NM_L2TP_KEY_MTU "mtu" #define NM_L2TP_KEY_MRU "mru" -#define NM_L2TP_KEY_DOMAIN "domain" #define NM_L2TP_KEY_REFUSE_EAP "refuse-eap" #define NM_L2TP_KEY_REFUSE_PAP "refuse-pap" #define NM_L2TP_KEY_REFUSE_CHAP "refuse-chap" #define NM_L2TP_KEY_REFUSE_MSCHAP "refuse-mschap" #define NM_L2TP_KEY_REFUSE_MSCHAPV2 "refuse-mschapv2" #define NM_L2TP_KEY_REQUIRE_MPPE "require-mppe" #define NM_L2TP_KEY_REQUIRE_MPPE_40 "require-mppe-40" #define NM_L2TP_KEY_REQUIRE_MPPE_128 "require-mppe-128" #define NM_L2TP_KEY_MPPE_STATEFUL "mppe-stateful" #define NM_L2TP_KEY_NOBSDCOMP "nobsdcomp" #define NM_L2TP_KEY_NODEFLATE "nodeflate" #define NM_L2TP_KEY_NO_VJ_COMP "no-vj-comp" #define NM_L2TP_KEY_NO_PCOMP "nopcomp" #define NM_L2TP_KEY_NO_ACCOMP "noaccomp" #define NM_L2TP_KEY_LCP_ECHO_FAILURE "lcp-echo-failure" #define NM_L2TP_KEY_LCP_ECHO_INTERVAL "lcp-echo-interval" #define NM_L2TP_KEY_UNIT_NUM "unit" - +#define NM_L2TP_KEY_MACHINE_AUTH_TYPE "machine-auth-type" +#define NM_L2TP_KEY_MACHINE_CA "machine-ca" +#define NM_L2TP_KEY_MACHINE_CERT "machine-cert" +#define NM_L2TP_KEY_MACHINE_KEY "machine-key" +#define NM_L2TP_KEY_MACHINE_CERTPASS "machine-certpass" #define NM_L2TP_KEY_IPSEC_ENABLE "ipsec-enabled" -#define NM_L2TP_KEY_IPSEC_GATEWAY_ID "ipsec-gateway-id" -#define NM_L2TP_KEY_IPSEC_GROUP_NAME "ipsec-group-name" +#define NM_L2TP_KEY_IPSEC_REMOTE_ID "ipsec-remote-id" +#define NM_L2TP_KEY_IPSEC_GATEWAY_ID "ipsec-gateway-id" /* deprecated, use ipsec-remote-id */ #define NM_L2TP_KEY_IPSEC_PSK "ipsec-psk" #define NM_L2TP_KEY_IPSEC_IKE "ipsec-ike" #define NM_L2TP_KEY_IPSEC_ESP "ipsec-esp" +#define NM_L2TP_KEY_IPSEC_IKELIFETIME "ipsec-ikelifetime" +#define NM_L2TP_KEY_IPSEC_SALIFETIME "ipsec-salifetime" #define NM_L2TP_KEY_IPSEC_FORCEENCAPS "ipsec-forceencaps" +#define NM_L2TP_KEY_IPSEC_IPCOMP "ipsec-ipcomp" +#define NM_L2TP_KEY_IPSEC_IKEV2 "ipsec-ikev2" +#define NM_L2TP_KEY_IPSEC_PFS "ipsec-pfs" + +/* Internal auth-dialog -> service token indicating that no secrets are required + * for the connection if X.509 private keys are used with no password protection. + */ +#define NM_L2TP_KEY_NOSECRET "no-secret" +#define NM_L2TP_AUTHTYPE_PASSWORD "password" +#define NM_L2TP_AUTHTYPE_TLS "tls" +#define NM_L2TP_AUTHTYPE_PSK "psk" #endif /* NM_L2TP_SERVICE_DEFINES_H */