Messagelib

autocryptutils.cpp
1 /*
2  SPDX-FileCopyrightText: 2020 Sandro Kanuß <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "autocryptutils.h"
8 
9 #include "autocryptstorage.h"
10 
11 #include "autocrypt_debug.h"
12 
13 
14 
15 #include <QHash>
16 
17 using namespace MessageCore;
18 
19 HeaderMixupNodeHelper::HeaderMixupNodeHelper(MimeTreeParser::NodeHelper *n, KMime::Content *m)
20  : message(m)
21  , mNodeHelper(n)
22 {
23 }
24 
25 QDateTime HeaderMixupNodeHelper::dateHeader() const
26 {
27  return mNodeHelper->dateHeader(message);
28 }
29 
30 bool HeaderMixupNodeHelper::hasMailHeader(const char *header) const
31 {
32  return mNodeHelper->hasMailHeader(header, message);
33 }
34 
35 QSharedPointer<KMime::Headers::Generics::AddressList> HeaderMixupNodeHelper::mailHeaderAsAddressList(const char *header) const
36 {
37  return mNodeHelper->mailHeaderAsAddressList(header, message);
38 }
39 
40 const KMime::Headers::Base *HeaderMixupNodeHelper::mailHeaderAsBase(const char *header) const
41 {
42  return mNodeHelper->mailHeaderAsBase(header, message);
43 }
44 
45 QVector<MimeTreeParser::MessagePart::Ptr> HeaderMixupNodeHelper::messagePartsOfMailHeader(const char *header) const
46 {
47  return mNodeHelper->messagePartsOfMailHeader(header, message);
48 }
49 
50 QVector<KMime::Headers::Base *> HeaderMixupNodeHelper::headers(const char *header) const
51 {
52  return mNodeHelper->headers(header, message);
53 }
54 
55 QHash<QByteArray, QByteArray> MessageCore::paramsFromAutocryptHeader(const KMime::Headers::Base *const header)
56 {
58 
59  const auto &parts = header->as7BitString(false).split(';');
60  for (const auto &part : parts) {
61  const auto &i = part.split('=');
62  params[i[0].trimmed()] = i[1].trimmed();
63  }
64  return params;
65 }
66 
67 void MessageCore::processAutocryptfromMail(const HeaderMixupNodeHelper &mixup)
68 {
69  auto storage = AutocryptStorage::self();
70 
71  const auto fromAddr = mixup.mailHeaderAsAddressList("from");
72  if (fromAddr->addresses().size() != 1) {
73  qInfo(AUTOCRYPT_LOG) << "Don't update Autocrypt storage, because we have multiple From addresses found in "
74  << mixup.mailHeaderAsBase("Message-ID")->as7BitString(false);
75  return;
76  }
77 
78  if (mixup.hasMailHeader("Autocrypt")) {
79  KMime::Headers::Base *header = nullptr;
80  int valid = 0;
81  for (const auto h : mixup.headers("Autocrypt")) {
82  const auto params = paramsFromAutocryptHeader(h);
83  if (params.value("addr") != fromAddr->addresses().value(0)) {
84  continue;
85  }
86  bool invalid = false;
87  for (const auto &key : params.keys()) {
88  if (key == "addr") {
89  continue;
90  } else if (key == "prefer-encrypt") {
91  continue;
92  } else if (key == "keydata") {
93  continue;
94  } else if (key[0] == '_') {
95  continue;
96  } else {
97  invalid = true;
98  break;
99  }
100  }
101  if (invalid) {
102  continue;
103  }
104  if (!header) {
105  header = h;
106  }
107  valid++;
108  }
109  if (valid == 1) {
110  const auto params = paramsFromAutocryptHeader(header);
111  auto recipient = storage->addRecipient(params.value("addr"));
112  recipient->updateFromMessage(mixup, header);
113  qInfo(AUTOCRYPT_LOG) << "Update Autocrypt information for " << recipient->addr() << " from "
114  << mixup.mailHeaderAsBase("Message-ID")->as7BitString(false);
115  } else {
116  qInfo(AUTOCRYPT_LOG) << "Don't update Autocrypt storage, because we have multiple valid Autocrypt headers found in "
117  << mixup.mailHeaderAsBase("Message-ID")->as7BitString(false);
118  }
119  } else {
120  auto recipient = storage->getRecipient(fromAddr->addresses().value(0));
121  if (recipient) {
122  recipient->updateFromMessage(mixup, nullptr);
123  qInfo(AUTOCRYPT_LOG) << "Update Autocrypt information for " << recipient->addr() << " from "
124  << mixup.mailHeaderAsBase("Message-ID")->as7BitString(false);
125  }
126  }
127 
128  if (mixup.hasMailHeader("Autocrypt-Gossip")) {
129  MimeTreeParser::MessagePart::Ptr messagePart(nullptr);
130  for (const auto &mp : mixup.messagePartsOfMailHeader("Autocrypt-Gossip")) {
131  if (mp.staticCast<MimeTreeParser::EncryptedMessagePart>()) {
132  messagePart = mp;
133  break;
134  }
135  }
136  if (messagePart) {
137  for (const auto &header : messagePart->headers("Autocrypt-Gossip")) {
138  const auto params = paramsFromAutocryptHeader(header);
139  auto recipient = storage->addRecipient(params.value("addr"));
140  recipient->updateFromGossip(mixup, header);
141  qInfo(AUTOCRYPT_LOG) << "Update Autocrypt Gossip information for" << recipient->addr() << " from "
142  << mixup.mailHeaderAsBase("Message-ID")->as7BitString(false);
143  }
144  }
145  }
146  storage->save();
147 }
KCOREADDONS_EXPORT void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
QList< QByteArray > split(char sep) const const
QList< Key > keys() const const
const T value(const Key &key) const const
virtual QByteArray as7BitString(bool withHeaderType=true) const =0
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Thu Dec 2 2021 23:06:07 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.