Commit 84ff7e94 authored by Sandro Knauß's avatar Sandro Knauß
Browse files

[messagecomposer]: Implement protected headers for SignEncryptJob.

Test Plan: run autotests.

Subscribers: kde-pim

Tags: #kde_pim

Differential Revision: https://phabricator.kde.org/D28450
parent 93a16b4b
/*
Copyright (C) 2009 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
Copyright (c) 2009 Leo Franchi <lfranchi@kde.org>
Copyright (C) 2020 Sandro Knauß <sknauss@kde.org>
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
......@@ -31,17 +30,14 @@
#include <KJob>
#include <MessageComposer/Composer>
#include <MessageComposer/EncryptJob>
#include <MessageComposer/SignEncryptJob>
#include <MessageComposer/MainTextJob>
#include <MessageComposer/SignJob>
#include <MessageComposer/TransparentJob>
#include <MessageComposer/GlobalPart>
#include <MessageComposer/TextPart>
#include <MimeTreeParser/NodeHelper>
#include <setupenv.h>
#include <MessageCore/NodeHelper>
QTEST_MAIN(SignEncryptTest)
using namespace MessageComposer;
......@@ -51,100 +47,153 @@ void SignEncryptTest::initTestCase()
Test::setupEnv();
}
void SignEncryptTest::testContent_data()
{
QTest::addColumn<int>("cryptoMessageFormat");
QTest::addColumn<QString>("error");
QTest::newRow("OpenPGPMimeFormat") << (int) Kleo::OpenPGPMIMEFormat << QString();
QTest::newRow("InlineOpenPGPFormat") << (int) Kleo::InlineOpenPGPFormat << QString();
QTest::newRow("SMIMEFormat") << (int) Kleo::SMIMEFormat << QStringLiteral("Not implemented");
QTest::newRow("SMIMEOpaqueFormat") << (int) Kleo::SMIMEOpaqueFormat << QStringLiteral("Not implemented");
}
void SignEncryptTest::testContent()
{
QFETCH(int, cryptoMessageFormat);
QFETCH(QString, error);
std::vector< GpgME::Key > keys = Test::getKeys();
const QString data(QString::fromLocal8Bit("one flew over the cuckoo's nest"));
Composer *composer = new Composer;
SignJob *sJob = new SignJob(composer);
EncryptJob *eJob = new EncryptJob(composer);
Composer composer;
QVERIFY(composer);
QVERIFY(sJob);
QVERIFY(eJob);
const QVector<QByteArray> charsets = {"us-ascii"};
composer.globalPart()->setCharsets(charsets);
QVector<QByteArray> charsets;
charsets << "us-ascii";
composer->globalPart()->setCharsets(charsets);
TextPart *part = new TextPart(this);
part->setWordWrappingEnabled(false);
part->setCleanPlainText(QStringLiteral("one flew over the cuckoo's nest"));
TextPart part;
part.setWordWrappingEnabled(false);
part.setCleanPlainText(data);
MainTextJob *mainTextJob = new MainTextJob(part, composer);
auto mainTextJob = new MainTextJob(&part, &composer);
auto seJob = new SignEncryptJob(&composer);
QVERIFY(composer);
QVERIFY(mainTextJob);
VERIFYEXEC(mainTextJob);
QStringList recipients;
recipients << QString::fromLocal8Bit("test@kolab.org");
const QStringList recipients = {QString::fromLocal8Bit("test@kolab.org")};
seJob->setContent(mainTextJob->content());
seJob->setSigningKeys(keys);
seJob->setCryptoMessageFormat((Kleo::CryptoMessageFormat)cryptoMessageFormat);
seJob->setRecipients(recipients);
seJob->setEncryptionKeys(keys);
sJob->setContent(mainTextJob->content());
sJob->setSigningKeys(keys);
sJob->setCryptoMessageFormat(Kleo::OpenPGPMIMEFormat);
if (!error.isEmpty()) {
QVERIFY(!seJob->exec());
QCOMPARE(seJob->errorString(), error);
return;
}
eJob->setCryptoMessageFormat(Kleo::OpenPGPMIMEFormat);
eJob->setRecipients(recipients);
eJob->setEncryptionKeys(keys);
VERIFYEXEC(seJob);
KMime::Content *result = seJob->content();
QVERIFY(result);
result->assemble();
eJob->appendSubjob(sJob);
ComposerTestUtil::verifySignatureAndEncryption(
result,
data.toUtf8(),
(Kleo::CryptoMessageFormat)cryptoMessageFormat,
false,
true);
VERIFYEXEC(eJob);
delete result;
}
void SignEncryptTest::testContentSubjobChained()
{
std::vector< GpgME::Key > keys = MessageComposer::Test::getKeys();
KMime::Content *result = eJob->content();
const QByteArray data(QString::fromLocal8Bit("one flew over the cuckoo's nest").toUtf8());
KMime::Message skeletonMessage;
auto content = new KMime::Content;
content->contentType(true)->setMimeType("text/plain");
content->setBody(data);
auto tJob = new TransparentJob;
tJob->setContent(content);
const QStringList recipients = {QString::fromLocal8Bit("test@kolab.org")};
Composer composer;
auto seJob = new SignEncryptJob(&composer);
seJob->setSigningKeys(keys);
seJob->setCryptoMessageFormat(Kleo::OpenPGPMIMEFormat);
seJob->setRecipients(recipients);
seJob->setEncryptionKeys(keys);
seJob->setSkeletonMessage(&skeletonMessage);
seJob->appendSubjob(tJob);
VERIFYEXEC(seJob);
KMime::Content *result = seJob->content();
QVERIFY(result);
result->assemble();
qDebug() << "result:" << result->encodedContent();
ComposerTestUtil::verifySignatureAndEncryption(
result,
QString::fromLocal8Bit("one flew over the cuckoo's nest").toUtf8(),
Kleo::OpenPGPMIMEFormat);
data,
Kleo::OpenPGPMIMEFormat,
false,
true);
delete result;
}
void SignEncryptTest::testHeaders()
{
std::vector< GpgME::Key > keys = Test::getKeys();
Composer *composer = new Composer;
SignJob *sJob = new SignJob(composer);
EncryptJob *eJob = new EncryptJob(composer);
Composer composer;
auto seJob = new SignEncryptJob(&composer);
QVERIFY(composer);
QVERIFY(sJob);
QVERIFY(eJob);
QVERIFY(seJob);
QByteArray data(QString::fromLocal8Bit("one flew over the cuckoo's nest").toUtf8());
KMime::Content *content = new KMime::Content;
const QByteArray data(QString::fromLocal8Bit("one flew over the cuckoo's nest").toUtf8());
auto content = new KMime::Content;
content->setBody(data);
QStringList recipients;
recipients << QString::fromLocal8Bit("test@kolab.org");
const QStringList recipients = {QString::fromLocal8Bit("test@kolab.org")};
sJob->setContent(content);
sJob->setSigningKeys(keys);
sJob->setCryptoMessageFormat(Kleo::OpenPGPMIMEFormat);
seJob->setContent(content);
seJob->setSigningKeys(keys);
seJob->setCryptoMessageFormat(Kleo::OpenPGPMIMEFormat);
seJob->setRecipients(recipients);
seJob->setEncryptionKeys(keys);
eJob->setCryptoMessageFormat(Kleo::OpenPGPMIMEFormat);
eJob->setRecipients(recipients);
eJob->setEncryptionKeys(keys);
VERIFYEXEC(seJob);
eJob->appendSubjob(sJob);
VERIFYEXEC(eJob);
KMime::Content *result = eJob->content();
KMime::Content *result = seJob->content();
QVERIFY(result);
result->assemble();
QByteArray mimeType("multipart/encrypted");
QByteArray charset("ISO-8859-1");
QFile f(QStringLiteral("test"));
QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
const QByteArray encodedContent(result->encodedContent());
f.write(encodedContent);
if (!encodedContent.endsWith('\n')) {
f.write("\n");
}
f.close();
QVERIFY(result->contentType(false));
QCOMPARE(result->contentType()->mimeType(), mimeType);
QCOMPARE(result->contentType()->charset(), charset);
QCOMPARE(result->contentType()->mimeType(), "multipart/encrypted");
QCOMPARE(result->contentType()->charset(), "ISO-8859-1");
QCOMPARE(result->contentType()->parameter(QString::fromLocal8Bit("protocol")), QString::fromLocal8Bit("application/pgp-encrypted"));
QCOMPARE(result->contentTransferEncoding()->encoding(), KMime::Headers::CE7Bit);
delete result;
}
/*
Copyright (C) 2009 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
Copyright (c) 2009 Leo Franchi <lfranchi@kde.org>
Copyright (C) 2020 Sandro Knauß <sknauss@kde.org>
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
......@@ -31,7 +30,9 @@ public Q_SLOTS:
void initTestCase();
private Q_SLOTS:
void testContent_data();
void testContent();
void testContentSubjobChained();
void testHeaders();
};
......
......@@ -274,6 +274,7 @@ QList<ContentJobBase *> ComposerPrivate::createEncryptJobs(ContentJobBase *conte
seJob->setSigningKeys(signers);
seJob->setEncryptionKeys(recipients.second);
seJob->setRecipients(recipients.first);
seJob->setSkeletonMessage(skeletonMessage);
subJob = seJob;
} else {
......
......@@ -21,7 +21,7 @@
#include "job/signencryptjob.h"
#include "contentjobbase_p.h"
#include "utils/util.h"
#include "job/protectedheaders.h"
#include "utils/util_p.h"
#include <Libkleo/Enum>
......@@ -54,6 +54,10 @@ public:
QStringList recipients;
Kleo::CryptoMessageFormat format;
KMime::Content *content = nullptr;
KMime::Message *skeletonMessage = nullptr;
bool protectedHeaders = true;
bool protectedHeadersObvoscate = false;
// copied from messagecomposer.cpp
bool binaryHint(Kleo::CryptoMessageFormat f)
......@@ -130,6 +134,27 @@ void SignEncryptJob::setRecipients(const QStringList &recipients)
d->recipients = recipients;
}
void SignEncryptJob::setSkeletonMessage(KMime::Message *skeletonMessage)
{
Q_D(SignEncryptJob);
d->skeletonMessage = skeletonMessage;
}
void SignEncryptJob::setProtectedHeaders(bool protectedHeaders)
{
Q_D(SignEncryptJob);
d->protectedHeaders = protectedHeaders;
}
void SignEncryptJob::setProtectedHeadersObvoscate(bool protectedHeadersObvoscate)
{
Q_D(SignEncryptJob);
d->protectedHeadersObvoscate = protectedHeadersObvoscate;
}
QStringList SignEncryptJob::recipients() const
{
Q_D(const SignEncryptJob);
......@@ -144,6 +169,48 @@ std::vector<GpgME::Key> SignEncryptJob::encryptionKeys() const
return d->encKeys;
}
void SignEncryptJob::doStart()
{
Q_D(SignEncryptJob);
Q_ASSERT(d->resultContent == nullptr); // Not processed before.
if (d->protectedHeaders && d->skeletonMessage && d->format & Kleo::OpenPGPMIMEFormat) {
ProtectedHeadersJob *pJob = new ProtectedHeadersJob;
pJob->setContent(d->content);
pJob->setSkeletonMessage(d->skeletonMessage);
pJob->setObvoscate(d->protectedHeadersObvoscate);
QObject::connect(pJob, &ProtectedHeadersJob::finished, this, [d, pJob](KJob *job) {
if (job->error()) {
return;
}
d->content = pJob->content();
});
appendSubjob(pJob);
}
ContentJobBase::doStart();
}
void SignEncryptJob::slotResult(KJob *job)
{
Q_D(SignEncryptJob);
if (error()) {
ContentJobBase::slotResult(job);
return;
}
if (subjobs().size() == 2) {
auto pjob = static_cast<ProtectedHeadersJob *>(subjobs().last());
if (pjob) {
auto cjob = dynamic_cast<ContentJobBase *>(job);
Q_ASSERT(cjob);
pjob->setContent(cjob->content());
}
}
ContentJobBase::slotResult(job);
}
void SignEncryptJob::process()
{
Q_D(SignEncryptJob);
......
......@@ -57,12 +57,19 @@ public:
void setEncryptionKeys(const std::vector<GpgME::Key> &keys) override;
void setRecipients(const QStringList &rec) override;
void setSkeletonMessage(KMime::Message *skeletonMessage);
void setProtectedHeaders(bool protectedHeaders);
void setProtectedHeadersObvoscate(bool protectedHeadersObvoscate);
Q_REQUIRED_RESULT std::vector<GpgME::Key> encryptionKeys() const override;
Q_REQUIRED_RESULT QStringList recipients() const override;
Q_REQUIRED_RESULT KMime::Content *origContent();
protected Q_SLOTS:
void doStart() override;
void slotResult(KJob *job) override;
void process() override;
private:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment