From 79fd78dd1bd0968bd7a8aee70093e514b0729afd Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Tue, 23 May 2017 19:34:39 +0200 Subject: Dropped in body-part formatters --- .../src/domain/mimetreeparser/otp/CMakeLists.txt | 138 ++-------------- .../mimetreeparser/otp/applicationpgpencrypted.cpp | 98 +++++++++++ .../mimetreeparser/otp/applicationpgpencrypted.h | 41 +++++ .../mimetreeparser/otp/applicationpkcs7mime.cpp | 178 ++++++++++++++++++++ .../mimetreeparser/otp/applicationpkcs7mime.h | 41 +++++ .../src/domain/mimetreeparser/otp/mailman.cpp | 183 +++++++++++++++++++++ framework/src/domain/mimetreeparser/otp/mailman.h | 44 +++++ .../mimetreeparser/otp/multipartalternative.cpp | 94 +++++++++++ .../mimetreeparser/otp/multipartalternative.h | 41 +++++ .../mimetreeparser/otp/multipartencrypted.cpp | 111 +++++++++++++ .../domain/mimetreeparser/otp/multipartencrypted.h | 41 +++++ .../domain/mimetreeparser/otp/multipartmixed.cpp | 61 +++++++ .../src/domain/mimetreeparser/otp/multipartmixed.h | 41 +++++ .../domain/mimetreeparser/otp/multipartsigned.cpp | 114 +++++++++++++ .../domain/mimetreeparser/otp/multipartsigned.h | 41 +++++ .../src/domain/mimetreeparser/otp/texthtml.cpp | 58 +++++++ framework/src/domain/mimetreeparser/otp/texthtml.h | 41 +++++ .../src/domain/mimetreeparser/otp/textplain.cpp | 78 +++++++++ .../src/domain/mimetreeparser/otp/textplain.h | 41 +++++ 19 files changed, 1361 insertions(+), 124 deletions(-) create mode 100644 framework/src/domain/mimetreeparser/otp/applicationpgpencrypted.cpp create mode 100644 framework/src/domain/mimetreeparser/otp/applicationpgpencrypted.h create mode 100644 framework/src/domain/mimetreeparser/otp/applicationpkcs7mime.cpp create mode 100644 framework/src/domain/mimetreeparser/otp/applicationpkcs7mime.h create mode 100644 framework/src/domain/mimetreeparser/otp/mailman.cpp create mode 100644 framework/src/domain/mimetreeparser/otp/mailman.h create mode 100644 framework/src/domain/mimetreeparser/otp/multipartalternative.cpp create mode 100644 framework/src/domain/mimetreeparser/otp/multipartalternative.h create mode 100644 framework/src/domain/mimetreeparser/otp/multipartencrypted.cpp create mode 100644 framework/src/domain/mimetreeparser/otp/multipartencrypted.h create mode 100644 framework/src/domain/mimetreeparser/otp/multipartmixed.cpp create mode 100644 framework/src/domain/mimetreeparser/otp/multipartmixed.h create mode 100644 framework/src/domain/mimetreeparser/otp/multipartsigned.cpp create mode 100644 framework/src/domain/mimetreeparser/otp/multipartsigned.h create mode 100644 framework/src/domain/mimetreeparser/otp/texthtml.cpp create mode 100644 framework/src/domain/mimetreeparser/otp/texthtml.h create mode 100644 framework/src/domain/mimetreeparser/otp/textplain.cpp create mode 100644 framework/src/domain/mimetreeparser/otp/textplain.h (limited to 'framework/src/domain') diff --git a/framework/src/domain/mimetreeparser/otp/CMakeLists.txt b/framework/src/domain/mimetreeparser/otp/CMakeLists.txt index fcbe574f..f79277c8 100644 --- a/framework/src/domain/mimetreeparser/otp/CMakeLists.txt +++ b/framework/src/domain/mimetreeparser/otp/CMakeLists.txt @@ -6,7 +6,6 @@ find_package(Qt5 COMPONENTS REQUIRED Core Gui) find_package(KF5Mime "4.87.0" CONFIG REQUIRED) find_package(QGpgme CONFIG REQUIRED) find_package(KF5Codecs CONFIG REQUIRED) -find_package(KF5Package CONFIG REQUIRED) find_package(KF5I18n CONFIG REQUIRED) #add_definitions(-DTRANSLATION_DOMAIN=\"libmimetreeparser\") @@ -14,18 +13,20 @@ find_package(KF5I18n CONFIG REQUIRED) # target_include_directories does not handle empty include paths include_directories(${GPGME_INCLUDES}) -set(libmimetreeparser_main_SRCS +set(libmimetreeparser_SRCS objecttreeparser.cpp - #bodyformatter/applicationpgpencrypted.cpp - #bodyformatter/applicationpkcs7mime.cpp - #bodyformatter/mailman.cpp - #bodyformatter/multipartalternative.cpp - #bodyformatter/multipartencrypted.cpp - #bodyformatter/multipartmixed.cpp - #bodyformatter/multipartsigned.cpp - #bodyformatter/textplain.cpp - #bodyformatter/texthtml.cpp - #bodyformatter/utils.cpp + + #Bodyformatter + applicationpgpencrypted.cpp + applicationpkcs7mime.cpp + mailman.cpp + multipartalternative.cpp + multipartencrypted.cpp + multipartmixed.cpp + multipartsigned.cpp + textplain.cpp + texthtml.cpp + utils.cpp #Interfaces bodypartformatter.cpp @@ -39,7 +40,6 @@ set(libmimetreeparser_main_SRCS cryptohelper.cpp nodehelper.cpp messagepart.cpp - utils.cpp partnodebodypart.cpp #Mementos cryptobodypartmemento.cpp @@ -57,104 +57,8 @@ set(libmimetreeparser_main_SRCS attachmenttemporaryfilesdirs.cpp ) -#ecm_generate_headers(MimeTreeParser_Camelcaseviewer_HEADERS -# HEADER_NAMES -# AttachmentStrategy -# BodyPartFormatterBaseFactory -# Enums -# MessagePart -# NodeHelper -# ObjectTreeParser -# PartMetaData -# PartNodeBodyPart -# REQUIRED_HEADERS MimeTreeParser_viewer_HEADERS -# PREFIX MimeTreeParser -# RELATIVE viewer -# ) -# -#ecm_generate_headers(MimeTreeParser_Camelcaseutils_HEADERS -# HEADER_NAMES -# Util -# REQUIRED_HEADERS MimeTreeParser_utils_HEADERS -# PREFIX MimeTreeParser -# RELATIVE utils -# ) -# -#ecm_generate_headers(MimeTreeParser_Camelcaseinterfaces_HEADERS -# HEADER_NAMES -# BodyPartFormatter -# BodyPart -# HtmlWriter -# MessagePartRenderer -# ObjectTreeSource -# REQUIRED_HEADERS MimeTreeParser_interfaces_HEADERS -# PREFIX MimeTreeParser -# RELATIVE interfaces -# ) -# -#ecm_generate_headers(MimeTreeParser_Camelcasehtmlwriter_HEADERS -# HEADER_NAMES -# FileHtmlWriter -# QueueHtmlWriter -# REQUIRED_HEADERS MimeTreeParser_htmlwriter_HEADERS -# PREFIX MimeTreeParser -# RELATIVE htmlwriter -# ) -# -#ecm_generate_headers(MimeTreeParser_Camelcasetemporaryfile_HEADERS -# HEADER_NAMES -# AttachmentTemporaryFilesDirs -# REQUIRED_HEADERS MimeTreeParser_temporaryfile_HEADERS -# PREFIX MimeTreeParser -# RELATIVE temporaryfile -# ) - -#install(FILES -# ${MimeTreeParser_Camelcasehtmlwriter_HEADERS} -# ${MimeTreeParser_Camelcaseutils_HEADERS} -# ${MimeTreeParser_Camelcaseinterfaces_HEADERS} -# ${MimeTreeParser_Camelcaseviewer_HEADERS} -# ${MimeTreeParser_Camelcasetemporaryfile_HEADERS} -# DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/MimeTreeParser -# COMPONENT Devel -# ) -# -#install(FILES -# ${MimeTreeParser_htmlwriter_HEADERS} -# ${MimeTreeParser_utils_HEADERS} -# ${MimeTreeParser_interfaces_HEADERS} -# ${MimeTreeParser_viewer_HEADERS} -# ${MimeTreeParser_temporaryfile_HEADERS} -# ${CMAKE_CURRENT_BINARY_DIR}/mimetreeparser_export.h -# ${CMAKE_CURRENT_BINARY_DIR}/mimetreeparser_debug.h -# -# DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/mimetreeparser -# COMPONENT Devel -# ) -# -#ecm_generate_pri_file(BASE_NAME MimeTreeParser -# LIB_NAME KF5MimeTreeParser -# FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/MimeTreeParser -# ) -# -#install(FILES -# ${PRI_FILENAME} -# DESTINATION ${ECM_MKSPECS_INSTALL_DIR} -# ) - -set(libmimetreeparser_SRCS - ${libmimetreeparser_main_SRCS} - ) - -#ecm_qt_declare_logging_category(libmimetreeparser_SRCS HEADER mimetreeparser_debug.h IDENTIFIER MIMETREEPARSER_LOG CATEGORY_NAME org.kde.pim.mimetreeparser) - add_library(kube_otp ${libmimetreeparser_SRCS}) -#generate_export_header(KF5MimeTreeParser BASE_NAME mimetreeparser) - -#set(mimetreeparser_LINK_LIBRARIES -# ) - target_link_libraries(kube_otp PRIVATE QGpgme @@ -162,19 +66,5 @@ target_link_libraries(kube_otp KF5::I18n KF5::Mime Qt5::Gui - ) +) install(TARGETS kube_otp DESTINATION ${LIB_INSTALL_DIR}) - -#install(TARGETS -# KF5MimeTreeParser -# EXPORT KF5MimeTreeParserTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS} ${LIBRARY_NAMELINK} -# ) -# -#set_target_properties(KF5MimeTreeParser PROPERTIES -# VERSION ${MIMETREEPARSER_VERSION_STRING} -# SOVERSION ${MIMETREEPARSER_SOVERSION} -# EXPORT_NAME MimeTreeParser -# ) -# -#target_include_directories(KF5MimeTreeParser INTERFACE "$") -# diff --git a/framework/src/domain/mimetreeparser/otp/applicationpgpencrypted.cpp b/framework/src/domain/mimetreeparser/otp/applicationpgpencrypted.cpp new file mode 100644 index 00000000..e0f8e30c --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/applicationpgpencrypted.cpp @@ -0,0 +1,98 @@ +/* + 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 "applicationpgpencrypted.h" + +#include "utils.h" + +#include "objecttreeparser.h" +#include "messagepart.h" + +#include + +#include + +#include "mimetreeparser_debug.h" + +using namespace MimeTreeParser; + +const ApplicationPGPEncryptedBodyPartFormatter *ApplicationPGPEncryptedBodyPartFormatter::self; + +const Interface::BodyPartFormatter *ApplicationPGPEncryptedBodyPartFormatter::create() +{ + if (!self) { + self = new ApplicationPGPEncryptedBodyPartFormatter(); + } + return self; +} + +Interface::BodyPartFormatter::Result ApplicationPGPEncryptedBodyPartFormatter::format(Interface::BodyPart *part, HtmlWriter *writer) const +{ + Q_UNUSED(writer) + const auto p = process(*part); + const auto mp = static_cast(p.data()); + if (mp) { + mp->html(false); + return Ok; + } + return Failed; +} + +Interface::MessagePart::Ptr ApplicationPGPEncryptedBodyPartFormatter::process(Interface::BodyPart &part) const +{ + KMime::Content *node(part.content()); + + if (node->decodedContent().trimmed() != "Version: 1") { + qCWarning(MIMETREEPARSER_LOG) << "Unknown PGP Version String:" << node->decodedContent().trimmed(); + } + + if (!part.content()->parent()) { + return MessagePart::Ptr(); + } + + KMime::Content *data = findTypeInDirectChilds(part.content()->parent(), "application/octet-stream"); + + if (!data) { + return MessagePart::Ptr(); //new MimeMessagePart(part.objectTreeParser(), node, false)); + } + + part.nodeHelper()->setEncryptionState(node, KMMsgFullyEncrypted); + + EncryptedMessagePart::Ptr mp(new EncryptedMessagePart(part.objectTreeParser(), + data->decodedText(), QGpgME::openpgp(), + part.nodeHelper()->fromAsString(data), node)); + mp->setIsEncrypted(true); + mp->setDecryptMessage(part.source()->decryptMessage()); + PartMetaData *messagePart(mp->partMetaData()); + if (!part.source()->decryptMessage()) { + part.nodeHelper()->setNodeProcessed(data, false); // Set the data node to done to prevent it from being processed + } else if (KMime::Content *newNode = part.nodeHelper()->decryptedNodeForContent(data)) { + // if we already have a decrypted node for this encrypted node, don't do the decryption again + return MessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), newNode, part.objectTreeParser()->showOnlyOneMimePart())); + } else { + mp->startDecryption(data); + if (!messagePart->inProgress) { + part.nodeHelper()->setNodeProcessed(data, false); // Set the data node to done to prevent it from being processed + if (messagePart->isDecryptable && messagePart->isSigned) { + part.nodeHelper()->setSignatureState(node, KMMsgFullySigned); + } + } + } + return mp; +} diff --git a/framework/src/domain/mimetreeparser/otp/applicationpgpencrypted.h b/framework/src/domain/mimetreeparser/otp/applicationpgpencrypted.h new file mode 100644 index 00000000..f0f4865c --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/applicationpgpencrypted.h @@ -0,0 +1,41 @@ +/* + 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. +*/ + +#ifndef __MIMETREEPARSER_BODYFORAMATTER_APPLICATIONPGPENCYPTED_H__ +#define __MIMETREEPARSER_BODYFORAMATTER_APPLICATIONPGPENCYPTED_H__ + +#include "bodypartformatter.h" +#include "bodypart.h" + +namespace MimeTreeParser +{ + +class ApplicationPGPEncryptedBodyPartFormatter : public Interface::BodyPartFormatter +{ + static const ApplicationPGPEncryptedBodyPartFormatter *self; +public: + Interface::MessagePart::Ptr process(Interface::BodyPart &part) const Q_DECL_OVERRIDE; + Interface::BodyPartFormatter::Result format(Interface::BodyPart *, HtmlWriter *) const Q_DECL_OVERRIDE; + using Interface::BodyPartFormatter::format; + static const Interface::BodyPartFormatter *create(); +}; + +} + +#endif diff --git a/framework/src/domain/mimetreeparser/otp/applicationpkcs7mime.cpp b/framework/src/domain/mimetreeparser/otp/applicationpkcs7mime.cpp new file mode 100644 index 00000000..bcfc0616 --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/applicationpkcs7mime.cpp @@ -0,0 +1,178 @@ +/* + 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 "applicationpkcs7mime.h" + +#include "utils.h" + +#include "attachmentstrategy.h" +#include "objecttreeparser.h" +#include "messagepart.h" + +#include + +#include + +#include + +#include "mimetreeparser_debug.h" + +using namespace MimeTreeParser; + +const ApplicationPkcs7MimeBodyPartFormatter *ApplicationPkcs7MimeBodyPartFormatter::self; + +const Interface::BodyPartFormatter *ApplicationPkcs7MimeBodyPartFormatter::create() +{ + if (!self) { + self = new ApplicationPkcs7MimeBodyPartFormatter(); + } + return self; +} +Interface::BodyPartFormatter::Result ApplicationPkcs7MimeBodyPartFormatter::format(Interface::BodyPart *part, HtmlWriter *writer) const +{ + Q_UNUSED(writer) + const auto p = process(*part); + const auto mp = static_cast(p.data()); + if (mp) { + mp->html(false); + return Ok; + } + return Failed; +} + +Interface::MessagePart::Ptr ApplicationPkcs7MimeBodyPartFormatter::process(Interface::BodyPart &part) const +{ + KMime::Content *node = part.content(); + + if (node->head().isEmpty()) { + return MessagePart::Ptr(); + } + + const auto smimeCrypto = QGpgME::smime(); + if (!smimeCrypto) { + return MessagePart::Ptr(); + } + + const QString smimeType = node->contentType()->parameter(QStringLiteral("smime-type")).toLower(); + + if (smimeType == QLatin1String("certs-only")) { + part.processResult()->setNeverDisplayInline(true); + + CertMessagePart::Ptr mp(new CertMessagePart(part.objectTreeParser(), node, smimeCrypto, part.source()->autoImportKeys())); + return mp; + } + + bool isSigned = (smimeType == QLatin1String("signed-data")); + bool isEncrypted = (smimeType == QLatin1String("enveloped-data")); + + // Analyze "signTestNode" node to find/verify a signature. + // If zero part.objectTreeParser() verification was successfully done after + // decrypting via recursion by insertAndParseNewChildNode(). + KMime::Content *signTestNode = isEncrypted ? nullptr : node; + + // We try decrypting the content + // if we either *know* that it is an encrypted message part + // or there is neither signed nor encrypted parameter. + MessagePart::Ptr mp; + if (!isSigned) { + if (isEncrypted) { + qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime == S/MIME TYPE: enveloped (encrypted) data"; + } else { + qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - type unknown - enveloped (encrypted) data ?"; + } + + auto _mp = EncryptedMessagePart::Ptr(new EncryptedMessagePart(part.objectTreeParser(), + node->decodedText(), smimeCrypto, + part.nodeHelper()->fromAsString(node), node)); + mp = _mp; + _mp->setIsEncrypted(true); + _mp->setDecryptMessage(part.source()->decryptMessage()); + PartMetaData *messagePart(_mp->partMetaData()); + if (!part.source()->decryptMessage()) { + isEncrypted = true; + signTestNode = nullptr; // PENDING(marc) to be abs. sure, we'd need to have to look at the content + } else { + _mp->startDecryption(); + if (messagePart->isDecryptable) { + qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - encryption found - enveloped (encrypted) data !"; + isEncrypted = true; + part.nodeHelper()->setEncryptionState(node, KMMsgFullyEncrypted); + signTestNode = nullptr; + + } else { + // decryption failed, which could be because the part was encrypted but + // decryption failed, or because we didn't know if it was encrypted, tried, + // and failed. If the message was not actually encrypted, we continue + // assuming it's signed + if (_mp->passphraseError() || (smimeType.isEmpty() && messagePart->isEncrypted)) { + isEncrypted = true; + signTestNode = nullptr; + } + + if (isEncrypted) { + qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - ERROR: COULD NOT DECRYPT enveloped data !"; + } else { + qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - NO encryption found"; + } + } + } + + if (isEncrypted) { + part.nodeHelper()->setEncryptionState(node, KMMsgFullyEncrypted); + } + } + + // We now try signature verification if necessarry. + if (signTestNode) { + if (isSigned) { + qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime == S/MIME TYPE: opaque signed data"; + } else { + qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - type unknown - opaque signed data ?"; + } + + const QTextCodec *aCodec(part.objectTreeParser()->codecFor(signTestNode)); + const QByteArray signaturetext = signTestNode->decodedContent(); + auto _mp = SignedMessagePart::Ptr(new SignedMessagePart(part.objectTreeParser(), + aCodec->toUnicode(signaturetext), smimeCrypto, + part.nodeHelper()->fromAsString(node), signTestNode)); + mp = _mp; + //mp->setDecryptMessage(part.source()->decryptMessage()); + PartMetaData *messagePart(mp->partMetaData()); + if (smimeCrypto) { + _mp->startVerificationDetached(signaturetext, nullptr, QByteArray()); + } else { + messagePart->auditLogError = GpgME::Error(GPG_ERR_NOT_IMPLEMENTED); + } + + if (_mp->isSigned()) { + if (!isSigned) { + qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - signature found - opaque signed data !"; + isSigned = true; + } + + if (signTestNode != node) { + part.nodeHelper()->setSignatureState(node, KMMsgFullySigned); + } + } else { + qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - NO signature found :-("; + } + } + + return mp; +} diff --git a/framework/src/domain/mimetreeparser/otp/applicationpkcs7mime.h b/framework/src/domain/mimetreeparser/otp/applicationpkcs7mime.h new file mode 100644 index 00000000..a9a33f7c --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/applicationpkcs7mime.h @@ -0,0 +1,41 @@ +/* + 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. +*/ + +#ifndef __MIMETREEPARSER_BODYFORAMATTER_APPLICATIONPKCS7MIME_H__ +#define __MIMETREEPARSER_BODYFORAMATTER_APPLICATIONPKCS7MIME_H__ + +#include "bodypartformatter.h" +#include "bodypart.h" + +namespace MimeTreeParser +{ + +class ApplicationPkcs7MimeBodyPartFormatter : public Interface::BodyPartFormatter +{ + static const ApplicationPkcs7MimeBodyPartFormatter *self; +public: + Interface::MessagePart::Ptr process(Interface::BodyPart &part) const Q_DECL_OVERRIDE; + Interface::BodyPartFormatter::Result format(Interface::BodyPart *, HtmlWriter *) const Q_DECL_OVERRIDE; + using Interface::BodyPartFormatter::format; + static const Interface::BodyPartFormatter *create(); +}; + +} + +#endif diff --git a/framework/src/domain/mimetreeparser/otp/mailman.cpp b/framework/src/domain/mimetreeparser/otp/mailman.cpp new file mode 100644 index 00000000..e79ef0fa --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/mailman.cpp @@ -0,0 +1,183 @@ +/* + 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 "mailman.h" + +#include "utils.h" + +#include "objecttreeparser.h" +#include "messagepart.h" + +#include + +#include "mimetreeparser_debug.h" + +using namespace MimeTreeParser; + +const MailmanBodyPartFormatter *MailmanBodyPartFormatter::self; + +const Interface::BodyPartFormatter *MailmanBodyPartFormatter::create() +{ + if (!self) { + self = new MailmanBodyPartFormatter(); + } + return self; +} +Interface::BodyPartFormatter::Result MailmanBodyPartFormatter::format(Interface::BodyPart *part, HtmlWriter *writer) const +{ + Q_UNUSED(writer) + const auto p = process(*part); + const auto mp = static_cast(p.data()); + if (mp) { + mp->html(false); + return Ok; + } + return Failed; +} + +bool MailmanBodyPartFormatter::isMailmanMessage(KMime::Content *curNode) const +{ + if (!curNode || curNode->head().isEmpty()) { + return false; + } + if (curNode->hasHeader("X-Mailman-Version")) { + return true; + } + if (KMime::Headers::Base *header = curNode->headerByType("X-Mailer")) { + if (header->asUnicodeString().contains(QStringLiteral("MAILMAN"), Qt::CaseInsensitive)) { + return true; + } + } + return false; +} + +Interface::MessagePart::Ptr MailmanBodyPartFormatter::process(Interface::BodyPart &part) const +{ + KMime::Content *curNode = part.content(); + + if (!isMailmanMessage(curNode)) { + return MessagePart::Ptr(); + } + + const QString str = QString::fromLatin1(curNode->decodedContent()); + + //### + const QLatin1String delim1("--__--__--\n\nMessage:"); + const QLatin1String delim2("--__--__--\r\n\r\nMessage:"); + const QLatin1String delimZ2("--__--__--\n\n_____________"); + const QLatin1String delimZ1("--__--__--\r\n\r\n_____________"); + QString partStr, digestHeaderStr; + int thisDelim = str.indexOf(delim1, Qt::CaseInsensitive); + if (thisDelim == -1) { + thisDelim = str.indexOf(delim2, Qt::CaseInsensitive); + } + if (thisDelim == -1) { + return MessagePart::Ptr(); + } + + int nextDelim = str.indexOf(delim1, thisDelim + 1, Qt::CaseInsensitive); + if (-1 == nextDelim) { + nextDelim = str.indexOf(delim2, thisDelim + 1, Qt::CaseInsensitive); + } + if (-1 == nextDelim) { + nextDelim = str.indexOf(delimZ1, thisDelim + 1, Qt::CaseInsensitive); + } + if (-1 == nextDelim) { + nextDelim = str.indexOf(delimZ2, thisDelim + 1, Qt::CaseInsensitive); + } + if (nextDelim < 0) { + return MessagePart::Ptr(); + } + + //if ( curNode->mRoot ) + // curNode = curNode->mRoot; + + // at least one message found: build a mime tree + digestHeaderStr = QStringLiteral("Content-Type: text/plain\nContent-Description: digest header\n\n"); + digestHeaderStr += str.midRef(0, thisDelim); + + MessagePartList::Ptr mpl(new MessagePartList(part.objectTreeParser())); + mpl->appendSubPart(createAndParseTempNode(part, part.topLevelContent(), digestHeaderStr.toLatin1().constData(), "Digest Header")); + //mReader->queueHtml("


