qt: Support decryption (with verification) directly to/from files
* lang/qt/src/Makefile.am: Add new files. * lang/qt/src/job.cpp (DecryptVerifyJob): Move definition of constructor and destructor and inclusion of the moc file to the corresponding .cpp file. * lang/qt/src/decryptverifyjob.cpp: New. * lang/qt/src/decryptverifyjob.h (DecryptVerifyJob): Add member functions setInputFile, inputFile, setOutputFile, outputFile. * lang/qt/src/decryptverifyjob_p.h: New. * lang/qt/src/qgpgmedecryptverifyjob.cpp (class QGpgMEDecryptVerifyJobPrivate): New. (QGpgMEDecryptVerifyJob::QGpgMEDecryptVerifyJob): Instantiate private job class. (decrypt_verify_from_filename): New. * lang/qt/tests/Makefile.am: Add new test program. * lang/qt/tests/run-decryptverifyjob.cpp: New. -- This makes it possible to tell gpg to read the input and write the output directly to a specified file bypassing GpgME's Data IO when decrypting (and verifying) a file. GnuPG-bug-id: 6550
This commit is contained in:
parent
a44d84772d
commit
20b32e0350
@ -36,6 +36,7 @@ qgpgme_sources = \
|
|||||||
dataprovider.cpp \
|
dataprovider.cpp \
|
||||||
debug.cpp \
|
debug.cpp \
|
||||||
decryptverifyarchivejob.cpp \
|
decryptverifyarchivejob.cpp \
|
||||||
|
decryptverifyjob.cpp \
|
||||||
encryptarchivejob.cpp \
|
encryptarchivejob.cpp \
|
||||||
filelistdataprovider.cpp \
|
filelistdataprovider.cpp \
|
||||||
job.cpp multideletejob.cpp qgpgmeadduseridjob.cpp \
|
job.cpp multideletejob.cpp qgpgmeadduseridjob.cpp \
|
||||||
@ -180,6 +181,7 @@ private_qgpgme_headers = \
|
|||||||
changeexpiryjob_p.h \
|
changeexpiryjob_p.h \
|
||||||
cleaner.h \
|
cleaner.h \
|
||||||
decryptverifyarchivejob_p.h \
|
decryptverifyarchivejob_p.h \
|
||||||
|
decryptverifyjob_p.h \
|
||||||
encryptarchivejob_p.h \
|
encryptarchivejob_p.h \
|
||||||
encryptjob_p.h \
|
encryptjob_p.h \
|
||||||
importjob_p.h \
|
importjob_p.h \
|
||||||
|
74
lang/qt/src/decryptverifyjob.cpp
Normal file
74
lang/qt/src/decryptverifyjob.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
decryptverifyjob.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 <dev@ingo-kloecker.de>
|
||||||
|
|
||||||
|
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 "decryptverifyjob.h"
|
||||||
|
#include "decryptverifyjob_p.h"
|
||||||
|
|
||||||
|
using namespace QGpgME;
|
||||||
|
|
||||||
|
DecryptVerifyJob::DecryptVerifyJob(QObject *parent)
|
||||||
|
: Job{parent}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DecryptVerifyJob::~DecryptVerifyJob() = default;
|
||||||
|
|
||||||
|
void DecryptVerifyJob::setInputFile(const QString &path)
|
||||||
|
{
|
||||||
|
auto d = jobPrivate<DecryptVerifyJobPrivate>(this);
|
||||||
|
d->m_inputFilePath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DecryptVerifyJob::inputFile() const
|
||||||
|
{
|
||||||
|
auto d = jobPrivate<DecryptVerifyJobPrivate>(this);
|
||||||
|
return d->m_inputFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecryptVerifyJob::setOutputFile(const QString &path)
|
||||||
|
{
|
||||||
|
auto d = jobPrivate<DecryptVerifyJobPrivate>(this);
|
||||||
|
d->m_outputFilePath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DecryptVerifyJob::outputFile() const
|
||||||
|
{
|
||||||
|
auto d = jobPrivate<DecryptVerifyJobPrivate>(this);
|
||||||
|
return d->m_outputFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "decryptverifyjob.moc"
|
@ -62,6 +62,14 @@ namespace QGpgME
|
|||||||
DecryptVerifyJob instance will have scheduled it's own destruction with
|
DecryptVerifyJob instance will have scheduled it's own destruction with
|
||||||
a call to QObject::deleteLater().
|
a call to QObject::deleteLater().
|
||||||
|
|
||||||
|
Alternatively, the job can be started with startIt() after setting
|
||||||
|
an input file and an output file. If the job is started this way then
|
||||||
|
the backend reads the input and writes the output directly from/to the
|
||||||
|
specified input file and output file. In this case the plainText value of
|
||||||
|
the result signal will always be empty. This direct IO mode is currently
|
||||||
|
only supported for OpenPGP. Note that startIt() does not schedule the job's
|
||||||
|
destruction if starting the job failed.
|
||||||
|
|
||||||
After result() is emitted, the DecryptVerifyJob will schedule it's own
|
After result() is emitted, the DecryptVerifyJob will schedule it's own
|
||||||
destruction by calling QObject::deleteLater().
|
destruction by calling QObject::deleteLater().
|
||||||
*/
|
*/
|
||||||
@ -71,7 +79,27 @@ class QGPGME_EXPORT DecryptVerifyJob : public Job
|
|||||||
protected:
|
protected:
|
||||||
explicit DecryptVerifyJob(QObject *parent);
|
explicit DecryptVerifyJob(QObject *parent);
|
||||||
public:
|
public:
|
||||||
~DecryptVerifyJob();
|
~DecryptVerifyJob() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the path of the file to decrypt (and verify).
|
||||||
|
*
|
||||||
|
* Used if the job is started with startIt().
|
||||||
|
*/
|
||||||
|
void setInputFile(const QString &path);
|
||||||
|
QString inputFile() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the path of the file to write the result to.
|
||||||
|
*
|
||||||
|
* Used if the job is started with startIt().
|
||||||
|
*
|
||||||
|
* \note If a file with this path exists, then the job will fail, i.e. you
|
||||||
|
* need to delete an existing file that shall be overwritten before you
|
||||||
|
* start the job.
|
||||||
|
*/
|
||||||
|
void setOutputFile(const QString &path);
|
||||||
|
QString outputFile() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Starts the combined decryption and verification operation.
|
Starts the combined decryption and verification operation.
|
||||||
|
50
lang/qt/src/decryptverifyjob_p.h
Normal file
50
lang/qt/src/decryptverifyjob_p.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
decryptverifyjob_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 <dev@ingo-kloecker.de>
|
||||||
|
|
||||||
|
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_DECRYPTVERIFYJOB_P_H__
|
||||||
|
#define __QGPGME_DECRYPTVERIFYJOB_P_H__
|
||||||
|
|
||||||
|
#include "job_p.h"
|
||||||
|
|
||||||
|
namespace QGpgME
|
||||||
|
{
|
||||||
|
|
||||||
|
struct DecryptVerifyJobPrivate : public JobPrivate
|
||||||
|
{
|
||||||
|
QString m_inputFilePath;
|
||||||
|
QString m_outputFilePath;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __QGPGME_DECRYPTVERIFYJOB_P_H__
|
@ -44,7 +44,6 @@
|
|||||||
#include "keylistjob.h"
|
#include "keylistjob.h"
|
||||||
#include "listallkeysjob.h"
|
#include "listallkeysjob.h"
|
||||||
#include "decryptjob.h"
|
#include "decryptjob.h"
|
||||||
#include "decryptverifyjob.h"
|
|
||||||
#include "signkeyjob.h"
|
#include "signkeyjob.h"
|
||||||
#include "verifydetachedjob.h"
|
#include "verifydetachedjob.h"
|
||||||
#include "verifyopaquejob.h"
|
#include "verifyopaquejob.h"
|
||||||
@ -162,7 +161,6 @@ void QGpgME::Job::startNow()
|
|||||||
make_job_subclass(KeyListJob)
|
make_job_subclass(KeyListJob)
|
||||||
make_job_subclass(ListAllKeysJob)
|
make_job_subclass(ListAllKeysJob)
|
||||||
make_job_subclass(DecryptJob)
|
make_job_subclass(DecryptJob)
|
||||||
make_job_subclass(DecryptVerifyJob)
|
|
||||||
make_job_subclass(SignKeyJob)
|
make_job_subclass(SignKeyJob)
|
||||||
make_job_subclass(VerifyDetachedJob)
|
make_job_subclass(VerifyDetachedJob)
|
||||||
make_job_subclass(VerifyOpaqueJob)
|
make_job_subclass(VerifyOpaqueJob)
|
||||||
@ -197,7 +195,6 @@ make_job_subclass(SetPrimaryUserIDJob)
|
|||||||
#include "keylistjob.moc"
|
#include "keylistjob.moc"
|
||||||
#include "listallkeysjob.moc"
|
#include "listallkeysjob.moc"
|
||||||
#include "decryptjob.moc"
|
#include "decryptjob.moc"
|
||||||
#include "decryptverifyjob.moc"
|
|
||||||
#include "signkeyjob.moc"
|
#include "signkeyjob.moc"
|
||||||
#include "verifydetachedjob.moc"
|
#include "verifydetachedjob.moc"
|
||||||
#include "verifyopaquejob.moc"
|
#include "verifyopaquejob.moc"
|
||||||
|
@ -39,25 +39,55 @@
|
|||||||
#include "qgpgmedecryptverifyjob.h"
|
#include "qgpgmedecryptverifyjob.h"
|
||||||
|
|
||||||
#include "dataprovider.h"
|
#include "dataprovider.h"
|
||||||
|
#include "decryptverifyjob_p.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include "context.h"
|
#include <context.h>
|
||||||
#include "decryptionresult.h"
|
#include <decryptionresult.h>
|
||||||
#include "verificationresult.h"
|
#include <verificationresult.h>
|
||||||
#include "data.h"
|
#include <data.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "qgpgme_debug.h"
|
#include "qgpgme_debug.h"
|
||||||
|
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
using namespace QGpgME;
|
using namespace QGpgME;
|
||||||
using namespace GpgME;
|
using namespace GpgME;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
class QGpgMEDecryptVerifyJobPrivate : public DecryptVerifyJobPrivate
|
||||||
|
{
|
||||||
|
QGpgMEDecryptVerifyJob *q = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QGpgMEDecryptVerifyJobPrivate(QGpgMEDecryptVerifyJob *qq)
|
||||||
|
: q{qq}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~QGpgMEDecryptVerifyJobPrivate() override = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GpgME::Error startIt() override;
|
||||||
|
|
||||||
|
void startNow() override
|
||||||
|
{
|
||||||
|
q->run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QGpgMEDecryptVerifyJob::QGpgMEDecryptVerifyJob(Context *context)
|
QGpgMEDecryptVerifyJob::QGpgMEDecryptVerifyJob(Context *context)
|
||||||
: mixin_type(context)
|
: mixin_type(context)
|
||||||
{
|
{
|
||||||
|
setJobPrivate(this, std::unique_ptr<QGpgMEDecryptVerifyJobPrivate>{new QGpgMEDecryptVerifyJobPrivate{this}});
|
||||||
lateInitialization();
|
lateInitialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +142,43 @@ static QGpgMEDecryptVerifyJob::result_type decrypt_verify_qba(Context *ctx, cons
|
|||||||
return decrypt_verify(ctx, nullptr, buffer, std::shared_ptr<QIODevice>());
|
return decrypt_verify(ctx, nullptr, buffer, std::shared_ptr<QIODevice>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QGpgMEDecryptVerifyJob::result_type decrypt_verify_from_filename(Context *ctx,
|
||||||
|
const QString &inputFilePath,
|
||||||
|
const QString &outputFilePath)
|
||||||
|
{
|
||||||
|
Data indata;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
indata.setFileName(inputFilePath().toUtf8().constData());
|
||||||
|
#else
|
||||||
|
indata.setFileName(QFile::encodeName(inputFilePath).constData());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PartialFileGuard partFileGuard{outputFilePath};
|
||||||
|
if (partFileGuard.tempFileName().isEmpty()) {
|
||||||
|
return std::make_tuple(DecryptionResult{Error::fromCode(GPG_ERR_EEXIST)}, VerificationResult{Error::fromCode(GPG_ERR_EEXIST)}, QByteArray{}, QString{}, Error{});
|
||||||
|
}
|
||||||
|
|
||||||
|
Data outdata;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
outdata.setFileName(partFileGuard.tempFileName().toUtf8().constData());
|
||||||
|
#else
|
||||||
|
outdata.setFileName(QFile::encodeName(partFileGuard.tempFileName()).constData());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const auto results = ctx->decryptAndVerify(indata, outdata);
|
||||||
|
const auto &decryptionResult = results.first;
|
||||||
|
const auto &verificationResult = results.second;
|
||||||
|
|
||||||
|
if (!decryptionResult.error().code() && !verificationResult.error().code()) {
|
||||||
|
// the operation succeeded -> save the result under the requested file name
|
||||||
|
partFileGuard.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error ae;
|
||||||
|
const QString log = _detail::audit_log_as_html(ctx, ae);
|
||||||
|
return std::make_tuple(decryptionResult, verificationResult, QByteArray{}, log, ae);
|
||||||
|
}
|
||||||
|
|
||||||
Error QGpgMEDecryptVerifyJob::start(const QByteArray &cipherText)
|
Error QGpgMEDecryptVerifyJob::start(const QByteArray &cipherText)
|
||||||
{
|
{
|
||||||
run(std::bind(&decrypt_verify_qba, std::placeholders::_1, cipherText));
|
run(std::bind(&decrypt_verify_qba, std::placeholders::_1, cipherText));
|
||||||
@ -132,10 +199,22 @@ QGpgME::QGpgMEDecryptVerifyJob::exec(const QByteArray &cipherText, QByteArray &p
|
|||||||
return mResult;
|
return mResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
//PENDING(marc) implement showErrorDialog()
|
|
||||||
|
|
||||||
void QGpgMEDecryptVerifyJob::resultHook(const result_type &tuple)
|
void QGpgMEDecryptVerifyJob::resultHook(const result_type &tuple)
|
||||||
{
|
{
|
||||||
mResult = std::make_pair(std::get<0>(tuple), std::get<1>(tuple));
|
mResult = std::make_pair(std::get<0>(tuple), std::get<1>(tuple));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GpgME::Error QGpgMEDecryptVerifyJobPrivate::startIt()
|
||||||
|
{
|
||||||
|
if (m_inputFilePath.isEmpty() || m_outputFilePath.isEmpty()) {
|
||||||
|
return Error::fromCode(GPG_ERR_INV_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
q->run([=](Context *ctx) {
|
||||||
|
return decrypt_verify_from_filename(ctx, m_inputFilePath, m_outputFilePath);
|
||||||
|
});
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
#include "qgpgmedecryptverifyjob.moc"
|
#include "qgpgmedecryptverifyjob.moc"
|
||||||
|
@ -89,6 +89,7 @@ t_wkdlookup_SOURCES = t-wkdlookup.cpp $(support_src)
|
|||||||
t_import_SOURCES = t-import.cpp $(support_src)
|
t_import_SOURCES = t-import.cpp $(support_src)
|
||||||
t_revokekey_SOURCES = t-revokekey.cpp $(support_src)
|
t_revokekey_SOURCES = t-revokekey.cpp $(support_src)
|
||||||
t_setprimaryuserid_SOURCES = t-setprimaryuserid.cpp $(support_src)
|
t_setprimaryuserid_SOURCES = t-setprimaryuserid.cpp $(support_src)
|
||||||
|
run_decryptverifyjob_SOURCES = run-decryptverifyjob.cpp
|
||||||
run_decryptverifyarchivejob_SOURCES = run-decryptverifyarchivejob.cpp
|
run_decryptverifyarchivejob_SOURCES = run-decryptverifyarchivejob.cpp
|
||||||
run_encryptarchivejob_SOURCES = run-encryptarchivejob.cpp
|
run_encryptarchivejob_SOURCES = run-encryptarchivejob.cpp
|
||||||
run_encryptjob_SOURCES = run-encryptjob.cpp
|
run_encryptjob_SOURCES = run-encryptjob.cpp
|
||||||
@ -113,6 +114,7 @@ noinst_PROGRAMS = \
|
|||||||
t-trustsignatures t-changeexpiryjob t-wkdlookup t-import t-revokekey \
|
t-trustsignatures t-changeexpiryjob t-wkdlookup t-import t-revokekey \
|
||||||
t-setprimaryuserid \
|
t-setprimaryuserid \
|
||||||
run-decryptverifyarchivejob \
|
run-decryptverifyarchivejob \
|
||||||
|
run-decryptverifyjob \
|
||||||
run-encryptarchivejob \
|
run-encryptarchivejob \
|
||||||
run-encryptjob \
|
run-encryptjob \
|
||||||
run-importjob run-exportjob run-receivekeysjob run-refreshkeysjob \
|
run-importjob run-exportjob run-receivekeysjob run-refreshkeysjob \
|
||||||
|
163
lang/qt/tests/run-decryptverifyjob.cpp
Normal file
163
lang/qt/tests/run-decryptverifyjob.cpp
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
run-decryptverifyjob.cpp
|
||||||
|
|
||||||
|
This file is part of QGpgME's test suite.
|
||||||
|
Copyright (c) 2023 by g10 Code GmbH
|
||||||
|
Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
|
||||||
|
|
||||||
|
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 <protocol.h>
|
||||||
|
#include <decryptverifyjob.h>
|
||||||
|
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <context.h>
|
||||||
|
#include <decryptionresult.h>
|
||||||
|
#include <verificationresult.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace GpgME;
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const QString &s)
|
||||||
|
{
|
||||||
|
return os << s.toLocal8Bit().constData();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CommandLineOptions {
|
||||||
|
QString inputFile;
|
||||||
|
QString outputFile;
|
||||||
|
std::chrono::seconds cancelTimeout{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
CommandLineOptions parseCommandLine(const QStringList &arguments)
|
||||||
|
{
|
||||||
|
CommandLineOptions options;
|
||||||
|
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.setApplicationDescription("Test program for DecryptVerifyJob");
|
||||||
|
parser.addHelpOption();
|
||||||
|
parser.addOptions({
|
||||||
|
{{"o", "output"}, "Write output to FILE.", "FILE"},
|
||||||
|
{"cancel-after", "Cancel the running job after SECONDS seconds.", "SECONDS"},
|
||||||
|
});
|
||||||
|
parser.addPositionalArgument("file", "File to decrypt", "FILE");
|
||||||
|
|
||||||
|
parser.process(arguments);
|
||||||
|
|
||||||
|
const auto args = parser.positionalArguments();
|
||||||
|
if (args.size() != 1) {
|
||||||
|
parser.showHelp(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
options.inputFile = args.front();
|
||||||
|
options.outputFile = parser.value("output");
|
||||||
|
if (parser.isSet("cancel-after")) {
|
||||||
|
bool ok;
|
||||||
|
options.cancelTimeout = std::chrono::seconds{parser.value("cancel-after").toInt(&ok)};
|
||||||
|
if (!ok) {
|
||||||
|
options.cancelTimeout = std::chrono::seconds{-1};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
GpgME::initializeLibrary();
|
||||||
|
|
||||||
|
QCoreApplication app{argc, argv};
|
||||||
|
app.setApplicationName("run-decryptverifyjob");
|
||||||
|
|
||||||
|
const auto options = parseCommandLine(app.arguments());
|
||||||
|
if (options.cancelTimeout.count() < 0) {
|
||||||
|
std::cerr << "Ignoring invalid timeout for cancel." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<QFile> output;
|
||||||
|
if (options.outputFile.isEmpty() || options.outputFile == QLatin1String{"-"}) {
|
||||||
|
output.reset(new QFile);
|
||||||
|
output->open(stdout, QIODevice::WriteOnly);
|
||||||
|
} else {
|
||||||
|
if (QFile::exists(options.outputFile)) {
|
||||||
|
qCritical() << "File" << options.outputFile << "exists. Bailing out.";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto job = QGpgME::openpgp()->decryptVerifyJob();
|
||||||
|
if (!job) {
|
||||||
|
std::cerr << "Error: Could not create job" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
QObject::connect(job,
|
||||||
|
&QGpgME::DecryptVerifyJob::result,
|
||||||
|
&app,
|
||||||
|
[](const GpgME::DecryptionResult &decryptionResult,
|
||||||
|
const GpgME::VerificationResult &verificationResult,
|
||||||
|
const QByteArray &,
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
if (options.cancelTimeout.count() > 0) {
|
||||||
|
QTimer::singleShot(options.cancelTimeout, job, [job]() {
|
||||||
|
std::cerr << "Canceling job" << std::endl;
|
||||||
|
job->slotCancel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<QFile> input;
|
||||||
|
GpgME::Error err;
|
||||||
|
if (output) {
|
||||||
|
input.reset(new QFile{options.inputFile});
|
||||||
|
input->open(QIODevice::ReadOnly);
|
||||||
|
job->start(input, output);
|
||||||
|
} else {
|
||||||
|
job->setInputFile(options.inputFile);
|
||||||
|
job->setOutputFile(options.outputFile);
|
||||||
|
err = job->startIt();
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
std::cerr << "Error: Starting the job failed: " << err.asString() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user