File indexing completed on 2024-06-23 05:13:47
0001 /* 0002 cryptooperationsconfigwidget.cpp 0003 0004 This file is part of kleopatra, the KDE key manager 0005 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB 0006 0007 SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik 0008 SPDX-FileContributor: Intevation GmbH 0009 0010 SPDX-FileCopyrightText: 2022 g10 Code GmbH 0011 SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de> 0012 0013 SPDX-License-Identifier: GPL-2.0-or-later 0014 */ 0015 0016 #include <config-kleopatra.h> 0017 0018 #include "cryptooperationsconfigwidget.h" 0019 #include "kleopatra_debug.h" 0020 0021 #include "fileoperationspreferences.h" 0022 #include "settings.h" 0023 0024 #include <Libkleo/ChecksumDefinition> 0025 #include <Libkleo/KeyFilterManager> 0026 #include <libkleo/classifyconfig.h> 0027 0028 #include <KConfig> 0029 #include <KConfigGroup> 0030 #include <KLocalizedString> 0031 #include <KMessageBox> 0032 #include <KSharedConfig> 0033 0034 #include <QCheckBox> 0035 #include <QComboBox> 0036 #include <QDir> 0037 #include <QGroupBox> 0038 #include <QHBoxLayout> 0039 #include <QLabel> 0040 #include <QPushButton> 0041 #include <QRegularExpression> 0042 #include <QVBoxLayout> 0043 0044 #include <memory> 0045 0046 using namespace Kleo; 0047 using namespace Kleo::Config; 0048 0049 CryptoOperationsConfigWidget::CryptoOperationsConfigWidget(QWidget *p, Qt::WindowFlags f) 0050 : QWidget{p, f} 0051 { 0052 setupGui(); 0053 } 0054 0055 void CryptoOperationsConfigWidget::setupGui() 0056 { 0057 auto baseLay = new QVBoxLayout(this); 0058 0059 mPGPFileExtCB = new QCheckBox(i18n(R"(Create OpenPGP encrypted files with ".pgp" file extensions instead of ".gpg")")); 0060 mASCIIArmorCB = new QCheckBox(i18n("Create signed or encrypted files as text files.")); 0061 mASCIIArmorCB->setToolTip(i18nc("@info", 0062 "Set this option to encode encrypted or signed files as base64 encoded text. " 0063 "So that they can be opened with an editor or sent in a mail body. " 0064 "This will increase file size by one third.")); 0065 mTreatP7mEmailCB = new QCheckBox(i18nc("@option:check", "Treat .p7m files without extensions as mails.")); 0066 mAutoDecryptVerifyCB = new QCheckBox(i18n("Automatically start operation based on input detection for decrypt/verify.")); 0067 mAutoExtractArchivesCB = new QCheckBox(i18n("Automatically extract file archives after decryption")); 0068 mTmpDirCB = new QCheckBox(i18n("Create temporary decrypted files in the folder of the encrypted file.")); 0069 mTmpDirCB->setToolTip(i18nc("@info", "Set this option to avoid using the users temporary directory.")); 0070 mSymmetricOnlyCB = new QCheckBox(i18n("Use symmetric encryption only.")); 0071 mSymmetricOnlyCB->setToolTip(i18nc("@info", "Set this option to disable public key encryption.")); 0072 0073 baseLay->addWidget(mPGPFileExtCB); 0074 baseLay->addWidget(mTreatP7mEmailCB); 0075 baseLay->addWidget(mAutoDecryptVerifyCB); 0076 baseLay->addWidget(mAutoExtractArchivesCB); 0077 baseLay->addWidget(mASCIIArmorCB); 0078 baseLay->addWidget(mTmpDirCB); 0079 baseLay->addWidget(mSymmetricOnlyCB); 0080 0081 auto comboLay = new QGridLayout; 0082 0083 mChecksumDefinitionCB.createWidgets(this); 0084 mChecksumDefinitionCB.label()->setText(i18n("Checksum program to use when creating checksum files:")); 0085 comboLay->addWidget(mChecksumDefinitionCB.label(), 0, 0); 0086 comboLay->addWidget(mChecksumDefinitionCB.widget(), 0, 1); 0087 0088 mArchiveDefinitionCB.createWidgets(this); 0089 mArchiveDefinitionCB.label()->setText(i18n("Archive command to use when archiving files:")); 0090 comboLay->addWidget(mArchiveDefinitionCB.label(), 1, 0); 0091 comboLay->addWidget(mArchiveDefinitionCB.widget(), 1, 1); 0092 0093 baseLay->addLayout(comboLay); 0094 baseLay->addStretch(1); 0095 0096 for (auto cb : findChildren<QCheckBox *>()) { 0097 connect(cb, &QCheckBox::toggled, this, &CryptoOperationsConfigWidget::changed); 0098 } 0099 for (auto combo : findChildren<QComboBox *>()) { 0100 connect(combo, &QComboBox::currentIndexChanged, this, &CryptoOperationsConfigWidget::changed); 0101 } 0102 } 0103 0104 CryptoOperationsConfigWidget::~CryptoOperationsConfigWidget() 0105 { 0106 } 0107 0108 void CryptoOperationsConfigWidget::defaults() 0109 { 0110 FileOperationsPreferences filePrefs; 0111 filePrefs.setUsePGPFileExt(filePrefs.findItem(QStringLiteral("UsePGPFileExt"))->getDefault().toBool()); 0112 filePrefs.setAutoDecryptVerify(filePrefs.findItem(QStringLiteral("AutoDecryptVerify"))->getDefault().toBool()); 0113 filePrefs.setAutoExtractArchives(filePrefs.findItem(QStringLiteral("AutoExtractArchives"))->getDefault().toBool()); 0114 filePrefs.setAddASCIIArmor(filePrefs.findItem(QStringLiteral("AddASCIIArmor"))->getDefault().toBool()); 0115 filePrefs.setDontUseTmpDir(filePrefs.findItem(QStringLiteral("DontUseTmpDir"))->getDefault().toBool()); 0116 filePrefs.setSymmetricEncryptionOnly(filePrefs.findItem(QStringLiteral("SymmetricEncryptionOnly"))->getDefault().toBool()); 0117 filePrefs.setArchiveCommand(filePrefs.findItem(QStringLiteral("ArchiveCommand"))->getDefault().toString()); 0118 0119 ClassifyConfig classifyConfig; 0120 classifyConfig.setP7mWithoutExtensionAreEmail(classifyConfig.defaultP7mWithoutExtensionAreEmailValue()); 0121 0122 Settings settings; 0123 settings.setChecksumDefinitionId(settings.findItem(QStringLiteral("ChecksumDefinitionId"))->getDefault().toString()); 0124 0125 load(filePrefs, settings, classifyConfig); 0126 } 0127 0128 void CryptoOperationsConfigWidget::load(const Kleo::FileOperationsPreferences &filePrefs, 0129 const Kleo::Settings &settings, 0130 const Kleo::ClassifyConfig &classifyConfig) 0131 { 0132 mPGPFileExtCB->setChecked(filePrefs.usePGPFileExt()); 0133 mPGPFileExtCB->setEnabled(!filePrefs.isImmutable(QStringLiteral("UsePGPFileExt"))); 0134 mAutoDecryptVerifyCB->setChecked(filePrefs.autoDecryptVerify()); 0135 mAutoDecryptVerifyCB->setEnabled(!filePrefs.isImmutable(QStringLiteral("AutoDecryptVerify"))); 0136 mAutoExtractArchivesCB->setChecked(filePrefs.autoExtractArchives()); 0137 mAutoExtractArchivesCB->setEnabled(!filePrefs.isImmutable(QStringLiteral("AutoExtractArchives"))); 0138 mASCIIArmorCB->setChecked(filePrefs.addASCIIArmor()); 0139 mASCIIArmorCB->setEnabled(!filePrefs.isImmutable(QStringLiteral("AddASCIIArmor"))); 0140 mTmpDirCB->setChecked(filePrefs.dontUseTmpDir()); 0141 mTmpDirCB->setEnabled(!filePrefs.isImmutable(QStringLiteral("DontUseTmpDir"))); 0142 mSymmetricOnlyCB->setChecked(filePrefs.symmetricEncryptionOnly()); 0143 mSymmetricOnlyCB->setEnabled(!filePrefs.isImmutable(QStringLiteral("SymmetricEncryptionOnly"))); 0144 mTreatP7mEmailCB->setEnabled(!classifyConfig.isP7mWithoutExtensionAreEmailImmutable()); 0145 0146 const auto defaultChecksumDefinitionId = settings.checksumDefinitionId(); 0147 { 0148 const auto index = mChecksumDefinitionCB.widget()->findData(defaultChecksumDefinitionId); 0149 if (index >= 0) { 0150 mChecksumDefinitionCB.widget()->setCurrentIndex(index); 0151 } else { 0152 qCWarning(KLEOPATRA_LOG) << "No checksum definition found with id" << defaultChecksumDefinitionId; 0153 } 0154 } 0155 mChecksumDefinitionCB.setEnabled(!settings.isImmutable(QStringLiteral("ChecksumDefinitionId"))); 0156 0157 const auto ad_default_id = filePrefs.archiveCommand(); 0158 { 0159 const auto index = mArchiveDefinitionCB.widget()->findData(ad_default_id); 0160 if (index >= 0) { 0161 mArchiveDefinitionCB.widget()->setCurrentIndex(index); 0162 } else { 0163 qCWarning(KLEOPATRA_LOG) << "No archive definition found with id" << ad_default_id; 0164 } 0165 } 0166 mArchiveDefinitionCB.setEnabled(!filePrefs.isImmutable(QStringLiteral("ArchiveCommand"))); 0167 } 0168 0169 void CryptoOperationsConfigWidget::load() 0170 { 0171 mChecksumDefinitionCB.widget()->clear(); 0172 const auto cds = ChecksumDefinition::getChecksumDefinitions(); 0173 for (const std::shared_ptr<ChecksumDefinition> &cd : cds) { 0174 mChecksumDefinitionCB.widget()->addItem(cd->label(), QVariant{cd->id()}); 0175 } 0176 0177 // This is a weird hack but because we are a KCM we can't link 0178 // against ArchiveDefinition which pulls in loads of other classes. 0179 // So we do the parsing which archive definitions exist here ourself. 0180 mArchiveDefinitionCB.widget()->clear(); 0181 if (KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("libkleopatrarc"))) { 0182 const QStringList groups = config->groupList().filter(QRegularExpression(QStringLiteral("^Archive Definition #"))); 0183 for (const QString &group : groups) { 0184 const KConfigGroup cGroup(config, group); 0185 const QString id = cGroup.readEntryUntranslated(QStringLiteral("id")); 0186 const QString name = cGroup.readEntry("Name"); 0187 mArchiveDefinitionCB.widget()->addItem(name, QVariant(id)); 0188 } 0189 } 0190 0191 load(FileOperationsPreferences{}, Settings{}, ClassifyConfig{}); 0192 } 0193 0194 void CryptoOperationsConfigWidget::save() 0195 { 0196 FileOperationsPreferences filePrefs; 0197 filePrefs.setUsePGPFileExt(mPGPFileExtCB->isChecked()); 0198 filePrefs.setAutoDecryptVerify(mAutoDecryptVerifyCB->isChecked()); 0199 filePrefs.setAutoExtractArchives(mAutoExtractArchivesCB->isChecked()); 0200 filePrefs.setAddASCIIArmor(mASCIIArmorCB->isChecked()); 0201 filePrefs.setDontUseTmpDir(mTmpDirCB->isChecked()); 0202 filePrefs.setSymmetricEncryptionOnly(mSymmetricOnlyCB->isChecked()); 0203 0204 Settings settings; 0205 const int idx = mChecksumDefinitionCB.widget()->currentIndex(); 0206 if (idx >= 0) { 0207 const auto id = mChecksumDefinitionCB.widget()->itemData(idx).toString(); 0208 settings.setChecksumDefinitionId(id); 0209 } 0210 settings.save(); 0211 0212 const int aidx = mArchiveDefinitionCB.widget()->currentIndex(); 0213 if (aidx >= 0) { 0214 const QString id = mArchiveDefinitionCB.widget()->itemData(aidx).toString(); 0215 filePrefs.setArchiveCommand(id); 0216 } 0217 filePrefs.save(); 0218 0219 ClassifyConfig classifyConfig; 0220 classifyConfig.setP7mWithoutExtensionAreEmail(mTreatP7mEmailCB->isChecked()); 0221 classifyConfig.save(); 0222 } 0223 0224 #include "moc_cryptooperationsconfigwidget.cpp"