summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Heinecke <aheinecke@gnupg.org>2020-02-12 11:52:24 +0100
committerAndre Heinecke <aheinecke@gnupg.org>2020-02-12 11:57:09 +0100
commit77feaa451074741c2d07051915bc23d8b8377242 (patch)
tree0e2b1e3b55d0dfde24e001eaa15ddb8b5ae0e530
parentcff600f1f65a2164ab25ff2b039cba008776ce62 (diff)
downloadgpgme-77feaa451074741c2d07051915bc23d8b8377242.tar.gz
qt: Add GpgCardJob following the job pattern
* lang/qt/src/Makefile.am: Add new files. * lang/qt/src/job.cpp (GpgCardJob): Add impl stuff. * lang/qt/src/protocol.h (gpgCardJob): Get one. * lang/qt/src/qgpgmebackend.cpp, lang/qt/src/qgpgmebackend.h: Add helpers to get the job. * lang/qt/src/qgpgmegpgcardjob.cpp, lang/qt/src/gpgcardjob.h, lang/qt/src/qgpgmegpgcardjob.h: New. -- This is annoyingly complex to add a simple new job. In the future we should implement something like this without the threadedjobmixin stuff. But the idea was to follow the usual job pattern. GnuPG-Bug-Id: T4794
-rw-r--r--NEWS3
-rw-r--r--lang/qt/src/Makefile.am10
-rw-r--r--lang/qt/src/gpgcardjob.h92
-rw-r--r--lang/qt/src/job.cpp3
-rw-r--r--lang/qt/src/protocol.h8
-rw-r--r--lang/qt/src/qgpgmebackend.cpp14
-rw-r--r--lang/qt/src/qgpgmebackend.h2
-rw-r--r--lang/qt/src/qgpgmegpgcardjob.cpp129
-rw-r--r--lang/qt/src/qgpgmegpgcardjob.h63
9 files changed, 322 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index dc9e0ff8..d87bc4ff 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ Noteworthy changes in version 1.14.0 (unreleased)
* qt: Extended signkeyjob to handle remarks and multiple signatures.
[#4734]
+ * qt: Added job API for gpg-card.
+
* Interface changes relative to the 1.13.1 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_user_id_t EXTENDED: New field 'uidhash'.
@@ -19,6 +21,7 @@ Noteworthy changes in version 1.14.0 (unreleased)
cpp: GpgSignKeyEditInteractor::setDupeOk NEW.
qt: SignKeyJob::setDupeOk NEW.
qt: SignKeyJob::setRemark NEW.
+ qt: GpgCardJob NEW.
Noteworthy changes in version 1.13.1 (2019-06-13)
diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am
index 80dcde15..cbf6a530 100644
--- a/lang/qt/src/Makefile.am
+++ b/lang/qt/src/Makefile.am
@@ -38,6 +38,7 @@ qgpgme_sources = \
qgpgmekeyformailboxjob.cpp gpgme_backend_debug.cpp \
qgpgmetofupolicyjob.cpp qgpgmequickjob.cpp \
defaultkeygenerationjob.cpp qgpgmewkspublishjob.cpp \
+ qgpgmegpgcardjob.cpp \
dn.cpp cryptoconfig.cpp
# If you add one here make sure that you also add one in camelcase
@@ -78,6 +79,7 @@ qgpgme_headers= \
defaultkeygenerationjob.h \
tofupolicyjob.h \
wkspublishjob.h \
+ gpgcardjob.h \
dn.h
camelcase_headers= \
@@ -116,7 +118,8 @@ camelcase_headers= \
KeyForMailboxJob \
DefaultKeyGenerationJob \
WKSPublishJob \
- TofuPolicyJob
+ TofuPolicyJob \
+ GpgCardJob
private_qgpgme_headers = \
qgpgme_export.h \
@@ -147,6 +150,7 @@ private_qgpgme_headers = \
qgpgmekeyformailboxjob.h \
qgpgmewkspublishjob.h \
qgpgmetofupolicyjob.h \
+ qgpgmegpgcardjob.h \
qgpgmequickjob.h \
threadedjobmixin.h
@@ -207,7 +211,9 @@ qgpgme_moc_sources = \
qgpgmekeyformailboxjob.moc \
defaultkeygenerationjob.moc \
quickjob.moc \
- qgpgmequickjob.moc
+ qgpgmequickjob.moc \
+ gpgcardjob.moc \
+ qgpgmegpgcardjob.moc
qgpgmeincludedir = $(includedir)/qgpgme
qgpgmeinclude_HEADERS = $(qgpgme_headers)
diff --git a/lang/qt/src/gpgcardjob.h b/lang/qt/src/gpgcardjob.h
new file mode 100644
index 00000000..63f5cf7c
--- /dev/null
+++ b/lang/qt/src/gpgcardjob.h
@@ -0,0 +1,92 @@
+/*
+ gpgcardjob.h
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2020 g10 Code 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 __KLEO_GPGCARDJOB_H__
+#define __KLEO_GPGCARDJOB_H__
+
+#include <QStringList>
+
+#include "job.h"
+
+namespace GpgME
+{
+class Error;
+}
+
+namespace QGpgME
+{
+
+/**
+ @short Get the best key to use for a Mailbox
+
+ To use the keyformailboxjob, first obtain an instance from the
+ CryptoBackend and either exec it or start and
+ conncet the result() signals to a suitable slot.
+ The job will be automatically deleted in which
+ case the KeylistJob instance will have schedules it's own
+ destruction with a call to QObject::deleteLater().
+
+ The best key is defined as the key with a UID that has an
+ E-Mail that matches the mailbox provided. If multiple
+ keys are found the one with the highest validity is returned.
+
+ After result() is emitted, the
+ KeyListJob will schedule it's own destruction by calling
+ QObject::deleteLater().
+*/
+class QGPGME_EXPORT GpgCardJob: public Job
+{
+ Q_OBJECT
+protected:
+ explicit GpgCardJob(QObject *parent);
+
+public:
+ ~GpgCardJob();
+
+ /**
+ Starts the operation. \a cmds are the commands to
+ execute.
+ */
+ virtual GpgME::Error start(const QStringList &cmds) = 0;
+
+ virtual GpgME::Error exec(const QStringList &cmds, QString &std_out, QString &std_err, int &exitCode) = 0;
+
+Q_SIGNALS:
+ /** The resulting stdout and stderr of gpgcard and the exitCode
+ *
+ * The auditlog params are always null / empty.
+ */
+ void result(const QString &std_out, const QString &std_err, int exitCode,
+ const QString &auditLogAsHtml = QString(), const GpgME::Error &auditLogError = GpgME::Error());
+};
+
+}
+#endif
diff --git a/lang/qt/src/job.cpp b/lang/qt/src/job.cpp
index c4270205..8ed0b576 100644
--- a/lang/qt/src/job.cpp
+++ b/lang/qt/src/job.cpp
@@ -65,6 +65,7 @@
#include "tofupolicyjob.h"
#include "threadedjobmixin.h"
#include "quickjob.h"
+#include "gpgcardjob.h"
#include <QCoreApplication>
#include <QDebug>
@@ -141,6 +142,7 @@ make_job_subclass(KeyForMailboxJob)
make_job_subclass(WKSPublishJob)
make_job_subclass(TofuPolicyJob)
make_job_subclass(QuickJob)
+make_job_subclass(GpgCardJob)
#undef make_job_subclass
@@ -173,3 +175,4 @@ make_job_subclass(QuickJob)
#include "wkspublishjob.moc"
#include "tofupolicyjob.moc"
#include "quickjob.moc"
+#include "gpgcardjob.moc"
diff --git a/lang/qt/src/protocol.h b/lang/qt/src/protocol.h
index 1a52097e..17db68a5 100644
--- a/lang/qt/src/protocol.h
+++ b/lang/qt/src/protocol.h
@@ -67,6 +67,7 @@ class KeyForMailboxJob;
class WKSPublishJob;
class TofuPolicyJob;
class QuickJob;
+class GpgCardJob;
/** The main entry point for QGpgME Comes in OpenPGP and SMIME(CMS) flavors.
*
@@ -184,5 +185,12 @@ QGPGME_EXPORT Protocol *smime();
*/
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/qgpgmebackend.cpp b/lang/qt/src/qgpgmebackend.cpp
index f7393f09..aa96db0d 100644
--- a/lang/qt/src/qgpgmebackend.cpp
+++ b/lang/qt/src/qgpgmebackend.cpp
@@ -38,6 +38,7 @@
#include "qgpgmebackend.h"
+#include "qgpgmegpgcardjob.h"
#include "error.h"
#include "engineinfo.h"
@@ -86,6 +87,11 @@ QGpgME::CryptoConfig *QGpgME::QGpgMEBackend::config() const
return mCryptoConfig;
}
+QGpgME::GpgCardJob *QGpgME::QGpgMEBackend::gpgCardJob() const
+{
+ return new QGpgME::QGpgMEGpgCardJob();
+}
+
static bool check(GpgME::Protocol proto, QString *reason)
{
if (!GpgME::checkEngine(proto)) {
@@ -206,3 +212,11 @@ QGpgME::Protocol *QGpgME::smime()
}
return gpgmeBackend->smime();
}
+
+QGpgME::GpgCardJob *QGpgME::gpgCardJob ()
+{
+ if (!gpgmeBackend) {
+ gpgmeBackend = new QGpgME::QGpgMEBackend();
+ }
+ return gpgmeBackend->gpgCardJob();
+}
diff --git a/lang/qt/src/qgpgmebackend.h b/lang/qt/src/qgpgmebackend.h
index a69b09a8..6c655e96 100644
--- a/lang/qt/src/qgpgmebackend.h
+++ b/lang/qt/src/qgpgmebackend.h
@@ -46,6 +46,7 @@ namespace QGpgME
{
class CryptoConfig;
class Protocol;
+class GpgCardJob;
class QGpgMEBackend
@@ -58,6 +59,7 @@ public:
QString displayName() const;
CryptoConfig *config() const;
+ GpgCardJob *gpgCardJob() const;
Protocol *openpgp() const;
Protocol *smime() const;
diff --git a/lang/qt/src/qgpgmegpgcardjob.cpp b/lang/qt/src/qgpgmegpgcardjob.cpp
new file mode 100644
index 00000000..a01ae604
--- /dev/null
+++ b/lang/qt/src/qgpgmegpgcardjob.cpp
@@ -0,0 +1,129 @@
+/*
+ qgpgmekeyformailboxjob.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "qgpgmegpgcardjob.h"
+
+#include <QStringList>
+#include <QFileInfo>
+#include <QDir>
+#include <QProcess>
+#include "util.h"
+
+/* We cannot have a timeout because key generation can
+ * take ages. Well maybe 10 minutes. */
+#define TIMEOUT_VALUE (600000)
+
+#include <tuple>
+
+using namespace GpgME;
+using namespace QGpgME;
+
+QGpgMEGpgCardJob::QGpgMEGpgCardJob()
+ : mixin_type(nullptr)
+{
+ lateInitialization();
+}
+
+QGpgMEGpgCardJob::~QGpgMEGpgCardJob() {}
+
+static QString getGpgCardPath()
+{
+ auto bindir = QString::fromLocal8Bit(dirInfo("bindir"));
+ if (bindir.isEmpty()) {
+ return QString();
+ }
+
+ const QFileInfo fi(QDir(bindir).absoluteFilePath(QStringLiteral("gpg-card")));
+ if (fi.exists() && fi.isExecutable()) {
+ return fi.absoluteFilePath();
+ }
+ return QString();
+}
+
+static QGpgMEGpgCardJob::result_type do_work(const QStringList &cmds, const QString &path)
+{
+ QStringList args;
+ args << QStringLiteral("--with-colons");
+ args += cmds;
+
+ QProcess proc;
+
+ proc.setProgram(path);
+ proc.setArguments(args);
+ proc.start();
+ if (!proc.waitForStarted()) {
+ return std::make_tuple (QString(), QString(), 1, QString(), Error());
+ }
+
+ if (!proc.waitForFinished(TIMEOUT_VALUE)) {
+ return std::make_tuple (QString(), QString(), 1, QString(), Error());
+ }
+ if (proc.exitStatus() == QProcess::NormalExit) {
+ return std::make_tuple (QString::fromUtf8(proc.readAllStandardOutput()),
+ QString::fromUtf8(proc.readAllStandardError()), proc.exitCode(),
+ QString(), Error());
+ }
+ return std::make_tuple (QString::fromUtf8(proc.readAllStandardOutput()),
+ QString::fromUtf8(proc.readAllStandardError()), 1,
+ QString(), Error());
+}
+
+Error QGpgMEGpgCardJob::start(const QStringList &cmds)
+{
+ const auto cardpath = getGpgCardPath ();
+ if (cardpath.isEmpty()) {
+ return Error(make_error(GPG_ERR_NOT_SUPPORTED));
+ }
+ run(std::bind(&do_work, cmds, cardpath));
+ return Error();
+}
+
+Error QGpgMEGpgCardJob::exec(const QStringList &cmds, QString &std_out, QString &std_err, int &exitCode)
+{
+ const auto cardpath = getGpgCardPath ();
+ if (cardpath.isEmpty()) {
+ return Error(make_error(GPG_ERR_NOT_SUPPORTED));
+ }
+ const result_type r = do_work(cmds, cardpath);
+ resultHook(r);
+ std_out = std::get<0>(r);
+ std_err = std::get<1>(r);
+ exitCode = std::get<2>(r);
+ return exitCode == 0 ? Error() : Error(make_error(GPG_ERR_GENERAL));
+}
+
+#include "qgpgmegpgcardjob.moc"
diff --git a/lang/qt/src/qgpgmegpgcardjob.h b/lang/qt/src/qgpgmegpgcardjob.h
new file mode 100644
index 00000000..bed68b2d
--- /dev/null
+++ b/lang/qt/src/qgpgmegpgcardjob.h
@@ -0,0 +1,63 @@
+/* qgpgmegpgcardjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2020 g10 Code 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_QGPGMEGPGCARDJOB_H__
+#define __QGPGME_QGPGMEGPGCARDJOB_H__
+#include "gpgcardjob.h"
+
+#include "threadedjobmixin.h"
+
+namespace QGpgME
+{
+
+class QGpgMEGpgCardJob
+#ifdef Q_MOC_RUN
+ : public GpgCardJob
+#else
+ : public _detail::ThreadedJobMixin<GpgCardJob, std::tuple<QString, QString, int, QString, GpgME::Error> >
+#endif
+{
+ Q_OBJECT
+#ifdef Q_MOC_RUN
+public Q_SLOTS:
+ void slotFinished();
+#endif
+public:
+ explicit QGpgMEGpgCardJob();
+ ~QGpgMEGpgCardJob();
+
+ GpgME::Error start(const QStringList &cmds) Q_DECL_OVERRIDE;
+
+ GpgME::Error exec(const QStringList &cmds, QString &std_out, QString &std_err, int &exitCode) Q_DECL_OVERRIDE;
+};
+
+}
+#endif