
* lang/qt/src/decryptverifyarchivejob.cpp, lang/qt/src/decryptverifyarchivejob.h (DecryptVerifyArchiveJob): Add member functions setProcessAllSignatures, processAllSignatures. * lang/qt/src/decryptverifyarchivejob_p.h (DecryptVerifyArchiveJobPrivate): Add member m_processAllSignatures. * lang/qt/src/decryptverifyjob.cpp, lang/qt/src/decryptverifyjob.h (DecryptVerifyJob): Add member functions setProcessAllSignatures, processAllSignatures. * lang/qt/src/decryptverifyjob_p.h (DecryptVerifyJobPrivate): Add member m_processAllSignatures. * lang/qt/src/qgpgmedecryptverifyarchivejob.cpp (decrypt_verify_from_file_name): Add argument "processAllSignatures". Set context flag "proc-all-sigs" if requested. (QGpgMEDecryptVerifyArchiveJob::start): Set context flag "proc-all-sigs" if requested. (QGpgMEDecryptVerifyArchiveJobPrivate::startIt): Pass m_processAllSignatures to decrypt_verify_from_file_name. * lang/qt/src/qgpgmedecryptverifyjob.cpp (decrypt_verify_from_filename): Add argument "processAllSignatures". Set context flag "proc-all-sigs" if requested. (QGpgMEDecryptVerifyJob::start, QGpgMEDecryptVerifyJob::exec): Set context flag "proc-all-sigs" if requested. (QGpgMEDecryptVerifyJobPrivate::startIt): Pass m_processAllSignatures to decrypt_verify_from_filename. * lang/qt/src/qgpgmeverifydetachedjob.cpp (verify_from_filename): Add argument "processAllSignatures". Set context flag "proc-all-sigs" if requested. (QGpgMEVerifyDetachedJob::start, QGpgMEVerifyDetachedJob::exec): Set context flag "proc-all-sigs" if requested. (QGpgMEVerifyDetachedJobPrivate::startIt): Pass m_processAllSignatures to decrypt_verify_from_filename. * lang/qt/src/qgpgmeverifyopaquejob.cpp (verify_from_filename): Add argument "processAllSignatures". Set context flag "proc-all-sigs" if requested. (QGpgMEVerifyOpaqueJob::start, QGpgMEVerifyOpaqueJob::exec): Set context flag "proc-all-sigs" if requested. (QGpgMEVerifyOpaqueJobPrivate::startIt): Pass m_processAllSignatures to decrypt_verify_from_filename. * lang/qt/src/verifydetachedjob.cpp, lang/qt/src/verifydetachedjob.h (VerifyDetachedJob): Add member functions setProcessAllSignatures, processAllSignatures. * lang/qt/src/verifydetachedjob_p.h (VerifyDetachedJobPrivate): Add member m_processAllSignatures. * lang/qt/src/verifyopaquejob.cpp, lang/qt/src/verifyopaquejob.h (VerifyOpaqueJob): Add member functions setProcessAllSignatures, processAllSignatures. * lang/qt/src/verifyopaquejob_p.h (VerifyOpaqueJobPrivate): Add member m_processAllSignatures. * lang/qt/tests/run-decryptverifyarchivejob.cpp, lang/qt/tests/run-decryptverifyjob.cpp, lang/qt/tests/run-verifydetachedjob.cpp, lang/qt/tests/run-verifyopaquejob.cpp (struct CommandLineOptions): Add member processAllSignatures. (parseCommandLine): Add command line option --process-all-signatures. (main): Pass new option to the job. -- The new option processAllSignatures is added to all jobs that verify data signatures. By enabling this option, one can tell gpg not to stop checking signatures after the first bad signature. GnuPG-bug-id: 6870
169 lines
5.5 KiB
C++
169 lines
5.5 KiB
C++
/*
|
|
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 <debug.h>
|
|
#include <protocol.h>
|
|
#include <decryptverifyjob.h>
|
|
|
|
#include <QCommandLineParser>
|
|
#include <QCoreApplication>
|
|
#include <QDebug>
|
|
#include <QFile>
|
|
#include <QTimer>
|
|
|
|
#include <gpgme++/context.h>
|
|
#include <gpgme++/decryptionresult.h>
|
|
#include <gpgme++/verificationresult.h>
|
|
|
|
#include <iostream>
|
|
|
|
using namespace GpgME;
|
|
|
|
std::ostream &operator<<(std::ostream &os, const QString &s)
|
|
{
|
|
return os << s.toLocal8Bit().constData();
|
|
}
|
|
|
|
struct CommandLineOptions {
|
|
bool processAllSignatures = false;
|
|
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"},
|
|
{"process-all-signatures", "Don't stop signature checking after bad signature."},
|
|
});
|
|
parser.addPositionalArgument("file", "File to decrypt", "FILE");
|
|
|
|
parser.process(arguments);
|
|
|
|
const auto args = parser.positionalArguments();
|
|
if (args.size() != 1) {
|
|
parser.showHelp(1);
|
|
}
|
|
|
|
options.processAllSignatures = parser.isSet("process-all-signatures");
|
|
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;
|
|
job->setProcessAllSignatures(options.processAllSignatures);
|
|
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 << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
return app.exec();
|
|
}
|