diff --git a/autotests/expirycheckertest.cpp b/autotests/expirycheckertest.cpp index bdf9526ca..abda2a61a 100644 --- a/autotests/expirycheckertest.cpp +++ b/autotests/expirycheckertest.cpp @@ -1,282 +1,246 @@ /* This file is part of libkleopatra's test suite. SPDX-FileCopyrightText: 2022 Sandro Knauß SPDX-License-Identifier: LGPL-2.0-or-later */ #include "../src/kleo/expirychecker_p.h" #include - -#include -#include +#include +#include #include #include #include #include #include -#include - using namespace Kleo; - -static std::vector> getKeys(bool smime = false) -{ - QGpgME::KeyListJob *job = nullptr; - - if (smime) { - const QGpgME::Protocol *const backend = QGpgME::smime(); - Q_ASSERT(backend); - job = backend->keyListJob(false); - } else { - const QGpgME::Protocol *const backend = QGpgME::openpgp(); - Q_ASSERT(backend); - job = backend->keyListJob(false); - } - Q_ASSERT(job); - - std::vector keys; - GpgME::KeyListResult res = job->exec(QStringList(), true, keys); - - Q_ASSERT(!res.error()); - - /* - qDebug() << "got private keys:" << keys.size(); - - for (std::vector< GpgME::Key >::iterator i = keys.begin(); i != keys.end(); ++i) { - qDebug() << "key isnull:" << i->isNull() << "isexpired:" << i->isExpired(); - qDebug() << "key numuserIds:" << i->numUserIDs(); - for (uint k = 0; k < i->numUserIDs(); ++k) { - qDebug() << "userIDs:" << i->userID(k).email(); - } - } - */ - - return keys; -} +using namespace GpgME; class ExpiryCheckerTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase() { qRegisterMetaType(); mGnupgHome = QTest::qExtractTestData(QStringLiteral("/fixtures/expirycheckertest")); qputenv("GNUPGHOME", mGnupgHome->path().toLocal8Bit()); + + // hold a reference to the key cache to avoid rebuilding while the test is running + mKeyCache = KeyCache::instance(); + // make sure that the key cache has been populated + (void)mKeyCache->keys(); } void cleanupTestCase() { + // verify that nobody else holds a reference to the key cache + QVERIFY(mKeyCache.use_count() == 1); + mKeyCache.reset(); + (void)QProcess::execute(QStringLiteral("gpgconf"), {"--kill", "all"}); mGnupgHome.reset(); qunsetenv("GNUPGHOME"); } void valid_data() { QTest::addColumn("key"); QTest::addColumn("difftime"); - QTest::newRow("neverExpire") << getKeys()[0] << -1; - - const auto backend = QGpgME::openpgp(); - Q_ASSERT(backend); - const auto job = backend->keyListJob(false); - Q_ASSERT(job); - - std::vector keys; - job->exec(QStringList() << QStringLiteral("EB85BB5FA33A75E15E944E63F231550C4F47E38E"), false, keys); - QTest::newRow("openpgp") << keys[0] << 2 * 24 * 60 * 60; - QTest::newRow("smime") << getKeys(true)[0] << 2 * 24 * 60 * 60; + QTest::newRow("neverExpire") << testKey("test@kolab.org", GpgME::OpenPGP) << -1; + QTest::newRow("openpgp") << testKey("alice@autocrypt.example", GpgME::OpenPGP) << 2 * 24 * 60 * 60; + QTest::newRow("smime") << testKey("test@example.com", GpgME::CMS) << 2 * 24 * 60 * 60; } void valid() { QFETCH(GpgME::Key, key); QFETCH(int, difftime); ExpiryChecker checker(1, 1, 1, 1); QSignalSpy spy(&checker, &ExpiryChecker::expiryMessage); checker.d->testMode = true; checker.d->difftime = difftime; checker.checkKey(key); QCOMPARE(spy.count(), 0); } void expired_data() { QTest::addColumn("key"); QTest::addColumn("msg"); QTest::addColumn("msgOwnKey"); QTest::addColumn("msgOwnSigningKey"); - const auto backend = QGpgME::openpgp(); - Q_ASSERT(backend); - const auto job = backend->keyListJob(false); - Q_ASSERT(job); - - std::vector keys; - job->exec(QStringList() << QStringLiteral("EB85BB5FA33A75E15E944E63F231550C4F47E38E"), false, keys); QTest::newRow("openpgp") - << keys[0] + << testKey("alice@autocrypt.example", GpgME::OpenPGP) << QStringLiteral( "

The OpenPGP key for

alice@autocrypt.example (KeyID 0xF231550C4F47E38E)

expired less than a day ago.

") << QStringLiteral( "

Your OpenPGP encryption key

alice@autocrypt.example (KeyID 0xF231550C4F47E38E)

expired less than a day " "ago.

") << QStringLiteral( "

Your OpenPGP signing key

alice@autocrypt.example (KeyID 0xF231550C4F47E38E)

expired less than a day " "ago.

"); - QTest::newRow("smime") << getKeys(true)[0] + QTest::newRow("smime") << testKey("test@example.com", GpgME::CMS) << QStringLiteral( "

The S/MIME certificate for

CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US (serial " "number 00D345203A186385C9)

expired less than a day ago.

") << QStringLiteral( "

Your S/MIME encryption certificate

CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US " "(serial number 00D345203A186385C9)

expired less than a day ago.

") << QStringLiteral( "

Your S/MIME signing certificate

CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US " "(serial number 00D345203A186385C9)

expired less than a day ago.

