Messagelib

dmarcinfo.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 "dmarcinfo.h"
8#include "messageviewer_dkimcheckerdebug.h"
9
10using namespace MessageViewer;
11DMARCInfo::DMARCInfo() = default;
12
13bool DMARCInfo::parseDMARC(const QString &key)
14{
15 if (key.isEmpty()) {
16 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "Error: key empty";
17 return false;
18 }
19 QString cleanKey = key;
20 cleanKey.replace(QLatin1StringView("; "), QLatin1StringView(";"));
21 const QStringList items = cleanKey.split(QLatin1Char(';'), Qt::SkipEmptyParts);
22 for (int i = 0; i < items.count(); ++i) {
23 const QString elem = items.at(i).trimmed();
24 if (elem.startsWith(QLatin1StringView("v="))) {
25 // v: Version (plain-text; REQUIRED). Identifies the record retrieved
26 // as a DMARC record. It MUST have the value of "DMARC1". The value
27 // of this tag MUST match precisely; if it does not or it is absent,
28 // the entire retrieved record MUST be ignored. It MUST be the first
29 // tag in the list.
30 mVersion = elem.right(elem.length() - 2);
31 } else if (elem.startsWith(QLatin1StringView("r="))) {
32 // adkim: (plain-text; OPTIONAL; default is "r".) Indicates whether
33 // strict or relaxed DKIM Identifier Alignment mode is required by
34 // the Domain Owner. See Section 3.1.1 for details. Valid values
35 // are as follows:
36 // r: relaxed mode
37 // s: strict mode
38 mAdkim = elem.right(elem.length() - 2);
39 } else if (elem.startsWith(QLatin1StringView("p="))) {
40 // p: Requested Mail Receiver policy (plain-text; REQUIRED for policy
41 // records). Indicates the policy to be enacted by the Receiver at
42 // the request of the Domain Owner. Policy applies to the domain
43 // queried and to subdomains, unless subdomain policy is explicitly
44 // described using the "sp" tag. This tag is mandatory for policy
45 // records only, but not for third-party reporting records (see
46 // Section 7.1). Possible values are as follows:
47
48 // none: The Domain Owner requests no specific action be taken
49 // regarding delivery of messages.
50
51 // quarantine: The Domain Owner wishes to have email that fails the
52 // DMARC mechanism check be treated by Mail Receivers as
53 // suspicious. Depending on the capabilities of the Mail
54 // Receiver, this can mean "place into spam folder", "scrutinize
55 // with additional intensity", and/or "flag as suspicious".
56
57 // reject: The Domain Owner wishes for Mail Receivers to reject
58 // email that fails the DMARC mechanism check. Rejection SHOULD
59 // occur during the SMTP transaction. See Section 10.3 for some
60 // discussion of SMTP rejection methods and their implications.
61 mPolicy = elem.right(elem.length() - 2);
62 } else if (elem.startsWith(QLatin1StringView("ptc="))) {
63 // pct: (plain-text integer between 0 and 100, inclusive; OPTIONAL;
64 // default is 100). Percentage of messages from the Domain Owner's
65 // mail stream to which the DMARC policy is to be applied. However,
66 // this MUST NOT be applied to the DMARC-generated reports, all of
67 // which must be sent and received unhindered. The purpose of the
68 // "pct" tag is to allow Domain Owners to enact a slow rollout
69 // enforcement of the DMARC mechanism. The prospect of "all or
70 // nothing" is recognized as preventing many organizations from
71 // experimenting with strong authentication-based mechanisms. See
72 // Section 6.6.4 for details. Note that random selection based on
73 // this percentage, such as the following pseudocode, is adequate:
74
75 // if (random mod 100) < pct then
76 // selected = true
77 // else
78 // selected = false
79 // TODO verify if it's a percentage
80 mPercentage = QStringView(elem).right(elem.length() - 4).toInt();
81 } else if (elem.startsWith(QLatin1StringView("sp="))) {
82 // sp: Requested Mail Receiver policy for all subdomains (plain-text;
83 // OPTIONAL). Indicates the policy to be enacted by the Receiver at
84 // the request of the Domain Owner. It applies only to subdomains of
85 // the domain queried and not to the domain itself. Its syntax is
86 // identical to that of the "p" tag defined above. If absent, the
87 // policy specified by the "p" tag MUST be applied for subdomains.
88 // Note that "sp" will be ignored for DMARC records published on
89 // subdomains of Organizational Domains due to the effect of the
90 // DMARC policy discovery mechanism described in Section 6.6.3.
91 mSubDomainPolicy = elem.right(elem.length() - 3);
92 }
93 }
94 if (mAdkim.isEmpty() && mVersion == QLatin1StringView("DMARC1")) {
95 mAdkim = QLatin1Char('r');
96 }
97
98 return true;
99}
100
101QString DMARCInfo::version() const
102{
103 return mVersion;
104}
105
106void DMARCInfo::setVersion(const QString &version)
107{
108 mVersion = version;
109}
110
111QString DMARCInfo::adkim() const
112{
113 return mAdkim;
114}
115
116void DMARCInfo::setAdkim(const QString &adkim)
117{
118 mAdkim = adkim;
119}
120
121QString DMARCInfo::policy() const
122{
123 return mPolicy;
124}
125
126void DMARCInfo::setPolicy(const QString &policy)
127{
128 mPolicy = policy;
129}
130
131int DMARCInfo::percentage() const
132{
133 return mPercentage;
134}
135
136void DMARCInfo::setPercentage(int percentage)
137{
138 mPercentage = percentage;
139}
140
141QString DMARCInfo::subDomainPolicy() const
142{
143 return mSubDomainPolicy;
144}
145
146void DMARCInfo::setSubDomainPolicy(const QString &subDomainPolicy)
147{
148 mSubDomainPolicy = subDomainPolicy;
149}
150
151bool DMARCInfo::operator==(const DMARCInfo &other) const
152{
153 return mVersion == other.version() && mAdkim == other.adkim() && mPolicy == other.policy() && mSubDomainPolicy == other.subDomainPolicy()
154 && mPercentage == other.percentage();
155}
156
158{
159 d << " mVersion " << t.version();
160 d << " mAdkim " << t.adkim();
161 d << " mPolicy " << t.policy();
162 d << " mSubDomainPolicy " << t.subDomainPolicy();
163 d << " mPercentage " << t.percentage();
164 return d;
165}
The DMARCInfo class.
Definition dmarcinfo.h:18
KCOREADDONS_EXPORT unsigned int version()
QDebug operator<<(QDebug dbg, const DcrawInfoContainer &c)
const_reference at(qsizetype i) const const
qsizetype count() const const
bool isEmpty() const const
qsizetype length() const const
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QString right(qsizetype n) const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QStringView right(qsizetype length) const const
int toInt(bool *ok, int base) const const
SkipEmptyParts
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:59:13 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.