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