File indexing completed on 2024-12-22 05:05:17
0001 // SPDX-FileCopyrightText: 2016 Sandro Knauß <knauss@kolabsystems.com> 0002 // SPDX-License-Identifier: LGPL-2.0-or-later 0003 0004 #include <MimeTreeParserCore/ObjectTreeParser> 0005 0006 #include <gpgme.h> 0007 0008 #include <QProcess> 0009 #include <QTest> 0010 0011 QByteArray readMailFromFile(const QString &mailFile) 0012 { 0013 QFile file(QLatin1StringView(MAIL_DATA_DIR) + QLatin1Char('/') + mailFile); 0014 file.open(QIODevice::ReadOnly); 0015 Q_ASSERT(file.isOpen()); 0016 return file.readAll(); 0017 } 0018 0019 void killAgent(const QString &dir) 0020 { 0021 QProcess proc; 0022 proc.setProgram(QStringLiteral("gpg-connect-agent")); 0023 QStringList arguments; 0024 arguments << QStringLiteral("-S ") << dir + QStringLiteral("/S.gpg-agent"); 0025 proc.start(); 0026 proc.waitForStarted(); 0027 proc.write("KILLAGENT\n"); 0028 proc.write("BYE\n"); 0029 proc.closeWriteChannel(); 0030 proc.waitForFinished(); 0031 } 0032 0033 class GpgErrorTest : public QObject 0034 { 0035 Q_OBJECT 0036 0037 private Q_SLOTS: 0038 0039 void testGpgConfiguredCorrectly() 0040 { 0041 setEnv("GNUPGHOME", GNUPGHOME); 0042 0043 MimeTreeParser::ObjectTreeParser otp; 0044 otp.parseObjectTree(readMailFromFile(QStringLiteral("openpgp-inline-charset-encrypted.mbox"))); 0045 otp.print(); 0046 otp.decryptAndVerify(); 0047 otp.print(); 0048 auto partList = otp.collectContentParts(); 0049 QCOMPARE(partList.size(), 1); 0050 auto part = partList[0]; 0051 QVERIFY(bool(part)); 0052 0053 QVERIFY(part->text().startsWith(QStringLiteral("asdasd"))); 0054 QCOMPARE(part->encryptions().size(), 1); 0055 auto enc = part->encryptions()[0]; 0056 QCOMPARE(enc->error(), MimeTreeParser::MessagePart::NoError); 0057 // QCOMPARE((int) enc->recipients().size(), 2); 0058 } 0059 0060 void testNoGPGInstalled_data() 0061 { 0062 QTest::addColumn<QString>("mailFileName"); 0063 0064 QTest::newRow("openpgp-inline-charset-encrypted") << "openpgp-inline-charset-encrypted.mbox"; 0065 QTest::newRow("openpgp-encrypted-attachment-and-non-encrypted-attachment") << "openpgp-encrypted-attachment-and-non-encrypted-attachment.mbox"; 0066 QTest::newRow("smime-encrypted") << "smime-encrypted.mbox"; 0067 } 0068 0069 void testNoGPGInstalled() 0070 { 0071 QFETCH(QString, mailFileName); 0072 0073 setEnv("PATH", "/nonexististing"); 0074 setGpgMEfname("/nonexisting/gpg", ""); 0075 0076 MimeTreeParser::ObjectTreeParser otp; 0077 otp.parseObjectTree(readMailFromFile(mailFileName)); 0078 otp.print(); 0079 otp.decryptAndVerify(); 0080 otp.print(); 0081 auto partList = otp.collectContentParts(); 0082 QCOMPARE(partList.size(), 1); 0083 auto part = partList[0].dynamicCast<MimeTreeParser::MessagePart>(); 0084 QVERIFY(bool(part)); 0085 0086 QCOMPARE(part->encryptions().size(), 1); 0087 QVERIFY(part->text().isEmpty()); 0088 auto enc = part->encryptions()[0]; 0089 QCOMPARE(enc->error(), MimeTreeParser::MessagePart::NoKeyError); 0090 } 0091 0092 void testGpgIncorrectGPGHOME_data() 0093 { 0094 QTest::addColumn<QString>("mailFileName"); 0095 0096 QTest::newRow("openpgp-inline-charset-encrypted") << "openpgp-inline-charset-encrypted.mbox"; 0097 QTest::newRow("openpgp-encrypted-attachment-and-non-encrypted-attachment") << "openpgp-encrypted-attachment-and-non-encrypted-attachment.mbox"; 0098 QTest::newRow("smime-encrypted") << "smime-encrypted.mbox"; 0099 } 0100 0101 void testGpgIncorrectGPGHOME() 0102 { 0103 QFETCH(QString, mailFileName); 0104 setEnv("GNUPGHOME", QByteArray(GNUPGHOME) + QByteArray("noexist")); 0105 0106 MimeTreeParser::ObjectTreeParser otp; 0107 otp.parseObjectTree(readMailFromFile(mailFileName)); 0108 otp.print(); 0109 otp.decryptAndVerify(); 0110 otp.print(); 0111 auto partList = otp.collectContentParts(); 0112 QCOMPARE(partList.size(), 1); 0113 auto part = partList[0].dynamicCast<MimeTreeParser::MessagePart>(); 0114 QVERIFY(bool(part)); 0115 0116 QCOMPARE(part->encryptions().size(), 1); 0117 QCOMPARE(part->signatures().size(), 0); 0118 QVERIFY(part->text().isEmpty()); 0119 auto enc = part->encryptions()[0]; 0120 QVERIFY(enc->isNoSecKey()); 0121 // QCOMPARE((int) enc->recipients().size(), 2); 0122 } 0123 0124 public Q_SLOTS: 0125 void init() 0126 { 0127 mResetGpgmeEngine = false; 0128 mModifiedEnv.clear(); 0129 { 0130 gpgme_check_version(nullptr); 0131 gpgme_ctx_t ctx = nullptr; 0132 gpgme_new(&ctx); 0133 gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); 0134 gpgme_engine_info_t info = gpgme_ctx_get_engine_info(ctx); 0135 mGpgmeEngine_fname = info->file_name; 0136 gpgme_release(ctx); 0137 } 0138 mEnv = QProcessEnvironment::systemEnvironment(); 0139 unsetEnv("GNUPGHOME"); 0140 } 0141 0142 void cleanup() 0143 { 0144 QCoreApplication::sendPostedEvents(); 0145 0146 const QString &gnupghome = QString::fromUtf8(qgetenv("GNUPGHOME")); 0147 if (!gnupghome.isEmpty()) { 0148 killAgent(gnupghome); 0149 } 0150 0151 resetGpgMfname(); 0152 resetEnv(); 0153 } 0154 0155 private: 0156 void unsetEnv(const QByteArray &name) 0157 { 0158 mModifiedEnv << name; 0159 qunsetenv(name.data()); 0160 } 0161 0162 void setEnv(const QByteArray &name, const QByteArray &value) 0163 { 0164 mModifiedEnv << name; 0165 qputenv(name.data(), value); 0166 } 0167 0168 void resetEnv() 0169 { 0170 for (const auto &i : std::as_const(mModifiedEnv)) { 0171 const auto env = i.data(); 0172 if (mEnv.contains(QString::fromUtf8(i))) { 0173 qputenv(env, mEnv.value(QString::fromUtf8(i)).toUtf8()); 0174 } else { 0175 qunsetenv(env); 0176 } 0177 } 0178 } 0179 0180 void resetGpgMfname() 0181 { 0182 if (mResetGpgmeEngine) { 0183 gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, mGpgmeEngine_fname.data(), nullptr); 0184 } 0185 } 0186 0187 void setGpgMEfname(const QByteArray &fname, const QByteArray &homedir) 0188 { 0189 mResetGpgmeEngine = true; 0190 gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, fname.data(), homedir.data()); 0191 } 0192 0193 QSet<QByteArray> mModifiedEnv; 0194 QProcessEnvironment mEnv; 0195 bool mResetGpgmeEngine; 0196 QByteArray mGpgmeEngine_fname; 0197 }; 0198 0199 QTEST_GUILESS_MAIN(GpgErrorTest) 0200 #include "gpgerrortest.moc"