File indexing completed on 2024-06-23 05:14:13
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 uiserver/decryptverifycommandfilesbase.cpp 0003 0004 This file is part of Kleopatra, the KDE keymanager 0005 SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include <config-kleopatra.h> 0011 0012 #include "decryptverifycommandfilesbase.h" 0013 #include "fileoperationspreferences.h" 0014 0015 #include <crypto/decryptverifytask.h> 0016 0017 #include "crypto/autodecryptverifyfilescontroller.h" 0018 #include "crypto/decryptverifyfilescontroller.h" 0019 0020 #include <utils/input.h> 0021 #include <utils/kleo_assert.h> 0022 #include <utils/output.h> 0023 0024 #include <Libkleo/Formatting> 0025 #include <Libkleo/Hex> 0026 #include <Libkleo/KeyCache> 0027 #include <Libkleo/KleoException> 0028 #include <Libkleo/Stl_Util> 0029 0030 #include <gpgme++/decryptionresult.h> 0031 #include <gpgme++/error.h> 0032 #include <gpgme++/key.h> 0033 #include <gpgme++/verificationresult.h> 0034 0035 #include <KLocalizedString> 0036 0037 #include <QFileInfo> 0038 0039 #include <gpg-error.h> 0040 0041 #include <memory> 0042 0043 using namespace Kleo; 0044 using namespace Kleo::Crypto; 0045 using namespace Kleo::Formatting; 0046 using namespace GpgME; 0047 0048 class DecryptVerifyCommandFilesBase::Private : public QObject 0049 { 0050 Q_OBJECT 0051 friend class ::Kleo::DecryptVerifyCommandFilesBase; 0052 DecryptVerifyCommandFilesBase *const q; 0053 0054 public: 0055 explicit Private(DecryptVerifyCommandFilesBase *qq) 0056 : QObject() 0057 , q(qq) 0058 , controller() 0059 { 0060 } 0061 0062 ~Private() override 0063 { 0064 } 0065 0066 void checkForErrors() const; 0067 0068 public Q_SLOTS: 0069 void slotProgress(const QString &what, int current, int total); 0070 void verificationResult(const GpgME::VerificationResult &); 0071 void slotDone() 0072 { 0073 q->done(); 0074 } 0075 void slotError(int err, const QString &details) 0076 { 0077 q->done(err, details); 0078 } 0079 0080 public: 0081 private: 0082 std::shared_ptr<DecryptVerifyFilesController> controller; 0083 }; 0084 0085 DecryptVerifyCommandFilesBase::DecryptVerifyCommandFilesBase() 0086 : AssuanCommandMixin<DecryptVerifyCommandFilesBase>() 0087 , d(new Private(this)) 0088 { 0089 } 0090 0091 DecryptVerifyCommandFilesBase::~DecryptVerifyCommandFilesBase() 0092 { 0093 } 0094 0095 int DecryptVerifyCommandFilesBase::doStart() 0096 { 0097 d->checkForErrors(); 0098 0099 FileOperationsPreferences prefs; 0100 if (prefs.autoDecryptVerify()) { 0101 d->controller.reset(new AutoDecryptVerifyFilesController()); 0102 } else { 0103 d->controller.reset(new DecryptVerifyFilesController(shared_from_this())); 0104 } 0105 0106 d->controller->setOperation(operation()); 0107 d->controller->setFiles(fileNames()); 0108 0109 QObject::connect(d->controller.get(), &Controller::done, d.get(), &Private::slotDone, Qt::QueuedConnection); 0110 QObject::connect(d->controller.get(), &Controller::error, d.get(), &Private::slotError, Qt::QueuedConnection); 0111 QObject::connect(d->controller.get(), &DecryptVerifyFilesController::verificationResult, d.get(), &Private::verificationResult, Qt::QueuedConnection); 0112 0113 d->controller->start(); 0114 0115 return 0; 0116 } 0117 0118 namespace 0119 { 0120 0121 struct is_file { 0122 bool operator()(const QString &file) const 0123 { 0124 return QFileInfo(file).isFile(); 0125 } 0126 }; 0127 } 0128 0129 void DecryptVerifyCommandFilesBase::Private::checkForErrors() const 0130 { 0131 if (!q->senders().empty()) 0132 throw Kleo::Exception(q->makeError(GPG_ERR_CONFLICT), i18n("Cannot use SENDER")); 0133 0134 if (!q->recipients().empty()) 0135 throw Kleo::Exception(q->makeError(GPG_ERR_CONFLICT), i18n("Cannot use RECIPIENT")); 0136 0137 const unsigned int numInputs = q->inputs().size(); 0138 const unsigned int numMessages = q->messages().size(); 0139 const unsigned int numOutputs = q->outputs().size(); 0140 0141 if (numInputs) { 0142 throw Kleo::Exception(q->makeError(GPG_ERR_CONFLICT), i18n("INPUT present")); 0143 } 0144 if (numMessages) { 0145 throw Kleo::Exception(q->makeError(GPG_ERR_CONFLICT), i18n("MESSAGE present")); 0146 } 0147 if (numOutputs) { 0148 throw Kleo::Exception(q->makeError(GPG_ERR_CONFLICT), i18n("OUTPUT present")); 0149 } 0150 const QStringList fileNames = q->fileNames(); 0151 if (fileNames.empty()) 0152 throw Exception(makeError(GPG_ERR_ASS_NO_INPUT), i18n("At least one FILE must be present")); 0153 if (!std::all_of(fileNames.cbegin(), fileNames.cend(), is_file())) 0154 throw Exception(makeError(GPG_ERR_INV_ARG), i18n("DECRYPT/VERIFY_FILES cannot use directories as input")); 0155 } 0156 0157 void DecryptVerifyCommandFilesBase::doCanceled() 0158 { 0159 if (d->controller) { 0160 d->controller->cancel(); 0161 } 0162 } 0163 0164 void DecryptVerifyCommandFilesBase::Private::slotProgress(const QString &what, int current, int total) 0165 { 0166 Q_UNUSED(what) 0167 Q_UNUSED(current) 0168 Q_UNUSED(total) 0169 // ### FIXME report progress, via sendStatus() 0170 } 0171 0172 void DecryptVerifyCommandFilesBase::Private::verificationResult(const VerificationResult &vResult) 0173 { 0174 try { 0175 const std::vector<Signature> sigs = vResult.signatures(); 0176 for (const Signature &sig : sigs) { 0177 const QString s = signatureToString(sig, sig.key(true, true)); 0178 const char *color = summaryToString(sig.summary()); 0179 q->sendStatusEncoded("SIGSTATUS", color + (' ' + hexencode(s.toUtf8().constData()))); 0180 } 0181 } catch (...) { 0182 } 0183 } 0184 0185 #include "decryptverifycommandfilesbase.moc"