File indexing completed on 2024-12-22 05:01:03

0001 /*
0002   SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org>
0003 
0004   SPDX-License-Identifier: GPL-2.0-only
0005 */
0006 
0007 #include "configuresecuritypage.h"
0008 #include <PimCommon/ConfigureImmutableWidgetUtils>
0009 using namespace PimCommon::ConfigureImmutableWidgetUtils;
0010 #include <MailCommon/FolderSettings>
0011 #include <MessageComposer/MessageComposerSettings>
0012 #include <MessageViewer/MessageViewerSettings>
0013 #include <MessageViewer/RemoteContentConfigureDialog>
0014 #include <WebEngineViewer/CheckPhishingUrlCache>
0015 
0016 #include "kmkernel.h"
0017 
0018 #include <Libkleo/KeyRequester>
0019 #include <Libkleo/KeySelectionDialog>
0020 #include <QGpgME/CryptoConfig>
0021 #include <QGpgME/Protocol>
0022 
0023 #include "kmail_debug.h"
0024 #include <KLocalizedString>
0025 #include <KMessageBox>
0026 #include <KPluginMetaData>
0027 
0028 #include <KWindowConfig>
0029 #include <QButtonGroup>
0030 #include <QDBusConnection>
0031 #include <QPointer>
0032 #include <QWhatsThis>
0033 #include <QWindow>
0034 
0035 QString SecurityPage::helpAnchor() const
0036 {
0037     return QStringLiteral("configure-security");
0038 }
0039 
0040 SecurityPage::SecurityPage(QObject *parent, const KPluginMetaData &data)
0041     : ConfigModuleWithTabs(parent, data)
0042 {
0043     //
0044     // "Reading" tab:
0045     //
0046     auto generalTab = new SecurityPageGeneralTab();
0047     addTab(generalTab, i18n("Reading"));
0048 
0049     addTab(new SecurityPageMDNTab(), i18n("Message Disposition Notifications"));
0050 
0051     //
0052     // "Encryption" tab:
0053     //
0054     auto encryptionTab = new SecurityPageEncryptionTab();
0055     addTab(encryptionTab, i18n("Encryption"));
0056 
0057     //
0058     // "S/MIME Validation" tab:
0059     //
0060     auto sMimeTab = new SecurityPageSMimeTab();
0061     addTab(sMimeTab, i18n("S/MIME Validation"));
0062 }
0063 
0064 QString SecurityPageGeneralTab::helpAnchor() const
0065 {
0066     return QStringLiteral("configure-security-reading");
0067 }
0068 
0069 SecurityPageGeneralTab::SecurityPageGeneralTab(QWidget *parent)
0070     : ConfigModuleTab(parent)
0071 {
0072     mSGTab.setupUi(this);
0073 
0074     connect(mSGTab.mConfigureExternalReference, &QPushButton::clicked, this, &SecurityPageGeneralTab::slotOpenExternalReferenceExceptions);
0075     connect(mSGTab.mHtmlMailCheck, &QCheckBox::stateChanged, this, &SecurityPageGeneralTab::slotEmitChanged);
0076     connect(mSGTab.mExternalReferences, &QCheckBox::stateChanged, this, &SecurityPageGeneralTab::slotEmitChanged);
0077     connect(mSGTab.labelWarnHTML, &QLabel::linkActivated, this, &SecurityPageGeneralTab::slotLinkClicked);
0078 
0079     connect(mSGTab.mAlwaysDecrypt, &QCheckBox::stateChanged, this, &SecurityPageGeneralTab::slotEmitChanged);
0080 
0081     connect(mSGTab.mAutomaticallyImportAttachedKeysCheck, &QAbstractButton::toggled, this, &ConfigModuleTab::slotEmitChanged);
0082 
0083     connect(mSGTab.mScamDetection, &QAbstractButton::toggled, this, &ConfigModuleTab::slotEmitChanged);
0084 
0085     connect(mSGTab.mCheckUrl, &QCheckBox::stateChanged, this, &SecurityPageGeneralTab::slotEmitChanged);
0086     connect(mSGTab.mCheckMailUrlTracking, &QCheckBox::stateChanged, this, &SecurityPageGeneralTab::slotEmitChanged);
0087     connect(mSGTab.scamWhiteList, &PimCommon::SimpleStringListEditor::changed, this, &ConfigModuleTab::slotEmitChanged);
0088     mSGTab.scamWhiteList->setAddDialogLabel(i18n("Email Address:"));
0089     mSGTab.scamWhiteList->setRemoveDialogLabel(i18n("Do you want to remove this email address?"));
0090 }
0091 
0092 void SecurityPageGeneralTab::slotOpenExternalReferenceExceptions()
0093 {
0094     MessageViewer::RemoteContentConfigureDialog dlg(this);
0095     dlg.exec();
0096 }
0097 
0098 void SecurityPageGeneralTab::slotLinkClicked(const QString &link)
0099 {
0100     if (link == QLatin1StringView("whatsthis1")) {
0101         QWhatsThis::showText(QCursor::pos(), mSGTab.mHtmlMailCheck->whatsThis());
0102     } else if (link == QLatin1StringView("whatsthis2")) {
0103         QWhatsThis::showText(QCursor::pos(), mSGTab.mExternalReferences->whatsThis());
0104     }
0105 }
0106 
0107 void SecurityPageGeneralTab::doLoadOther()
0108 {
0109     loadWidget(mSGTab.mHtmlMailCheck, MessageViewer::MessageViewerSettings::self()->htmlMailItem());
0110     loadWidget(mSGTab.mExternalReferences, MessageViewer::MessageViewerSettings::self()->htmlLoadExternalItem());
0111     loadWidget(mSGTab.mAutomaticallyImportAttachedKeysCheck, MessageViewer::MessageViewerSettings::self()->autoImportKeysItem());
0112     loadWidget(mSGTab.mAlwaysDecrypt, MessageViewer::MessageViewerSettings::self()->alwaysDecryptItem());
0113 
0114     loadWidget(mSGTab.mScamDetection, MessageViewer::MessageViewerSettings::self()->scamDetectionEnabledItem());
0115     loadWidget(mSGTab.scamWhiteList, MessageViewer::MessageViewerSettings::self()->scamDetectionWhiteListItem());
0116     loadWidget(mSGTab.mCheckUrl, MessageViewer::MessageViewerSettings::self()->checkPhishingUrlItem());
0117     loadWidget(mSGTab.mCheckMailUrlTracking, MessageViewer::MessageViewerSettings::self()->mailTrackingUrlEnabledItem());
0118 }
0119 
0120 void SecurityPageGeneralTab::save()
0121 {
0122     if (MessageViewer::MessageViewerSettings::self()->htmlMail() != mSGTab.mHtmlMailCheck->isChecked()) {
0123         if (KMessageBox::warningContinueCancel(this,
0124                                                i18n("Changing the global "
0125                                                     "HTML setting will override all folder specific values."),
0126                                                QString(),
0127                                                KStandardGuiItem::cont(),
0128                                                KStandardGuiItem::cancel(),
0129                                                QStringLiteral("htmlMailOverride"))
0130             == KMessageBox::Continue) {
0131             saveCheckBox(mSGTab.mHtmlMailCheck, MessageViewer::MessageViewerSettings::self()->htmlMailItem());
0132             if (kmkernel) {
0133                 const auto allFolders = kmkernel->allFolders();
0134                 for (const Akonadi::Collection &collection : allFolders) {
0135                     KConfigGroup config(KMKernel::self()->config(), MailCommon::FolderSettings::configGroupName(collection));
0136                     // Old config
0137                     config.deleteEntry("htmlMailOverride");
0138                     config.deleteEntry("displayFormatOverride");
0139                     MailCommon::FolderSettings::resetHtmlFormat();
0140                 }
0141             }
0142         }
0143     }
0144     saveCheckBox(mSGTab.mExternalReferences, MessageViewer::MessageViewerSettings::self()->htmlLoadExternalItem());
0145 
0146     saveCheckBox(mSGTab.mAutomaticallyImportAttachedKeysCheck, MessageViewer::MessageViewerSettings::self()->autoImportKeysItem());
0147     saveCheckBox(mSGTab.mAlwaysDecrypt, MessageViewer::MessageViewerSettings::self()->alwaysDecryptItem());
0148     saveCheckBox(mSGTab.mScamDetection, MessageViewer::MessageViewerSettings::self()->scamDetectionEnabledItem());
0149     saveSimpleStringListEditor(mSGTab.scamWhiteList, MessageViewer::MessageViewerSettings::self()->scamDetectionWhiteListItem());
0150     saveCheckBox(mSGTab.mCheckUrl, MessageViewer::MessageViewerSettings::self()->checkPhishingUrlItem());
0151     saveCheckBox(mSGTab.mCheckMailUrlTracking, MessageViewer::MessageViewerSettings::self()->mailTrackingUrlEnabledItem());
0152     if (!mSGTab.mCheckUrl->isChecked()) {
0153         WebEngineViewer::CheckPhishingUrlCache::self()->clearCache();
0154     }
0155 }
0156 
0157 QString SecurityPageMDNTab::helpAnchor() const
0158 {
0159     return QStringLiteral("configure-security-mdn");
0160 }
0161 
0162 SecurityPageMDNTab::SecurityPageMDNTab(QWidget *parent)
0163     : ConfigModuleTab(parent)
0164 {
0165     mUi.setupUi(this);
0166 
0167     // "ignore", "ask", "deny", "always send" radiobuttons
0168     mMDNGroup = new QButtonGroup(this);
0169     connect(mMDNGroup, &QButtonGroup::buttonClicked, this, &SecurityPageMDNTab::slotEmitChanged);
0170     mMDNGroup->addButton(mUi.radioIgnore, 0);
0171     mMDNGroup->addButton(mUi.radioAsk, 1);
0172     mMDNGroup->addButton(mUi.radioDeny, 2);
0173     mMDNGroup->addButton(mUi.radioAlways, 3);
0174 
0175     // "Original Message quote" radiobuttons
0176     mOrigQuoteGroup = new QButtonGroup(this);
0177     connect(mOrigQuoteGroup, &QButtonGroup::buttonClicked, this, &SecurityPageMDNTab::slotEmitChanged);
0178     mOrigQuoteGroup->addButton(mUi.radioNothing, 0);
0179     mOrigQuoteGroup->addButton(mUi.radioFull, 1);
0180     mOrigQuoteGroup->addButton(mUi.radioHeaders, 2);
0181 
0182     connect(mUi.mNoMDNsWhenEncryptedCheck, &QAbstractButton::toggled, this, &ConfigModuleTab::slotEmitChanged);
0183     connect(mUi.labelWarning, &QLabel::linkActivated, this, &SecurityPageMDNTab::slotLinkClicked);
0184 }
0185 
0186 void SecurityPageMDNTab::slotLinkClicked(const QString &link)
0187 {
0188     if (link == QLatin1StringView("whatsthis-mdn")) {
0189         QWhatsThis::showText(QCursor::pos(), mUi.radioIgnore->whatsThis());
0190     }
0191 }
0192 
0193 void SecurityPageMDNTab::doLoadOther()
0194 {
0195     int num = MessageViewer::MessageViewerSettings::self()->defaultPolicy();
0196     if (num < 0 || num >= mMDNGroup->buttons().count()) {
0197         num = 0;
0198     }
0199     mMDNGroup->button(num)->setChecked(true);
0200     num = MessageViewer::MessageViewerSettings::self()->quoteMessage();
0201     if (num < 0 || num >= mOrigQuoteGroup->buttons().count()) {
0202         num = 0;
0203     }
0204     mOrigQuoteGroup->button(num)->setChecked(true);
0205     loadWidget(mUi.mNoMDNsWhenEncryptedCheck, MessageViewer::MessageViewerSettings::self()->notSendWhenEncryptedItem());
0206 }
0207 
0208 void SecurityPageMDNTab::save()
0209 {
0210     MessageViewer::MessageViewerSettings::self()->setDefaultPolicy(mMDNGroup->checkedId());
0211     MessageViewer::MessageViewerSettings::self()->setQuoteMessage(mOrigQuoteGroup->checkedId());
0212     saveCheckBox(mUi.mNoMDNsWhenEncryptedCheck, MessageViewer::MessageViewerSettings::self()->notSendWhenEncryptedItem());
0213 }
0214 
0215 QString SecurityPageEncryptionTab::helpAnchor() const
0216 {
0217     return QStringLiteral("configure-security-composing");
0218 }
0219 
0220 SecurityPageEncryptionTab::SecurityPageEncryptionTab(QWidget *parent)
0221     : ConfigModuleTab(parent)
0222     , mWidget(new Ui::SecurityPageEncryptionTab)
0223 {
0224     mWidget->setupUi(this);
0225     connect(mWidget->mAlwaysEncryptWhenSavingInDrafts, &QCheckBox::toggled, this, &SecurityPageEncryptionTab::slotEmitChanged);
0226     connect(mWidget->mStoreEncrypted, &QCheckBox::toggled, this, &SecurityPageEncryptionTab::slotEmitChanged);
0227     connect(mWidget->mAutoSign, &QCheckBox::toggled, this, &SecurityPageEncryptionTab::slotEmitChanged);
0228     connect(mWidget->mAutoEncrypt, &QCheckBox::toggled, this, &SecurityPageEncryptionTab::slotEmitChanged);
0229 
0230     connect(mWidget->mShowEncSignIndicator, &QCheckBox::toggled, this, &SecurityPageEncryptionTab::slotEmitChanged);
0231     connect(mWidget->mShowCryptoOwnertrust, &QCheckBox::toggled, this, &SecurityPageEncryptionTab::slotEmitChanged);
0232     mWidget->mShowCryptoOwnertrust->setVisible(false);
0233 
0234     connect(mWidget->mShowKeyApprovalDlg, &QCheckBox::toggled, this, &SecurityPageEncryptionTab::slotEmitChanged);
0235     connect(mWidget->mWarnUnsigned, &QCheckBox::toggled, this, &SecurityPageEncryptionTab::slotEmitChanged);
0236     connect(mWidget->warnUnencryptedCB, &QCheckBox::toggled, this, &SecurityPageEncryptionTab::slotEmitChanged);
0237 
0238     connect(mWidget->warnGroupBox, &QGroupBox::toggled, this, &SecurityPageEncryptionTab::slotEmitChanged);
0239     connect(mWidget->mWarnEncrOwnKeyExpiresSB, &KPluralHandlingSpinBox::valueChanged, this, &SecurityPageEncryptionTab::slotEmitChanged);
0240     connect(mWidget->mWarnEncrKeyExpiresSB, &KPluralHandlingSpinBox::valueChanged, this, &SecurityPageEncryptionTab::slotEmitChanged);
0241     connect(mWidget->mWarnEncrChainCertExpiresSB, &KPluralHandlingSpinBox::valueChanged, this, &SecurityPageEncryptionTab::slotEmitChanged);
0242     connect(mWidget->mWarnEncrRootCertExpiresSB, &KPluralHandlingSpinBox::valueChanged, this, &SecurityPageEncryptionTab::slotEmitChanged);
0243 
0244     connect(mWidget->gnupgButton, &QPushButton::clicked, this, &SecurityPageEncryptionTab::slotConfigureGnupg);
0245     connect(mWidget->enableAllWarningsPB, &QPushButton::clicked, this, &SecurityPageEncryptionTab::slotReenableAllWarningsClicked);
0246 }
0247 
0248 SecurityPageEncryptionTab::~SecurityPageEncryptionTab()
0249 {
0250     delete mWidget;
0251 }
0252 
0253 void SecurityPageEncryptionTab::doLoadFromGlobalSettings()
0254 {
0255     loadWidget(mWidget->mAlwaysEncryptWhenSavingInDrafts, KMailSettings::self()->alwaysEncryptDraftsItem());
0256     loadWidget(mWidget->mStoreEncrypted, KMailSettings::self()->cryptoStoreEncryptedItem());
0257     loadWidget(mWidget->mAutoSign, MessageComposer::MessageComposerSettings::self()->cryptoAutoSignItem());
0258     loadWidget(mWidget->mAutoEncrypt, MessageComposer::MessageComposerSettings::self()->cryptoAutoEncryptItem());
0259 
0260     loadWidget(mWidget->mShowEncSignIndicator, KMailSettings::self()->showCryptoLabelIndicatorItem());
0261     loadWidget(mWidget->mShowCryptoOwnertrust, KMailSettings::self()->showCryptoOwnertrustItem());
0262 
0263     loadWidget(mWidget->mShowKeyApprovalDlg, MessageComposer::MessageComposerSettings::self()->cryptoShowKeysForApprovalItem());
0264     loadWidget(mWidget->mWarnUnsigned, MessageComposer::MessageComposerSettings::self()->cryptoWarningUnsignedItem());
0265     loadWidget(mWidget->warnUnencryptedCB, MessageComposer::MessageComposerSettings::self()->cryptoWarningUnencryptedItem());
0266 
0267     mWidget->warnGroupBox->setChecked(MessageComposer::MessageComposerSettings::self()->cryptoWarnWhenNearExpire());
0268 
0269     loadWidget(mWidget->mWarnEncrKeyExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnEncrKeyNearExpiryThresholdDaysItem());
0270     loadWidget(mWidget->mWarnEncrOwnKeyExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnOwnEncrKeyNearExpiryThresholdDaysItem());
0271     loadWidget(mWidget->mWarnEncrChainCertExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnEncrChaincertNearExpiryThresholdDaysItem());
0272     loadWidget(mWidget->mWarnEncrRootCertExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnEncrRootNearExpiryThresholdDaysItem());
0273 }
0274 
0275 void SecurityPageEncryptionTab::doLoadOther()
0276 {
0277     loadWidget(mWidget->mAlwaysEncryptWhenSavingInDrafts, KMailSettings::self()->alwaysEncryptDraftsItem());
0278     loadWidget(mWidget->mStoreEncrypted, KMailSettings::self()->cryptoStoreEncryptedItem());
0279     loadWidget(mWidget->mAutoSign, MessageComposer::MessageComposerSettings::self()->cryptoAutoSignItem());
0280     loadWidget(mWidget->mAutoEncrypt, MessageComposer::MessageComposerSettings::self()->cryptoAutoEncryptItem());
0281 
0282     loadWidget(mWidget->mShowEncSignIndicator, KMailSettings::self()->showCryptoLabelIndicatorItem());
0283     loadWidget(mWidget->mShowCryptoOwnertrust, KMailSettings::self()->showCryptoOwnertrustItem());
0284 
0285     loadWidget(mWidget->mShowKeyApprovalDlg, MessageComposer::MessageComposerSettings::self()->cryptoShowKeysForApprovalItem());
0286     loadWidget(mWidget->mWarnUnsigned, MessageComposer::MessageComposerSettings::self()->cryptoWarningUnsignedItem());
0287     loadWidget(mWidget->warnUnencryptedCB, MessageComposer::MessageComposerSettings::self()->cryptoWarningUnencryptedItem());
0288 
0289     mWidget->warnGroupBox->setChecked(MessageComposer::MessageComposerSettings::self()->cryptoWarnWhenNearExpire());
0290 
0291     loadWidget(mWidget->mWarnEncrOwnKeyExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnOwnEncrKeyNearExpiryThresholdDaysItem());
0292     mWidget->mWarnEncrOwnKeyExpiresSB->setSuffix(ki18np(" day", " days"));
0293     loadWidget(mWidget->mWarnEncrKeyExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnEncrKeyNearExpiryThresholdDaysItem());
0294     mWidget->mWarnEncrKeyExpiresSB->setSuffix(ki18np(" day", " days"));
0295     loadWidget(mWidget->mWarnEncrChainCertExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnEncrChaincertNearExpiryThresholdDaysItem());
0296     mWidget->mWarnEncrChainCertExpiresSB->setSuffix(ki18np(" day", " days"));
0297     loadWidget(mWidget->mWarnEncrRootCertExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnEncrRootNearExpiryThresholdDaysItem());
0298     mWidget->mWarnEncrRootCertExpiresSB->setSuffix(ki18np(" day", " days"));
0299 
0300     mWidget->enableAllWarningsPB->setEnabled(true);
0301 }
0302 
0303 void SecurityPageEncryptionTab::save()
0304 {
0305     saveCheckBox(mWidget->mAlwaysEncryptWhenSavingInDrafts, KMailSettings::self()->alwaysEncryptDraftsItem());
0306     saveCheckBox(mWidget->mStoreEncrypted, KMailSettings::self()->cryptoStoreEncryptedItem());
0307     saveCheckBox(mWidget->mAutoSign, MessageComposer::MessageComposerSettings::self()->cryptoAutoSignItem());
0308     saveCheckBox(mWidget->mAutoEncrypt, MessageComposer::MessageComposerSettings::self()->cryptoAutoEncryptItem());
0309 
0310     saveCheckBox(mWidget->mShowEncSignIndicator, KMailSettings::self()->showCryptoLabelIndicatorItem());
0311     saveCheckBox(mWidget->mShowCryptoOwnertrust, KMailSettings::self()->showCryptoOwnertrustItem());
0312 
0313     saveCheckBox(mWidget->mShowKeyApprovalDlg, MessageComposer::MessageComposerSettings::self()->cryptoShowKeysForApprovalItem());
0314     saveCheckBox(mWidget->mWarnUnsigned, MessageComposer::MessageComposerSettings::self()->cryptoWarningUnsignedItem());
0315     saveCheckBox(mWidget->warnUnencryptedCB, MessageComposer::MessageComposerSettings::self()->cryptoWarningUnencryptedItem());
0316 
0317     MessageComposer::MessageComposerSettings::self()->setCryptoWarnWhenNearExpire(mWidget->warnGroupBox->isChecked());
0318 
0319     saveSpinBox(mWidget->mWarnEncrOwnKeyExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnOwnEncrKeyNearExpiryThresholdDaysItem());
0320     saveSpinBox(mWidget->mWarnEncrKeyExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnEncrKeyNearExpiryThresholdDaysItem());
0321     saveSpinBox(mWidget->mWarnEncrChainCertExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnEncrChaincertNearExpiryThresholdDaysItem());
0322     saveSpinBox(mWidget->mWarnEncrRootCertExpiresSB, MessageComposer::MessageComposerSettings::self()->cryptoWarnEncrRootNearExpiryThresholdDaysItem());
0323 }
0324 
0325 void SecurityPageEncryptionTab::slotReenableAllWarningsClicked()
0326 {
0327     KMessageBox::enableAllMessages();
0328     mWidget->enableAllWarningsPB->setEnabled(false);
0329 }
0330 
0331 void SecurityPageEncryptionTab::slotConfigureGnupg()
0332 {
0333     QPointer<GpgSettingsDialog> dlg(new GpgSettingsDialog(this));
0334     dlg->setWindowTitle(i18nc("@title:window", "GnuPG Settings"));
0335     KPageWidgetItem *page = nullptr;
0336     const auto plugin = KPluginMetaData::findPluginById((QStringLiteral("pim6/kcms/kleopatra")), QStringLiteral("kleopatra_config_gnupgsystem"));
0337     if (plugin.isValid()) {
0338         page = dlg->addModule(plugin);
0339     }
0340     if (!page) {
0341         auto info = new QLabel(i18n("The module is missing. Please verify your installation. This module is provided by Kleopatra."), this);
0342         QFont font = info->font();
0343         font.setBold(true);
0344         info->setFont(font);
0345         info->setWordWrap(true);
0346         dlg->addPage(info, i18n("GnuPG Configure Module Error"));
0347     }
0348     dlg->exec();
0349     delete dlg;
0350 }
0351 
0352 QString SecurityPageSMimeTab::helpAnchor() const
0353 {
0354     return QStringLiteral("configure-security-smime-validation");
0355 }
0356 
0357 SecurityPageSMimeTab::SecurityPageSMimeTab(QWidget *parent)
0358     : ConfigModuleTab(parent)
0359     , mWidget(new Ui::SMimeConfiguration)
0360 {
0361     mWidget->setupUi(this);
0362 
0363     // Button-group for exclusive radiobuttons
0364     auto bg = new QButtonGroup(this);
0365     bg->addButton(mWidget->CRLRB);
0366     bg->addButton(mWidget->OCSPRB);
0367 
0368     // Settings for the keyrequester custom widget
0369     mWidget->OCSPResponderSignature->setAllowedKeys(Kleo::KeySelectionDialog::SMIMEKeys | Kleo::KeySelectionDialog::TrustedKeys
0370                                                     | Kleo::KeySelectionDialog::ValidKeys | Kleo::KeySelectionDialog::SigningKeys
0371                                                     | Kleo::KeySelectionDialog::PublicKeys);
0372     mWidget->OCSPResponderSignature->setMultipleKeysEnabled(false);
0373 
0374     mConfig = QGpgME::cryptoConfig();
0375 
0376     connect(mWidget->CRLRB, &QRadioButton::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0377     connect(mWidget->OCSPRB, &QRadioButton::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0378     connect(mWidget->OCSPResponderURL, &QLineEdit::textChanged, this, &SecurityPageSMimeTab::slotEmitChanged);
0379     connect(mWidget->OCSPResponderSignature, &Kleo::KeyRequester::changed, this, &SecurityPageSMimeTab::slotEmitChanged);
0380     connect(mWidget->doNotCheckCertPolicyCB, &QCheckBox::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0381     connect(mWidget->neverConsultCB, &QCheckBox::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0382     connect(mWidget->fetchMissingCB, &QCheckBox::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0383 
0384     connect(mWidget->ignoreServiceURLCB, &QCheckBox::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0385     connect(mWidget->ignoreHTTPDPCB, &QCheckBox::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0386     connect(mWidget->disableHTTPCB, &QCheckBox::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0387     connect(mWidget->honorHTTPProxyRB, &QRadioButton::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0388     connect(mWidget->useCustomHTTPProxyRB, &QRadioButton::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0389     connect(mWidget->customHTTPProxy, &QLineEdit::textChanged, this, &SecurityPageSMimeTab::slotEmitChanged);
0390     connect(mWidget->ignoreLDAPDPCB, &QCheckBox::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0391     connect(mWidget->disableLDAPCB, &QCheckBox::toggled, this, &SecurityPageSMimeTab::slotEmitChanged);
0392     connect(mWidget->customLDAPProxy, &QLineEdit::textChanged, this, &SecurityPageSMimeTab::slotEmitChanged);
0393 
0394     connect(mWidget->disableHTTPCB, &QCheckBox::toggled, this, &SecurityPageSMimeTab::slotUpdateHTTPActions);
0395     connect(mWidget->ignoreHTTPDPCB, &QCheckBox::toggled, this, &SecurityPageSMimeTab::slotUpdateHTTPActions);
0396 
0397     // Button-group for exclusive radiobuttons
0398     auto bgHTTPProxy = new QButtonGroup(this);
0399     bgHTTPProxy->addButton(mWidget->honorHTTPProxyRB);
0400     bgHTTPProxy->addButton(mWidget->useCustomHTTPProxyRB);
0401 
0402     QDBusConnection::sessionBus().connect(QString(), QString(), QStringLiteral("org.kde.kleo.CryptoConfig"), QStringLiteral("changed"), this, SLOT(load()));
0403 }
0404 
0405 SecurityPageSMimeTab::~SecurityPageSMimeTab()
0406 {
0407     delete mWidget;
0408 }
0409 
0410 static void disableDirmngrWidget(QWidget *w)
0411 {
0412     w->setEnabled(false);
0413     w->setWhatsThis(i18n("This option requires dirmngr >= 0.9.0"));
0414 }
0415 
0416 static void initializeDirmngrCheckbox(QCheckBox *cb, QGpgME::CryptoConfigEntry *entry)
0417 {
0418     if (entry) {
0419         cb->setChecked(entry->boolValue());
0420     } else {
0421         disableDirmngrWidget(cb);
0422     }
0423 }
0424 
0425 struct SMIMECryptoConfigEntries {
0426     explicit SMIMECryptoConfigEntries(QGpgME::CryptoConfig *config)
0427         : mConfig(config)
0428     {
0429         // Checkboxes
0430         mCheckUsingOCSPConfigEntry =
0431             configEntry(QStringLiteral("gpgsm"), QStringLiteral("Security"), QStringLiteral("enable-ocsp"), QGpgME::CryptoConfigEntry::ArgType_None, false);
0432         mEnableOCSPsendingConfigEntry =
0433             configEntry(QStringLiteral("dirmngr"), QStringLiteral("OCSP"), QStringLiteral("allow-ocsp"), QGpgME::CryptoConfigEntry::ArgType_None, false);
0434         mDoNotCheckCertPolicyConfigEntry = configEntry(QStringLiteral("gpgsm"),
0435                                                        QStringLiteral("Security"),
0436                                                        QStringLiteral("disable-policy-checks"),
0437                                                        QGpgME::CryptoConfigEntry::ArgType_None,
0438                                                        false);
0439         mNeverConsultConfigEntry = configEntry(QStringLiteral("gpgsm"),
0440                                                QStringLiteral("Security"),
0441                                                QStringLiteral("disable-crl-checks"),
0442                                                QGpgME::CryptoConfigEntry::ArgType_None,
0443                                                false);
0444         mFetchMissingConfigEntry = configEntry(QStringLiteral("gpgsm"),
0445                                                QStringLiteral("Security"),
0446                                                QStringLiteral("auto-issuer-key-retrieve"),
0447                                                QGpgME::CryptoConfigEntry::ArgType_None,
0448                                                false);
0449         // dirmngr-0.9.0 options
0450         mIgnoreServiceURLEntry = configEntry(QStringLiteral("dirmngr"),
0451                                              QStringLiteral("OCSP"),
0452                                              QStringLiteral("ignore-ocsp-service-url"),
0453                                              QGpgME::CryptoConfigEntry::ArgType_None,
0454                                              false);
0455         mIgnoreHTTPDPEntry =
0456             configEntry(QStringLiteral("dirmngr"), QStringLiteral("HTTP"), QStringLiteral("ignore-http-dp"), QGpgME::CryptoConfigEntry::ArgType_None, false);
0457         mDisableHTTPEntry =
0458             configEntry(QStringLiteral("dirmngr"), QStringLiteral("HTTP"), QStringLiteral("disable-http"), QGpgME::CryptoConfigEntry::ArgType_None, false);
0459         mHonorHTTPProxy =
0460             configEntry(QStringLiteral("dirmngr"), QStringLiteral("HTTP"), QStringLiteral("honor-http-proxy"), QGpgME::CryptoConfigEntry::ArgType_None, false);
0461 
0462         mIgnoreLDAPDPEntry =
0463             configEntry(QStringLiteral("dirmngr"), QStringLiteral("LDAP"), QStringLiteral("ignore-ldap-dp"), QGpgME::CryptoConfigEntry::ArgType_None, false);
0464         mDisableLDAPEntry =
0465             configEntry(QStringLiteral("dirmngr"), QStringLiteral("LDAP"), QStringLiteral("disable-ldap"), QGpgME::CryptoConfigEntry::ArgType_None, false);
0466         // Other widgets
0467         mOCSPResponderURLConfigEntry =
0468             configEntry(QStringLiteral("dirmngr"), QStringLiteral("OCSP"), QStringLiteral("ocsp-responder"), QGpgME::CryptoConfigEntry::ArgType_String, false);
0469         mOCSPResponderSignature =
0470             configEntry(QStringLiteral("dirmngr"), QStringLiteral("OCSP"), QStringLiteral("ocsp-signer"), QGpgME::CryptoConfigEntry::ArgType_String, false);
0471         mCustomHTTPProxy =
0472             configEntry(QStringLiteral("dirmngr"), QStringLiteral("HTTP"), QStringLiteral("http-proxy"), QGpgME::CryptoConfigEntry::ArgType_String, false);
0473         mCustomLDAPProxy =
0474             configEntry(QStringLiteral("dirmngr"), QStringLiteral("LDAP"), QStringLiteral("ldap-proxy"), QGpgME::CryptoConfigEntry::ArgType_String, false);
0475     }
0476 
0477     QGpgME::CryptoConfigEntry *configEntry(const QString &componentName, const QString &groupName, const QString &entryName, int argType, bool isList);
0478 
0479     // Checkboxes
0480     QGpgME::CryptoConfigEntry *mCheckUsingOCSPConfigEntry = nullptr;
0481     QGpgME::CryptoConfigEntry *mEnableOCSPsendingConfigEntry = nullptr;
0482     QGpgME::CryptoConfigEntry *mDoNotCheckCertPolicyConfigEntry = nullptr;
0483     QGpgME::CryptoConfigEntry *mNeverConsultConfigEntry = nullptr;
0484     QGpgME::CryptoConfigEntry *mFetchMissingConfigEntry = nullptr;
0485     QGpgME::CryptoConfigEntry *mIgnoreServiceURLEntry = nullptr;
0486     QGpgME::CryptoConfigEntry *mIgnoreHTTPDPEntry = nullptr;
0487     QGpgME::CryptoConfigEntry *mDisableHTTPEntry = nullptr;
0488     QGpgME::CryptoConfigEntry *mHonorHTTPProxy = nullptr;
0489     QGpgME::CryptoConfigEntry *mIgnoreLDAPDPEntry = nullptr;
0490     QGpgME::CryptoConfigEntry *mDisableLDAPEntry = nullptr;
0491     // Other widgets
0492     QGpgME::CryptoConfigEntry *mOCSPResponderURLConfigEntry = nullptr;
0493     QGpgME::CryptoConfigEntry *mOCSPResponderSignature = nullptr;
0494     QGpgME::CryptoConfigEntry *mCustomHTTPProxy = nullptr;
0495     QGpgME::CryptoConfigEntry *mCustomLDAPProxy = nullptr;
0496 
0497     QGpgME::CryptoConfig *mConfig = nullptr;
0498 };
0499 
0500 void SecurityPageSMimeTab::doLoadOther()
0501 {
0502     if (!mConfig) {
0503         setEnabled(false);
0504         return;
0505     }
0506 
0507     // Force re-parsing gpgconf data, in case e.g. kleopatra or "configure backend" was used
0508     // (which ends up calling us via D-Bus)
0509     mConfig->clear();
0510 
0511     // Create config entries
0512     // Don't keep them around, they'll get deleted by clear(), which could be
0513     // done by the "configure backend" button even before we save().
0514     SMIMECryptoConfigEntries e(mConfig);
0515 
0516     // Initialize GUI items from the config entries
0517 
0518     if (e.mCheckUsingOCSPConfigEntry) {
0519         bool b = e.mCheckUsingOCSPConfigEntry->boolValue();
0520         mWidget->OCSPRB->setChecked(b);
0521         mWidget->CRLRB->setChecked(!b);
0522         mWidget->OCSPGroupBox->setEnabled(b);
0523     } else {
0524         mWidget->OCSPGroupBox->setEnabled(false);
0525     }
0526     if (e.mDoNotCheckCertPolicyConfigEntry) {
0527         mWidget->doNotCheckCertPolicyCB->setChecked(e.mDoNotCheckCertPolicyConfigEntry->boolValue());
0528     }
0529     if (e.mNeverConsultConfigEntry) {
0530         mWidget->neverConsultCB->setChecked(e.mNeverConsultConfigEntry->boolValue());
0531     }
0532     if (e.mFetchMissingConfigEntry) {
0533         mWidget->fetchMissingCB->setChecked(e.mFetchMissingConfigEntry->boolValue());
0534     }
0535 
0536     if (e.mOCSPResponderURLConfigEntry) {
0537         mWidget->OCSPResponderURL->setText(e.mOCSPResponderURLConfigEntry->stringValue());
0538     }
0539     if (e.mOCSPResponderSignature) {
0540         mWidget->OCSPResponderSignature->setFingerprint(e.mOCSPResponderSignature->stringValue());
0541     }
0542 
0543     // dirmngr-0.9.0 options
0544     initializeDirmngrCheckbox(mWidget->ignoreServiceURLCB, e.mIgnoreServiceURLEntry);
0545     initializeDirmngrCheckbox(mWidget->ignoreHTTPDPCB, e.mIgnoreHTTPDPEntry);
0546     initializeDirmngrCheckbox(mWidget->disableHTTPCB, e.mDisableHTTPEntry);
0547     initializeDirmngrCheckbox(mWidget->ignoreLDAPDPCB, e.mIgnoreLDAPDPEntry);
0548     initializeDirmngrCheckbox(mWidget->disableLDAPCB, e.mDisableLDAPEntry);
0549     if (e.mCustomHTTPProxy) {
0550         QString systemProxy = QString::fromLocal8Bit(qgetenv("http_proxy"));
0551         if (systemProxy.isEmpty()) {
0552             systemProxy = i18n("no proxy");
0553         }
0554         mWidget->systemHTTPProxy->setText(i18n("(Current system setting: %1)", systemProxy));
0555         bool honor = e.mHonorHTTPProxy && e.mHonorHTTPProxy->boolValue();
0556         mWidget->honorHTTPProxyRB->setChecked(honor);
0557         mWidget->useCustomHTTPProxyRB->setChecked(!honor);
0558         mWidget->customHTTPProxy->setText(e.mCustomHTTPProxy->stringValue());
0559     } else {
0560         disableDirmngrWidget(mWidget->honorHTTPProxyRB);
0561         disableDirmngrWidget(mWidget->useCustomHTTPProxyRB);
0562         disableDirmngrWidget(mWidget->systemHTTPProxy);
0563         disableDirmngrWidget(mWidget->customHTTPProxy);
0564     }
0565     if (e.mCustomLDAPProxy) {
0566         mWidget->customLDAPProxy->setText(e.mCustomLDAPProxy->stringValue());
0567     } else {
0568         disableDirmngrWidget(mWidget->customLDAPProxy);
0569         disableDirmngrWidget(mWidget->customLDAPLabel);
0570     }
0571     slotUpdateHTTPActions();
0572 }
0573 
0574 void SecurityPageSMimeTab::slotUpdateHTTPActions()
0575 {
0576     mWidget->ignoreHTTPDPCB->setEnabled(!mWidget->disableHTTPCB->isChecked());
0577 
0578     // The proxy settings only make sense when "Ignore HTTP CRL DPs of certificate" is checked.
0579     bool enableProxySettings = !mWidget->disableHTTPCB->isChecked() && mWidget->ignoreHTTPDPCB->isChecked();
0580     mWidget->systemHTTPProxy->setEnabled(enableProxySettings);
0581     mWidget->useCustomHTTPProxyRB->setEnabled(enableProxySettings);
0582     mWidget->honorHTTPProxyRB->setEnabled(enableProxySettings);
0583     mWidget->customHTTPProxy->setEnabled(enableProxySettings && mWidget->useCustomHTTPProxyRB->isChecked());
0584 
0585     if (!mWidget->useCustomHTTPProxyRB->isChecked() && !mWidget->honorHTTPProxyRB->isChecked()) {
0586         mWidget->honorHTTPProxyRB->setChecked(true);
0587     }
0588 }
0589 
0590 static void saveCheckBoxToKleoEntry(QCheckBox *cb, QGpgME::CryptoConfigEntry *entry)
0591 {
0592     const bool b = cb->isChecked();
0593     if (entry && entry->boolValue() != b) {
0594         entry->setBoolValue(b);
0595     }
0596 }
0597 
0598 void SecurityPageSMimeTab::save()
0599 {
0600     if (!mConfig) {
0601         return;
0602     }
0603     // Create config entries
0604     // Don't keep them around, they'll get deleted by clear(), which could be done by the
0605     // "configure backend" button.
0606     SMIMECryptoConfigEntries e(mConfig);
0607 
0608     bool b = mWidget->OCSPRB->isChecked();
0609     if (e.mCheckUsingOCSPConfigEntry && e.mCheckUsingOCSPConfigEntry->boolValue() != b) {
0610         e.mCheckUsingOCSPConfigEntry->setBoolValue(b);
0611     }
0612     // Set allow-ocsp together with enable-ocsp
0613     if (e.mEnableOCSPsendingConfigEntry && e.mEnableOCSPsendingConfigEntry->boolValue() != b) {
0614         e.mEnableOCSPsendingConfigEntry->setBoolValue(b);
0615     }
0616 
0617     saveCheckBoxToKleoEntry(mWidget->doNotCheckCertPolicyCB, e.mDoNotCheckCertPolicyConfigEntry);
0618     saveCheckBoxToKleoEntry(mWidget->neverConsultCB, e.mNeverConsultConfigEntry);
0619     saveCheckBoxToKleoEntry(mWidget->fetchMissingCB, e.mFetchMissingConfigEntry);
0620 
0621     QString txt = mWidget->OCSPResponderURL->text();
0622     if (e.mOCSPResponderURLConfigEntry && e.mOCSPResponderURLConfigEntry->stringValue() != txt) {
0623         e.mOCSPResponderURLConfigEntry->setStringValue(txt);
0624     }
0625 
0626     txt = mWidget->OCSPResponderSignature->fingerprint();
0627     if (e.mOCSPResponderSignature && e.mOCSPResponderSignature->stringValue() != txt) {
0628         e.mOCSPResponderSignature->setStringValue(txt);
0629     }
0630 
0631     // dirmngr-0.9.0 options
0632     saveCheckBoxToKleoEntry(mWidget->ignoreServiceURLCB, e.mIgnoreServiceURLEntry);
0633     saveCheckBoxToKleoEntry(mWidget->ignoreHTTPDPCB, e.mIgnoreHTTPDPEntry);
0634     saveCheckBoxToKleoEntry(mWidget->disableHTTPCB, e.mDisableHTTPEntry);
0635     saveCheckBoxToKleoEntry(mWidget->ignoreLDAPDPCB, e.mIgnoreLDAPDPEntry);
0636     saveCheckBoxToKleoEntry(mWidget->disableLDAPCB, e.mDisableLDAPEntry);
0637     if (e.mCustomHTTPProxy) {
0638         const bool honor = mWidget->honorHTTPProxyRB->isChecked();
0639         if (e.mHonorHTTPProxy && e.mHonorHTTPProxy->boolValue() != honor) {
0640             e.mHonorHTTPProxy->setBoolValue(honor);
0641         }
0642 
0643         QString chosenProxy = mWidget->customHTTPProxy->text();
0644         if (chosenProxy != e.mCustomHTTPProxy->stringValue()) {
0645             e.mCustomHTTPProxy->setStringValue(chosenProxy);
0646         }
0647     }
0648     txt = mWidget->customLDAPProxy->text();
0649     if (e.mCustomLDAPProxy && e.mCustomLDAPProxy->stringValue() != txt) {
0650         e.mCustomLDAPProxy->setStringValue(mWidget->customLDAPProxy->text());
0651     }
0652 
0653     mConfig->sync(true);
0654 }
0655 
0656 QGpgME::CryptoConfigEntry *SMIMECryptoConfigEntries::configEntry(const QString &componentName,
0657                                                                  const QString &groupName,
0658                                                                  const QString &entryName,
0659                                                                  int /*Kleo::CryptoConfigEntry::ArgType*/ argType,
0660                                                                  bool isList)
0661 {
0662     QGpgME::CryptoConfigEntry *entry = mConfig->entry(componentName, groupName, entryName);
0663     if (!entry) {
0664         qCWarning(KMAIL_LOG) << QStringLiteral("Backend error: gpgconf doesn't seem to know the entry for %1/%2/%3").arg(componentName, groupName, entryName);
0665         return nullptr;
0666     }
0667     if (entry->argType() != argType || entry->isList() != isList) {
0668         qCWarning(KMAIL_LOG) << QStringLiteral("Backend error: gpgconf has wrong type for %1/%2/%3: %4 %5")
0669                                     .arg(componentName, groupName, entryName)
0670                                     .arg(entry->argType())
0671                                     .arg(entry->isList());
0672         return nullptr;
0673     }
0674     return entry;
0675 }
0676 
0677 namespace
0678 {
0679 static const char myGpgSettingsDialogGroupName[] = "GpgSettingsDialog";
0680 }
0681 
0682 GpgSettingsDialog::GpgSettingsDialog(QWidget *parent)
0683     : KCMultiDialog(parent)
0684 {
0685     readConfig();
0686 }
0687 
0688 GpgSettingsDialog::~GpgSettingsDialog()
0689 {
0690     saveConfig();
0691 }
0692 
0693 void GpgSettingsDialog::readConfig()
0694 {
0695     create(); // ensure a window is created
0696     windowHandle()->resize(QSize(600, 400));
0697     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myGpgSettingsDialogGroupName));
0698     KWindowConfig::restoreWindowSize(windowHandle(), group);
0699     resize(windowHandle()->size()); // workaround for QTBUG-40584
0700 }
0701 
0702 void GpgSettingsDialog::saveConfig()
0703 {
0704     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myGpgSettingsDialogGroupName));
0705     KWindowConfig::saveWindowSize(windowHandle(), group);
0706     group.sync();
0707 }
0708 
0709 #include "moc_configuresecuritypage.cpp"