diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am index 18456d54..5a41a318 100644 --- a/lang/qt/src/Makefile.am +++ b/lang/qt/src/Makefile.am @@ -1,317 +1,320 @@ # Makefile.am for GPGMEPP. # Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik # Software engineering by Intevation GmbH # # This file is part of GPGMEPP. # # GPGME-CL 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. # # GPGME-CL 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA lib_LTLIBRARIES = libqgpgme.la EXTRA_DIST = QGpgmeConfig.cmake.in.in QGpgmeConfigVersion.cmake.in \ qgpgme_debug.h qgpgme_version.h.in \ QGpgmeConfig.cmake.in.in qgpgme_sources = \ dataprovider.cpp \ debug.cpp \ job.cpp multideletejob.cpp qgpgmeadduseridjob.cpp \ qgpgmeaddexistingsubkeyjob.cpp \ qgpgmebackend.cpp qgpgmechangeexpiryjob.cpp qgpgmechangeownertrustjob.cpp \ qgpgmechangepasswdjob.cpp qgpgmedecryptjob.cpp \ qgpgmedecryptverifyjob.cpp qgpgmedeletejob.cpp qgpgmedownloadjob.cpp \ qgpgmeencryptjob.cpp qgpgmeexportjob.cpp qgpgmeimportfromkeyserverjob.cpp \ qgpgmeimportjob.cpp qgpgmekeygenerationjob.cpp qgpgmekeylistjob.cpp \ qgpgmelistallkeysjob.cpp qgpgmenewcryptoconfig.cpp \ qgpgmereceivekeysjob.cpp \ qgpgmerefreshopenpgpkeysjob.cpp \ qgpgmerefreshsmimekeysjob.cpp \ qgpgmerevokekeyjob.cpp \ qgpgmesignencryptjob.cpp \ qgpgmesignjob.cpp qgpgmesignkeyjob.cpp qgpgmeverifydetachedjob.cpp \ qgpgmeverifyopaquejob.cpp qgpgmewkdlookupjob.cpp threadedjobmixin.cpp \ qgpgmekeyformailboxjob.cpp qgpgme_debug.cpp \ qgpgmetofupolicyjob.cpp qgpgmequickjob.cpp \ defaultkeygenerationjob.cpp qgpgmewkspublishjob.cpp \ qgpgmegpgcardjob.cpp changeexpiryjob.cpp importjob.cpp \ dn.cpp cryptoconfig.cpp wkdlookupresult.cpp \ util.cpp # If you add one here make sure that you also add one in camelcase qgpgme_headers= \ abstractimportjob.h \ addexistingsubkeyjob.h \ adduseridjob.h \ changeexpiryjob.h \ changeownertrustjob.h \ changepasswdjob.h \ dataprovider.h \ debug.h \ decryptjob.h \ decryptverifyjob.h \ downloadjob.h \ encryptjob.h \ exportjob.h \ hierarchicalkeylistjob.h \ job.h \ keyformailboxjob.h \ multideletejob.h \ protocol.h \ qgpgme_export.h \ qgpgmenewcryptoconfig.h \ quickjob.h \ receivekeysjob.h \ revokekeyjob.h \ specialjob.h \ signjob.h \ signkeyjob.h \ signencryptjob.h \ verifyopaquejob.h \ refreshkeysjob.h \ + refreshopenpgpkeysjob.h \ cryptoconfig.h \ deletejob.h \ importfromkeyserverjob.h \ importjob.h \ keygenerationjob.h \ keylistjob.h \ listallkeysjob.h \ verifydetachedjob.h \ defaultkeygenerationjob.h \ tofupolicyjob.h \ wkdlookupjob.h \ wkdlookupresult.h \ wkspublishjob.h \ gpgcardjob.h \ dn.h camelcase_headers= \ AddExistingSubkeyJob \ AddUserIDJob \ AbstractImportJob \ ChangeExpiryJob \ ChangeOwnerTrustJob \ ChangePasswdJob \ DataProvider \ Debug \ DecryptJob \ DecryptVerifyJob \ DN \ DownloadJob \ EncryptJob \ ExportJob \ HierarchicalKeyKistJob \ Job \ MultiDeleteJob \ Protocol \ QGpgMENewCryptoConfig \ QuickJob \ ReceiveKeysJob \ RevokeKeyJob \ SpecialJob \ SignJob \ SignKeyJob \ SignEncryptJob \ VerifyOpaqueJob \ RefreshKeysJob \ + RefreshOpenPGPKeysJob \ CryptoConfig \ DeleteJob \ ImportFromKeyserverJob \ ImportJob \ KeyGenerationJob \ KeyListJob \ ListAllKeysJob \ VerifyDetachedJob \ KeyForMailboxJob \ DefaultKeyGenerationJob \ WKDLookupJob \ WKDLookupResult \ WKSPublishJob \ TofuPolicyJob \ GpgCardJob private_qgpgme_headers = \ qgpgme_export.h \ protocol_p.h \ job_p.h \ qgpgmeaddexistingsubkeyjob.h \ qgpgmeadduseridjob.h \ qgpgmebackend.h \ qgpgmechangeexpiryjob.h \ qgpgmechangeownertrustjob.h \ qgpgmechangepasswdjob.h \ qgpgmedecryptjob.h \ qgpgmedecryptverifyjob.h \ qgpgmedeletejob.h \ qgpgmedownloadjob.h \ qgpgmeencryptjob.h \ qgpgmeexportjob.h \ qgpgmeimportfromkeyserverjob.h \ qgpgmeimportjob.h \ qgpgmekeygenerationjob.h \ qgpgmekeylistjob.h \ qgpgmelistallkeysjob.h \ qgpgmereceivekeysjob.h \ qgpgmerefreshopenpgpkeysjob.h \ qgpgmerefreshsmimekeysjob.h \ qgpgmerevokekeyjob.h \ qgpgmesignencryptjob.h \ qgpgmesignjob.h \ qgpgmesignkeyjob.h \ qgpgmeverifydetachedjob.h \ qgpgmeverifyopaquejob.h \ qgpgmewkdlookupjob.h \ qgpgmekeyformailboxjob.h \ qgpgmewkspublishjob.h \ qgpgmetofupolicyjob.h \ qgpgmegpgcardjob.h \ qgpgmequickjob.h \ threadedjobmixin.h \ util.h qgpgme_moc_sources = \ abstractimportjob.moc \ addexistingsubkeyjob.moc \ adduseridjob.moc \ changeexpiryjob.moc \ changeownertrustjob.moc \ changepasswdjob.moc \ decryptjob.moc \ decryptverifyjob.moc \ deletejob.moc \ downloadjob.moc \ encryptjob.moc \ exportjob.moc \ hierarchicalkeylistjob.moc \ importfromkeyserverjob.moc \ importjob.moc \ job.moc \ keygenerationjob.moc \ keylistjob.moc \ listallkeysjob.moc \ multideletejob.moc \ qgpgmeaddexistingsubkeyjob.moc \ qgpgmeadduseridjob.moc \ qgpgmechangeexpiryjob.moc \ qgpgmechangeownertrustjob.moc \ qgpgmechangepasswdjob.moc \ qgpgmedecryptjob.moc \ qgpgmedecryptverifyjob.moc \ qgpgmedeletejob.moc \ qgpgmedownloadjob.moc \ qgpgmeencryptjob.moc \ qgpgmeexportjob.moc \ qgpgmeimportfromkeyserverjob.moc \ qgpgmeimportjob.moc \ qgpgmekeygenerationjob.moc \ qgpgmekeylistjob.moc \ qgpgmelistallkeysjob.moc \ qgpgmereceivekeysjob.moc \ qgpgmerefreshopenpgpkeysjob.moc \ qgpgmerefreshsmimekeysjob.moc \ qgpgmerevokekeyjob.moc \ qgpgmesignencryptjob.moc \ qgpgmesignjob.moc \ qgpgmesignkeyjob.moc \ qgpgmeverifydetachedjob.moc \ qgpgmeverifyopaquejob.moc \ qgpgmewkdlookupjob.moc \ qgpgmewkspublishjob.moc \ tofupolicyjob.moc \ qgpgmetofupolicyjob.moc \ receivekeysjob.moc \ refreshkeysjob.moc \ + refreshopenpgpkeysjob.moc \ revokekeyjob.moc \ signencryptjob.moc \ signjob.moc \ signkeyjob.moc \ specialjob.moc \ verifydetachedjob.moc \ verifyopaquejob.moc \ wkdlookupjob.moc \ keyformailboxjob.moc \ wkspublishjob.moc \ qgpgmekeyformailboxjob.moc \ defaultkeygenerationjob.moc \ quickjob.moc \ qgpgmequickjob.moc \ gpgcardjob.moc \ qgpgmegpgcardjob.moc qgpgmeincludedir = $(includedir)/qgpgme qgpgmeinclude_HEADERS = $(qgpgme_headers) camelcaseincludedir = $(includedir)/QGpgME camelcaseinclude_HEADERS = $(camelcase_headers) nodist_qgpgmeinclude_HEADERS = qgpgme_version.h libqgpgme_la_SOURCES = $(qgpgme_sources) $(qgpgme_headers) $(private_qgpgme_headers) AM_CPPFLAGS = -I$(top_srcdir)/lang/cpp/src -I$(top_builddir)/src \ @GPGME_QT_CFLAGS@ @GPG_ERROR_CFLAGS@ @LIBASSUAN_CFLAGS@ \ -DBUILDING_QGPGME -Wsuggest-override \ -Wzero-as-null-pointer-constant libqgpgme_la_LIBADD = ../../cpp/src/libgpgmepp.la ../../../src/libgpgme.la \ @LIBASSUAN_LIBS@ @GPG_ERROR_LIBS@ @GPGME_QT_LIBS@ libqgpgme_la_LDFLAGS = -no-undefined -version-info \ @LIBQGPGME_LT_CURRENT@:@LIBQGPGME_LT_REVISION@:@LIBQGPGME_LT_AGE@ if HAVE_MACOS_SYSTEM libsuffix=.dylib else libsuffix=.so endif if HAVE_W32_SYSTEM QGpgmeConfig.cmake: QGpgmeConfig-w32.cmake.in sed -e 's|[@]resolved_bindir@|$(bindir)|g' < "$<" | \ sed -e 's|[@]resolved_libdir@|$(libdir)|g' | \ sed -e 's|[@]resolved_includedir@|$(includedir)|g' > $@ else QGpgmeConfig.cmake: QGpgmeConfig.cmake.in sed -e 's|[@]resolved_libdir@|$(libdir)|g' < "$<" | \ sed -e 's|[@]libsuffix@|$(libsuffix)|g' | \ sed -e 's|[@]resolved_includedir@|$(includedir)|g' > $@ endif $(camelcase_headers): Makefile.am echo -n "#include \"qgpgme/" > "$@" echo -n "$@" | tr '[:upper:]' '[:lower:]' >> "$@" echo ".h\"" >> "$@" install-cmake-files: QGpgmeConfig.cmake QGpgmeConfigVersion.cmake -$(INSTALL) -d $(DESTDIR)$(libdir)/cmake/QGpgme $(INSTALL) -m 644 QGpgmeConfig.cmake \ $(DESTDIR)$(libdir)/cmake/QGpgme/QGpgmeConfig.cmake $(INSTALL) -m 644 QGpgmeConfigVersion.cmake \ $(DESTDIR)$(libdir)/cmake/QGpgme/QGpgmeConfigVersion.cmake uninstall-cmake-files: -rm $(DESTDIR)$(libdir)/cmake/QGpgme/QGpgmeConfigVersion.cmake -rm $(DESTDIR)$(libdir)/cmake/QGpgme/QGpgmeConfig.cmake -rmdir $(DESTDIR)$(libdir)/cmake/QGpgme/ install-data-local: install-cmake-files uninstall-local: uninstall-cmake-files BUILT_SOURCES = $(qgpgme_moc_sources) $(camelcase_headers) CLEANFILES = $(qgpgme_moc_sources) $(camelcase_headers) QGpgmeConfig.cmake \ qgpgme_version.h QGpgmeConfig.cmake.in \ QGpgmeConfigVersion.cmake nodist_libqgpgme_la_SOURCES = $(qgpgme_moc_sources) .h.moc: $(MOC) `test -f '$<' || echo '$(srcdir)/'`$< -o $@ diff --git a/lang/qt/src/job.cpp b/lang/qt/src/job.cpp index dba7556b..4a379f12 100644 --- a/lang/qt/src/job.cpp +++ b/lang/qt/src/job.cpp @@ -1,213 +1,216 @@ /* job.cpp This file is part of qgpgme, the Qt API binding for gpgme Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik Software engineering by Intevation GmbH Copyright (c) 2021 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 "job.h" #include "job_p.h" #include "keylistjob.h" #include "listallkeysjob.h" #include "encryptjob.h" #include "decryptjob.h" #include "decryptverifyjob.h" #include "signjob.h" #include "signkeyjob.h" #include "signencryptjob.h" #include "verifydetachedjob.h" #include "verifyopaquejob.h" #include "keygenerationjob.h" #include "importjob.h" #include "importfromkeyserverjob.h" #include "exportjob.h" #include "changeexpiryjob.h" #include "changeownertrustjob.h" #include "changepasswdjob.h" #include "downloadjob.h" #include "deletejob.h" #include "refreshkeysjob.h" +#include "refreshopenpgpkeysjob.h" #include "addexistingsubkeyjob.h" #include "adduseridjob.h" #include "specialjob.h" #include "keyformailboxjob.h" #include "wkdlookupjob.h" #include "wkspublishjob.h" #include "tofupolicyjob.h" #include "threadedjobmixin.h" #include "quickjob.h" #include "gpgcardjob.h" #include "receivekeysjob.h" #include "revokekeyjob.h" #include #include #include #include namespace { typedef std::unordered_map> JobPrivateHash; Q_GLOBAL_STATIC(JobPrivateHash, d_func) } void QGpgME::setJobPrivate(const Job *job, std::unique_ptr d) { auto &ref = d_func()->operator[](job); ref = std::move(d); } QGpgME::JobPrivate *QGpgME::getJobPrivate(const Job *job) { return d_func()->operator[](job).get(); } QGpgME::Job::Job(QObject *parent) : QObject(parent) { if (QCoreApplication *app = QCoreApplication::instance()) { connect(app, &QCoreApplication::aboutToQuit, this, &Job::slotCancel); } } QGpgME::Job::~Job() { ::d_func()->erase(this); } QString QGpgME::Job::auditLogAsHtml() const { qDebug() << "QGpgME::Job::auditLogAsHtml() should be reimplemented in Kleo::Job subclasses!"; return QString(); } GpgME::Error QGpgME::Job::auditLogError() const { qDebug() << "QGpgME::Job::auditLogError() should be reimplemented in Kleo::Job subclasses!"; return GpgME::Error::fromCode(GPG_ERR_NOT_IMPLEMENTED); } bool QGpgME::Job::isAuditLogSupported() const { return auditLogError().code() != GPG_ERR_NOT_IMPLEMENTED; } QMap QGpgME::g_context_map; /* static */ GpgME::Context *QGpgME::Job::context(QGpgME::Job *job) { return QGpgME::g_context_map.value (job, nullptr); } #define make_job_subclass_ext(x,y) \ QGpgME::x::x( QObject * parent ) : y( parent ) {} \ QGpgME::x::~x() {} #define make_job_subclass(x) make_job_subclass_ext(x,Job) make_job_subclass(KeyListJob) make_job_subclass(ListAllKeysJob) make_job_subclass(EncryptJob) make_job_subclass(DecryptJob) make_job_subclass(DecryptVerifyJob) make_job_subclass(SignJob) make_job_subclass(SignEncryptJob) make_job_subclass(SignKeyJob) make_job_subclass(VerifyDetachedJob) make_job_subclass(VerifyOpaqueJob) 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_ext(RefreshOpenPGPKeysJob, AbstractImportJob) make_job_subclass(ExportJob) make_job_subclass(ChangeExpiryJob) make_job_subclass(ChangeOwnerTrustJob) make_job_subclass(ChangePasswdJob) make_job_subclass(DownloadJob) make_job_subclass(DeleteJob) make_job_subclass(RefreshKeysJob) make_job_subclass(AddExistingSubkeyJob) make_job_subclass(AddUserIDJob) make_job_subclass(SpecialJob) make_job_subclass(KeyForMailboxJob) make_job_subclass(WKDLookupJob) make_job_subclass(WKSPublishJob) make_job_subclass(TofuPolicyJob) make_job_subclass(QuickJob) make_job_subclass(GpgCardJob) make_job_subclass(RevokeKeyJob) #undef make_job_subclass #include "job.moc" #include "keylistjob.moc" #include "listallkeysjob.moc" #include "encryptjob.moc" #include "decryptjob.moc" #include "decryptverifyjob.moc" #include "signjob.moc" #include "signencryptjob.moc" #include "signkeyjob.moc" #include "verifydetachedjob.moc" #include "verifyopaquejob.moc" #include "keygenerationjob.moc" #include "abstractimportjob.moc" #include "importjob.moc" #include "importfromkeyserverjob.moc" #include "exportjob.moc" #include "changeexpiryjob.moc" #include "changeownertrustjob.moc" #include "changepasswdjob.moc" #include "downloadjob.moc" #include "deletejob.moc" #include "refreshkeysjob.moc" +#include "refreshopenpgpkeysjob.moc" #include "addexistingsubkeyjob.moc" #include "adduseridjob.moc" #include "specialjob.moc" #include "keyformailboxjob.moc" #include "wkdlookupjob.moc" #include "wkspublishjob.moc" #include "tofupolicyjob.moc" #include "quickjob.moc" #include "gpgcardjob.moc" #include "receivekeysjob.moc" #include "revokekeyjob.moc" diff --git a/lang/qt/src/protocol.h b/lang/qt/src/protocol.h index d8500174..f0772eef 100644 --- a/lang/qt/src/protocol.h +++ b/lang/qt/src/protocol.h @@ -1,218 +1,224 @@ /* protocol.h This file is part of qgpgme, the Qt API binding for gpgme Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik Software engineering by Intevation GmbH 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_PROTOCOL_H__ #define __QGPGME_PROTOCOL_H__ #include #include #include "qgpgme_export.h" namespace QGpgME { class AddExistingSubkeyJob; class CryptoConfig; class KeyListJob; class ListAllKeysJob; class KeyGenerationJob; class ImportJob; class ImportFromKeyserverJob; class ExportJob; class DownloadJob; class DeleteJob; class EncryptJob; class DecryptJob; class SignJob; class SignKeyJob; class VerifyDetachedJob; class VerifyOpaqueJob; class SignEncryptJob; class DecryptVerifyJob; class RefreshKeysJob; +class RefreshOpenPGPKeysJob; class ChangeExpiryJob; class ChangeOwnerTrustJob; class ChangePasswdJob; class AddUserIDJob; class SpecialJob; class KeyForMailboxJob; class WKDLookupJob; class WKSPublishJob; class TofuPolicyJob; class QuickJob; class GpgCardJob; class ReceiveKeysJob; class RevokeKeyJob; /** The main entry point for QGpgME Comes in OpenPGP and SMIME(CMS) flavors. * * Use the proctocol class to obtain an instance of a job. Jobs * provide async API for GnuPG that can be connected to signals / slots. * * A job is usually started with start() and emits a result signal. * The parameters of the result signal depend on the job but the last * two are always a QString for the auditlog and an GpgME::Error for * an eventual error. * * In case async API is used and the result signal is emitted a * job schedules its own deletion. * * Most jobs also provide a synchronous call exec in which case * you have to explicitly delete the job if you don't need it anymore. * * \code * // Async example: * KeyListJob *job = openpgp()->keyListJob(); * connect(job, &KeyListJob::result, job, [this, job](KeyListResult, std::vector keys, QString, Error) * { * // keys and resuls can now be used. * }); * job->start({QStringLiteral("alfa@example.net")}, false); * \endcode * * \code * // Sync eaxmple: * KeyListJob *job = openpgp()->keyListJob(false, false, false); * std::vector keys; * GpgME::KeyListResult result = job->exec(QStringList() << * QStringLiteral("alfa@example.net"), * false, keys); * delete job; * \endcode */ class QGPGME_EXPORT Protocol { public: virtual ~Protocol() {} virtual QString name() const = 0; virtual QString displayName() const = 0; virtual KeyListJob *keyListJob(bool remote = false, bool includeSigs = false, bool validate = false) const = 0; virtual ListAllKeysJob *listAllKeysJob(bool includeSigs = false, bool validate = false) const = 0; virtual EncryptJob *encryptJob(bool armor = false, bool textmode = false) const = 0; virtual DecryptJob *decryptJob() const = 0; virtual SignJob *signJob(bool armor = false, bool textMode = false) const = 0; virtual VerifyDetachedJob *verifyDetachedJob(bool textmode = false) const = 0; virtual VerifyOpaqueJob *verifyOpaqueJob(bool textmode = false) const = 0; virtual KeyGenerationJob *keyGenerationJob() const = 0; virtual ImportJob *importJob() const = 0; virtual ImportFromKeyserverJob *importFromKeyserverJob() 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; virtual DownloadJob *downloadJob(bool armor = false) const = 0; virtual DeleteJob *deleteJob() const = 0; virtual SignEncryptJob *signEncryptJob(bool armor = false, bool textMode = false) const = 0; virtual DecryptVerifyJob *decryptVerifyJob(bool textmode = false) const = 0; /** * For S/MIME keys this job performs a full validation check of the keys * with updated CRLs. - * For OpenPGP keys this job performs a refresh of keys via the external - * methods as defined by the \c auto-key-locate option and from the - * configured keyserver. + * For OpenPGP keys, use refreshOpenPGPKeysJob. */ virtual RefreshKeysJob *refreshKeysJob() const = 0; virtual ChangeExpiryJob *changeExpiryJob() const = 0; virtual SignKeyJob *signKeyJob() const = 0; virtual ChangePasswdJob *changePasswdJob() const = 0; virtual ChangeOwnerTrustJob *changeOwnerTrustJob() const = 0; virtual AddUserIDJob *addUserIDJob() const = 0; virtual SpecialJob *specialJob(const char *type, const QMap &args) const = 0; /** A key locate job. * * This tries to find a key in local * and remote sources, if the key was remote it is imported * by GnuPG. Same as KeyListJob but intended to be used * to locate keys automatically. This ends up calling --locate-keys. * * Only available for OpenPGP * * Results are validated. As if keyListJob was called * with both includeSigs and validate options. */ virtual KeyListJob *locateKeysJob() const = 0; /** Find the best key to use for a mailbox. */ virtual KeyForMailboxJob *keyForMailboxJob() const = 0; /** A Job for interacting with gnupg's wks tools. */ virtual WKSPublishJob *wksPublishJob() const = 0; /** A Job to set tofu policy */ virtual TofuPolicyJob *tofuPolicyJob() const = 0; /** A Job for the quick commands */ virtual QuickJob *quickJob() const = 0; /** This job looks up a key via WKD without importing it. */ virtual WKDLookupJob *wkdLookupJob() const = 0; virtual ExportJob *secretSubkeyExportJob(bool armor = false) const = 0; virtual AddExistingSubkeyJob *addExistingSubkeyJob() const = 0; virtual ReceiveKeysJob *receiveKeysJob() const = 0; virtual RevokeKeyJob *revokeKeyJob() const = 0; + + /** + * This job performs a refresh of OpenPGP keys via the external methods + * as defined by the \c auto-key-locate option and via an import from the + * configured keyserver. + */ + virtual RefreshOpenPGPKeysJob *refreshOpenPGPKeysJob() const = 0; }; /** Obtain a reference to the OpenPGP Protocol. * * The reference is to a static object. * @returns Reference to the OpenPGP Protocol. */ QGPGME_EXPORT Protocol *openpgp(); /** Obtain a reference to the smime Protocol. * * The reference is to a static object. * @returns Reference to the smime Protocol. */ QGPGME_EXPORT Protocol *smime(); /** Obtain a reference to a cryptoConfig object. * * The reference is to a static object. * @returns reference to cryptoConfig object. */ QGPGME_EXPORT CryptoConfig *cryptoConfig(); /** Obtain a reference to a protocol agnostic GpgCardJob. * * The reference is to a static object. * @returns reference to a GpgCardJob following the job pattern. */ QGPGME_EXPORT GpgCardJob *gpgCardJob(); } #endif diff --git a/lang/qt/src/protocol_p.h b/lang/qt/src/protocol_p.h index 56c296c0..36cb7199 100644 --- a/lang/qt/src/protocol_p.h +++ b/lang/qt/src/protocol_p.h @@ -1,504 +1,513 @@ /* protocol_p.h This file is part of qgpgme, the Qt API binding for gpgme Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik Software engineering by Intevation GmbH 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 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_PROTOCOL_P_H__ #define __QGPGME_PROTOCOL_P_H__ #include "qgpgmenewcryptoconfig.h" #include "qgpgmekeygenerationjob.h" #include "qgpgmekeylistjob.h" #include "qgpgmelistallkeysjob.h" #include "qgpgmedecryptjob.h" #include "qgpgmedecryptverifyjob.h" #include "qgpgmerefreshopenpgpkeysjob.h" #include "qgpgmerefreshsmimekeysjob.h" #include "qgpgmedeletejob.h" #include "qgpgmedownloadjob.h" #include "qgpgmesignencryptjob.h" #include "qgpgmeencryptjob.h" #include "qgpgmesignjob.h" #include "qgpgmesignkeyjob.h" #include "qgpgmeexportjob.h" #include "qgpgmeverifydetachedjob.h" #include "qgpgmeimportjob.h" #include "qgpgmeimportfromkeyserverjob.h" #include "qgpgmeverifyopaquejob.h" #include "qgpgmechangeexpiryjob.h" #include "qgpgmechangeownertrustjob.h" #include "qgpgmechangepasswdjob.h" #include "qgpgmeaddexistingsubkeyjob.h" #include "qgpgmeadduseridjob.h" #include "qgpgmekeyformailboxjob.h" #include "qgpgmewkdlookupjob.h" #include "qgpgmewkspublishjob.h" #include "qgpgmetofupolicyjob.h" #include "qgpgmequickjob.h" #include "qgpgmereceivekeysjob.h" #include "qgpgmerevokekeyjob.h" namespace { class Protocol : public QGpgME::Protocol { GpgME::Protocol mProtocol; public: explicit Protocol(GpgME::Protocol proto) : mProtocol(proto) {} QString name() const Q_DECL_OVERRIDE { switch (mProtocol) { case GpgME::OpenPGP: return QStringLiteral("OpenPGP"); case GpgME::CMS: return QStringLiteral("SMIME"); default: return QString(); } } QString displayName() const Q_DECL_OVERRIDE { // ah (2.4.16): Where is this used and isn't this inverted // with name switch (mProtocol) { case GpgME::OpenPGP: return QStringLiteral("gpg"); case GpgME::CMS: return QStringLiteral("gpgsm"); default: return QStringLiteral("unknown"); } } QGpgME::SpecialJob *specialJob(const char *, const QMap &) const Q_DECL_OVERRIDE { return nullptr; } QGpgME::KeyListJob *keyListJob(bool remote, bool includeSigs, bool validate) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } unsigned int mode = context->keyListMode(); if (remote) { mode |= GpgME::Extern; mode &= ~GpgME::Local; } else { mode |= GpgME::Local; mode &= ~GpgME::Extern; } if (includeSigs) { mode |= GpgME::Signatures; } if (validate) { mode |= GpgME::Validate; } context->setKeyListMode(mode); return new QGpgME::QGpgMEKeyListJob(context); } QGpgME::ListAllKeysJob *listAllKeysJob(bool includeSigs, bool validate) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } unsigned int mode = context->keyListMode(); mode |= GpgME::Local; mode &= ~GpgME::Extern; if (includeSigs) { mode |= GpgME::Signatures; } if (validate) { mode |= GpgME::Validate; /* Setting the context to offline mode disables CRL / OCSP checks in this Job. Otherwise we would try to fetch the CRL's for all CMS keys in the users keyring because GpgME::Validate includes remote resources by default in the validity check. This setting only has any effect if gpgsm >= 2.1.6 is used. */ context->setOffline(true); } context->setKeyListMode(mode); return new QGpgME::QGpgMEListAllKeysJob(context); } QGpgME::EncryptJob *encryptJob(bool armor, bool textmode) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } context->setArmor(armor); context->setTextMode(textmode); return new QGpgME::QGpgMEEncryptJob(context); } QGpgME::DecryptJob *decryptJob() const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEDecryptJob(context); } QGpgME::SignJob *signJob(bool armor, bool textMode) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } context->setArmor(armor); context->setTextMode(textMode); return new QGpgME::QGpgMESignJob(context); } QGpgME::VerifyDetachedJob *verifyDetachedJob(bool textMode) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } context->setTextMode(textMode); return new QGpgME::QGpgMEVerifyDetachedJob(context); } QGpgME::VerifyOpaqueJob *verifyOpaqueJob(bool textMode) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } context->setTextMode(textMode); return new QGpgME::QGpgMEVerifyOpaqueJob(context); } QGpgME::KeyGenerationJob *keyGenerationJob() const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEKeyGenerationJob(context); } QGpgME::ImportJob *importJob() const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEImportJob(context); } QGpgME::ImportFromKeyserverJob *importFromKeyserverJob() const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } 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); if (!context) { return nullptr; } context->setArmor(armor); return new QGpgME::QGpgMEExportJob(context); } QGpgME::ExportJob *secretKeyExportJob(bool armor, const QString &) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } context->setArmor(armor); return new QGpgME::QGpgMEExportJob(context, GpgME::Context::ExportSecret); } QGpgME::ExportJob *secretSubkeyExportJob(bool armor) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } context->setArmor(armor); return new QGpgME::QGpgMEExportJob(context, GpgME::Context::ExportSecretSubkey); } QGpgME::RefreshKeysJob *refreshKeysJob() const Q_DECL_OVERRIDE { - if (mProtocol == GpgME::CMS) { - return new QGpgME::QGpgMERefreshSMIMEKeysJob; + if (mProtocol != GpgME::CMS) { + return nullptr; + } + + return new QGpgME::QGpgMERefreshSMIMEKeysJob; + } + + QGpgME::RefreshOpenPGPKeysJob *refreshOpenPGPKeysJob() const Q_DECL_OVERRIDE + { + if (mProtocol != GpgME::OpenPGP) { + return nullptr; } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMERefreshOpenPGPKeysJob{context}; } QGpgME::DownloadJob *downloadJob(bool armor) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } context->setArmor(armor); // this is the hackish interface for downloading from keyserers currently: context->setKeyListMode(GpgME::Extern); return new QGpgME::QGpgMEDownloadJob(context); } QGpgME::DeleteJob *deleteJob() const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEDeleteJob(context); } QGpgME::SignEncryptJob *signEncryptJob(bool armor, bool textMode) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } context->setArmor(armor); context->setTextMode(textMode); return new QGpgME::QGpgMESignEncryptJob(context); } QGpgME::DecryptVerifyJob *decryptVerifyJob(bool textMode) const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } context->setTextMode(textMode); return new QGpgME::QGpgMEDecryptVerifyJob(context); } QGpgME::ChangeExpiryJob *changeExpiryJob() const Q_DECL_OVERRIDE { if (mProtocol != GpgME::OpenPGP) { return nullptr; // only supported by gpg } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEChangeExpiryJob(context); } QGpgME::ChangePasswdJob *changePasswdJob() const Q_DECL_OVERRIDE { if (!GpgME::hasFeature(GpgME::PasswdFeature, 0)) { return nullptr; } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEChangePasswdJob(context); } QGpgME::SignKeyJob *signKeyJob() const Q_DECL_OVERRIDE { if (mProtocol != GpgME::OpenPGP) { return nullptr; // only supported by gpg } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMESignKeyJob(context); } QGpgME::ChangeOwnerTrustJob *changeOwnerTrustJob() const Q_DECL_OVERRIDE { if (mProtocol != GpgME::OpenPGP) { return nullptr; // only supported by gpg } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEChangeOwnerTrustJob(context); } QGpgME:: AddExistingSubkeyJob *addExistingSubkeyJob() const override { if (mProtocol != GpgME::OpenPGP) { return nullptr; // only supported by gpg } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEAddExistingSubkeyJob{context}; } QGpgME::AddUserIDJob *addUserIDJob() const Q_DECL_OVERRIDE { if (mProtocol != GpgME::OpenPGP) { return nullptr; // only supported by gpg } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEAddUserIDJob(context); } QGpgME::KeyListJob *locateKeysJob() const Q_DECL_OVERRIDE { if (mProtocol != GpgME::OpenPGP) { return nullptr; } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } context->setKeyListMode(GpgME::Locate | GpgME::Signatures | GpgME::Validate); return new QGpgME::QGpgMEKeyListJob(context); } QGpgME::KeyForMailboxJob *keyForMailboxJob() const Q_DECL_OVERRIDE { GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEKeyForMailboxJob(context); } QGpgME::WKDLookupJob *wkdLookupJob() const Q_DECL_OVERRIDE { if (mProtocol != GpgME::OpenPGP) { return nullptr; } auto context = GpgME::Context::createForEngine(GpgME::AssuanEngine); if (!context) { return nullptr; } return new QGpgME::QGpgMEWKDLookupJob(context.release()); } QGpgME::WKSPublishJob *wksPublishJob() const Q_DECL_OVERRIDE { if (mProtocol != GpgME::OpenPGP) { return nullptr; } auto context = GpgME::Context::createForEngine(GpgME::SpawnEngine); if (!context) { return nullptr; } return new QGpgME::QGpgMEWKSPublishJob(context.release()); } QGpgME::TofuPolicyJob *tofuPolicyJob() const Q_DECL_OVERRIDE { if (mProtocol != GpgME::OpenPGP) { return nullptr; } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMETofuPolicyJob(context); } QGpgME::QuickJob *quickJob() const Q_DECL_OVERRIDE { if (mProtocol != GpgME::OpenPGP) { return nullptr; } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMEQuickJob(context); } QGpgME::RevokeKeyJob *revokeKeyJob() const Q_DECL_OVERRIDE { if (mProtocol != GpgME::OpenPGP) { return nullptr; } GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); if (!context) { return nullptr; } return new QGpgME::QGpgMERevokeKeyJob(context); } }; } #endif diff --git a/lang/qt/src/qgpgmerefreshopenpgpkeysjob.cpp b/lang/qt/src/qgpgmerefreshopenpgpkeysjob.cpp index 425b9bf7..36ea9a1b 100644 --- a/lang/qt/src/qgpgmerefreshopenpgpkeysjob.cpp +++ b/lang/qt/src/qgpgmerefreshopenpgpkeysjob.cpp @@ -1,132 +1,130 @@ /* qgpgmerefreshopenpgpkeysjob.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 "qgpgmerefreshopenpgpkeysjob.h" #include "qgpgmekeylistjob.h" #include "qgpgmereceivekeysjob.h" #include "util.h" #include #include #include #include "qgpgme_debug.h" using namespace QGpgME; using namespace GpgME; QStringList toEmailAddresses(const std::vector &keys) { const auto numUserIDs = std::accumulate(std::begin(keys), std::end(keys), 0, [](auto num, const auto &key) { return num + key.numUserIDs(); }); QStringList emails; emails.reserve(numUserIDs); emails = std::accumulate(std::begin(keys), std::end(keys), emails, [](auto &emails, const auto &key) { const auto userIDs = key.userIDs(); emails = std::accumulate(std::begin(userIDs), std::end(userIDs), emails, [](auto &emails, const auto &userID) { if (!userID.isRevoked() && !userID.addrSpec().empty()) { emails.push_back(QString::fromStdString(userID.addrSpec())); } return emails; }); return emails; }); return emails; } QGpgMERefreshOpenPGPKeysJob::QGpgMERefreshOpenPGPKeysJob(Context *context) : mixin_type{context} { lateInitialization(); } QGpgMERefreshOpenPGPKeysJob::~QGpgMERefreshOpenPGPKeysJob() = default; -static Error locate_external_keys(Context *ctx, const std::vector &keys) +static ImportResult locate_external_keys(Context *ctx, const std::vector &keys) { Context::KeyListModeSaver saver{ctx}; ctx->setKeyListMode(GpgME::LocateExternal); const auto emails = toEmailAddresses(keys); std::vector dummy; auto job = std::unique_ptr{new QGpgMEKeyListJob{ctx}}; - const auto result = job->exec(emails, false, dummy); + (void) job->exec(emails, false, dummy); + const auto result = ctx->importResult(); job.release(); - return result.error(); + return result; } -static Error receive_keys(Context *ctx, const std::vector &keys) +static ImportResult receive_keys(Context *ctx, const std::vector &keys) { const auto fprs = toFingerprints(keys); auto job = std::unique_ptr{new QGpgMEReceiveKeysJob{ctx}}; const auto result = job->exec(fprs); job.release(); - return result.error(); + return result; } static QGpgMERefreshOpenPGPKeysJob::result_type refresh_keys(Context *ctx, const std::vector &keys) { - Error err; - - err = locate_external_keys(ctx, keys); - if (!err) { - err = receive_keys(ctx, keys); + ImportResult result; + + result = locate_external_keys(ctx, keys); + if (!result.error()) { + const auto res2 = receive_keys(ctx, keys); + if (!res2.error()) { + result.mergeWith(res2); + } } - return std::make_tuple(err, /*err ? WKDLookupResult{pattern, err} : result,*/ QString{}, Error{}); -} - -GpgME::Error QGpgMERefreshOpenPGPKeysJob::start(const QStringList &patterns) -{ - Q_UNUSED(patterns); - return GpgME::Error::fromCode(GPG_ERR_NOT_IMPLEMENTED); + return std::make_tuple(result, QString{}, Error{}); } GpgME::Error QGpgMERefreshOpenPGPKeysJob::start(const std::vector &keys) { run(std::bind(&refresh_keys, std::placeholders::_1, keys)); return Error{}; } #include "qgpgmerefreshopenpgpkeysjob.moc" diff --git a/lang/qt/src/qgpgmerefreshopenpgpkeysjob.h b/lang/qt/src/qgpgmerefreshopenpgpkeysjob.h index 3ccfb5cf..be322e41 100644 --- a/lang/qt/src/qgpgmerefreshopenpgpkeysjob.h +++ b/lang/qt/src/qgpgmerefreshopenpgpkeysjob.h @@ -1,67 +1,70 @@ /* qgpgmerefreshopenpgpkeysjob.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_QGPGMEREFRESHOPENPGPKEYSJOB_H__ #define __QGPGME_QGPGMEREFRESHOPENPGPKEYSJOB_H__ -#include "refreshkeysjob.h" +#include "refreshopenpgpkeysjob.h" #include "threadedjobmixin.h" +#ifdef BUILDING_QGPGME +# include "importresult.h" +#else +# include +#endif + namespace QGpgME { class QGpgMERefreshOpenPGPKeysJob #ifdef Q_MOC_RUN - : public RefreshKeysJob + : public RefreshOpenPGPKeysJob #else - : public _detail::ThreadedJobMixin + : public _detail::ThreadedJobMixin> #endif { Q_OBJECT #ifdef Q_MOC_RUN public Q_SLOTS: void slotFinished(); #endif public: explicit QGpgMERefreshOpenPGPKeysJob(GpgME::Context *context); ~QGpgMERefreshOpenPGPKeysJob() override; - /** This overload is not implemented. Use the other overload. */ - GpgME::Error start(const QStringList &patterns) override; - GpgME::Error start(const std::vector &keys) override; }; } #endif // __QGPGME_QGPGMEREFRESHOPENPGPKEYSJOB_H__ diff --git a/lang/qt/src/qgpgmerefreshopenpgpkeysjob.h b/lang/qt/src/refreshopenpgpkeysjob.h similarity index 67% copy from lang/qt/src/qgpgmerefreshopenpgpkeysjob.h copy to lang/qt/src/refreshopenpgpkeysjob.h index 3ccfb5cf..74233b61 100644 --- a/lang/qt/src/qgpgmerefreshopenpgpkeysjob.h +++ b/lang/qt/src/refreshopenpgpkeysjob.h @@ -1,67 +1,67 @@ /* - qgpgmerefreshopenpgpkeysjob.h + refreshopenpgpkeysjob.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_QGPGMEREFRESHOPENPGPKEYSJOB_H__ -#define __QGPGME_QGPGMEREFRESHOPENPGPKEYSJOB_H__ +#ifndef __KLEO_REFRESHOPENPGPKEYSJOB_H__ +#define __KLEO_REFRESHOPENPGPKEYSJOB_H__ -#include "refreshkeysjob.h" -#include "threadedjobmixin.h" +#include "abstractimportjob.h" +#include "qgpgme_export.h" + +#include + +namespace GpgME +{ +class Error; +class Key; +} namespace QGpgME { -class QGpgMERefreshOpenPGPKeysJob -#ifdef Q_MOC_RUN - : public RefreshKeysJob -#else - : public _detail::ThreadedJobMixin -#endif +class QGPGME_EXPORT RefreshOpenPGPKeysJob : public AbstractImportJob { Q_OBJECT -#ifdef Q_MOC_RUN -public Q_SLOTS: - void slotFinished(); -#endif +protected: + explicit RefreshOpenPGPKeysJob(QObject *parent); public: - explicit QGpgMERefreshOpenPGPKeysJob(GpgME::Context *context); - ~QGpgMERefreshOpenPGPKeysJob() override; - - /** This overload is not implemented. Use the other overload. */ - GpgME::Error start(const QStringList &patterns) override; + ~RefreshOpenPGPKeysJob() override; - GpgME::Error start(const std::vector &keys) override; + /** + Starts a refresh of the \a keys. + */ + virtual GpgME::Error start(const std::vector &keys) = 0; }; } -#endif // __QGPGME_QGPGMEREFRESHOPENPGPKEYSJOB_H__ +#endif // __KLEO_REFRESHOPENPGPKEYSJOB_H__ diff --git a/lang/qt/tests/run-refreshkeysjob.cpp b/lang/qt/tests/run-refreshkeysjob.cpp index a9cf5e61..4c8f4086 100644 --- a/lang/qt/tests/run-refreshkeysjob.cpp +++ b/lang/qt/tests/run-refreshkeysjob.cpp @@ -1,138 +1,155 @@ /* run-refreshkeysjob.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 +#include #include using namespace GpgME; std::ostream &operator<<(std::ostream &os, const QString &s) { return os << s.toLocal8Bit().constData(); } const char *displayName(Protocol protocol) { switch (protocol) { case GpgME::OpenPGP: return "OpenPGP"; case GpgME::CMS: return "S/MIME"; default: return "Unknown protocol"; } } struct KeyAndError { Key key; Error error; }; KeyAndError getKey(const QString &keyId, Protocol protocol) { KeyAndError result; auto ctx = Context::create(protocol); if (!ctx) { result.error = Error::fromCode(GPG_ERR_GENERAL); return result; } result.key = ctx->key(keyId.toLatin1().constData(), result.error); if (result.error.code() == GPG_ERR_EOF) { result.error = Error{}; } return result; } 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 auto keyId = qApp->arguments().last(); auto openPGPKey = getKey(keyId, GpgME::OpenPGP); auto smimeKey = getKey(keyId, GpgME::CMS); if ((!openPGPKey.key.isNull() && !smimeKey.key.isNull()) || (openPGPKey.error.code() == GPG_ERR_AMBIGUOUS_NAME) || (smimeKey.error.code() == GPG_ERR_AMBIGUOUS_NAME)) { std::cerr << "Error: Multiple keys matching '" << keyId << "' found" << std::endl; return 1; } else if (openPGPKey.key.isNull() && smimeKey.key.isNull()) { std::cerr << "Error: No key matching '" << keyId << "' found" << std::endl; return 1; } if (openPGPKey.error) { std::cerr << "Warning: Error while getting OpenPGP key: " << openPGPKey.error.asString() << std::endl; } if (smimeKey.error) { std::cerr << "Warning: Error while getting S/MIME key: " << openPGPKey.error.asString() << std::endl; } auto key = openPGPKey.key.isNull() ? smimeKey.key : openPGPKey.key; std::cout << "Refreshing " << displayName(key.protocol()) << " key " << key.userID(0).id() << std::endl; - auto jobFactory = key.protocol() == GpgME::OpenPGP ? QGpgME::openpgp() : QGpgME::smime(); - auto job = jobFactory->refreshKeysJob(); - if (!job) { - std::cerr << "Error: Could not create job to refresh " << displayName(key.protocol()) << " key" << std::endl; - return 1; - } - QObject::connect(job, &QGpgME::RefreshKeysJob::result, &app, [](const GpgME::Error &err, const QString &, const GpgME::Error &) { - std::cout << "Result: " << err.asString() << std::endl; - qApp->quit(); - }); - - const auto err = job->start({key}); - if (err) { - std::cerr << "Error: " << err.asString() << std::endl; - return 1; + if (key.protocol() == GpgME::OpenPGP) { + auto job = QGpgME::openpgp()->refreshOpenPGPKeysJob(); + if (!job) { + std::cerr << "Error: Could not create job to refresh OpenPGP key" << std::endl; + return 1; + } + QObject::connect(job, &QGpgME::RefreshOpenPGPKeysJob::result, &app, [](const GpgME::ImportResult &result, const QString &, const GpgME::Error &) { + std::cout << "Result: " << result << std::endl; + qApp->quit(); + }); + const auto err = job->start({key}); + if (err) { + std::cerr << "Error: " << err.asString() << std::endl; + return 1; + } + } else { + auto job = QGpgME::smime()->refreshKeysJob(); + if (!job) { + std::cerr << "Error: Could not create job to refresh S/MIME key" << std::endl; + return 1; + } + QObject::connect(job, &QGpgME::RefreshKeysJob::result, &app, [](const GpgME::Error &err, const QString &, const GpgME::Error &) { + std::cout << "Result: " << err.asString() << std::endl; + qApp->quit(); + }); + const auto err = job->start({key}); + if (err) { + std::cerr << "Error: " << err.asString() << std::endl; + return 1; + } } return app.exec(); }