From df9e47668b510e9dc92e4c98d17764ae626809dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Tue, 15 Nov 2016 15:53:26 +0100 Subject: Add mimetreeparsertest for different gpgme errors --- framework/domain/mimetreeparser/interface.cpp | 26 +++ .../domain/mimetreeparser/tests/CMakeLists.txt | 11 ++ .../domain/mimetreeparser/tests/gpgerrortest.cpp | 202 +++++++++++++++++++++ .../tests/kdepim_add_gpg_crypto_test.cmake | 2 +- 4 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 framework/domain/mimetreeparser/tests/gpgerrortest.cpp (limited to 'framework') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index 6184ae82..15e28349 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -308,6 +308,7 @@ public: void createMailMime(const MimeTreeParser::TextMessagePart::Ptr &part); void createMailMime(const MimeTreeParser::AlternativeMessagePart::Ptr &part); void createMailMime(const MimeTreeParser::HtmlMessagePart::Ptr &part); + void createMailMime(const MimeTreeParser::EncryptedMessagePart::Ptr &part); static Encryption::Ptr createEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& part); void appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr &part); @@ -359,6 +360,12 @@ void PartPrivate::createMailMime(const MimeTreeParser::MimeMessagePart::Ptr& par mMailMime->d->mNode = part->mNode; } +void PartPrivate::createMailMime(const MimeTreeParser::EncryptedMessagePart::Ptr& part) +{ + mMailMime = MailMime::Ptr(new MailMime); + mMailMime->d->mNode = part->mNode; +} + void PartPrivate::appendSubPart(Part::Ptr subpart) { subpart->d->mParent = q; @@ -763,6 +770,7 @@ public: void fillFrom(MimeTreeParser::TextMessagePart::Ptr part); void fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part); void fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part); + void createEncryptionFailBlock(const MimeTreeParser::EncryptedMessagePart::Ptr &part); SinglePart *q; QVector mContent; @@ -781,6 +789,9 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) auto sig = mp.dynamicCast(); if (enc) { d_ptr->appendEncryption(enc); + if (!enc->isDecryptable()) { + d_ptr->mContent = QByteArray(); + } const auto s = enc->subParts(); if (s.size() == 1) { sig = s[0].dynamicCast(); @@ -822,6 +833,14 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part } } +void SinglePartPrivate::createEncryptionFailBlock(const MimeTreeParser::EncryptedMessagePart::Ptr &part) +{ + mType = "plaintext"; + mContent.clear(); + mContent.append(std::make_shared(QByteArray(), q)); + q->reachParentD()->createMailMime(part); +} + SinglePart::SinglePart() : d(std::unique_ptr(new SinglePartPrivate)) { @@ -917,6 +936,13 @@ void ParserPrivate::createTree(const MimeTreeParser::MessagePart::Ptr &start, co auto subTree = std::make_shared(); if (enc) { subTree->d->appendEncryption(enc); + if (!enc->isDecryptable()) { + auto part = std::make_shared(); + part->d->createEncryptionFailBlock(enc); + part->reachParentD()->setEncryptions(subTree->d->encryptions()); + tree->d->appendSubPart(part); + return; + } } if (sig) { subTree->d->appendSignature(sig); diff --git a/framework/domain/mimetreeparser/tests/CMakeLists.txt b/framework/domain/mimetreeparser/tests/CMakeLists.txt index 7945c5a0..a23f639c 100644 --- a/framework/domain/mimetreeparser/tests/CMakeLists.txt +++ b/framework/domain/mimetreeparser/tests/CMakeLists.txt @@ -6,7 +6,18 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ) +include(ECMAddTests) + add_executable(mimetreeparsertest interfacetest.cpp) add_gpg_crypto_test(mimetreeparsertest mimetreeparsertest) qt5_use_modules(mimetreeparsertest Core Test) target_link_libraries(mimetreeparsertest mimetreeparser) + +find_package(Gpgmepp 1.7.1 CONFIG) +find_package(QGpgME 1.7.1 CONFIG) + +ecm_add_test(gpgerrortest.cpp + TEST_NAME "gpgerrortest" + NAME_PREFIX "mimetreeparser-" + LINK_LIBRARIES Qt5::Core Qt5::Test mimetreeparser Gpgmepp QGpgme +) diff --git a/framework/domain/mimetreeparser/tests/gpgerrortest.cpp b/framework/domain/mimetreeparser/tests/gpgerrortest.cpp new file mode 100644 index 00000000..aca12280 --- /dev/null +++ b/framework/domain/mimetreeparser/tests/gpgerrortest.cpp @@ -0,0 +1,202 @@ +/* + Copyright (c) 2016 Sandro Knauß + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "interface.h" +#include "interface_p.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +QByteArray readMailFromFile(const QString &mailFile) +{ + QFile file(QLatin1String(MAIL_DATA_DIR) + QLatin1Char('/') + mailFile); + file.open(QIODevice::ReadOnly); + Q_ASSERT(file.isOpen()); + return file.readAll(); +} + +void killAgent(const QString& dir) +{ + QProcess proc; + proc.setProgram(QStringLiteral("gpg-connect-agent")); + QStringList arguments; + arguments << "-S " << dir + "/S.gpg-agent"; + proc.start(); + proc.waitForStarted(); + proc.write("KILLAGENT\n"); + proc.write("BYE\n"); + proc.closeWriteChannel(); + proc.waitForFinished(); +} + +class GpgErrorTest : public QObject +{ + Q_OBJECT + +private slots: + + void testGpgConfiguredCorrectly() + { + setEnv("GNUPGHOME", GNUPGHOME); + + Parser parser(readMailFromFile("openpgp-inline-charset-encrypted.mbox")); + + auto contentPartList = parser.collectContentParts(); + QCOMPARE(contentPartList.size(), 1); + auto contentPart = contentPartList[0]; + QCOMPARE(contentPart->availableContents(), QVector() << "plaintext"); + auto contentList = contentPart->content("plaintext"); + QVERIFY(contentList[0]->content().startsWith("asdasd")); + QCOMPARE(contentList[0]->encryptions().size(), 1); + QCOMPARE(contentList[0]->signatures().size(), 1); + } + + void testNoGPGInstalled_data() + { + QTest::addColumn("mailFileName"); + + QTest::newRow("openpgp-inline-charset-encrypted") << "openpgp-inline-charset-encrypted.mbox"; + QTest::newRow("openpgp-encrypted-attachment-and-non-encrypted-attachment") << "openpgp-encrypted-attachment-and-non-encrypted-attachment.mbox"; + QTest::newRow("smime-encrypted") << "smime-encrypted.mbox"; + } + + void testNoGPGInstalled() + { + QFETCH(QString, mailFileName); + + setEnv("PATH", "/nonexististing"); + setGpgMEfname("/nonexisting/gpg", ""); + + Parser parser(readMailFromFile(mailFileName)); + auto contentPartList = parser.collectContentParts(); + + QCOMPARE(contentPartList.size(), 1); + auto contentPart = contentPartList[0]; + QCOMPARE(contentPart->availableContents(), QVector() << "plaintext"); + auto contentList = contentPart->content("plaintext"); + QCOMPARE(contentList[0]->encryptions().size(), 1); + QCOMPARE(contentList[0]->signatures().size(), 0); + QVERIFY(contentList[0]->content().isEmpty()); + } + + void testGpgIncorrectGPGHOME_data() + { + QTest::addColumn("mailFileName"); + + QTest::newRow("openpgp-inline-charset-encrypted") << "openpgp-inline-charset-encrypted.mbox"; + QTest::newRow("openpgp-encrypted-attachment-and-non-encrypted-attachment") << "openpgp-encrypted-attachment-and-non-encrypted-attachment.mbox"; + QTest::newRow("smime-encrypted") << "smime-encrypted.mbox"; + } + + void testGpgIncorrectGPGHOME() + { + QFETCH(QString, mailFileName); + setEnv("GNUPGHOME", QByteArray(GNUPGHOME) + QByteArray("noexist")); + + Parser parser(readMailFromFile(mailFileName)); + + auto contentPartList = parser.collectContentParts(); + QCOMPARE(contentPartList.size(), 1); + auto contentPart = contentPartList[0]; + QCOMPARE(contentPart->availableContents(), QVector() << "plaintext"); + auto contentList = contentPart->content("plaintext"); + QCOMPARE(contentList[0]->encryptions().size(), 1); + QCOMPARE(contentList[0]->signatures().size(), 0); + QVERIFY(contentList[0]->content().isEmpty()); + } + +public Q_SLOTS: + void init() + { + mResetGpgmeEngine = false; + mModifiedEnv.clear(); + { + QGpgME::openpgp(); // We need to intialize it, otherwise ctx will be a nullpointer + const GpgME::Context *ctx = GpgME::Context::createForProtocol(GpgME::Protocol::OpenPGP); + const auto engineinfo = ctx->engineInfo(); + mGpgmeEngine_fname = engineinfo.fileName(); + } + mEnv = QProcessEnvironment::systemEnvironment(); + unsetEnv("GNUPGHOME"); + } + + void cleanup() + { + QCoreApplication::sendPostedEvents(); + + const QString &gnupghome = qgetenv("GNUPGHOME"); + if (!gnupghome.isEmpty()) { + killAgent(gnupghome); + } + + resetGpgMfname(); + resetEnv(); + } +private: + void unsetEnv(const QByteArray &name) + { + mModifiedEnv << name; + unsetenv(name); + } + + void setEnv(const QByteArray &name, const QByteArray &value) + { + mModifiedEnv << name; + setenv(name, value , 1); + } + + void resetEnv() + { + foreach(const auto &i, mModifiedEnv) { + if (mEnv.contains(i)) { + setenv(i, mEnv.value(i).toUtf8(), 1); + } else { + unsetenv(i); + } + } + } + + void resetGpgMfname() + { + if (mResetGpgmeEngine) { + gpgme_set_engine_info (GPGME_PROTOCOL_OpenPGP, mGpgmeEngine_fname, NULL); + } + } + + void setGpgMEfname(const QByteArray &fname, const QByteArray &homedir) + { + mResetGpgmeEngine = true; + gpgme_set_engine_info (GPGME_PROTOCOL_OpenPGP, fname, homedir); + } + + QSet mModifiedEnv; + QProcessEnvironment mEnv; + bool mResetGpgmeEngine; + QByteArray mGpgmeEngine_fname; +}; + +QTEST_GUILESS_MAIN(GpgErrorTest) +#include "gpgerrortest.moc" diff --git a/framework/domain/mimetreeparser/tests/kdepim_add_gpg_crypto_test.cmake b/framework/domain/mimetreeparser/tests/kdepim_add_gpg_crypto_test.cmake index 17078202..281752a7 100644 --- a/framework/domain/mimetreeparser/tests/kdepim_add_gpg_crypto_test.cmake +++ b/framework/domain/mimetreeparser/tests/kdepim_add_gpg_crypto_test.cmake @@ -4,7 +4,7 @@ # For details see the accompanying COPYING-CMAKE-SCRIPTS file. set( GNUPGHOME ${CMAKE_BINARY_DIR}/framework/domain/mimetreeparser/tests/gnupg_home ) -add_definitions( -DGNUPGHOME="\\"${GNUPGHOME}\\"" ) +add_definitions( -DGNUPGHOME="${GNUPGHOME}" ) macro (ADD_GPG_CRYPTO_TEST _target _testname) if (UNIX) -- cgit v1.2.3