From 930bd5c974c6e0e276a6b7e9f751fa0d2bdec0ac Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Tue, 12 Dec 2017 10:06:18 +0100 Subject: Avoid using the non-threadsafe QGpgME --- framework/src/domain/mime/mailcrypto.cpp | 46 +++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/framework/src/domain/mime/mailcrypto.cpp b/framework/src/domain/mime/mailcrypto.cpp index a4723199..62a71e42 100644 --- a/framework/src/domain/mime/mailcrypto.cpp +++ b/framework/src/domain/mime/mailcrypto.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -32,8 +31,6 @@ #include #include #include -#include -#include /* * FIXME: @@ -473,22 +470,41 @@ void MailCrypto::importKeys(const std::vector &keys) job->exec(keys); } -QMutex sMutex; - -std::vector MailCrypto::findKeys(const QStringList &filter, bool findPrivate, bool remote, Protocol protocol) +static GpgME::KeyListResult listKeys(GpgME::Protocol protocol, const QStringList &patterns, bool secretOnly, int keyListMode, std::vector &keys) { - QMutexLocker locker{&sMutex}; - const QGpgME::Protocol *const backend = protocol == SMIME ? QGpgME::smime() : QGpgME::openpgp(); - Q_ASSERT(backend); - QGpgME::KeyListJob *job = backend->keyListJob(remote); - Q_ASSERT(job); - locker.unlock(); + QByteArrayList list; + std::transform(patterns.constBegin(), patterns.constEnd(), std::back_inserter(list), [] (const QString &s) { return s.toUtf8(); }); + std::vector pattern; + std::transform(list.constBegin(), list.constEnd(), std::back_inserter(pattern), [] (const QByteArray &s) { return s.constData(); }); + pattern.push_back(0); + + GpgME::initializeLibrary(); + auto ctx = QSharedPointer{GpgME::Context::createForProtocol(protocol)}; + ctx->setKeyListMode(keyListMode); + if (const GpgME::Error err = ctx->startKeyListing(pattern.data(), secretOnly)) { + return GpgME::KeyListResult(0, err); + } - std::vector keys; - GpgME::KeyListResult res = job->exec(filter, findPrivate, keys); + GpgME::Error err; + do { + keys.push_back( ctx->nextKey(err)); + } while ( !err ); + + keys.pop_back(); - Q_ASSERT(!res.error()); + const GpgME::KeyListResult result = ctx->endKeyListing(); + ctx->cancelPendingOperation(); + return result; +} +std::vector MailCrypto::findKeys(const QStringList &filter, bool findPrivate, bool remote, Protocol protocol) +{ + std::vector keys; + GpgME::KeyListResult res = listKeys(protocol == SMIME ? GpgME::CMS : GpgME::OpenPGP, filter, findPrivate, remote ? GpgME::Extern : GpgME::Local, keys); + if (res.error()) { + qWarning() << "Failed to lookup keys: " << res.error().asString(); + return keys; + } qWarning() << "got keys:" << keys.size(); for (std::vector< GpgME::Key >::iterator i = keys.begin(); i != keys.end(); ++i) { -- cgit v1.2.3