Messagelib

encrypted.cpp
1/*
2 SPDX-FileCopyrightText: 2017 Sandro KnauƟ <sknauss@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "encrypted.h"
8
9#include "messagepart.h"
10#include "objecttreeparser.h"
11
12#include <KMime/Content>
13
14#include <QGpgME/DataProvider>
15#include <QGpgME/Protocol>
16#include <gpgme++/data.h>
17
18#include "mimetreeparser_debug.h"
19
20using namespace MimeTreeParser;
21
22const Interface::BodyPartFormatter *EncryptedBodyPartFormatter::create(EncryptedBodyPartFormatter::EncryptionFlags flags)
23{
24 auto self = new EncryptedBodyPartFormatter;
25 self->mFlags = flags;
26 return self;
27}
28
29MessagePart::Ptr EncryptedBodyPartFormatter::process(Interface::BodyPart &part) const
30{
31 KMime::Content *node = part.content();
32 const auto nodeHelper = part.nodeHelper();
33
34 if (!node->contents().isEmpty()) {
35 Q_ASSERT(false);
36 return {};
37 }
38
39 const QByteArray content(node->decodedContent());
40 if (content.isEmpty()) {
41 return nullptr;
42 }
43
44 if (!(mFlags & EncryptedBodyPartFormatter::ForcePGP)) {
45 // If not forcing the data to be interpreted as PGP encrypted,
46 // only check for encryption if it starts with a 7-bit ASCII
47 // character. Valid armored PGP data always starts with an
48 // ASCII character, so if the first byte has bit 8 set then it
49 // cannot be PGP armored. This way we retain support for armored
50 // inline PGP data, but avoid random binary data being detected
51 // as PGP data. See bug 390002 and messagelib!83.
52 unsigned char firstByte = content[0];
53 if ((firstByte & 0x80) != 0) {
54 return nullptr;
55 }
56
57 QGpgME::QByteArrayDataProvider dp(content);
58 GpgME::Data data(&dp);
59
60 if (data.type() == GpgME::Data::Unknown) {
61 return nullptr;
62 }
63 }
64
65 const QGpgME::Protocol *useThisCryptProto = nullptr;
66
67 useThisCryptProto = QGpgME::openpgp();
68
69 // TODO: Load correct crypto Proto
70
71 nodeHelper->setEncryptionState(node, KMMsgFullyEncrypted);
72
74 new EncryptedMessagePart(part.objectTreeParser(), node->decodedText(), useThisCryptProto, nodeHelper->fromAsString(node), node));
75 mp->setIsEncrypted(true);
76 mp->setDecryptMessage(part.source()->decryptMessage());
77 PartMetaData *messagePart(mp->partMetaData());
78
79 if (!part.source()->decryptMessage()) {
80 nodeHelper->setNodeProcessed(node, false); // Set the data node to done to prevent it from being processed
81 } else if (KMime::Content *newNode = nodeHelper->decryptedNodeForContent(node)) {
82 // if we already have a decrypted node for part.objectTreeParser() encrypted node, don't do the decryption again
83 return MessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), newNode, true));
84 } else {
85 // Codec of the decrypted content is not delivered.
86 // Gnupgp tells that you should use UTF-8 by default.
87 // The user has the possibility to override the default charset.
88
89 QByteArray codecName = "utf-8";
90 if (!part.source()->overrideCodecName().isEmpty()) {
91 codecName = part.source()->overrideCodecName();
92 }
93
94 mp->startDecryption(node->decodedContent(), codecName);
95 qCDebug(MIMETREEPARSER_LOG) << "decrypted, signed?:" << messagePart->isSigned;
96
97 if (!messagePart->inProgress) {
98 if (!messagePart->isEncrypted) {
99 return nullptr;
100 }
101 auto tempNode = new KMime::Content();
102 tempNode->setBody(KMime::CRLFtoLF(mp->text().toUtf8()));
103 tempNode->parse();
104 // inside startDecryption we use toCodec and we
105 // converted the decoded text to utf-8 already.
106 tempNode->contentType()->setCharset("utf-8");
107
108 NodeHelper::magicSetType(tempNode);
109 if (node->topLevel()->textContent() != node && node->contentDisposition(false) && !tempNode->contentDisposition(false)) {
110 tempNode->contentDisposition()->setDisposition(node->contentDisposition()->disposition());
111 const auto fname = node->contentDisposition(false)->filename();
112 if (!fname.isEmpty()) {
113 tempNode->contentDisposition(false)->setFilename(fname);
114 }
115 }
116
117 if (!tempNode->head().isEmpty()) {
118 tempNode->contentDescription()->from7BitString("decrypted data");
119 }
120 tempNode->assemble();
121
122 nodeHelper->cleanExtraContent(node);
123 mp->clearSubParts();
124
125 nodeHelper->attachExtraContent(node, tempNode);
126
127 mp->parseInternal(tempNode, false);
128
129 nodeHelper->setNodeProcessed(node, false); // Set the data node to done to prevent it from being processed
130 }
131 }
132 return mp;
133}
QString decodedText(bool trimText=false, bool removeTrailingNewlines=false)
Content * topLevel() const
Headers::ContentDisposition * contentDisposition(bool create=true)
QByteArray decodedContent()
Content * textContent()
QList< Content * > contents() const
contentDisposition disposition() const
interface of message body parts.
Definition bodypart.h:45
virtual MimeTreeParser::ObjectTreeParser * objectTreeParser() const =0
For making it easier to refactor, add objectTreeParser.
virtual MimeTreeParser::NodeHelper * nodeHelper() const =0
Ok, this is ugly, exposing the node helper here, but there is too much useful stuff in there for real...
virtual KMime::Content * content() const =0
Returns the KMime::Content node represented here.
virtual bool decryptMessage() const =0
Return true if an encrypted mail should be decrypted.
virtual QByteArray overrideCodecName() const =0
The override codec that should be used for the mail.
static void magicSetType(KMime::Content *node, bool autoDecode=true)
Set the 'Content-Type' by mime-magic from the contents of the body.
bool isEmpty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:37:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.