diff --git a/messageviewer/src/viewer/messagepart.h b/messageviewer/src/viewer/messagepart.h --- a/messageviewer/src/viewer/messagepart.h +++ b/messageviewer/src/viewer/messagepart.h @@ -179,22 +179,25 @@ { public: typedef QSharedPointer Ptr; - TextMessagePart(MessageViewer::ObjectTreeParser* otp, KMime::Content* node, bool drawFrame, bool showLink); + TextMessagePart(MessageViewer::ObjectTreeParser* otp, KMime::Content* node, bool drawFrame, bool showLink, bool decryptMessage); virtual ~TextMessagePart(); QString text() const Q_DECL_OVERRIDE; void html(bool decorate) Q_DECL_OVERRIDE; KMMsgSignatureState signatureState() const; KMMsgEncryptionState encryptionState() const; + bool decryptMessage() const; private: + void parseContent(); KMime::Content* mNode; KMMsgSignatureState mSignatureState; KMMsgEncryptionState mEncryptionState; QVector mBlocks; bool mDrawFrame; bool mShowLink; + bool mDecryptMessage; }; class HtmlMessagePart : public MessagePart diff --git a/messageviewer/src/viewer/messagepart.cpp b/messageviewer/src/viewer/messagepart.cpp --- a/messageviewer/src/viewer/messagepart.cpp +++ b/messageviewer/src/viewer/messagepart.cpp @@ -24,10 +24,12 @@ #include "converthtmltoplaintext.h" #include "htmlquotecolorer.h" #include "csshelper.h" +#include "cryptohelper.h" #include #include +#include #include #include @@ -342,25 +344,114 @@ //-----TextMessageBlock---------------------- -TextMessagePart::TextMessagePart(ObjectTreeParser* otp, KMime::Content* node, bool drawFrame, bool showLink) +TextMessagePart::TextMessagePart(ObjectTreeParser* otp, KMime::Content* node, bool drawFrame, bool showLink, bool decryptMessage) : MessagePart(otp, QString()) , mNode(node) , mDrawFrame(drawFrame) , mShowLink(showLink) + , mDecryptMessage(decryptMessage) { if (!mNode) { qCWarning(MESSAGEVIEWER_LOG) << "not a valid node"; return; } - - mBlocks = mOtp->writeBodyStr2(mNode->decodedContent(), mOtp->codecFor(mNode), NodeHelper::fromAsString(mNode), mSignatureState, mEncryptionState); + parseContent(); } TextMessagePart::~TextMessagePart() { } +bool TextMessagePart::decryptMessage() const +{ + return mDecryptMessage; +} + +void TextMessagePart::parseContent() +{ + const auto aCodec = mOtp->codecFor(mNode); + const QString &fromAddress = NodeHelper::fromAsString(mNode); + mSignatureState = KMMsgNotSigned; + mEncryptionState = KMMsgNotEncrypted; + const auto blocks = prepareMessageForDecryption(mNode->decodedContent()); + + const auto cryptProto = Kleo::CryptoBackendFactory::instance()->openpgp(); + + if (!blocks.isEmpty()) { + + if (blocks.count() > 1 || blocks.at(0).type() != MessageViewer::NoPgpBlock) { + mOtp->setCryptoProtocol(cryptProto); + } + + + QString htmlStr; + QString plainTextStr; + + /* The (overall) signature/encrypted status is broken + * if one unencrypted part is at the beginning or in the middle + * because mailmain adds an unencrypted part at the end this should not break the overall status + * + * That's why we first set the tmp status and if one crypted/signed block comes afterwards, than + * the status is set to unencryped + */ + bool fullySignedOrEncrypted = true; + bool fullySignedOrEncryptedTmp = true; + + Q_FOREACH (const auto &block, blocks) { + + if (!fullySignedOrEncryptedTmp) { + fullySignedOrEncrypted = false; + } + + if (block.type() == NoPgpBlock && !block.text().trimmed().isEmpty()) { + fullySignedOrEncryptedTmp = false; + mBlocks.append(MessagePart::Ptr(new MessagePart(mOtp, aCodec->toUnicode(block.text())))); + } else if (block.type() == PgpMessageBlock) { + CryptoMessagePart::Ptr mp(new CryptoMessagePart(mOtp, QString(), cryptProto, fromAddress, 0)); + mBlocks.append(mp); + if (!decryptMessage()) { + continue; + } + mp->startDecryption(block.text(), aCodec); + if (mp->partMetaData()->inProgress) { + continue; + } + } else if (block.type() == ClearsignedBlock) { + CryptoMessagePart::Ptr mp(new CryptoMessagePart(mOtp, QString(), cryptProto, fromAddress, 0)); + mBlocks.append(mp); + mp->startVerification(block.text(), aCodec); + } else { + continue; + } + + const PartMetaData *messagePart(mBlocks.last()->partMetaData()); + + if (!messagePart->isEncrypted && !messagePart->isSigned && !block.text().trimmed().isEmpty()) { + mBlocks.last()->setText(aCodec->toUnicode(block.text())); + } + + if (messagePart->isEncrypted) { + mEncryptionState = KMMsgPartiallyEncrypted; + } + + if (messagePart->isSigned) { + mSignatureState = KMMsgPartiallySigned; + } + } + + //Do we have an fully Signed/Encrypted Message? + if (fullySignedOrEncrypted) { + if (mSignatureState == KMMsgPartiallySigned) { + mSignatureState = KMMsgFullySigned; + } + if (mEncryptionState == KMMsgPartiallyEncrypted) { + mEncryptionState = KMMsgFullyEncrypted; + } + } + } +} + void TextMessagePart::html(bool decorate) { HTMLBlock::Ptr block; diff --git a/messageviewer/src/viewer/objecttreeparser.h b/messageviewer/src/viewer/objecttreeparser.h --- a/messageviewer/src/viewer/objecttreeparser.h +++ b/messageviewer/src/viewer/objecttreeparser.h @@ -410,11 +410,6 @@ MessagePart::Ptr processApplicationPkcs7MimeSubtype(KMime::Content *node, ProcessResult &result); - void writeBodyString(const QByteArray &bodyString, - const QString &fromAddress, - const QTextCodec *codec, - ProcessResult &result, bool decorate); - void writePartIcon(KMime::Content *msgPart, bool inlineImage = false); QString sigStatusToString(const Kleo::CryptoBackend::Protocol *cryptProto, @@ -428,18 +423,6 @@ KMime::Content *node = 0); QString writeSigstatFooter(PartMetaData &part); - void writeBodyStr(const QByteArray &bodyString, - const QTextCodec *aCodec, - const QString &fromAddress, - KMMsgSignatureState &inlineSignatureState, - KMMsgEncryptionState &inlineEncryptionState, - bool decorate); - - QVector writeBodyStr2(const QByteArray &aStr, const QTextCodec *aCodec, - const QString &fromAddress, - KMMsgSignatureState &inlineSignatureState, - KMMsgEncryptionState &inlineEncryptionState); - bool isMailmanMessage(KMime::Content *curNode); public: diff --git a/messageviewer/src/viewer/objecttreeparser.cpp b/messageviewer/src/viewer/objecttreeparser.cpp --- a/messageviewer/src/viewer/objecttreeparser.cpp +++ b/messageviewer/src/viewer/objecttreeparser.cpp @@ -467,7 +467,7 @@ writePartIcon(node, true); } else { mNodeHelper->setNodeDisplayedEmbedded(node, true); - const auto mp = TextMessagePart::Ptr(new TextMessagePart(this, node, false, false)); + const auto mp = TextMessagePart::Ptr(new TextMessagePart(this, node, false, false, mSource->decryptMessage())); result.setInlineSignatureState(mp->signatureState()); result.setInlineEncryptionState(mp->encryptionState()); return mp; @@ -927,7 +927,7 @@ //if (!isMailmanMessage(curNode) || // !processMailmanMessage(curNode)) { - TextMessagePart::Ptr mp(new TextMessagePart(this, curNode, bDrawFrame, !fileName.isEmpty())); + TextMessagePart::Ptr mp(new TextMessagePart(this, curNode, bDrawFrame, !fileName.isEmpty(), mSource->decryptMessage())); result.setInlineSignatureState(mp->signatureState()); result.setInlineEncryptionState(mp->encryptionState()); @@ -1273,21 +1273,6 @@ return mp; } -void ObjectTreeParser::writeBodyString(const QByteArray &bodyString, - const QString &fromAddress, - const QTextCodec *codec, - ProcessResult &result, - bool decorate) -{ - assert(codec); - KMMsgSignatureState inlineSignatureState = result.inlineSignatureState(); - KMMsgEncryptionState inlineEncryptionState = result.inlineEncryptionState(); - writeBodyStr(bodyString, codec, fromAddress, - inlineSignatureState, inlineEncryptionState, decorate); - result.setInlineSignatureState(inlineSignatureState); - result.setInlineEncryptionState(inlineEncryptionState); -} - void ObjectTreeParser::writePartIcon(KMime::Content *msgPart, bool inlineImage) { if (!htmlWriter() || !msgPart) { @@ -2214,120 +2199,6 @@ } } -//----------------------------------------------------------------------------- -QVector ObjectTreeParser::writeBodyStr2(const QByteArray &aStr, const QTextCodec *aCodec, - const QString &fromAddress, - KMMsgSignatureState &inlineSignatureState, - KMMsgEncryptionState &inlineEncryptionState) -{ - inlineSignatureState = KMMsgNotSigned; - inlineEncryptionState = KMMsgNotEncrypted; - QList blocks = prepareMessageForDecryption(aStr); - - QVector mpl; - - if (!blocks.isEmpty()) { - - if (blocks.count() > 1 || blocks.at(0).type() != MessageViewer::NoPgpBlock) { - const Kleo::CryptoBackend::Protocol *cryptProto = Kleo::CryptoBackendFactory::instance()->openpgp(); - setCryptoProtocol(cryptProto); - } - - QString htmlStr; - QString plainTextStr; - - /* The (overall) signature/encrypted status is broken - * if one unencrypted part is at the beginning or in the middle - * because mailmain adds an unencrypted part at the end this should not break the overall status - * - * That's why we first set the tmp status and if one crypted/signed block comes afterwards, than - * the status is set to unencryped - */ - bool fullySignedOrEncrypted = true; - bool fullySignedOrEncryptedTmp = true; - - Q_FOREACH (const Block &block, blocks) { - - if (!fullySignedOrEncryptedTmp) { - fullySignedOrEncrypted = false; - } - - if (block.type() == NoPgpBlock && !block.text().trimmed().isEmpty()) { - fullySignedOrEncryptedTmp = false; - mpl.append(MessagePart::Ptr(new MessagePart(this, aCodec->toUnicode(block.text())))); - } else if (block.type() == PgpMessageBlock) { - CryptoMessagePart::Ptr mp(new CryptoMessagePart(this, QString(), cryptoProtocol(), fromAddress, 0)); - mpl.append(mp); - if (!mSource->decryptMessage()) { - continue; - } - mp->startDecryption(block.text(), aCodec); - if (mp->partMetaData()->inProgress) { - continue; - } - } else if (block.type() == ClearsignedBlock) { - CryptoMessagePart::Ptr mp(new CryptoMessagePart(this, QString(), cryptoProtocol(), fromAddress, 0)); - mpl.append(mp); - mp->startVerification(block.text(), aCodec); - } else { - continue; - } - - const PartMetaData *messagePart(mpl.last()->partMetaData()); - - if (!messagePart->isEncrypted && !messagePart->isSigned && !block.text().trimmed().isEmpty()) { - mpl.last()->setText(aCodec->toUnicode(block.text())); - } - - if (messagePart->isEncrypted) { - inlineEncryptionState = KMMsgPartiallyEncrypted; - } - - if (messagePart->isSigned) { - inlineSignatureState = KMMsgPartiallySigned; - } - } - - //Do we have an fully Signed/Encrypted Message? - if (fullySignedOrEncrypted) { - if (inlineSignatureState == KMMsgPartiallySigned) { - inlineSignatureState = KMMsgFullySigned; - } - if (inlineEncryptionState == KMMsgPartiallyEncrypted) { - inlineEncryptionState = KMMsgFullyEncrypted; - } - } - } - return mpl; -} - -void ObjectTreeParser::writeBodyStr(const QByteArray &aStr, const QTextCodec *aCodec, - const QString &fromAddress, - KMMsgSignatureState &inlineSignatureState, - KMMsgEncryptionState &inlineEncryptionState, - bool decorate) -{ - const auto mpl = writeBodyStr2(aStr, aCodec, fromAddress, inlineSignatureState, inlineEncryptionState); - - if (!mpl.isEmpty()) { - if (htmlWriter()) { - foreach (const MessagePart::Ptr &mp, mpl) { - mp->html(decorate); - } - } - - const bool updatePlainText = (inlineSignatureState != KMMsgNotSigned - || inlineEncryptionState != KMMsgNotEncrypted); - if (updatePlainText || mPlainTextContent.isEmpty()) { - mPlainTextContent.clear(); - foreach (const MessagePart::Ptr &mp, mpl) { - mPlainTextContent += mp->text(); - } - mPlainTextContentCharset = aCodec->name(); - } - } -} - static QString iconToDataUrl(const QString &iconPath) { QFile f(iconPath);