"); } void expired() { QFETCH(GpgME::Key, key); QFETCH(QString, msg); QFETCH(QString, msgOwnKey); QFETCH(QString, msgOwnSigningKey); ExpiryChecker checker(1, 1, 1, 1); checker.d->testMode = true; checker.d->difftime = -1; { QSignalSpy spy(&checker, &ExpiryChecker::expiryMessage); checker.checkKey(key); QCOMPARE(spy.count(), 1); QList arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).value().keyID(), key.keyID()); QCOMPARE(arguments.at(1).toString(), msg); QCOMPARE(arguments.at(2).value(), ExpiryChecker::OtherKeyExpired); } checker.d->alreadyWarnedFingerprints.clear(); { QSignalSpy spy(&checker, &ExpiryChecker::expiryMessage); checker.checkOwnKey(key); QCOMPARE(spy.count(), 1); QList arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).value().keyID(), key.keyID()); QCOMPARE(arguments.at(1).toString(), msgOwnKey); QCOMPARE(arguments.at(2).value(), ExpiryChecker::OwnKeyExpired); } checker.d->alreadyWarnedFingerprints.clear(); { QSignalSpy spy(&checker, &ExpiryChecker::expiryMessage); checker.checkOwnSigningKey(key); QCOMPARE(spy.count(), 1); QList arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).value().keyID(), key.keyID()); QCOMPARE(arguments.at(1).toString(), msgOwnSigningKey); QCOMPARE(arguments.at(2).value(), ExpiryChecker::OwnKeyExpired); } } void nearexpiry_data() { QTest::addColumn("key"); QTest::addColumn("msg"); QTest::addColumn("msgOwnKey"); QTest::addColumn("msgOwnSigningKey"); - const auto backend = QGpgME::openpgp(); - Q_ASSERT(backend); - const auto job = backend->keyListJob(false); - Q_ASSERT(job); - - std::vector keys; - job->exec(QStringList() << QStringLiteral("EB85BB5FA33A75E15E944E63F231550C4F47E38E"), false, keys); QTest::newRow("openpgp") - << keys[0] + << testKey("alice@autocrypt.example", GpgME::OpenPGP) << QStringLiteral( "

The OpenPGP key for

alice@autocrypt.example (KeyID 0xF231550C4F47E38E)

expires in less than 6 days.

") << QStringLiteral( "

Your OpenPGP encryption key

alice@autocrypt.example (KeyID 0xF231550C4F47E38E)

expires in less than 6 " "days.

") << QStringLiteral( "

Your OpenPGP signing key

alice@autocrypt.example (KeyID 0xF231550C4F47E38E)

expires in less than 6 " "days.

"); - QTest::newRow("smime") << getKeys(true)[0] + QTest::newRow("smime") << testKey("test@example.com", GpgME::CMS) << QStringLiteral( "

The S/MIME certificate for

CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US (serial " "number 00D345203A186385C9);

expires in less than 6 days.

") << QStringLiteral( "

Your S/MIME encryption certificate

CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US " "(serial number 00D345203A186385C9);

expires in less than 6 days.

") << QStringLiteral( "

Your S/MIME signing certificate

CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US " "(serial number 00D345203A186385C9);

expires in less than 6 days.

"); } void nearexpiry() { QFETCH(GpgME::Key, key); QFETCH(QString, msg); QFETCH(QString, msgOwnKey); QFETCH(QString, msgOwnSigningKey); { ExpiryChecker checker(1, 10, 1, 1); checker.d->testMode = true; checker.d->difftime = 5 * 24 * 3600; // 5 days QSignalSpy spy(&checker, &ExpiryChecker::expiryMessage); // Test if the correct treshold is taken checker.checkKey(key); checker.checkOwnKey(key); checker.checkOwnSigningKey(key); QCOMPARE(spy.count(), 1); QList arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).value().keyID(), key.keyID()); QCOMPARE(arguments.at(1).toString(), msg); QCOMPARE(arguments.at(2).value(), ExpiryChecker::OtherKeyNearExpiry); } { ExpiryChecker checker(10, 1, 1, 1); checker.d->testMode = true; checker.d->difftime = 5 * 24 * 3600; // 5 days QSignalSpy spy(&checker, &ExpiryChecker::expiryMessage); // Test if the correct treshold is taken checker.checkKey(key); checker.checkOwnKey(key); QCOMPARE(spy.count(), 1); QList arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).value().keyID(), key.keyID()); QCOMPARE(arguments.at(1).toString(), msgOwnKey); QCOMPARE(arguments.at(2).value(), ExpiryChecker::OwnKeyNearExpiry); } { ExpiryChecker checker(10, 1, 1, 1); checker.d->testMode = true; checker.d->difftime = 5 * 24 * 3600; // 5 days QSignalSpy spy(&checker, &ExpiryChecker::expiryMessage); // Test if the correct treshold is taken checker.checkKey(key); checker.checkOwnSigningKey(key); QCOMPARE(spy.count(), 1); QList arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).value().keyID(), key.keyID()); QCOMPARE(arguments.at(1).toString(), msgOwnSigningKey); QCOMPARE(arguments.at(2).value(), ExpiryChecker::OwnKeyNearExpiry); } } +private: + Key testKey(const char *email, Protocol protocol = UnknownProtocol) + { + const std::vector keys = KeyCache::instance()->findByEMailAddress(email); + for (const auto &key : keys) { + if (protocol == UnknownProtocol || key.protocol() == protocol) { + return key; + } + } + qWarning() << "No" << Formatting::displayName(protocol) << "test key found for" << email; + return {}; + } + private: QSharedPointer mGnupgHome; + std::shared_ptr mKeyCache; }; QTEST_MAIN(ExpiryCheckerTest) #include "expirycheckertest.moc"