"); + // temporarily change curent node's Content-Type + // to get our embedded RfC822 messages properly inserted + curNode->contentType()->setMimeType("multipart/digest"); + while (-1 < nextDelim) { + int thisEoL = str.indexOf(QLatin1String("\nMessage:"), thisDelim, Qt::CaseInsensitive); + if (-1 < thisEoL) { + thisDelim = thisEoL + 1; + } else { + thisEoL = str.indexOf(QLatin1String("\n_____________"), thisDelim, Qt::CaseInsensitive); + if (-1 < thisEoL) { + thisDelim = thisEoL + 1; + } + } + thisEoL = str.indexOf(QLatin1Char('\n'), thisDelim); + if (-1 < thisEoL) { + thisDelim = thisEoL + 1; + } else { + thisDelim = thisDelim + 1; + } + //while( thisDelim < cstr.size() && '\n' == cstr[thisDelim] ) + // ++thisDelim; + + partStr = QStringLiteral("Content-Type: message/rfc822\nContent-Description: embedded message\n\n"); + partStr += str.midRef(thisDelim, nextDelim - thisDelim); + QString subject = QStringLiteral("embedded message"); + QString subSearch = QStringLiteral("\nSubject:"); + int subPos = partStr.indexOf(subSearch, 0, Qt::CaseInsensitive); + if (-1 < subPos) { + subject = partStr.mid(subPos + subSearch.length()); + thisEoL = subject.indexOf(QLatin1Char('\n')); + if (-1 < thisEoL) { + subject.truncate(thisEoL); + } + } + qCDebug(MIMETREEPARSER_LOG) << " embedded message found: \"" << subject; + mpl->appendSubPart(createAndParseTempNode(part, part.topLevelContent(), partStr.toLatin1().constData(), subject.toLatin1().constData())); + //mReader->queueHtml("


