Messagelib

dkimcheckfulljob.cpp
1/*
2 SPDX-FileCopyrightText: 2019-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "dkimcheckfulljob.h"
8#include "dkimauthenticationstatusinfoconverter.h"
9#include "dkimcheckauthenticationstatusjob.h"
10#include "dkimcheckpolicyjob.h"
11#include "dkimgeneraterulejob.h"
12#include "dkimmanagerkey.h"
13#include "dkimstoreresultjob.h"
14#include "messageviewer_dkimcheckerdebug.h"
15#include <KLocalizedString>
16#include <KMessageBox>
17using namespace MessageViewer;
18
19DKIMCheckFullJob::DKIMCheckFullJob(QObject *parent)
20 : QObject(parent)
21{
22}
23
24DKIMCheckFullJob::~DKIMCheckFullJob() = default;
25
26DKIMCheckPolicy DKIMCheckFullJob::policy() const
27{
28 return mCheckPolicy;
29}
30
31void DKIMCheckFullJob::setPolicy(const DKIMCheckPolicy &policy)
32{
33 mCheckPolicy = policy;
34}
35
36void DKIMCheckFullJob::startCheckFullInfo(const Akonadi::Item &item)
37{
38 if (!item.isValid()) {
40 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "Invalid item";
41 return;
42 }
43 mAkonadiItem = item;
44 if (mAkonadiItem.hasPayload<KMime::Message::Ptr>()) {
45 mMessage = mAkonadiItem.payload<KMime::Message::Ptr>();
46 }
47 if (!mMessage) {
49 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "Invalid message";
50 return;
51 }
52 checkAuthenticationResults();
53}
54
55void DKIMCheckFullJob::checkAuthenticationResults()
56{
57 if (mCheckPolicy.useAuthenticationResults()) {
58 auto job = new DKIMCheckAuthenticationStatusJob(this);
59 mHeaderParser.setHead(mMessage->head());
60 mHeaderParser.parse();
61 job->setHeaderParser(mHeaderParser);
62 job->setUseRelaxedParsing(mCheckPolicy.useRelaxedParsing());
63 connect(job, &DKIMCheckAuthenticationStatusJob::result, this, &DKIMCheckFullJob::slotCheckAuthenticationStatusResult);
64 job->start();
65 } else {
66 checkSignature();
67 }
68}
69
70void DKIMCheckFullJob::checkSignature(const QList<DKIMCheckSignatureJob::DKIMCheckSignatureAuthenticationResult> &lst)
71{
72 auto job = new DKIMCheckSignatureJob(this);
73 connect(job, &DKIMCheckSignatureJob::storeKey, this, &DKIMCheckFullJob::storeKey);
74 connect(job, &DKIMCheckSignatureJob::result, this, &DKIMCheckFullJob::slotCheckSignatureResult);
75 job->setMessage(mMessage);
76 job->setHeaderParser(mHeaderParser);
77 job->setPolicy(mCheckPolicy);
78 job->setCheckSignatureAuthenticationResult(lst);
79 job->start();
80}
81
82void DKIMCheckFullJob::startCheckFullInfo(const KMime::Message::Ptr &message)
83{
84 mMessage = message;
85 if (!mMessage) {
87 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "Invalid message";
88 return;
89 }
90 checkAuthenticationResults();
91}
92
93void DKIMCheckFullJob::storeKey(const QString &key, const QString &domain, const QString &selector)
94{
95 switch (mCheckPolicy.saveKey()) {
96 case MessageViewer::MessageViewerSettings::EnumSaveKey::NotSaving:
97 // Nothing
98 break;
99 case MessageViewer::MessageViewerSettings::EnumSaveKey::Save:
100 storeInKeyManager(key, selector, domain, false);
101 break;
102 case MessageViewer::MessageViewerSettings::EnumSaveKey::SaveAndCompare:
103 storeInKeyManager(key, selector, domain, true);
104 break;
105 }
106}
107
108void DKIMCheckFullJob::storeInKeyManager(const QString &key, const QString &domain, const QString &selector, bool verify)
109{
110 const MessageViewer::KeyInfo info{key, selector, domain, QDateTime::currentDateTime()};
111 if (verify) {
112 const QString keyStored = MessageViewer::DKIMManagerKey::self()->keyValue(selector, domain);
113 if (!keyStored.isEmpty()) {
114 if (keyStored != key) {
115 // qDebug() << "storeInKeyManager : keyStored " << keyStored << " key " << key;
116 // qDebug() << "domain " << domain << " selector " << selector;
117 const int answer = KMessageBox::warningTwoActions(nullptr,
118 i18n("Stored DKIM key is different from the current one. Do you want to store this one too?"),
119 i18nc("@title:window", "Key Changed"),
120 KGuiItem(i18nc("@action:button", "Store")),
122 if (answer == KMessageBox::ButtonCode::SecondaryAction) {
123 return;
124 }
125 }
126 }
127 }
128 MessageViewer::DKIMManagerKey::self()->addKey(info);
129}
130
131void DKIMCheckFullJob::slotCheckAuthenticationStatusResult(const MessageViewer::DKIMAuthenticationStatusInfo &info)
132{
133 // qDebug() << "info " << info;
134 DKIMAuthenticationStatusInfoConverter converter;
135 converter.setStatusInfo(info);
136 // TODO Convert to CheckSignatureAuthenticationResult + add this list to CheckSignatureResult directly
138 // qDebug() << " lst " << lst;
139 // TODO use it.
140
141 // TODO check info ! if auth is ok not necessary to checkSignature
142 if (mCheckPolicy.useOnlyAuthenticationResults()) {
143 // Don't check signature if not necessary.
144 }
145 checkSignature(lst);
146}
147
148void DKIMCheckFullJob::storeResult(const DKIMCheckSignatureJob::CheckSignatureResult &checkResult)
149{
150 if (mCheckPolicy.saveDkimResult()) {
151 if (checkResult.status == DKIMCheckSignatureJob::DKIMStatus::Valid || checkResult.status == DKIMCheckSignatureJob::DKIMStatus::Invalid
152 || checkResult.status == DKIMCheckSignatureJob::DKIMStatus::NeedToBeSigned) {
153 auto job = new DKIMStoreResultJob(this);
154 job->setItem(mAkonadiItem);
155 job->setResult(checkResult);
156 job->start();
157 }
158 }
159 if (mCheckPolicy.autogenerateRule()) {
160 if (mCheckPolicy.autogenerateRuleOnlyIfSenderInSDID()) {
161 // TODO
162 // FIXME Check value SDID !
163 generateRule(checkResult);
164 } else {
165 generateRule(checkResult);
166 }
167 }
168
169 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) << "result : status " << checkResult.status << " error : " << checkResult.error << " warning "
170 << checkResult.warning;
171 Q_EMIT result(checkResult, mAkonadiItem.id());
172 deleteLater();
173}
174
175void DKIMCheckFullJob::generateRule(const DKIMCheckSignatureJob::CheckSignatureResult &checkResult)
176{
177 if (checkResult.status == DKIMCheckSignatureJob::DKIMStatus::Valid) {
178 auto job = new DKIMGenerateRuleJob(this);
179 job->setResult(checkResult);
180 if (!job->start()) {
181 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "Impossible to start autogenerate rule";
182 }
183 }
184}
185
186void DKIMCheckFullJob::slotCheckSignatureResult(const DKIMCheckSignatureJob::CheckSignatureResult &checkResult)
187{
188 if (mCheckPolicy.checkIfEmailShouldBeSigned() && (checkResult.status == DKIMCheckSignatureJob::DKIMStatus::EmailNotSigned)) {
189 auto job = new DKIMCheckPolicyJob(this);
190 connect(job, &DKIMCheckPolicyJob::result, this, &DKIMCheckFullJob::storeResult);
191 job->setCheckResult(checkResult);
192 job->setEmailAddress(checkResult.fromEmail);
193 if (!job->start()) {
194 storeResult(checkResult);
195 }
196 } else {
197 storeResult(checkResult);
198 }
199}
200
201#include "moc_dkimcheckfulljob.cpp"
T payload() const
Id id() const
bool isValid() const
bool hasPayload() const
The DKIMCheckPolicyJob class.
The DKIMCheckPolicy class.
The DKIMCheckSignatureJob class.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
ButtonCode warningTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous))
KGuiItem discard()
QDateTime currentDateTime()
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
T qobject_cast(QObject *object)
The KeyInfo struct.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:12:43 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.