Messagelib

encrypted.cpp
1 /*
2  SPDX-FileCopyrightText: 2017 Sandro KnauƟ <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "encrypted.h"
8 
9 #include "utils.h"
10 
11 #include "messagepart.h"
12 #include "objecttreeparser.h"
13 
14 #include <KMime/Content>
15 
16 #include <QGpgME/DataProvider>
17 #include <QGpgME/Protocol>
18 #include <gpgme++/data.h>
19 
20 #include <QTextCodec>
21 
22 #include "mimetreeparser_debug.h"
23 
24 using namespace MimeTreeParser;
25 
26 const EncryptedBodyPartFormatter *EncryptedBodyPartFormatter::self;
27 
28 const Interface::BodyPartFormatter *EncryptedBodyPartFormatter::create()
29 {
30  if (!self) {
31  self = new EncryptedBodyPartFormatter();
32  }
33  return self;
34 }
35 
36 MessagePart::Ptr EncryptedBodyPartFormatter::process(Interface::BodyPart &part) const
37 {
38  KMime::Content *node = part.content();
39 
40  if (!node->contents().isEmpty()) {
41  Q_ASSERT(false);
42  return {};
43  }
44 
45  QGpgME::QByteArrayDataProvider dp(node->decodedContent());
46  GpgME::Data data(&dp);
47 
48  if (data.type() == GpgME::Data::Unknown) {
49  return nullptr;
50  }
51 
52  const QGpgME::Protocol *useThisCryptProto = nullptr;
53 
54  useThisCryptProto = QGpgME::openpgp();
55 
56  // TODO: Load correct crypto Proto
57 
58  part.nodeHelper()->setEncryptionState(node, KMMsgFullyEncrypted);
59 
61  new EncryptedMessagePart(part.objectTreeParser(), node->decodedText(), useThisCryptProto, part.nodeHelper()->fromAsString(node), node));
62  mp->setIsEncrypted(true);
63  mp->setDecryptMessage(part.source()->decryptMessage());
64  PartMetaData *messagePart(mp->partMetaData());
65  if (!part.source()->decryptMessage()) {
66  part.nodeHelper()->setNodeProcessed(node, false); // Set the data node to done to prevent it from being processed
67  } else if (KMime::Content *newNode = part.nodeHelper()->decryptedNodeForContent(node)) {
68  // if we already have a decrypted node for part.objectTreeParser() encrypted node, don't do the decryption again
69  return MessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), newNode, true));
70  } else {
71  const auto codec = QTextCodec::codecForName("utf-8");
72  mp->startDecryption(node->decodedContent(), codec);
73 
74  qCDebug(MIMETREEPARSER_LOG) << "decrypted, signed?:" << messagePart->isSigned;
75 
76  if (!messagePart->inProgress) {
77  if (!messagePart->isEncrypted) {
78  return nullptr;
79  }
80  auto tempNode = new KMime::Content();
81  tempNode->contentType()->setCharset("utf-8");
82  tempNode->setBody(KMime::CRLFtoLF(part.nodeHelper()->codec(node)->fromUnicode(mp->text())));
83  tempNode->parse();
84  NodeHelper::magicSetType(tempNode);
85  if (node->topLevel()->textContent() != node && node->contentDisposition(false) && !tempNode->contentDisposition(false)) {
86  tempNode->contentDisposition()->setDisposition(node->contentDisposition()->disposition());
87  const auto fname = node->contentDisposition(false)->filename();
88  if (!fname.isEmpty()) {
89  tempNode->contentDisposition(false)->setFilename(fname);
90  }
91  }
92 
93  if (!tempNode->head().isEmpty()) {
94  tempNode->contentDescription()->from7BitString("decrypted data");
95  }
96  tempNode->assemble();
97 
98  part.nodeHelper()->cleanExtraContent(node);
99  mp->clearSubParts();
100 
101  part.nodeHelper()->attachExtraContent(node, tempNode);
102 
103  mp->parseInternal(tempNode, false);
104 
105  part.nodeHelper()->setNodeProcessed(node, false); // Set the data node to done to prevent it from being processed
106  }
107  }
108  return mp;
109 }
QByteArray fromUnicode(const QString &str) const const
const QTextCodec * codec(KMime::Content *node)
Get a QTextCodec suitable for this message part.
virtual bool decryptMessage() const =0
Return true if an encrypted mail should be decrypted.
Headers::ContentDisposition * contentDisposition(bool create=true)
QString decodedText(bool trimText=false, bool removeTrailingNewlines=false)
static void magicSetType(KMime::Content *node, bool autoDecode=true)
Set the &#39;Content-Type&#39; by mime-magic from the contents of the body.
QByteArray decodedContent()
QVector< Content * > contents() const
void attachExtraContent(KMime::Content *topLevelNode, KMime::Content *content)
Attach an extra node to an existing node.
Content * topLevel() const
virtual KMime::Content * content() const =0
Returns the KMime::Content node represented here.
Content * textContent()
QTextCodec * codecForName(const QByteArray &name)
interface of message body parts.
Definition: bodypart.h:44
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...
contentDisposition disposition() const
virtual MimeTreeParser::ObjectTreeParser * objectTreeParser() const =0
For making it easier to refactor, add objectTreeParser.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Dec 6 2021 23:04:57 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.