File indexing completed on 2024-06-02 05:24:12
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 commands/exportopenpgpcerttoprovidercommand.cpp 0003 0004 This file is part of Kleopatra, the KDE keymanager 0005 SPDX-FileCopyrightText: 2022 Felix Tiede 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include <config-kleopatra.h> 0011 0012 #include "command_p.h" 0013 #include "exportopenpgpcerttoprovidercommand.h" 0014 0015 #ifdef MAILAKONADI_ENABLED 0016 #include <KIdentityManagementCore/Identity> 0017 #include <KIdentityManagementCore/IdentityManager> 0018 #include <Akonadi/MessageQueueJob> 0019 #include <MailTransport/TransportManager> 0020 #endif // MAILAKONADI_ENABLED 0021 0022 #include <KLocalizedString> 0023 #include <KMessageBox> 0024 0025 #include <QGpgME/Protocol> 0026 #include <QGpgME/WKSPublishJob> 0027 0028 #include <QString> 0029 0030 #include <gpgme++/key.h> 0031 0032 using namespace Kleo; 0033 using namespace Kleo::Commands; 0034 using namespace GpgME; 0035 using namespace QGpgME; 0036 0037 #ifdef MAILAKONADI_ENABLED 0038 static const QString identityTransportForAddress(const QString &senderAddress) 0039 { 0040 static const KIdentityManagementCore::IdentityManager *idManager = new KIdentityManagementCore::IdentityManager{true}; 0041 0042 const KIdentityManagementCore::Identity identity = idManager->identityForAddress(senderAddress); 0043 if (identity.isNull()) { 0044 return idManager->defaultIdentity().transport(); 0045 } else { 0046 return identity.transport(); 0047 } 0048 } 0049 #endif // MAILAKONADI_ENABLED 0050 0051 ExportOpenPGPCertToProviderCommand::ExportOpenPGPCertToProviderCommand(QAbstractItemView *v, KeyListController *c) 0052 : Command{v, c} 0053 { 0054 } 0055 0056 ExportOpenPGPCertToProviderCommand::ExportOpenPGPCertToProviderCommand(const UserID &uid) 0057 : Command{uid.parent()} 0058 , uid{uid} 0059 { 0060 } 0061 0062 ExportOpenPGPCertToProviderCommand::~ExportOpenPGPCertToProviderCommand() = default; 0063 0064 void ExportOpenPGPCertToProviderCommand::doStart() 0065 { 0066 const QString sender = senderAddress(); 0067 0068 #ifdef MAILAKONADI_ENABLED 0069 const QString transportName = identityTransportForAddress(sender); 0070 0071 if (transportName.isEmpty()) { 0072 KMessageBox::error(d->parentWidgetOrView(), 0073 xi18nc("@warning", 0074 "<para><email>%1</email> has no usable transport for mailing a key available, " 0075 "WKS upload not possible.</para>", 0076 sender), 0077 i18nc("@title:window", "OpenPGP Certificate Export")); 0078 d->canceled(); 0079 return; 0080 } 0081 #endif // MAILAKONADI_ENABLED 0082 0083 if (KMessageBox::warningContinueCancel(d->parentWidgetOrView(), 0084 xi18nc("@info", 0085 "<para>Not every mail provider supports WKS, so any key being " 0086 "exported this way may fail individually.</para><para>If exported, " 0087 "a confirmation request mail will be sent to <email>%1</email> " 0088 "which needs to be acknowledged with a mail program to complete the " 0089 "export process.</para><para><application>KMail</application> " 0090 "can handle these mails, but not all mail programs can.</para>" 0091 "<para>Once exported, the standard does not (yet) allow for " 0092 "automated removal of a published key.</para>" 0093 "<para>Are you sure you want to continue?</para>", 0094 sender), 0095 i18nc("@title:window", "OpenPGP Certificate Export"), 0096 KStandardGuiItem::cont(), 0097 KStandardGuiItem::cancel(), 0098 QStringLiteral("warn-export-openpgp-wks-unsupported")) 0099 == KMessageBox::Continue) { 0100 wksJob = QGpgME::openpgp()->wksPublishJob(); 0101 connect(wksJob, &QGpgME::WKSPublishJob::result, this, &ExportOpenPGPCertToProviderCommand::wksJobResult); 0102 wksJob->startCreate(d->key().primaryFingerprint(), senderAddress()); 0103 } else { 0104 d->canceled(); 0105 } 0106 } 0107 0108 void ExportOpenPGPCertToProviderCommand::doCancel() 0109 { 0110 if (wksJob) { 0111 delete wksJob; 0112 } 0113 d->canceled(); 0114 } 0115 0116 void ExportOpenPGPCertToProviderCommand::wksJobResult(const GpgME::Error &error, const QByteArray &returnedData, const QByteArray &returnedError) 0117 { 0118 if (error) { 0119 KMessageBox::error(d->parentWidgetOrView(), 0120 xi18nc("@error", 0121 "<para>An error occurred while trying to export OpenPGP certificates.</para> " 0122 "<para>The output from GnuPG WKS client was: <message>%1</message></para>", 0123 QString::fromUtf8(returnedError)), 0124 i18nc("@title:window", "OpenPGP Certificate Export")); 0125 d->canceled(); 0126 return; 0127 } 0128 0129 #ifdef MAILAKONADI_ENABLED 0130 MailTransport::Transport *transport = MailTransport::TransportManager::self()->transportByName(identityTransportForAddress(senderAddress())); 0131 0132 if (!transport) { 0133 d->canceled(); 0134 return; 0135 } 0136 0137 KMime::Message *msg = new KMime::Message; 0138 0139 msg->setContent(KMime::CRLFtoLF(returnedData)); 0140 msg->parse(); 0141 0142 Akonadi::MessageQueueJob *job = new Akonadi::MessageQueueJob(d->parentWidgetOrView()); 0143 job->transportAttribute().setTransportId(transport->id()); 0144 job->addressAttribute().setFrom(msg->from()->asUnicodeString()); 0145 job->addressAttribute().setTo(msg->to()->displayNames()); 0146 job->setMessage(KMime::Message::Ptr{msg}); 0147 connect(job, &Akonadi::MessageQueueJob::result, this, [this](const KJob *mailJob) { 0148 if (mailJob->error()) { 0149 KMessageBox::error(d->parentWidgetOrView(), 0150 xi18nc("@error", 0151 "<para>An error occurred when creating the mail to publish key:</para>" 0152 "<message>%1</message>", 0153 mailJob->errorString()), 0154 i18nc("@title:window", "OpenPGP Certificate Export")); 0155 d->canceled(); 0156 } else { 0157 d->finished(); 0158 } 0159 }); 0160 0161 job->start(); 0162 #else // MAILAKONADI_ENABLED 0163 Q_UNUSED(returnedData); 0164 #endif // MAILAKONADI_ENABLED 0165 } 0166 0167 QString ExportOpenPGPCertToProviderCommand::senderAddress() const 0168 { 0169 if (uid.isNull()) { 0170 return QString::fromUtf8(d->key().userID(0).addrSpec().data()); 0171 } else { 0172 return QString::fromUtf8(uid.addrSpec().data()); 0173 } 0174 } 0175 0176 #include "moc_exportopenpgpcerttoprovidercommand.cpp"