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

KDE's Doxygen guidelines are available online.