From ca1c30b6fa29a7a1f18ecda14375b47893a0c1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= Date: Wed, 2 Feb 2022 11:53:29 +0100 Subject: [PATCH] qt: Add job to import keys given by key ids * lang/qt/src/receivekeysjob.h, lang/qt/src/qgpgmereceivekeysjob.h, lang/qt/src/qgpgmereceivekeysjob.cpp: New. * lang/qt/src/protocol.h (class Protocol): Add pure virtual member function receiveKeysJob. * lang/qt/src/protocol_p.h (Protocol::receiveKeysJob): Implement it. * lang/qt/src/job.cpp, lang/qt/src/Makefile.am: Update accordingly. * lang/qt/tests/run-receivekeysjob.cpp: New. * lang/qt/tests/Makefile.am: Add new test runner. -- This job allows importing keys that are given by their key ids (or fingerprints) from keyservers as with gpg's recv-keys command. GnuPG-bug-id: 5808 --- lang/qt/src/Makefile.am | 6 +++ lang/qt/src/job.cpp | 3 ++ lang/qt/src/protocol.h | 2 + lang/qt/src/protocol_p.h | 14 +++++ lang/qt/src/qgpgmereceivekeysjob.cpp | 79 ++++++++++++++++++++++++++++ lang/qt/src/qgpgmereceivekeysjob.h | 79 ++++++++++++++++++++++++++++ lang/qt/src/receivekeysjob.h | 66 +++++++++++++++++++++++ lang/qt/tests/Makefile.am | 3 +- lang/qt/tests/run-receivekeysjob.cpp | 65 +++++++++++++++++++++++ 9 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 lang/qt/src/qgpgmereceivekeysjob.cpp create mode 100644 lang/qt/src/qgpgmereceivekeysjob.h create mode 100644 lang/qt/src/receivekeysjob.h create mode 100644 lang/qt/tests/run-receivekeysjob.cpp diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am index 51962f31..d47da895 100644 --- a/lang/qt/src/Makefile.am +++ b/lang/qt/src/Makefile.am @@ -34,6 +34,7 @@ qgpgme_sources = \ qgpgmeencryptjob.cpp qgpgmeexportjob.cpp qgpgmeimportfromkeyserverjob.cpp \ qgpgmeimportjob.cpp qgpgmekeygenerationjob.cpp qgpgmekeylistjob.cpp \ qgpgmelistallkeysjob.cpp qgpgmenewcryptoconfig.cpp \ + qgpgmereceivekeysjob.cpp \ qgpgmerefreshkeysjob.cpp \ qgpgmesignencryptjob.cpp \ qgpgmesignjob.cpp qgpgmesignkeyjob.cpp qgpgmeverifydetachedjob.cpp \ @@ -68,6 +69,7 @@ qgpgme_headers= \ qgpgme_export.h \ qgpgmenewcryptoconfig.h \ quickjob.h \ + receivekeysjob.h \ specialjob.h \ signjob.h \ signkeyjob.h \ @@ -111,6 +113,7 @@ camelcase_headers= \ Protocol \ QGpgMENewCryptoConfig \ QuickJob \ + ReceiveKeysJob \ SpecialJob \ SignJob \ SignKeyJob \ @@ -154,6 +157,7 @@ private_qgpgme_headers = \ qgpgmekeygenerationjob.h \ qgpgmekeylistjob.h \ qgpgmelistallkeysjob.h \ + qgpgmereceivekeysjob.h \ qgpgmerefreshkeysjob.h \ qgpgmesignencryptjob.h \ qgpgmesignjob.h \ @@ -206,6 +210,7 @@ qgpgme_moc_sources = \ qgpgmekeygenerationjob.moc \ qgpgmekeylistjob.moc \ qgpgmelistallkeysjob.moc \ + qgpgmereceivekeysjob.moc \ qgpgmerefreshkeysjob.moc \ qgpgmesignencryptjob.moc \ qgpgmesignjob.moc \ @@ -216,6 +221,7 @@ qgpgme_moc_sources = \ qgpgmewkspublishjob.moc \ tofupolicyjob.moc \ qgpgmetofupolicyjob.moc \ + receivekeysjob.moc \ refreshkeysjob.moc \ signencryptjob.moc \ signjob.moc \ diff --git a/lang/qt/src/job.cpp b/lang/qt/src/job.cpp index 14fe1426..a9edc8ea 100644 --- a/lang/qt/src/job.cpp +++ b/lang/qt/src/job.cpp @@ -71,6 +71,7 @@ #include "threadedjobmixin.h" #include "quickjob.h" #include "gpgcardjob.h" +#include "receivekeysjob.h" #include #include @@ -154,6 +155,7 @@ make_job_subclass(KeyGenerationJob) make_job_subclass(AbstractImportJob) make_job_subclass_ext(ImportJob, AbstractImportJob) make_job_subclass_ext(ImportFromKeyserverJob, AbstractImportJob) +make_job_subclass_ext(ReceiveKeysJob, AbstractImportJob) make_job_subclass(ExportJob) make_job_subclass(ChangeExpiryJob) make_job_subclass(ChangeOwnerTrustJob) @@ -205,3 +207,4 @@ make_job_subclass(GpgCardJob) #include "tofupolicyjob.moc" #include "quickjob.moc" #include "gpgcardjob.moc" +#include "receivekeysjob.moc" diff --git a/lang/qt/src/protocol.h b/lang/qt/src/protocol.h index 3ffd99b3..25c71eff 100644 --- a/lang/qt/src/protocol.h +++ b/lang/qt/src/protocol.h @@ -70,6 +70,7 @@ class WKSPublishJob; class TofuPolicyJob; class QuickJob; class GpgCardJob; +class ReceiveKeysJob; /** The main entry point for QGpgME Comes in OpenPGP and SMIME(CMS) flavors. * @@ -126,6 +127,7 @@ public: virtual KeyGenerationJob *keyGenerationJob() const = 0; virtual ImportJob *importJob() const = 0; virtual ImportFromKeyserverJob *importFromKeyserverJob() const = 0; + virtual ReceiveKeysJob *receiveKeysJob() const = 0; virtual ExportJob *publicKeyExportJob(bool armor = false) const = 0; // the second parameter is ignored; the passphrase in the exported file is always utf-8 encoded virtual ExportJob *secretKeyExportJob(bool armor = false, const QString & = QString()) const = 0; diff --git a/lang/qt/src/protocol_p.h b/lang/qt/src/protocol_p.h index a9cfd824..4211e001 100644 --- a/lang/qt/src/protocol_p.h +++ b/lang/qt/src/protocol_p.h @@ -64,6 +64,7 @@ #include "qgpgmewkspublishjob.h" #include "qgpgmetofupolicyjob.h" #include "qgpgmequickjob.h" +#include "qgpgmereceivekeysjob.h" namespace { @@ -233,6 +234,19 @@ public: return new QGpgME::QGpgMEImportFromKeyserverJob(context); } + QGpgME::ReceiveKeysJob *receiveKeysJob() const override + { + if (mProtocol != GpgME::OpenPGP) { + return nullptr; + } + + GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); + if (!context) { + return nullptr; + } + return new QGpgME::QGpgMEReceiveKeysJob{context}; + } + QGpgME::ExportJob *publicKeyExportJob(bool armor) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); diff --git a/lang/qt/src/qgpgmereceivekeysjob.cpp b/lang/qt/src/qgpgmereceivekeysjob.cpp new file mode 100644 index 00000000..bedf7a27 --- /dev/null +++ b/lang/qt/src/qgpgmereceivekeysjob.cpp @@ -0,0 +1,79 @@ +/* + qgpgmereceivekeysjob.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2022 g10 Code GmbH + Software engineering by Ingo Klöcker + + QGpgME is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "qgpgmereceivekeysjob.h" + +#include "util.h" + +using namespace QGpgME; +using namespace GpgME; + +QGpgMEReceiveKeysJob::QGpgMEReceiveKeysJob(Context *context) + : mixin_type{context} +{ + lateInitialization(); +} + +QGpgMEReceiveKeysJob::~QGpgMEReceiveKeysJob() = default; + +static QGpgMEReceiveKeysJob::result_type importfromkeyserver(Context *ctx, const QStringList &keyIds) +{ + const ImportResult res = ctx->importKeys(toStrings(keyIds)); + Error ae; + const QString log = _detail::audit_log_as_html(ctx, ae); + return std::make_tuple(res, log, ae); +} + +Error QGpgMEReceiveKeysJob::start(const QStringList &keyIds) +{ + run(std::bind(&importfromkeyserver, std::placeholders::_1, keyIds)); + return Error(); +} + +GpgME::ImportResult QGpgME::QGpgMEReceiveKeysJob::exec(const QStringList &keyIds) +{ + const result_type r = importfromkeyserver(context(), keyIds); + resultHook(r); + return mResult; +} + +void QGpgME::QGpgMEReceiveKeysJob::resultHook(const result_type &tuple) +{ + mResult = std::get<0>(tuple); +} + +#include "qgpgmereceivekeysjob.moc" diff --git a/lang/qt/src/qgpgmereceivekeysjob.h b/lang/qt/src/qgpgmereceivekeysjob.h new file mode 100644 index 00000000..96628df4 --- /dev/null +++ b/lang/qt/src/qgpgmereceivekeysjob.h @@ -0,0 +1,79 @@ +/* + qgpgmereceivekeysjob.h + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2022 g10 Code GmbH + Software engineering by Ingo Klöcker + + QGpgME is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __QGPGME_QGPGMERECEIVEKEYSJOB_H__ +#define __QGPGME_QGPGMERECEIVEKEYSJOB_H__ + +#include "receivekeysjob.h" + +#include "threadedjobmixin.h" + +#ifdef BUILDING_QGPGME +# include "importresult.h" +#else +# include +#endif + +namespace QGpgME +{ + +class QGpgMEReceiveKeysJob +#ifdef Q_MOC_RUN + : public ReceiveKeysJob +#else + : public _detail::ThreadedJobMixin> +#endif +{ + Q_OBJECT +#ifdef Q_MOC_RUN +public Q_SLOTS: + void slotFinished(); +#endif +public: + explicit QGpgMEReceiveKeysJob(GpgME::Context *context); + ~QGpgMEReceiveKeysJob() override; + + GpgME::Error start(const QStringList &keyIds) override; + + GpgME::ImportResult exec(const QStringList &keyIds) override; + + /* from ThreadedJobMixin */ + void resultHook(const result_type &r) override; + +private: + GpgME::ImportResult mResult; +}; + +} + +#endif // __QGPGME_QGPGMERECEIVEKEYSJOB_H__ diff --git a/lang/qt/src/receivekeysjob.h b/lang/qt/src/receivekeysjob.h new file mode 100644 index 00000000..3f85792f --- /dev/null +++ b/lang/qt/src/receivekeysjob.h @@ -0,0 +1,66 @@ +/* + receivekeysjob.h + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2022 g10 Code GmbH + Software engineering by Ingo Klöcker + + QGpgME is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __QGPGME_RECEIVEKEYSJOB_H__ +#define __QGPGME_RECEIVEKEYSJOB_H__ + +#include "abstractimportjob.h" +#include "qgpgme_export.h" + +namespace QGpgME +{ + +class QGPGME_EXPORT ReceiveKeysJob : public AbstractImportJob +{ + Q_OBJECT +protected: + explicit ReceiveKeysJob(QObject *parent); +public: + ~ReceiveKeysJob() override; + + /** + Starts the import of keys from a keyserver. \a keyIds is a list of + key ids and/or fingerprints specifying the keys to import. + */ + virtual GpgME::Error start(const QStringList &keyIds) = 0; + + /** + Runs the import of keys from a keyserver. \a keyIds is a list of + key ids and/or fingerprints specifying the keys to import. + */ + virtual GpgME::ImportResult exec(const QStringList &keyIds) = 0; +}; + +} + +#endif // __QGPGME_RECEIVEKEYSJOB_H__ diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am index 18dd989a..6c082b07 100644 --- a/lang/qt/tests/Makefile.am +++ b/lang/qt/tests/Makefile.am @@ -73,6 +73,7 @@ t_import_SOURCES = t-import.cpp $(support_src) run_exportjob_SOURCES = run-exportjob.cpp run_importjob_SOURCES = run-importjob.cpp run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp +run_receivekeysjob_SOURCES = run-receivekeysjob.cpp nodist_t_keylist_SOURCES = $(moc_files) @@ -83,7 +84,7 @@ noinst_PROGRAMS = \ t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt \ run-keyformailboxjob t-wkspublish t-verify t-various t-config t-remarks \ t-trustsignatures t-changeexpiryjob t-wkdlookup t-import run-importjob \ - run-exportjob + run-exportjob run-receivekeysjob CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \ gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \ diff --git a/lang/qt/tests/run-receivekeysjob.cpp b/lang/qt/tests/run-receivekeysjob.cpp new file mode 100644 index 00000000..0dc1575b --- /dev/null +++ b/lang/qt/tests/run-receivekeysjob.cpp @@ -0,0 +1,65 @@ +/* + run-receivekeysjob.cpp + + This file is part of QGpgME's test suite. + Copyright (c) 2022 by g10 Code GmbH + Software engineering by Ingo Klöcker + + QGpgME is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include +#include + +#include +#include + +#include + +int main(int argc, char **argv) +{ + GpgME::initializeLibrary(); + + if (argc < 2) { + std::cerr << "Usage: " << argv[0] << " KEYID..." << std::endl; + return 1; + } + + QCoreApplication app(argc, argv); + const QStringList keyIds = qApp->arguments().mid(1); + + auto job = QGpgME::openpgp()->receiveKeysJob(); + const auto result = job->exec(keyIds); + + std::cout << "Result: " << result.error().asString() << std::endl; + std::cout << "Details:\n" << result << std::endl; + + return 0; +}