diff --git a/NEWS b/NEWS index abab96ab..96457191 100644 --- a/NEWS +++ b/NEWS @@ -34,7 +34,7 @@ Noteworthy changes in version 1.19.0 (unreleased) * qt: Allow deferred start of import jobs. [T6323] - * qt: Support creating signed and encrypted archives. [T6342] + * qt: Support creating and extracting signed and encrypted archives. [T6342] * Interface changes relative to the 1.18.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -59,9 +59,11 @@ Noteworthy changes in version 1.19.0 (unreleased) qt: Job::startNow NEW. qt: ImportJob::startLater NEW. qt: FileListDataProvider NEW. + qt: DecryptVerifyArchiveJob NEW. qt: EncryptArchiveJob NEW. qt: SignArchiveJob NEW. qt: SignEncryptArchiveJob NEW. + qt: Protocol::decryptVerifyArchiveJob NEW. qt: Protocol::encryptArchiveJob NEW. qt: Protocol::signArchiveJob NEW. qt: Protocol::signEncryptArchiveJob NEW. diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am index 8775531e..3b3f1e80 100644 --- a/lang/qt/src/Makefile.am +++ b/lang/qt/src/Makefile.am @@ -34,12 +34,14 @@ EXTRA_DIST = QGpgmeConfig.cmake.in.in QGpgmeConfigVersion.cmake.in \ qgpgme_sources = \ dataprovider.cpp \ debug.cpp \ + decryptverifyarchivejob.cpp \ encryptarchivejob.cpp \ filelistdataprovider.cpp \ job.cpp multideletejob.cpp qgpgmeadduseridjob.cpp \ qgpgmeaddexistingsubkeyjob.cpp \ qgpgmebackend.cpp qgpgmechangeexpiryjob.cpp qgpgmechangeownertrustjob.cpp \ qgpgmechangepasswdjob.cpp qgpgmedecryptjob.cpp \ + qgpgmedecryptverifyarchivejob.cpp \ qgpgmedecryptverifyjob.cpp qgpgmedeletejob.cpp qgpgmedownloadjob.cpp \ qgpgmeencryptarchivejob.cpp \ qgpgmeencryptjob.cpp qgpgmeexportjob.cpp qgpgmeimportfromkeyserverjob.cpp \ @@ -75,6 +77,7 @@ qgpgme_headers= \ dataprovider.h \ debug.h \ decryptjob.h \ + decryptverifyarchivejob.h \ decryptverifyjob.h \ downloadjob.h \ encryptarchivejob.h \ @@ -126,6 +129,7 @@ camelcase_headers= \ DataProvider \ Debug \ DecryptJob \ + DecryptVerifyArchiveJob \ DecryptVerifyJob \ DN \ DownloadJob \ @@ -168,6 +172,7 @@ camelcase_headers= \ private_qgpgme_headers = \ changeexpiryjob_p.h \ + decryptverifyarchivejob_p.h \ encryptarchivejob_p.h \ encryptjob_p.h \ importjob_p.h \ @@ -182,6 +187,7 @@ private_qgpgme_headers = \ qgpgmechangeownertrustjob.h \ qgpgmechangepasswdjob.h \ qgpgmedecryptjob.h \ + qgpgmedecryptverifyarchivejob.h \ qgpgmedecryptverifyjob.h \ qgpgmedeletejob.h \ qgpgmedownloadjob.h \ @@ -224,6 +230,7 @@ qgpgme_moc_sources = \ changeownertrustjob.moc \ changepasswdjob.moc \ decryptjob.moc \ + decryptverifyarchivejob.moc \ decryptverifyjob.moc \ deletejob.moc \ downloadjob.moc \ @@ -244,6 +251,7 @@ qgpgme_moc_sources = \ qgpgmechangeownertrustjob.moc \ qgpgmechangepasswdjob.moc \ qgpgmedecryptjob.moc \ + qgpgmedecryptverifyarchivejob.moc \ qgpgmedecryptverifyjob.moc \ qgpgmedeletejob.moc \ qgpgmedownloadjob.moc \ diff --git a/lang/qt/src/decryptverifyarchivejob.cpp b/lang/qt/src/decryptverifyarchivejob.cpp new file mode 100644 index 00000000..ebfd36ca --- /dev/null +++ b/lang/qt/src/decryptverifyarchivejob.cpp @@ -0,0 +1,71 @@ +/* + decryptverifyarchivejob.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2023 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 "decryptverifyarchivejob.h" +#include "decryptverifyarchivejob_p.h" + +#include + +using namespace QGpgME; + +DecryptVerifyArchiveJob::DecryptVerifyArchiveJob(QObject *parent) + : Job{parent} +{ +} + +DecryptVerifyArchiveJob::~DecryptVerifyArchiveJob() = default; + +// static +bool DecryptVerifyArchiveJob::isSupported() +{ + static const auto gpgVersion = GpgME::engineInfo(GpgME::GpgEngine).engineVersion(); + return (gpgVersion >= "2.4.1") || (gpgVersion >= "2.2.42" && gpgVersion < "2.3.0"); +} + +void DecryptVerifyArchiveJob::setOutputDirectory(const QString &outputDirectory) +{ + auto d = jobPrivate(this); + d->m_outputDirectory = outputDirectory; +} + +QString DecryptVerifyArchiveJob::outputDirectory() const +{ + auto d = jobPrivate(this); + return d->m_outputDirectory; +} + +#include "decryptverifyarchivejob.moc" diff --git a/lang/qt/src/decryptverifyarchivejob.h b/lang/qt/src/decryptverifyarchivejob.h new file mode 100644 index 00000000..ea922bc4 --- /dev/null +++ b/lang/qt/src/decryptverifyarchivejob.h @@ -0,0 +1,91 @@ +/* + decryptverifyarchivejob.h + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2023 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_DECRYPTVERIFYARCHIVEJOB_H__ +#define __QGPGME_DECRYPTVERIFYARCHIVEJOB_H__ + +#include "job.h" + +#ifdef BUILDING_QGPGME +# include "context.h" +#else +# include +#endif + +namespace GpgME +{ +class Key; +} + +namespace QGpgME +{ + +/** + * Abstract base class for job for decrypting encrypted (signed) archives + */ +class QGPGME_EXPORT DecryptVerifyArchiveJob : public Job +{ + Q_OBJECT +protected: + explicit DecryptVerifyArchiveJob(QObject *parent); +public: + ~DecryptVerifyArchiveJob() override; + + static bool isSupported(); + + void setOutputDirectory(const QString &outputDirectory); + QString outputDirectory() const; + + /** + * Starts the decryption of an encrypted (and signed) archive. + * + * Decrypts and extracts the encrypted archive in \a cipherText. If the + * archive is signed, then the signature is verified. + * If a non-empty output directory was set, then the content of the archive + * is extracted into this directory. Otherwise, it is extracted into a + * directory named \c GPGARCH_n_ (where \c n is a number). + * + * Emits result() when the job has finished. + */ + virtual GpgME::Error start(const std::shared_ptr &cipherText) = 0; + +Q_SIGNALS: + void result(const GpgME::DecryptionResult &decryptionResult, + const GpgME::VerificationResult &verificationResult, + const QString &auditLogAsHtml = {}, + const GpgME::Error &auditLogError = {}); +}; + +} + +#endif // __QGPGME_DECRYPTVERIFYARCHIVEJOB_H__ diff --git a/lang/qt/src/decryptverifyarchivejob_p.h b/lang/qt/src/decryptverifyarchivejob_p.h new file mode 100644 index 00000000..b4e66530 --- /dev/null +++ b/lang/qt/src/decryptverifyarchivejob_p.h @@ -0,0 +1,49 @@ +/* + decryptverifyarchivejob_p.h + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2023 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_DECRYPTVERIFYARCHIVEJOB_P_H__ +#define __QGPGME_DECRYPTVERIFYARCHIVEJOB_P_H__ + +#include "job_p.h" + +namespace QGpgME +{ + +struct DecryptVerifyArchiveJobPrivate : public JobPrivate +{ + QString m_outputDirectory; +}; + +} + +#endif // __QGPGME_DECRYPTVERIFYARCHIVEJOB_P_H__ diff --git a/lang/qt/src/protocol.h b/lang/qt/src/protocol.h index e689ba66..cbd93877 100644 --- a/lang/qt/src/protocol.h +++ b/lang/qt/src/protocol.h @@ -60,6 +60,7 @@ class SignKeyJob; class VerifyDetachedJob; class VerifyOpaqueJob; class SignEncryptJob; +class DecryptVerifyArchiveJob; class DecryptVerifyJob; class RefreshKeysJob; class ChangeExpiryJob; @@ -196,6 +197,7 @@ public: virtual EncryptArchiveJob *encryptArchiveJob(bool armor = false) const = 0; virtual SignArchiveJob *signArchiveJob(bool armor = false) const = 0; virtual SignEncryptArchiveJob *signEncryptArchiveJob(bool armor = false) const = 0; + virtual DecryptVerifyArchiveJob *decryptVerifyArchiveJob() const = 0; }; /** Obtain a reference to the OpenPGP Protocol. diff --git a/lang/qt/src/protocol_p.h b/lang/qt/src/protocol_p.h index a4a33acb..fcb2b30a 100644 --- a/lang/qt/src/protocol_p.h +++ b/lang/qt/src/protocol_p.h @@ -41,6 +41,7 @@ #include "qgpgmekeylistjob.h" #include "qgpgmelistallkeysjob.h" #include "qgpgmedecryptjob.h" +#include "qgpgmedecryptverifyarchivejob.h" #include "qgpgmedecryptverifyjob.h" #include "qgpgmerefreshsmimekeysjob.h" #include "qgpgmedeletejob.h" @@ -545,6 +546,17 @@ public: } return nullptr; } + + QGpgME::DecryptVerifyArchiveJob *decryptVerifyArchiveJob() const override + { + if (mProtocol != GpgME::OpenPGP) { + return nullptr; + } + if (auto context = GpgME::Context::createForProtocol(mProtocol)) { + return new QGpgME::QGpgMEDecryptVerifyArchiveJob{context}; + } + return nullptr; + } }; } diff --git a/lang/qt/src/qgpgmedecryptverifyarchivejob.cpp b/lang/qt/src/qgpgmedecryptverifyarchivejob.cpp new file mode 100644 index 00000000..2e8c89c1 --- /dev/null +++ b/lang/qt/src/qgpgmedecryptverifyarchivejob.cpp @@ -0,0 +1,119 @@ +/* + qgpgmedecryptverifyarchivejob.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2004,2008 Klarälvdalens Datakonsult AB + Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik + Software engineering by Intevation GmbH + Copyright (c) 2023 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 "qgpgmedecryptverifyarchivejob.h" + +#include "dataprovider.h" +#include "decryptverifyarchivejob_p.h" + +#include + +using namespace QGpgME; +using namespace GpgME; + +namespace +{ + +class QGpgMEDecryptVerifyArchiveJobPrivate : public DecryptVerifyArchiveJobPrivate +{ + QGpgMEDecryptVerifyArchiveJob *q = nullptr; + +public: + QGpgMEDecryptVerifyArchiveJobPrivate(QGpgMEDecryptVerifyArchiveJob *qq) + : q{qq} + { + } + + ~QGpgMEDecryptVerifyArchiveJobPrivate() override = default; + +private: + void start() override + { + q->run(); + } +}; + +} + +QGpgMEDecryptVerifyArchiveJob::QGpgMEDecryptVerifyArchiveJob(Context *context) + : mixin_type{context} +{ + setJobPrivate(this, std::unique_ptr{new QGpgMEDecryptVerifyArchiveJobPrivate{this}}); + lateInitialization(); +} + +static QGpgMEDecryptVerifyArchiveJob::result_type decrypt_verify(Context *ctx, + QThread *thread, + const std::weak_ptr &cipherText_, + const QString &outputDirectory) +{ + const std::shared_ptr cipherText = cipherText_.lock(); + const _detail::ToThreadMover ctMover(cipherText, thread); + + QGpgME::QIODeviceDataProvider in{cipherText}; + Data indata(&in); + + Data outdata; + if (!outputDirectory.isEmpty()) { + outdata.setFileName(outputDirectory.toStdString()); + } + + const auto res = ctx->decryptAndVerify(indata, outdata, Context::DecryptArchive); + Error ae; + const QString log = _detail::audit_log_as_html(ctx, ae); + return std::make_tuple(res.first, res.second, log, ae); +} + +GpgME::Error QGpgMEDecryptVerifyArchiveJob::start(const std::shared_ptr &cipherText) +{ + if (!cipherText) { + return Error::fromCode(GPG_ERR_INV_VALUE); + } + + run(std::bind(&decrypt_verify, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + outputDirectory()), + cipherText); + return {}; +} + +#include "qgpgmedecryptverifyarchivejob.moc" diff --git a/lang/qt/src/qgpgmedecryptverifyarchivejob.h b/lang/qt/src/qgpgmedecryptverifyarchivejob.h new file mode 100644 index 00000000..b43be070 --- /dev/null +++ b/lang/qt/src/qgpgmedecryptverifyarchivejob.h @@ -0,0 +1,68 @@ +/* + qgpgmedecryptverifyarchivejob.h + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2023 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_QGPGMEDECRYPTVERIFYARCHIVEJOB_H__ +#define __QGPGME_QGPGMEDECRYPTVERIFYARCHIVEJOB_H__ + +#include "decryptverifyarchivejob.h" + +#include "threadedjobmixin.h" + +#include +#include + +namespace QGpgME +{ + +class QGpgMEDecryptVerifyArchiveJob +#ifdef Q_MOC_RUN + : public DecryptVerifyArchiveJob +#else + : public _detail::ThreadedJobMixin> +#endif +{ + Q_OBJECT +#ifdef Q_MOC_RUN +public Q_SLOTS: + void slotFinished(); +#endif +public: + explicit QGpgMEDecryptVerifyArchiveJob(GpgME::Context *context); + ~QGpgMEDecryptVerifyArchiveJob() = default; + + GpgME::Error start(const std::shared_ptr &cipherText) override; +}; + +} + +#endif // __QGPGME_QGPGMEDECRYPTVERIFYARCHIVEJOB_H__ diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am index 4e43d986..f7e50efa 100644 --- a/lang/qt/tests/Makefile.am +++ b/lang/qt/tests/Makefile.am @@ -86,6 +86,7 @@ t_wkdlookup_SOURCES = t-wkdlookup.cpp $(support_src) t_import_SOURCES = t-import.cpp $(support_src) t_revokekey_SOURCES = t-revokekey.cpp $(support_src) t_setprimaryuserid_SOURCES = t-setprimaryuserid.cpp $(support_src) +run_decryptverifyarchivejob_SOURCES = run-decryptverifyarchivejob.cpp run_encryptarchivejob_SOURCES = run-encryptarchivejob.cpp run_exportjob_SOURCES = run-exportjob.cpp run_importjob_SOURCES = run-importjob.cpp @@ -104,6 +105,7 @@ noinst_PROGRAMS = \ run-keyformailboxjob t-wkspublish t-verify t-various t-config t-remarks \ t-trustsignatures t-changeexpiryjob t-wkdlookup t-import t-revokekey \ t-setprimaryuserid \ + run-decryptverifyarchivejob \ run-encryptarchivejob \ run-importjob run-exportjob run-receivekeysjob run-refreshkeysjob \ run-signarchivejob diff --git a/lang/qt/tests/run-decryptverifyarchivejob.cpp b/lang/qt/tests/run-decryptverifyarchivejob.cpp new file mode 100644 index 00000000..cc588fcc --- /dev/null +++ b/lang/qt/tests/run-decryptverifyarchivejob.cpp @@ -0,0 +1,141 @@ +/* + run-decryptverifyarchivejob.cpp + + This file is part of QGpgME's test suite. + Copyright (c) 2023 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 +#include + +#include + +using namespace GpgME; + +std::ostream &operator<<(std::ostream &os, const QString &s) +{ + return os << s.toLocal8Bit().constData(); +} + +struct CommandLineOptions { + QString outputDirectory; + QString archiveName; +}; + +CommandLineOptions parseCommandLine(const QStringList &arguments) +{ + CommandLineOptions options; + + QCommandLineParser parser; + parser.setApplicationDescription("Test program for DecryptVerifyArchiveJob"); + parser.addHelpOption(); + parser.addOptions({ + {{"C", "directory"}, "Extract the files into the directory DIRECTORY.", "DIRECTORY"}, + }); + parser.addPositionalArgument("archive", "The archive to decrypt and extract"); + + parser.process(arguments); + + const auto args = parser.positionalArguments(); + if (args.size() != 1) { + parser.showHelp(1); + } + + options.outputDirectory = parser.value("directory"); + options.archiveName = args.first(); + + return options; +} + +std::shared_ptr createInput(const QString &fileName) +{ + std::shared_ptr input; + + if (!QFile::exists(fileName)) { + qCritical() << "Error: File" << fileName << "does not exist."; + } else { + input.reset(new QFile{fileName}); + input->open(QIODevice::ReadOnly); + } + + return input; +} + +int main(int argc, char **argv) +{ + GpgME::initializeLibrary(); + + QCoreApplication app{argc, argv}; + app.setApplicationName("run-decryptverifyarchivejob"); + + const auto options = parseCommandLine(app.arguments()); + + if (!QGpgME::DecryptVerifyArchiveJob::isSupported()) { + std::cerr << "Error: Decrypting and extracting archives is not supported by your version of gpg." << std::endl; + return 1; + } + + auto input = createInput(options.archiveName); + if (!input) { + return 1; + } + + auto job = QGpgME::openpgp()->decryptVerifyArchiveJob(); + if (!job) { + std::cerr << "Error: Could not create job" << std::endl; + return 1; + } + job->setOutputDirectory(options.outputDirectory); + QObject::connect(job, &QGpgME::DecryptVerifyArchiveJob::result, &app, [](const GpgME::DecryptionResult &decryptionResult, const GpgME::VerificationResult &verificationResult, const QString &auditLog, const GpgME::Error &) { + std::cerr << "Diagnostics: " << auditLog << std::endl; + std::cerr << "Decryption Result: " << decryptionResult << std::endl; + std::cerr << "Verification Result: " << verificationResult << std::endl; + qApp->quit(); + }); + + const auto err = job->start(input); + if (err) { + std::cerr << "Error: Starting the job failed: " << err.asString() << std::endl; + return 1; + } + + return app.exec(); +}