2016-08-25 12:35:09 +00:00
|
|
|
/* t-wkspublish.cpp
|
|
|
|
|
|
|
|
This file is part of qgpgme, the Qt API binding for gpgme
|
|
|
|
Copyright (c) 2016 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.
|
|
|
|
*/
|
cpp, qt: Include config.h
lang/cpp/src/callbacks.cpp,
lang/cpp/src/configuration.cpp,
lang/cpp/src/context.cpp,
lang/cpp/src/context_glib.cpp,
lang/cpp/src/context_qt.cpp,
lang/cpp/src/context_vanilla.cpp,
lang/cpp/src/data.cpp,
lang/cpp/src/decryptionresult.cpp,
lang/cpp/src/defaultassuantransaction.cpp,
lang/cpp/src/editinteractor.cpp,
lang/cpp/src/encryptionresult.cpp,
lang/cpp/src/engineinfo.cpp,
lang/cpp/src/eventloopinteractor.cpp,
lang/cpp/src/exception.cpp,
lang/cpp/src/gpgadduserideditinteractor.cpp,
lang/cpp/src/gpgagentgetinfoassuantransaction.cpp,
lang/cpp/src/gpgsetexpirytimeeditinteractor.cpp,
lang/cpp/src/gpgsetownertrusteditinteractor.cpp,
lang/cpp/src/gpgsignkeyeditinteractor.cpp,
lang/cpp/src/importresult.cpp,
lang/cpp/src/key.cpp,
lang/cpp/src/keygenerationresult.cpp,
lang/cpp/src/keylistresult.cpp,
lang/cpp/src/scdgetinfoassuantransaction.cpp,
lang/cpp/src/signingresult.cpp,
lang/cpp/src/tofuinfo.cpp,
lang/cpp/src/trustitem.cpp,
lang/cpp/src/verificationresult.cpp,
lang/cpp/src/vfsmountresult.cpp,
lang/qt/src/dataprovider.cpp,
lang/qt/src/defaultkeygenerationjob.cpp,
lang/qt/src/gpgme_backend_debug.cpp,
lang/qt/src/job.cpp,
lang/qt/src/qgpgmeadduseridjob.cpp,
lang/qt/src/qgpgmebackend.cpp,
lang/qt/src/qgpgmechangeexpiryjob.cpp,
lang/qt/src/qgpgmechangeownertrustjob.cpp,
lang/qt/src/qgpgmechangepasswdjob.cpp,
lang/qt/src/qgpgmedecryptjob.cpp,
lang/qt/src/qgpgmedecryptverifyjob.cpp,
lang/qt/src/qgpgmedeletejob.cpp,
lang/qt/src/qgpgmedownloadjob.cpp,
lang/qt/src/qgpgmeencryptjob.cpp,
lang/qt/src/qgpgmeexportjob.cpp,
lang/qt/src/qgpgmeimportfromkeyserverjob.cpp,
lang/qt/src/qgpgmeimportjob.cpp,
lang/qt/src/qgpgmekeyformailboxjob.cpp,
lang/qt/src/qgpgmekeygenerationjob.cpp,
lang/qt/src/qgpgmekeylistjob.cpp,
lang/qt/src/qgpgmelistallkeysjob.cpp,
lang/qt/src/qgpgmenewcryptoconfig.cpp,
lang/qt/src/qgpgmerefreshkeysjob.cpp,
lang/qt/src/qgpgmesecretkeyexportjob.cpp,
lang/qt/src/qgpgmesignencryptjob.cpp,
lang/qt/src/qgpgmesignjob.cpp,
lang/qt/src/qgpgmesignkeyjob.cpp,
lang/qt/src/qgpgmetofupolicyjob.cpp,
lang/qt/src/qgpgmeverifydetachedjob.cpp,
lang/qt/src/qgpgmeverifyopaquejob.cpp,
lang/qt/src/qgpgmewkspublishjob.cpp,
lang/qt/src/threadedjobmixin.cpp,
lang/qt/tests/run-keyformailboxjob.cpp,
lang/qt/tests/t-encrypt.cpp,
lang/qt/tests/t-keylist.cpp,
lang/qt/tests/t-keylocate.cpp,
lang/qt/tests/t-ownertrust.cpp,
lang/qt/tests/t-support.cpp,
lang/qt/tests/t-tofuinfo.cpp,
lang/qt/tests/t-wkspublish.cpp: Include config.h
--
This fixes problems with mismatching definitions. Most
notably _FILE_OFFSET_BITS is now always set correctly.
2016-09-23 13:22:29 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2016-08-25 12:35:09 +00:00
|
|
|
#include <QDebug>
|
|
|
|
#include <QTest>
|
|
|
|
#include <QSignalSpy>
|
|
|
|
#include <QTemporaryDir>
|
|
|
|
#include "wkspublishjob.h"
|
|
|
|
#include "keygenerationjob.h"
|
|
|
|
#include "keygenerationresult.h"
|
|
|
|
#include "importjob.h"
|
|
|
|
#include "importresult.h"
|
|
|
|
#include "protocol.h"
|
|
|
|
#include "engineinfo.h"
|
|
|
|
|
|
|
|
#include "t-support.h"
|
|
|
|
|
|
|
|
using namespace QGpgME;
|
|
|
|
using namespace GpgME;
|
|
|
|
|
|
|
|
//#define DO_ONLINE_TESTS
|
|
|
|
|
|
|
|
#define TEST_ADDRESS "testuser2@test.gnupg.org"
|
|
|
|
|
|
|
|
static const char *testSecKey =
|
|
|
|
"-----BEGIN PGP PRIVATE KEY BLOCK-----\n"
|
|
|
|
"\n"
|
|
|
|
"lHgEV77hVhMJKyQDAwIIAQEHAgMEN3qKqBr9EecnfUnpw8RS8DHAjJqhwm2HAoEE\n"
|
|
|
|
"3yfQQ9w8uB/bKm5dqW4HML3JWRH8YoJaKSVrJY2D1FZUY+vHlgABAKDwEAB0HND8\n"
|
|
|
|
"5kbxiJmqKIuuNqCJ2jHgs9G0xk4GdKvZEdq0JlRlc3QgVXNlciAyIDx0ZXN0dXNl\n"
|
|
|
|
"cjJAdGVzdC5nbnVwZy5vcmc+iHkEExMIACEFAle+4VYCGwMFCwkIBwIGFQgJCgsC\n"
|
|
|
|
"BBYCAwECHgECF4AACgkQRVRoUEJO+6zgFQD7BF3pnS3w3A7J9y+Y3kyGfmscXFWJ\n"
|
|
|
|
"Kme1PAsAlVSm1y4A+weReMvWFYHJH257v94yhStmV8egGoybsNDttNAW53cbnHwE\n"
|
|
|
|
"V77hVhIJKyQDAwIIAQEHAgMEX+6cF0HEn4g3ztFvwHyr7uwXMVYUGL3lE3mjhnV3\n"
|
|
|
|
"SbY6Dmy3OeFVnEVkawHqSv+HobpQTeEqNoQHAoIiXFCRlgMBCAcAAP9FykiyDspm\n"
|
|
|
|
"T33XWRPD+LAOmaIU7CIhfv9+lVkeExlU1w+qiGEEGBMIAAkFAle+4VYCGwwACgkQ\n"
|
|
|
|
"RVRoUEJO+6xjhgD/ZJ/MwYZJPk/xPYhTP8+wF+tErVNA8w3pP9D69dgUPdcA/izZ\n"
|
|
|
|
"Pji6YetVhgsyaHc4PrKynsk5G6nM3KkAOehUQsX8\n"
|
|
|
|
"=S/Wa\n"
|
|
|
|
"-----END PGP PRIVATE KEY BLOCK-----\n";
|
|
|
|
|
|
|
|
static const char *testResponse =
|
|
|
|
"From key-submission@test.gnupg.org Thu Aug 25 12:15:54 2016\n"
|
|
|
|
"Return-Path: <webkey@g10code.com>\n"
|
|
|
|
"From: key-submission@test.gnupg.org\n"
|
|
|
|
"To: testuser2@test.gnupg.org\n"
|
|
|
|
"Subject: Confirm your key publication\n"
|
|
|
|
"X-Wks-Loop: webkey.g10code.com\n"
|
|
|
|
"MIME-Version: 1.0\n"
|
|
|
|
"Content-Type: multipart/encrypted; protocol=\"application/pgp-encrypted\";\n"
|
|
|
|
" boundary=\"=-=01-wbu5fr9nu6fix5tcojjo=-=\"\n"
|
|
|
|
"Date: Thu, 25 Aug 2016 12:15:54 +0000\n"
|
|
|
|
"Message-Id: <E1bctZa-0004LE-Fr@kerckhoffs.g10code.com>\n"
|
|
|
|
"Sender: <webkey@g10code.com>\n"
|
|
|
|
"X-Kolab-Scheduling-Message: FALSE\n"
|
|
|
|
"\n"
|
|
|
|
" \n"
|
|
|
|
"\n"
|
|
|
|
"--=-=01-wbu5fr9nu6fix5tcojjo=-=\n"
|
|
|
|
"Content-Type: application/pgp-encrypted\n"
|
|
|
|
"\n"
|
|
|
|
"Version: 1\n"
|
|
|
|
"\n"
|
|
|
|
"--=-=01-wbu5fr9nu6fix5tcojjo=-=\n"
|
|
|
|
"Content-Type: application/octet-stream\n"
|
|
|
|
"\n"
|
|
|
|
"-----BEGIN PGP MESSAGE-----\n"
|
|
|
|
"Version: GnuPG v2\n"
|
|
|
|
"\n"
|
|
|
|
"hH4D8pSp7hUsFUASAgMEg0w39E6d0TkFYxLbT6n3YcoKTT+Ur/c7Sn1ECyL7Rnuk\n"
|
|
|
|
"cmPO0adt3JxueK7Oz5COlk32SECFODdF3cQuDhkGxzC6Sfc4SfisdILmNhaT/MeW\n"
|
|
|
|
"8a+yE4skSK70absif4kw5XkvxXNxHeIHfAteP50jPJLSwEsBTEceb9cRMoP7s8w0\n"
|
|
|
|
"lYyi+RWQ7UKlKKywtcRCL4ow2H7spjx+a+3FzNOAoy7K0/thhLVRk8z+iuPi0/4n\n"
|
|
|
|
"Z2Ql60USLLUlfV2ZIpXdCd+5GjTJsnGhDos1pas5TZcOOAxO12Cg5TcqHISOaqa8\n"
|
|
|
|
"6BqxcKCU3NypIynOKHj375KArSs0WsEH8HWHyBBHB+NYtNpnTAuHNKxM+JtNxf+U\n"
|
|
|
|
"NfD2zptS6kyiHLw+4zjL5pEV7RHS2PBwWBDS6vhnyybNwckleya96U04iYiGRYGE\n"
|
|
|
|
"lUUR6Fl8H6x04dItFH1/jJA6Ppcu4FoYou04HADWCqJXPTgztjiW1/9QoCeXl5lm\n"
|
|
|
|
"CcOCcuw7lXp+qTejuns=\n"
|
|
|
|
"=SsWX\n"
|
|
|
|
"-----END PGP MESSAGE-----\n"
|
|
|
|
"\n"
|
|
|
|
"--=-=01-wbu5fr9nu6fix5tcojjo=-=--\n";
|
|
|
|
|
|
|
|
|
|
|
|
class WKSPublishTest : public QGpgMETest
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
Q_SIGNALS:
|
|
|
|
void asyncDone();
|
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void testUnsupported()
|
|
|
|
{
|
|
|
|
// First check if it is supported
|
|
|
|
auto job = openpgp()->wksPublishJob();
|
|
|
|
connect(job, &WKSPublishJob::result, this,
|
2016-10-05 14:44:53 +00:00
|
|
|
[this] (Error err, QByteArray, QByteArray, QString, Error) {
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(err);
|
2016-08-25 12:35:09 +00:00
|
|
|
Q_EMIT asyncDone();
|
|
|
|
});
|
|
|
|
job->startCheck ("testuser1@localhost");
|
|
|
|
QSignalSpy spy (this, SIGNAL(asyncDone()));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(spy.wait());
|
2016-08-25 12:35:09 +00:00
|
|
|
}
|
|
|
|
#ifdef DO_ONLINE_TESTS
|
|
|
|
private Q_SLOTS:
|
|
|
|
#else
|
|
|
|
private:
|
|
|
|
#endif
|
|
|
|
void testWSKPublishSupport()
|
|
|
|
{
|
|
|
|
// First check if it is supported
|
|
|
|
auto job = openpgp()->wksPublishJob();
|
|
|
|
connect(job, &WKSPublishJob::result, this,
|
2016-10-05 14:44:53 +00:00
|
|
|
[this] (Error err, QByteArray, QByteArray, QString, Error) {
|
2016-08-25 12:35:09 +00:00
|
|
|
if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") {
|
|
|
|
std::cout << err;
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(err);
|
2016-08-25 12:35:09 +00:00
|
|
|
} else {
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(!err);
|
2016-08-25 12:35:09 +00:00
|
|
|
}
|
|
|
|
Q_EMIT asyncDone();
|
|
|
|
});
|
|
|
|
job->startCheck ("testuser1@test.gnupg.org");
|
|
|
|
QSignalSpy spy (this, SIGNAL(asyncDone()));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(spy.wait());
|
2016-08-25 12:35:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void testWKSPublishErrors() {
|
|
|
|
if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") {
|
|
|
|
/* Not supported */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto job = openpgp()->wksPublishJob();
|
|
|
|
connect(job, &WKSPublishJob::result, this,
|
2016-10-05 14:44:53 +00:00
|
|
|
[this] (Error err, QByteArray, QByteArray, QString, Error) {
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(err);
|
2016-08-25 12:35:09 +00:00
|
|
|
Q_EMIT asyncDone();
|
|
|
|
});
|
|
|
|
job->startCreate("AB874F24E98EBB8487EE7B170F8E3D97FE7011B7",
|
|
|
|
QStringLiteral("Foo@bar.baz"));
|
|
|
|
QSignalSpy spy (this, SIGNAL(asyncDone()));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(spy.wait());
|
2016-08-25 12:35:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void testWKSPublishCreate() {
|
|
|
|
if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") {
|
|
|
|
/* Not supported */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* First generate a test key */
|
|
|
|
const QString args = QStringLiteral("<GnupgKeyParms format=\"internal\">\n"
|
|
|
|
"%no-protection\n"
|
|
|
|
"%transient-key\n"
|
|
|
|
"key-type: ECDSA\n"
|
|
|
|
"key-curve: brainpoolP256r1\n"
|
|
|
|
"key-usage: sign\n"
|
|
|
|
"subkey-type: ECDH\n"
|
|
|
|
"subkey-curve: brainpoolP256r1\n"
|
|
|
|
"subkey-usage: encrypt\n"
|
|
|
|
"name-email: %1\n"
|
|
|
|
"name-real: Test User\n"
|
|
|
|
"</GnupgKeyParms>").arg(TEST_ADDRESS);
|
|
|
|
|
|
|
|
auto keygenjob = openpgp()->keyGenerationJob();
|
|
|
|
QByteArray fpr;
|
|
|
|
connect(keygenjob, &KeyGenerationJob::result, this,
|
2016-10-05 14:44:53 +00:00
|
|
|
[this, &fpr](KeyGenerationResult result, QByteArray, QString, Error)
|
2016-08-25 12:35:09 +00:00
|
|
|
{
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(!result.error());
|
2016-08-25 12:35:09 +00:00
|
|
|
fpr = QByteArray(result.fingerprint());
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(!fpr.isEmpty());
|
2016-08-25 12:35:09 +00:00
|
|
|
Q_EMIT asyncDone();
|
|
|
|
});
|
|
|
|
keygenjob->start(args);
|
|
|
|
QSignalSpy spy (this, SIGNAL(asyncDone()));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(spy.wait());
|
2016-08-25 12:35:09 +00:00
|
|
|
|
|
|
|
/* Then try to create a request. */
|
|
|
|
auto job = openpgp()->wksPublishJob();
|
|
|
|
connect(job, &WKSPublishJob::result, this,
|
2016-10-05 14:44:53 +00:00
|
|
|
[this] (Error err, QByteArray out, QByteArray, QString, Error) {
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(!err);
|
2016-08-25 12:35:09 +00:00
|
|
|
Q_EMIT asyncDone();
|
|
|
|
const QString outstr = QString(out);
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(outstr.contains(
|
2016-08-25 12:35:09 +00:00
|
|
|
QStringLiteral("-----BEGIN PGP PUBLIC KEY BLOCK-----")));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(outstr.contains(
|
2016-08-25 12:35:09 +00:00
|
|
|
QStringLiteral("Content-Type: application/pgp-keys")));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(outstr.contains(
|
2016-08-25 12:35:09 +00:00
|
|
|
QStringLiteral("From: " TEST_ADDRESS)));
|
|
|
|
});
|
|
|
|
job->startCreate(fpr.constData(), QLatin1String(TEST_ADDRESS));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(spy.wait());
|
2016-08-25 12:35:09 +00:00
|
|
|
}
|
|
|
|
|
2016-10-05 15:27:36 +00:00
|
|
|
void testWKSPublishReceive() {
|
2016-08-25 12:35:09 +00:00
|
|
|
if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") {
|
|
|
|
/* Not supported */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto importjob = openpgp()->importJob();
|
|
|
|
connect(importjob, &ImportJob::result, this,
|
|
|
|
[this](ImportResult result, QString, Error)
|
|
|
|
{
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(!result.error());
|
|
|
|
QVERIFY(!result.imports().empty());
|
|
|
|
QVERIFY(result.numSecretKeysImported());
|
2016-08-25 12:35:09 +00:00
|
|
|
Q_EMIT asyncDone();
|
|
|
|
});
|
|
|
|
importjob->start(QByteArray(testSecKey));
|
|
|
|
QSignalSpy spy (this, SIGNAL(asyncDone()));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(spy.wait());
|
2016-08-25 12:35:09 +00:00
|
|
|
|
|
|
|
/* Get a response. */
|
|
|
|
auto job = openpgp()->wksPublishJob();
|
|
|
|
connect(job, &WKSPublishJob::result, this,
|
2016-10-05 14:44:53 +00:00
|
|
|
[this] (Error err, QByteArray out, QByteArray, QString, Error) {
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(!err);
|
2016-08-25 12:35:09 +00:00
|
|
|
Q_EMIT asyncDone();
|
|
|
|
const QString outstr = QString(out);
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(outstr.contains(
|
2016-08-25 12:35:09 +00:00
|
|
|
QStringLiteral("-----BEGIN PGP MESSAGE-----")));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(outstr.contains(
|
2016-08-25 12:35:09 +00:00
|
|
|
QStringLiteral("Content-Type: multipart/encrypted;")));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(outstr.contains(
|
2016-08-25 12:35:09 +00:00
|
|
|
QStringLiteral("From: " TEST_ADDRESS)));
|
|
|
|
});
|
2016-10-05 15:27:36 +00:00
|
|
|
job->startReceive(QByteArray(testResponse));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(spy.wait());
|
2016-08-25 12:35:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void initTestCase()
|
|
|
|
{
|
|
|
|
QGpgMETest::initTestCase();
|
|
|
|
const QString gpgHome = qgetenv("GNUPGHOME");
|
|
|
|
qputenv("GNUPGHOME", mDir.path().toUtf8());
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(mDir.isValid());
|
2016-08-25 12:35:09 +00:00
|
|
|
QFile agentConf(mDir.path() + QStringLiteral("/gpg-agent.conf"));
|
2017-01-11 15:20:31 +00:00
|
|
|
QVERIFY(agentConf.open(QIODevice::WriteOnly));
|
2016-08-25 12:35:09 +00:00
|
|
|
agentConf.write("allow-loopback-pinentry");
|
|
|
|
agentConf.close();
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
QTemporaryDir mDir;
|
|
|
|
};
|
|
|
|
|
|
|
|
QTEST_MAIN(WKSPublishTest)
|
|
|
|
|
|
|
|
#include "t-wkspublish.moc"
|