"); + thisDelim = nextDelim + 1; + nextDelim = str.indexOf(delim1, thisDelim, Qt::CaseInsensitive); + if (-1 == nextDelim) { + nextDelim = str.indexOf(delim2, thisDelim, Qt::CaseInsensitive); + } + if (-1 == nextDelim) { + nextDelim = str.indexOf(delimZ1, thisDelim, Qt::CaseInsensitive); + } + if (-1 == nextDelim) { + nextDelim = str.indexOf(delimZ2, thisDelim, Qt::CaseInsensitive); + } + } + // reset curent node's Content-Type + curNode->contentType()->setMimeType("text/plain"); + int thisEoL = str.indexOf(QLatin1String("_____________"), thisDelim); + if (-1 < thisEoL) { + thisDelim = thisEoL; + thisEoL = str.indexOf(QLatin1Char('\n'), thisDelim); + if (-1 < thisEoL) { + thisDelim = thisEoL + 1; + } + } else { + thisDelim = thisDelim + 1; + } + partStr = QStringLiteral("Content-Type: text/plain\nContent-Description: digest footer\n\n"); + partStr += str.midRef(thisDelim); + mpl->appendSubPart(createAndParseTempNode(part, part.topLevelContent(), partStr.toLatin1().constData(), "Digest Footer")); + return mpl; +} diff --git a/framework/src/domain/mimetreeparser/otp/mailman.h b/framework/src/domain/mimetreeparser/otp/mailman.h new file mode 100644 index 00000000..742830b2 --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/mailman.h @@ -0,0 +1,44 @@ +/* + 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. +*/ + +#ifndef __MIMETREEPARSER_BODYFORAMATTER_MAILMAN_H__ +#define __MIMETREEPARSER_BODYFORAMATTER_MAILMAN_H__ + +#include "bodypartformatter.h" +#include "bodypart.h" + +namespace MimeTreeParser +{ + +class MailmanBodyPartFormatter : public Interface::BodyPartFormatter +{ + static const MailmanBodyPartFormatter *self; +public: + Interface::MessagePart::Ptr process(Interface::BodyPart &part) const Q_DECL_OVERRIDE; + Interface::BodyPartFormatter::Result format(Interface::BodyPart *, HtmlWriter *) const Q_DECL_OVERRIDE; + using Interface::BodyPartFormatter::format; + static const Interface::BodyPartFormatter *create(); + +private: + bool isMailmanMessage(KMime::Content *curNode) const; +}; + +} + +#endif diff --git a/framework/src/domain/mimetreeparser/otp/multipartalternative.cpp b/framework/src/domain/mimetreeparser/otp/multipartalternative.cpp new file mode 100644 index 00000000..42c70e28 --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/multipartalternative.cpp @@ -0,0 +1,94 @@ +/* + 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 "multipartalternative.h" + +#include "utils.h" + +#include "objecttreeparser.h" +#include "messagepart.h" + +#include + +#include "mimetreeparser_debug.h" + +using namespace MimeTreeParser; + +const MultiPartAlternativeBodyPartFormatter *MultiPartAlternativeBodyPartFormatter::self; + +const Interface::BodyPartFormatter *MultiPartAlternativeBodyPartFormatter::create() +{ + if (!self) { + self = new MultiPartAlternativeBodyPartFormatter(); + } + return self; +} +Interface::BodyPartFormatter::Result MultiPartAlternativeBodyPartFormatter::format(Interface::BodyPart *part, HtmlWriter *writer) const +{ + Q_UNUSED(writer) + const auto p = process(*part); + const auto mp = static_cast(p.data()); + if (mp) { + mp->html(false); + return Ok; + } + return Failed; +} + +Interface::MessagePart::Ptr MultiPartAlternativeBodyPartFormatter::process(Interface::BodyPart &part) const +{ + KMime::Content *node = part.content(); + if (node->contents().isEmpty()) { + return MessagePart::Ptr(); + } + + auto preferredMode = part.source()->preferredMode(); + AlternativeMessagePart::Ptr mp(new AlternativeMessagePart(part.objectTreeParser(), node, preferredMode)); + if (mp->mChildNodes.isEmpty()) { + MimeMessagePart::Ptr _mp(new MimeMessagePart(part.objectTreeParser(), node->contents().at(0), false)); + return _mp; + } + + KMime::Content *dataIcal = mp->mChildNodes.contains(Util::MultipartIcal) ? mp->mChildNodes[Util::MultipartIcal] : nullptr; + KMime::Content *dataHtml = mp->mChildNodes.contains(Util::MultipartHtml) ? mp->mChildNodes[Util::MultipartHtml] : nullptr; + KMime::Content *dataPlain = mp->mChildNodes.contains(Util::MultipartPlain) ? mp->mChildNodes[Util::MultipartPlain] : nullptr; + + // Make sure that in default ical is prefered over html and plain text + if (dataIcal && ((preferredMode != Util::MultipartHtml && preferredMode != Util::MultipartPlain))) { + if (dataHtml) { + part.nodeHelper()->setNodeProcessed(dataHtml, false); + } + if (dataPlain) { + part.nodeHelper()->setNodeProcessed(dataPlain, false); + } + preferredMode = Util::MultipartIcal; + } else if ((dataHtml && (preferredMode == Util::MultipartHtml || preferredMode == Util::Html)) || + (dataHtml && dataPlain && dataPlain->body().isEmpty())) { + if (dataPlain) { + part.nodeHelper()->setNodeProcessed(dataPlain, false); + } + preferredMode = Util::MultipartHtml; + } else if (!(preferredMode == Util::MultipartHtml) && dataPlain) { + part.nodeHelper()->setNodeProcessed(dataHtml, false); + preferredMode = Util::MultipartPlain; + } + part.source()->setHtmlMode(preferredMode, mp->availableModes()); + mp->mPreferredMode = preferredMode; + return mp; +} diff --git a/framework/src/domain/mimetreeparser/otp/multipartalternative.h b/framework/src/domain/mimetreeparser/otp/multipartalternative.h new file mode 100644 index 00000000..78e5ef38 --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/multipartalternative.h @@ -0,0 +1,41 @@ +/* + 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. +*/ + +#ifndef __MIMETREEPARSER_BODYFORAMATTER_MULTIPARTALTERNATIVE_H__ +#define __MIMETREEPARSER_BODYFORAMATTER_MULTIPARTALTERNATIVE_H__ + +#include "bodypartformatter.h" +#include "bodypart.h" + +namespace MimeTreeParser +{ + +class MultiPartAlternativeBodyPartFormatter : public Interface::BodyPartFormatter +{ + static const MultiPartAlternativeBodyPartFormatter *self; +public: + Interface::MessagePart::Ptr process(Interface::BodyPart &part) const Q_DECL_OVERRIDE; + Interface::BodyPartFormatter::Result format(Interface::BodyPart *, HtmlWriter *) const Q_DECL_OVERRIDE; + using Interface::BodyPartFormatter::format; + static const Interface::BodyPartFormatter *create(); +}; + +} + +#endif diff --git a/framework/src/domain/mimetreeparser/otp/multipartencrypted.cpp b/framework/src/domain/mimetreeparser/otp/multipartencrypted.cpp new file mode 100644 index 00000000..7a049318 --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/multipartencrypted.cpp @@ -0,0 +1,111 @@ +/* + 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 "multipartencrypted.h" + +#include "utils.h" + +#include "objecttreeparser.h" +#include "messagepart.h" + +#include + +#include + +#include "mimetreeparser_debug.h" + +using namespace MimeTreeParser; + +const MultiPartEncryptedBodyPartFormatter *MultiPartEncryptedBodyPartFormatter::self; + +const Interface::BodyPartFormatter *MultiPartEncryptedBodyPartFormatter::create() +{ + if (!self) { + self = new MultiPartEncryptedBodyPartFormatter(); + } + return self; +} +Interface::BodyPartFormatter::Result MultiPartEncryptedBodyPartFormatter::format(Interface::BodyPart *part, HtmlWriter *writer) const +{ + Q_UNUSED(writer) + const auto p = process(*part); + const auto mp = static_cast(p.data()); + if (mp) { + mp->html(false); + return Ok; + } + return Failed; +} + +Interface::MessagePart::Ptr MultiPartEncryptedBodyPartFormatter::process(Interface::BodyPart &part) const +{ + KMime::Content *node = part.content(); + + if (node->contents().isEmpty()) { + Q_ASSERT(false); + return MessagePart::Ptr(); + } + + const QGpgME::Protocol *useThisCryptProto = nullptr; + + /* + ATTENTION: This code is to be replaced by the new 'auto-detect' feature. -------------------------------------- + */ + KMime::Content *data = findTypeInDirectChilds(node, "application/octet-stream"); + if (data) { + useThisCryptProto = QGpgME::openpgp(); + } + if (!data) { + data = findTypeInDirectChilds(node, "application/pkcs7-mime"); + if (data) { + useThisCryptProto = QGpgME::smime(); + } + } + /* + --------------------------------------------------------------------------------------------------------------- + */ + + if (!data) { + return MessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), node->contents().at(0), false)); + } + + part.nodeHelper()->setEncryptionState(node, KMMsgFullyEncrypted); + + EncryptedMessagePart::Ptr mp(new EncryptedMessagePart(part.objectTreeParser(), + data->decodedText(), useThisCryptProto, + part.nodeHelper()->fromAsString(data), node)); + mp->setIsEncrypted(true); + mp->setDecryptMessage(part.source()->decryptMessage()); + PartMetaData *messagePart(mp->partMetaData()); + if (!part.source()->decryptMessage()) { + part.nodeHelper()->setNodeProcessed(data, false); // Set the data node to done to prevent it from being processed + } else if (KMime::Content *newNode = part.nodeHelper()->decryptedNodeForContent(data)) { + // if we already have a decrypted node for part.objectTreeParser() encrypted node, don't do the decryption again + return MessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), newNode, true)); + } else { + mp->startDecryption(data); + + qCDebug(MIMETREEPARSER_LOG) << "decrypted, signed?:" << messagePart->isSigned; + + if (!messagePart->inProgress) { + part.nodeHelper()->setNodeProcessed(data, false); // Set the data node to done to prevent it from being processed + } + } + return mp; +} diff --git a/framework/src/domain/mimetreeparser/otp/multipartencrypted.h b/framework/src/domain/mimetreeparser/otp/multipartencrypted.h new file mode 100644 index 00000000..0d2e01a8 --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/multipartencrypted.h @@ -0,0 +1,41 @@ +/* + 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. +*/ + +#ifndef __MIMETREEPARSER_BODYFORAMATTER_MULTIPARTENCRYPTED_H__ +#define __MIMETREEPARSER_BODYFORAMATTER_MULTIPARTENCRYPTED_H__ + +#include "bodypartformatter.h" +#include "bodypart.h" + +namespace MimeTreeParser +{ + +class MultiPartEncryptedBodyPartFormatter : public Interface::BodyPartFormatter +{ + static const MultiPartEncryptedBodyPartFormatter *self; +public: + Interface::MessagePart::Ptr process(Interface::BodyPart &part) const Q_DECL_OVERRIDE; + Interface::BodyPartFormatter::Result format(Interface::BodyPart *, HtmlWriter *) const Q_DECL_OVERRIDE; + using Interface::BodyPartFormatter::format; + static const Interface::BodyPartFormatter *create(); +}; + +} + +#endif diff --git a/framework/src/domain/mimetreeparser/otp/multipartmixed.cpp b/framework/src/domain/mimetreeparser/otp/multipartmixed.cpp new file mode 100644 index 00000000..43056e51 --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/multipartmixed.cpp @@ -0,0 +1,61 @@ +/* + 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 "multipartmixed.h" + +#include "objecttreeparser.h" +#include "messagepart.h" + +#include + +#include "mimetreeparser_debug.h" + +using namespace MimeTreeParser; + +const MultiPartMixedBodyPartFormatter *MultiPartMixedBodyPartFormatter::self; + +const Interface::BodyPartFormatter *MultiPartMixedBodyPartFormatter::create() +{ + if (!self) { + self = new MultiPartMixedBodyPartFormatter(); + } + return self; +} +Interface::BodyPartFormatter::Result MultiPartMixedBodyPartFormatter::format(Interface::BodyPart *part, HtmlWriter *writer) const +{ + Q_UNUSED(writer) + const auto p = process(*part); + const auto mp = static_cast(p.data()); + if (mp) { + mp->html(false); + return Ok; + } + return Failed; +} + +Interface::MessagePart::Ptr MultiPartMixedBodyPartFormatter::process(Interface::BodyPart &part) const +{ + if (part.content()->contents().isEmpty()) { + return MessagePart::Ptr(); + } + + // normal treatment of the parts in the mp/mixed container + MimeMessagePart::Ptr mp(new MimeMessagePart(part.objectTreeParser(), part.content()->contents().at(0), false)); + return mp; +} diff --git a/framework/src/domain/mimetreeparser/otp/multipartmixed.h b/framework/src/domain/mimetreeparser/otp/multipartmixed.h new file mode 100644 index 00000000..0029501b --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/multipartmixed.h @@ -0,0 +1,41 @@ +/* + 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. +*/ + +#ifndef __MIMETREEPARSER_BODYFORAMATTER_MULTIPARTMIXED_H__ +#define __MIMETREEPARSER_BODYFORAMATTER_MULTIPARTMIXED_H__ + +#include "bodypartformatter.h" +#include "bodypart.h" + +namespace MimeTreeParser +{ + +class MultiPartMixedBodyPartFormatter : public Interface::BodyPartFormatter +{ + static const MultiPartMixedBodyPartFormatter *self; +public: + Interface::MessagePart::Ptr process(Interface::BodyPart &part) const Q_DECL_OVERRIDE; + Interface::BodyPartFormatter::Result format(Interface::BodyPart *, HtmlWriter *) const Q_DECL_OVERRIDE; + using Interface::BodyPartFormatter::format; + static const Interface::BodyPartFormatter *create(); +}; + +} + +#endif diff --git a/framework/src/domain/mimetreeparser/otp/multipartsigned.cpp b/framework/src/domain/mimetreeparser/otp/multipartsigned.cpp new file mode 100644 index 00000000..cb0def6c --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/multipartsigned.cpp @@ -0,0 +1,114 @@ +/* + 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 "multipartsigned.h" + +#include "objecttreeparser.h" +#include "messagepart.h" + +#include + +#include + +#include "mimetreeparser_debug.h" + +#include + +using namespace MimeTreeParser; + +const MultiPartSignedBodyPartFormatter *MultiPartSignedBodyPartFormatter::self; + +const Interface::BodyPartFormatter *MultiPartSignedBodyPartFormatter::create() +{ + if (!self) { + self = new MultiPartSignedBodyPartFormatter(); + } + return self; +} +Interface::BodyPartFormatter::Result MultiPartSignedBodyPartFormatter::format(Interface::BodyPart *part, HtmlWriter *writer) const +{ + Q_UNUSED(writer) + const auto p = process(*part); + const auto mp = static_cast(p.data()); + if (mp) { + mp->html(false); + return Ok; + } + return Failed; +} + +Interface::MessagePart::Ptr MultiPartSignedBodyPartFormatter::process(Interface::BodyPart &part) const +{ + KMime::Content *node = part.content(); + if (node->contents().size() != 2) { + qCDebug(MIMETREEPARSER_LOG) << "mulitpart/signed must have exactly two child parts!" << endl + << "processing as multipart/mixed"; + if (!node->contents().isEmpty()) { + return MessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), node->contents().at(0), false)); + } else { + return MessagePart::Ptr(); + } + } + + KMime::Content *signedData = node->contents().at(0); + KMime::Content *signature = node->contents().at(1); + Q_ASSERT(signedData); + Q_ASSERT(signature); + + QString protocolContentType = node->contentType()->parameter(QStringLiteral("protocol")).toLower(); + const QString signatureContentType = QLatin1String(signature->contentType()->mimeType().toLower()); + if (protocolContentType.isEmpty()) { + qCWarning(MIMETREEPARSER_LOG) << "Message doesn't set the protocol for the multipart/signed content-type, " + "using content-type of the signature:" << signatureContentType; + protocolContentType = signatureContentType; + } + + const QGpgME::Protocol *protocol = nullptr; + if (protocolContentType == QLatin1String("application/pkcs7-signature") || + protocolContentType == QLatin1String("application/x-pkcs7-signature")) { + protocol = QGpgME::smime(); + } else if (protocolContentType == QLatin1String("application/pgp-signature") || + protocolContentType == QLatin1String("application/x-pgp-signature")) { + protocol = QGpgME::openpgp(); + } + + if (!protocol) { + return MessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), signedData, false)); + } + + part.nodeHelper()->setNodeProcessed(signature, true); + + part.nodeHelper()->setSignatureState(node, KMMsgFullySigned); + + const QByteArray cleartext = KMime::LFtoCRLF(signedData->encodedContent()); + const QTextCodec *aCodec(part.objectTreeParser()->codecFor(signedData)); + + SignedMessagePart::Ptr mp(new SignedMessagePart(part.objectTreeParser(), + aCodec->toUnicode(cleartext), protocol, + part.nodeHelper()->fromAsString(node), signature)); + PartMetaData *messagePart(mp->partMetaData()); + + if (protocol) { + mp->startVerificationDetached(cleartext, signedData, signature->decodedContent()); + } else { + messagePart->auditLogError = GpgME::Error(GPG_ERR_NOT_IMPLEMENTED); + } + + return mp; +} diff --git a/framework/src/domain/mimetreeparser/otp/multipartsigned.h b/framework/src/domain/mimetreeparser/otp/multipartsigned.h new file mode 100644 index 00000000..4b8921ad --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/multipartsigned.h @@ -0,0 +1,41 @@ +/* + 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. +*/ + +#ifndef __MIMETREEPARSER_BODYFORAMATTER_MULTIPARTSIGNED_H__ +#define __MIMETREEPARSER_BODYFORAMATTER_MULTIPARTSIGNED_H__ + +#include "bodypartformatter.h" +#include "bodypart.h" + +namespace MimeTreeParser +{ + +class MultiPartSignedBodyPartFormatter : public Interface::BodyPartFormatter +{ + static const MultiPartSignedBodyPartFormatter *self; +public: + Interface::MessagePart::Ptr process(Interface::BodyPart &part) const Q_DECL_OVERRIDE; + Interface::BodyPartFormatter::Result format(Interface::BodyPart *, HtmlWriter *) const Q_DECL_OVERRIDE; + using Interface::BodyPartFormatter::format; + static const Interface::BodyPartFormatter *create(); +}; + +} + +#endif diff --git a/framework/src/domain/mimetreeparser/otp/texthtml.cpp b/framework/src/domain/mimetreeparser/otp/texthtml.cpp new file mode 100644 index 00000000..51332cff --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/texthtml.cpp @@ -0,0 +1,58 @@ +/* + 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 "texthtml.h" + +#include "attachmentstrategy.h" +#include "objecttreeparser.h" +#include "messagepart.h" + +#include + +#include "mimetreeparser_debug.h" + +using namespace MimeTreeParser; + +const TextHtmlBodyPartFormatter *TextHtmlBodyPartFormatter::self; + +const Interface::BodyPartFormatter *TextHtmlBodyPartFormatter::create() +{ + if (!self) { + self = new TextHtmlBodyPartFormatter(); + } + return self; +} +Interface::BodyPartFormatter::Result TextHtmlBodyPartFormatter::format(Interface::BodyPart *part, HtmlWriter *writer) const +{ + Q_UNUSED(writer) + const auto p = process(*part); + const auto mp = static_cast(p.data()); + if (mp) { + mp->html(false); + return Ok; + } + return Failed; +} + +Interface::MessagePart::Ptr TextHtmlBodyPartFormatter::process(Interface::BodyPart &part) const +{ + KMime::Content *node = part.content(); + HtmlMessagePart::Ptr mp(new HtmlMessagePart(part.objectTreeParser(), node, part.source())); + return mp; +} diff --git a/framework/src/domain/mimetreeparser/otp/texthtml.h b/framework/src/domain/mimetreeparser/otp/texthtml.h new file mode 100644 index 00000000..a03cfe50 --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/texthtml.h @@ -0,0 +1,41 @@ +/* + 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. +*/ + +#ifndef __MIMETREEPARSER_BODYFORAMATTER_TEXTHTML_H__ +#define __MIMETREEPARSER_BODYFORAMATTER_TEXTHTML_H__ + +#include "bodypartformatter.h" +#include "bodypart.h" + +namespace MimeTreeParser +{ + +class TextHtmlBodyPartFormatter : public Interface::BodyPartFormatter +{ + static const TextHtmlBodyPartFormatter *self; +public: + Interface::MessagePart::Ptr process(Interface::BodyPart &part) const Q_DECL_OVERRIDE; + Interface::BodyPartFormatter::Result format(Interface::BodyPart *, HtmlWriter *) const Q_DECL_OVERRIDE; + using Interface::BodyPartFormatter::format; + static const Interface::BodyPartFormatter *create(); +}; + +} + +#endif diff --git a/framework/src/domain/mimetreeparser/otp/textplain.cpp b/framework/src/domain/mimetreeparser/otp/textplain.cpp new file mode 100644 index 00000000..d3437f04 --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/textplain.cpp @@ -0,0 +1,78 @@ +/* + 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 "textplain.h" + +#include "attachmentstrategy.h" +#include "objecttreeparser.h" +#include "messagepart.h" + +#include + +#include "mimetreeparser_debug.h" + +using namespace MimeTreeParser; + +const TextPlainBodyPartFormatter *TextPlainBodyPartFormatter::self; + +const Interface::BodyPartFormatter *TextPlainBodyPartFormatter::create() +{ + if (!self) { + self = new TextPlainBodyPartFormatter(); + } + return self; +} +Interface::BodyPartFormatter::Result TextPlainBodyPartFormatter::format(Interface::BodyPart *part, HtmlWriter *writer) const +{ + Q_UNUSED(writer) + const auto p = process(*part); + const auto mp = static_cast(p.data()); + if (mp) { + mp->html(false); + return Ok; + } + return Failed; +} + +Interface::MessagePart::Ptr TextPlainBodyPartFormatter::process(Interface::BodyPart &part) const +{ + KMime::Content *node = part.content(); + const bool isFirstTextPart = (node->topLevel()->textContent() == node); + + QString label = NodeHelper::fileName(node); + + const bool bDrawFrame = !isFirstTextPart + && !part.objectTreeParser()->showOnlyOneMimePart() + && !label.isEmpty(); + const QString fileName = part.nodeHelper()->writeNodeToTempFile(node); + + TextMessagePart::Ptr mp; + if (isFirstTextPart) { + mp = TextMessagePart::Ptr(new TextMessagePart(part.objectTreeParser(), node, bDrawFrame, fileName.isEmpty(), part.source()->decryptMessage())); + } else { + mp = TextMessagePart::Ptr(new AttachmentMessagePart(part.objectTreeParser(), node, bDrawFrame, fileName.isEmpty(), part.source()->decryptMessage())); + } + + part.processResult()->setInlineSignatureState(mp->signatureState()); + part.processResult()->setInlineEncryptionState(mp->encryptionState()); + + part.nodeHelper()->setNodeDisplayedEmbedded(node, true); + + return mp; +} diff --git a/framework/src/domain/mimetreeparser/otp/textplain.h b/framework/src/domain/mimetreeparser/otp/textplain.h new file mode 100644 index 00000000..c97a6aec --- /dev/null +++ b/framework/src/domain/mimetreeparser/otp/textplain.h @@ -0,0 +1,41 @@ +/* + 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. +*/ + +#ifndef __MIMETREEPARSER_BODYFORAMATTER_TEXTPLAIN_H__ +#define __MIMETREEPARSER_BODYFORAMATTER_TEXTPLAIN_H__ + +#include "bodypartformatter.h" +#include "bodypart.h" + +namespace MimeTreeParser +{ + +class TextPlainBodyPartFormatter : public Interface::BodyPartFormatter +{ + static const TextPlainBodyPartFormatter *self; +public: + Interface::MessagePart::Ptr process(Interface::BodyPart &part) const Q_DECL_OVERRIDE; + Interface::BodyPartFormatter::Result format(Interface::BodyPart *, HtmlWriter *) const Q_DECL_OVERRIDE; + using Interface::BodyPartFormatter::format; + static const Interface::BodyPartFormatter *create(); +}; + +} + +#endif -- cgit v1.2.3