File indexing completed on 2024-04-21 16:20:26
0001 /* 0002 SPDX-FileCopyrightText: 2011 Ilia Kats <ilia-kats@gmx.net> 0003 SPDX-FileCopyrightText: 2013 Lukáš Tinkl <ltinkl@redhat.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 #include "openvpnauth.h" 0009 #include "passwordfield.h" 0010 0011 #include <QCheckBox> 0012 #include <QFormLayout> 0013 #include <QLabel> 0014 #include <QString> 0015 0016 #include <KLocalizedString> 0017 0018 #include "nm-openvpn-service.h" 0019 #include "plasma_nm_openvpn.h" 0020 0021 class OpenVpnAuthWidgetPrivate 0022 { 0023 public: 0024 NetworkManager::VpnSetting::Ptr setting; 0025 QFormLayout *layout; 0026 }; 0027 0028 OpenVpnAuthWidget::OpenVpnAuthWidget(const NetworkManager::VpnSetting::Ptr &setting, const QStringList &hints, QWidget *parent) 0029 : SettingWidget(setting, hints, parent) 0030 , d_ptr(new OpenVpnAuthWidgetPrivate) 0031 { 0032 Q_D(OpenVpnAuthWidget); 0033 d->setting = setting; 0034 d->layout = new QFormLayout(this); 0035 setLayout(d->layout); 0036 0037 readSecrets(); 0038 0039 KAcceleratorManager::manage(this); 0040 } 0041 0042 OpenVpnAuthWidget::~OpenVpnAuthWidget() 0043 { 0044 delete d_ptr; 0045 } 0046 0047 void OpenVpnAuthWidget::readSecrets() 0048 { 0049 Q_D(OpenVpnAuthWidget); 0050 0051 const NMStringMap dataMap = d->setting->data(); 0052 const NMStringMap secrets = d->setting->secrets(); 0053 const QString cType = dataMap[NM_OPENVPN_KEY_CONNECTION_TYPE]; 0054 NetworkManager::Setting::SecretFlags certType = (NetworkManager::Setting::SecretFlags)dataMap.value(NM_OPENVPN_KEY_CERTPASS "-flags").toInt(); 0055 NetworkManager::Setting::SecretFlags passType = (NetworkManager::Setting::SecretFlags)dataMap.value(NM_OPENVPN_KEY_PASSWORD "-flags").toInt(); 0056 NetworkManager::Setting::SecretFlags proxyType = (NetworkManager::Setting::SecretFlags)dataMap.value(NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD "-flags").toInt(); 0057 0058 // If hints are given, then always ask for what the hints require 0059 if (!m_hints.isEmpty()) { 0060 QString passwordType; 0061 QString prompt; 0062 for (const QString &hint : std::as_const(m_hints)) { 0063 const QString vpnMessage = QStringLiteral("x-vpn-message:"); 0064 if (hint.startsWith(vpnMessage)) { 0065 prompt = hint.right(hint.length() - vpnMessage.length()); 0066 } else { 0067 passwordType = hint; 0068 } 0069 } 0070 0071 if (prompt.isEmpty()) { 0072 if (passwordType == QLatin1String(NM_OPENVPN_KEY_CERTPASS)) { 0073 prompt = i18n("Key Password:"); 0074 } else if (passwordType == QLatin1String(NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD)) { 0075 prompt = i18n("Proxy Password:"); 0076 } else { 0077 prompt = i18n("Password:"); 0078 } 0079 } else if (prompt.endsWith(QLatin1Char('.'))) { 0080 prompt = prompt.replace(prompt.length() - 1, 1, QLatin1Char(':')); 0081 } else if (!prompt.endsWith(QLatin1Char(':'))) { 0082 prompt += QLatin1Char(':'); 0083 } 0084 0085 bool isOTP = false; 0086 QStringList possibleTokens = {i18n("OTP"), i18n("authenticator"), i18n("code"), i18n("token"), i18n("one-time password")}; 0087 for (const QString &possibleToken : possibleTokens) { 0088 if (prompt.toLower().contains(possibleToken.toLower())) { 0089 isOTP = true; 0090 break; 0091 } 0092 } 0093 0094 addPasswordField(prompt, QString(), passwordType, !isOTP); 0095 } else { 0096 if (cType == QLatin1String(NM_OPENVPN_CONTYPE_TLS) || cType == QLatin1String(NM_OPENVPN_CONTYPE_PASSWORD_TLS)) { 0097 // Normal user password 0098 if (cType == QLatin1String(NM_OPENVPN_CONTYPE_PASSWORD_TLS) && !passType.testFlag(NetworkManager::Setting::NotRequired)) { 0099 addPasswordField(i18n("Password:"), secrets.value(QStringLiteral(NM_OPENVPN_KEY_PASSWORD)), QLatin1String(NM_OPENVPN_KEY_PASSWORD)); 0100 } 0101 // Encrypted private key password 0102 if (dataMap.contains(QLatin1String(NM_OPENVPN_KEY_KEY)) && !certType.testFlag(NetworkManager::Setting::NotRequired)) { 0103 addPasswordField(i18n("Key Password:"), secrets.value(QStringLiteral(NM_OPENVPN_KEY_CERTPASS)), QLatin1String(NM_OPENVPN_KEY_CERTPASS)); 0104 } 0105 } else if (cType == QLatin1String(NM_OPENVPN_CONTYPE_PASSWORD)) { 0106 addPasswordField(i18n("Password:"), secrets.value(QStringLiteral(NM_OPENVPN_KEY_PASSWORD)), QLatin1String(NM_OPENVPN_KEY_PASSWORD)); 0107 } 0108 0109 if (dataMap.contains(NM_OPENVPN_KEY_PROXY_SERVER) && !proxyType.testFlag(NetworkManager::Setting::NotRequired)) { 0110 addPasswordField(i18n("Proxy Password:"), 0111 secrets.value(QStringLiteral(NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD)), 0112 QLatin1String(NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD)); 0113 } 0114 } 0115 0116 for (int i = 0; i < d->layout->rowCount(); i++) { 0117 auto le = qobject_cast<PasswordField *>(d->layout->itemAt(i, QFormLayout::FieldRole)->widget()); 0118 if (le && le->text().isEmpty()) { 0119 le->setFocus(Qt::OtherFocusReason); 0120 break; 0121 } 0122 } 0123 } 0124 0125 QVariantMap OpenVpnAuthWidget::setting() const 0126 { 0127 Q_D(const OpenVpnAuthWidget); 0128 0129 NMStringMap secrets; 0130 QVariantMap secretData; 0131 for (int i = 0; i < d->layout->rowCount(); i++) { 0132 auto le = qobject_cast<PasswordField *>(d->layout->itemAt(i, QFormLayout::FieldRole)->widget()); 0133 if (le && !le->text().isEmpty()) { 0134 const QString key = le->property("nm_secrets_key").toString(); 0135 secrets.insert(key, le->text()); 0136 } 0137 } 0138 0139 secretData.insert("secrets", QVariant::fromValue<NMStringMap>(secrets)); 0140 return secretData; 0141 } 0142 0143 void OpenVpnAuthWidget::addPasswordField(const QString &labelText, const QString &password, const QString &secretKey, bool passwordMode) 0144 { 0145 Q_D(const OpenVpnAuthWidget); 0146 0147 auto label = new QLabel(this); 0148 label->setText(labelText); 0149 auto lineEdit = new PasswordField(this); 0150 lineEdit->setPasswordModeEnabled(passwordMode); 0151 lineEdit->setProperty("nm_secrets_key", secretKey); 0152 lineEdit->setText(password); 0153 d->layout->addRow(label, lineEdit); 0154 }