File indexing completed on 2024-06-02 05:24:46
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 uiserver/prepencryptcommand.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 "prepencryptcommand.h" 0013 0014 #include <crypto/newsignencryptemailcontroller.h> 0015 0016 #include <Libkleo/KleoException> 0017 0018 #include <KLocalizedString> 0019 0020 #include <QPointer> 0021 0022 using namespace Kleo; 0023 using namespace Kleo::Crypto; 0024 0025 class PrepEncryptCommand::Private : public QObject 0026 { 0027 Q_OBJECT 0028 private: 0029 friend class ::Kleo::PrepEncryptCommand; 0030 PrepEncryptCommand *const q; 0031 0032 public: 0033 explicit Private(PrepEncryptCommand *qq) 0034 : q(qq) 0035 , controller() 0036 { 0037 } 0038 0039 private: 0040 void checkForErrors() const; 0041 0042 public Q_SLOTS: 0043 void slotRecipientsResolved(); 0044 void slotError(int, const QString &); 0045 0046 private: 0047 std::shared_ptr<NewSignEncryptEMailController> controller; 0048 }; 0049 0050 PrepEncryptCommand::PrepEncryptCommand() 0051 : AssuanCommandMixin<PrepEncryptCommand>() 0052 , d(new Private(this)) 0053 { 0054 } 0055 0056 PrepEncryptCommand::~PrepEncryptCommand() 0057 { 0058 } 0059 0060 void PrepEncryptCommand::Private::checkForErrors() const 0061 { 0062 if (!q->inputs().empty() || !q->outputs().empty() || !q->messages().empty()) 0063 throw Exception(makeError(GPG_ERR_CONFLICT), i18n("INPUT/OUTPUT/MESSAGE may only be given after PREP_ENCRYPT")); 0064 0065 if (q->numFiles()) 0066 throw Exception(makeError(GPG_ERR_CONFLICT), i18n("PREP_ENCRYPT is an email mode command, connection seems to be in filemanager mode")); 0067 0068 if (!q->senders().empty() && !q->informativeSenders()) 0069 throw Exception(makeError(GPG_ERR_CONFLICT), i18n("SENDER may not be given prior to PREP_ENCRYPT, except with --info")); 0070 0071 if (q->recipients().empty() || q->informativeRecipients()) 0072 throw Exception(makeError(GPG_ERR_MISSING_VALUE), i18n("No recipients given, or only with --info")); 0073 } 0074 0075 int PrepEncryptCommand::doStart() 0076 { 0077 removeMemento(NewSignEncryptEMailController::mementoName()); 0078 0079 d->checkForErrors(); 0080 0081 d->controller.reset(new NewSignEncryptEMailController(shared_from_this())); 0082 d->controller->setEncrypting(true); 0083 0084 const QString session = sessionTitle(); 0085 if (!session.isEmpty()) { 0086 d->controller->setSubject(session); 0087 } 0088 0089 if (hasOption("protocol")) 0090 // --protocol is optional for PREP_ENCRYPT 0091 { 0092 d->controller->setProtocol(checkProtocol(EMail)); 0093 } 0094 0095 d->controller->setSigning(hasOption("expect-sign")); 0096 0097 QObject::connect(d->controller.get(), &NewSignEncryptEMailController::certificatesResolved, d.get(), &Private::slotRecipientsResolved); 0098 QObject::connect(d->controller.get(), SIGNAL(error(int, QString)), d.get(), SLOT(slotError(int, QString))); 0099 0100 d->controller->startResolveCertificates(recipients(), senders()); 0101 0102 return 0; 0103 } 0104 0105 void PrepEncryptCommand::Private::slotRecipientsResolved() 0106 { 0107 // hold local std::shared_ptr to member as q->done() deletes *this 0108 const std::shared_ptr<NewSignEncryptEMailController> cont = controller; 0109 QPointer<Private> that(this); 0110 0111 try { 0112 q->sendStatus("PROTOCOL", QLatin1StringView(controller->protocolAsString())); 0113 q->registerMemento(NewSignEncryptEMailController::mementoName(), make_typed_memento(controller)); 0114 q->done(); 0115 return; 0116 0117 } catch (const Exception &e) { 0118 q->done(e.error(), e.message()); 0119 } catch (const std::exception &e) { 0120 q->done(makeError(GPG_ERR_UNEXPECTED), 0121 i18n("Caught unexpected exception in PrepEncryptCommand::Private::slotRecipientsResolved: %1", QString::fromLocal8Bit(e.what()))); 0122 } catch (...) { 0123 q->done(makeError(GPG_ERR_UNEXPECTED), i18n("Caught unknown exception in PrepEncryptCommand::Private::slotRecipientsResolved")); 0124 } 0125 if (that) { // isn't this always deleted here and thus unnecessary? 0126 q->removeMemento(NewSignEncryptEMailController::mementoName()); 0127 } 0128 cont->cancel(); 0129 } 0130 0131 void PrepEncryptCommand::Private::slotError(int err, const QString &details) 0132 { 0133 q->done(err, details); 0134 } 0135 0136 void PrepEncryptCommand::doCanceled() 0137 { 0138 if (d->controller) { 0139 d->controller->cancel(); 0140 } 0141 } 0142 0143 #include "prepencryptcommand.moc"