File indexing completed on 2024-04-28 16:52:51

0001 /*
0002     SPDX-FileCopyrightText: 2009 Will Stephenson <wstephenson@kde.org>
0003     SPDX-FileCopyrightText: 2009 Pavel Andreev <apavelm@gmail.com>
0004     SPDX-FileCopyrightText: 2013 Lukáš Tinkl <ltinkl@redhat.com>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0007 */
0008 
0009 #include "pptpwidget.h"
0010 
0011 #include "ui_pptpadvanced.h"
0012 #include "ui_pptpprop.h"
0013 
0014 #include <QDialog>
0015 #include <QDialogButtonBox>
0016 #include <QString>
0017 
0018 #include "nm-pptp-service.h"
0019 
0020 class PptpSettingWidgetPrivate
0021 {
0022 public:
0023     Ui_PptpProp ui;
0024     Ui_PptpAdvanced advUi;
0025     NetworkManager::VpnSetting::Ptr setting;
0026     QDialog *advancedDlg;
0027     QWidget *advancedWid;
0028 };
0029 
0030 PptpSettingWidget::PptpSettingWidget(const NetworkManager::VpnSetting::Ptr &setting, QWidget *parent)
0031     : SettingWidget(setting, parent)
0032     , d_ptr(new PptpSettingWidgetPrivate)
0033 {
0034     Q_D(PptpSettingWidget);
0035     d->ui.setupUi(this);
0036 
0037     d->setting = setting;
0038 
0039     d->ui.edt_password->setPasswordOptionsEnabled(true);
0040     d->ui.edt_password->setPasswordNotRequiredEnabled(true);
0041 
0042     connect(d->ui.btnAdvanced, &QPushButton::clicked, this, &PptpSettingWidget::doAdvancedDialog);
0043 
0044     d->advancedDlg = new QDialog(this);
0045     d->advancedWid = new QWidget(this);
0046     d->advUi.setupUi(d->advancedWid);
0047     auto layout = new QVBoxLayout(d->advancedDlg);
0048     layout->addWidget(d->advancedWid);
0049     d->advancedDlg->setLayout(layout);
0050     auto buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, d->advancedDlg);
0051     connect(buttons, &QDialogButtonBox::accepted, d->advancedDlg, &QDialog::accept);
0052     connect(buttons, &QDialogButtonBox::rejected, d->advancedDlg, &QDialog::reject);
0053     layout->addWidget(buttons);
0054 
0055     // Connect for setting check
0056     watchChangedSetting();
0057 
0058     // Connect for validity check
0059     connect(d->ui.edt_gateway, &QLineEdit::textChanged, this, &PptpSettingWidget::slotWidgetChanged);
0060 
0061     KAcceleratorManager::manage(this);
0062 
0063     if (d->setting && !d->setting->isNull()) {
0064         loadConfig(d->setting);
0065     }
0066 }
0067 
0068 PptpSettingWidget::~PptpSettingWidget()
0069 {
0070     delete d_ptr;
0071 }
0072 
0073 void PptpSettingWidget::doAdvancedDialog()
0074 {
0075     Q_D(PptpSettingWidget);
0076     d->advancedDlg->setModal(true);
0077     d->advancedDlg->show();
0078 }
0079 
0080 void PptpSettingWidget::loadConfig(const NetworkManager::Setting::Ptr &setting)
0081 {
0082     Q_D(PptpSettingWidget);
0083     Q_UNUSED(setting)
0084 
0085     // General settings
0086     const NMStringMap dataMap = d->setting->data();
0087 
0088     // Authentication
0089     const QString sGateway = dataMap[NM_PPTP_KEY_GATEWAY];
0090     if (!sGateway.isEmpty()) {
0091         d->ui.edt_gateway->setText(sGateway);
0092     }
0093 
0094     const QString sLogin = dataMap[NM_PPTP_KEY_USER];
0095     if (!sLogin.isEmpty()) {
0096         d->ui.edt_login->setText(sLogin);
0097     }
0098 
0099     const QString sDomain = dataMap[NM_PPTP_KEY_DOMAIN];
0100     if (!sDomain.isEmpty()) {
0101         d->ui.edt_ntDomain->setText(sDomain);
0102     }
0103 
0104     // Options below is belongs to "Advanced" dialog
0105 
0106     // Authentication options
0107     const QString yesString = QLatin1String("yes");
0108     bool refuse_pap = (dataMap[NM_PPTP_KEY_REFUSE_PAP] == yesString);
0109     bool refuse_chap = (dataMap[NM_PPTP_KEY_REFUSE_CHAP] == yesString);
0110     bool refuse_mschap = (dataMap[NM_PPTP_KEY_REFUSE_MSCHAP] == yesString);
0111     bool refuse_mschapv2 = (dataMap[NM_PPTP_KEY_REFUSE_MSCHAPV2] == yesString);
0112     bool refuse_eap = (dataMap[NM_PPTP_KEY_REFUSE_EAP] == yesString);
0113 
0114     QListWidgetItem *item = nullptr;
0115     item = d->advUi.listWidget->item(0); // PAP
0116     item->setCheckState(refuse_pap ? Qt::Unchecked : Qt::Checked);
0117     item = d->advUi.listWidget->item(1); // CHAP
0118     item->setCheckState(refuse_chap ? Qt::Unchecked : Qt::Checked);
0119     item = d->advUi.listWidget->item(2); // MSCHAP
0120     item->setCheckState(refuse_mschap ? Qt::Unchecked : Qt::Checked);
0121     item = d->advUi.listWidget->item(3); // MSCHAPv2
0122     item->setCheckState(refuse_mschapv2 ? Qt::Unchecked : Qt::Checked);
0123     item = d->advUi.listWidget->item(4); // EAP
0124     item->setCheckState(refuse_eap ? Qt::Unchecked : Qt::Checked);
0125 
0126     // Cryptography and compression
0127     const bool mppe = (dataMap[NM_PPTP_KEY_REQUIRE_MPPE] == yesString);
0128     const bool mppe40 = (dataMap[NM_PPTP_KEY_REQUIRE_MPPE_40] == yesString);
0129     const bool mppe128 = (dataMap[NM_PPTP_KEY_REQUIRE_MPPE_128] == yesString);
0130     const bool mppe_stateful = (dataMap[NM_PPTP_KEY_MPPE_STATEFUL] == yesString);
0131 
0132     if (mppe || mppe40 || mppe128) { // If MPPE is use
0133         d->advUi.gb_MPPE->setChecked(mppe || mppe40 || mppe128);
0134         if (mppe128) {
0135             d->advUi.cb_MPPECrypto->setCurrentIndex(1); // 128 bit
0136         } else if (mppe40) {
0137             d->advUi.cb_MPPECrypto->setCurrentIndex(2); // 40 bit
0138         } else {
0139             d->advUi.cb_MPPECrypto->setCurrentIndex(0); // Any
0140         }
0141         d->advUi.cb_statefulEncryption->setChecked(mppe_stateful);
0142     }
0143 
0144     const bool nobsd = (dataMap[NM_PPTP_KEY_NOBSDCOMP] == yesString);
0145     d->advUi.cb_BSD->setChecked(!nobsd);
0146 
0147     const bool nodeflate = (dataMap[NM_PPTP_KEY_NODEFLATE] == yesString);
0148     d->advUi.cb_deflate->setChecked(!nodeflate);
0149 
0150     const bool novjcomp = (dataMap[NM_PPTP_KEY_NO_VJ_COMP] == yesString);
0151     d->advUi.cb_TCPheaders->setChecked(!novjcomp);
0152 
0153     // Echo
0154     const int lcp_echo_interval = QString(dataMap[NM_PPTP_KEY_LCP_ECHO_INTERVAL]).toInt();
0155     d->advUi.cb_sendEcho->setChecked(lcp_echo_interval > 0);
0156 
0157     // secrets
0158     const NetworkManager::Setting::SecretFlags type = (NetworkManager::Setting::SecretFlags)dataMap[NM_PPTP_KEY_PASSWORD "-flags"].toInt();
0159     fillOnePasswordCombo(d->ui.edt_password, type);
0160 
0161     loadSecrets(setting);
0162 }
0163 
0164 void PptpSettingWidget::loadSecrets(const NetworkManager::Setting::Ptr &setting)
0165 {
0166     Q_D(PptpSettingWidget);
0167 
0168     NetworkManager::VpnSetting::Ptr vpnSetting = setting.staticCast<NetworkManager::VpnSetting>();
0169 
0170     if (vpnSetting) {
0171         const NMStringMap secrets = vpnSetting->secrets();
0172         const QString keyPassword = secrets.value(QLatin1String(NM_PPTP_KEY_PASSWORD));
0173         if (!keyPassword.isEmpty()) {
0174             d->ui.edt_password->setText(keyPassword);
0175         }
0176     }
0177 }
0178 
0179 QVariantMap PptpSettingWidget::setting() const
0180 {
0181     Q_D(const PptpSettingWidget);
0182 
0183     NetworkManager::VpnSetting setting;
0184     setting.setServiceType(QLatin1String(NM_DBUS_SERVICE_PPTP));
0185 
0186     // save the main dialog's data in the setting
0187     // if the advanced dialog is dirty, save its data in the vpn setting too
0188     //
0189     NMStringMap data;
0190     NMStringMap secretData;
0191 
0192     data.insert(NM_PPTP_KEY_GATEWAY, d->ui.edt_gateway->text());
0193     data.insert(NM_PPTP_KEY_USER, d->ui.edt_login->text());
0194     if (!d->ui.edt_password->text().isEmpty()) {
0195         secretData.insert(QLatin1String(NM_PPTP_KEY_PASSWORD), d->ui.edt_password->text());
0196     }
0197     handleOnePasswordType(d->ui.edt_password, NM_PPTP_KEY_PASSWORD "-flags", data);
0198     if (!d->ui.edt_ntDomain->text().isEmpty()) {
0199         data.insert(NM_PPTP_KEY_DOMAIN, d->ui.edt_ntDomain->text());
0200     }
0201 
0202     // Advanced dialog settings
0203 
0204     // Authentication options
0205     QListWidgetItem *item = nullptr;
0206     item = d->advUi.listWidget->item(0); // PAP
0207     const QString yesString = QLatin1String("yes");
0208     if (item->checkState() == Qt::Unchecked) {
0209         data.insert(NM_PPTP_KEY_REFUSE_PAP, yesString);
0210     }
0211     item = d->advUi.listWidget->item(1); // CHAP
0212     if (item->checkState() == Qt::Unchecked) {
0213         data.insert(NM_PPTP_KEY_REFUSE_CHAP, yesString);
0214     }
0215     item = d->advUi.listWidget->item(2); // MSCHAP
0216     if (item->checkState() == Qt::Unchecked) {
0217         data.insert(NM_PPTP_KEY_REFUSE_MSCHAP, yesString);
0218     }
0219     item = d->advUi.listWidget->item(3); // MSCHAPv2
0220     if (item->checkState() == Qt::Unchecked) {
0221         data.insert(NM_PPTP_KEY_REFUSE_MSCHAPV2, yesString);
0222     }
0223     item = d->advUi.listWidget->item(4); // EAP
0224     if (item->checkState() == Qt::Unchecked) {
0225         data.insert(NM_PPTP_KEY_REFUSE_EAP, yesString);
0226     }
0227 
0228     // Cryptography and compression
0229     if (d->advUi.gb_MPPE->isChecked()) {
0230         int index = d->advUi.cb_MPPECrypto->currentIndex();
0231 
0232         switch (index) {
0233         case 0:
0234             data.insert(NM_PPTP_KEY_REQUIRE_MPPE, yesString);
0235             break;
0236         case 1:
0237             data.insert(NM_PPTP_KEY_REQUIRE_MPPE_128, yesString);
0238             break;
0239         case 2:
0240             data.insert(NM_PPTP_KEY_REQUIRE_MPPE_40, yesString);
0241             break;
0242         }
0243 
0244         if (d->advUi.cb_statefulEncryption->isChecked()) {
0245             data.insert(NM_PPTP_KEY_MPPE_STATEFUL, yesString);
0246         }
0247     }
0248 
0249     if (!d->advUi.cb_BSD->isChecked()) {
0250         data.insert(NM_PPTP_KEY_NOBSDCOMP, yesString);
0251     }
0252     if (!d->advUi.cb_deflate->isChecked()) {
0253         data.insert(NM_PPTP_KEY_NODEFLATE, yesString);
0254     }
0255 
0256     if (!d->advUi.cb_TCPheaders->isChecked()) {
0257         data.insert(NM_PPTP_KEY_NO_VJ_COMP, yesString);
0258     }
0259     // Echo
0260     if (d->advUi.cb_sendEcho->isChecked()) {
0261         data.insert(NM_PPTP_KEY_LCP_ECHO_FAILURE, "5");
0262         data.insert(NM_PPTP_KEY_LCP_ECHO_INTERVAL, "30");
0263     }
0264 
0265     // save it all
0266     setting.setData(data);
0267     setting.setSecrets(secretData);
0268 
0269     return setting.toMap();
0270 }
0271 
0272 void PptpSettingWidget::fillOnePasswordCombo(PasswordField *passwordField, NetworkManager::Setting::SecretFlags type)
0273 {
0274     if (type.testFlag(NetworkManager::Setting::None)) {
0275         passwordField->setPasswordOption(PasswordField::StoreForAllUsers);
0276     } else if (type.testFlag(NetworkManager::Setting::AgentOwned)) {
0277         passwordField->setPasswordOption(PasswordField::StoreForUser);
0278     } else if (type.testFlag(NetworkManager::Setting::NotSaved)) {
0279         passwordField->setPasswordOption(PasswordField::AlwaysAsk);
0280     } else {
0281         passwordField->setPasswordOption(PasswordField::PasswordField::NotRequired);
0282     }
0283 }
0284 
0285 void PptpSettingWidget::handleOnePasswordType(const PasswordField *passwordField, const QString &key, NMStringMap &data) const
0286 {
0287     const PasswordField::PasswordOption option = passwordField->passwordOption();
0288     switch (option) {
0289     case PasswordField::StoreForAllUsers:
0290         data.insert(key, QString::number(NetworkManager::Setting::None));
0291         break;
0292     case PasswordField::StoreForUser:
0293         data.insert(key, QString::number(NetworkManager::Setting::AgentOwned));
0294         break;
0295     case PasswordField::AlwaysAsk:
0296         data.insert(key, QString::number(NetworkManager::Setting::NotSaved));
0297         break;
0298     case PasswordField::NotRequired:
0299         data.insert(key, QString::number(NetworkManager::Setting::NotRequired));
0300         break;
0301     }
0302 }
0303 
0304 bool PptpSettingWidget::isValid() const
0305 {
0306     Q_D(const PptpSettingWidget);
0307 
0308     return !d->ui.edt_gateway->text().isEmpty();
0309 }