File indexing completed on 2025-03-09 04:54:28

0001 /*
0002    SPDX-FileCopyrightText: 2019-2024 Laurent Montel <montel@kde.org>
0003 
0004    Code based on ARHParser.jsm from dkim_verifier (Copyright (c) Philippe Lieser)
0005    (This software is licensed under the terms of the MIT License.)
0006 
0007    SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #include "dkimauthenticationstatusinfoutil.h"
0011 
0012 /*
0013 // domain-name as specified in Section 3.5 of RFC 6376 [DKIM].
0014 let domain_name_p = "(?:" + sub_domain_p + "(?:\\." + sub_domain_p + ")+)";
0015 */
0016 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::wsp_p()
0017 {
0018     // WSP as specified in Appendix B.1 of RFC 5234
0019     return QStringLiteral("[ \t]");
0020 }
0021 
0022 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::vchar_p()
0023 {
0024     // VCHAR as specified in Appendix B.1 of RFC 5234
0025     return QStringLiteral("[!-~]");
0026 }
0027 
0028 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::letDig_p()
0029 {
0030     // Let-dig  as specified in Section 4.1.2 of RFC 5321 [SMTP].
0031     return QStringLiteral("[A-Za-z0-9]");
0032 }
0033 
0034 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::ldhStr_p()
0035 {
0036     // Ldh-str  as specified in Section 4.1.2 of RFC 5321 [SMTP].
0037     return QStringLiteral("(?:[A-Za-z0-9-]*%1)").arg(DKIMAuthenticationStatusInfoUtil::letDig_p());
0038 }
0039 
0040 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::keyword_p()
0041 {
0042     // "Keyword" as specified in Section 4.1.2 of RFC 5321 [SMTP].
0043     return DKIMAuthenticationStatusInfoUtil::ldhStr_p();
0044 }
0045 
0046 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::subDomain_p()
0047 {
0048     // sub-domain as specified in Section 4.1.2 of RFC 5321 [SMTP].
0049     return QStringLiteral("(?:%1%2?)").arg(DKIMAuthenticationStatusInfoUtil::letDig_p(), DKIMAuthenticationStatusInfoUtil::ldhStr_p());
0050 }
0051 
0052 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::obsFws_p()
0053 {
0054     // obs-FWS as specified in Section 4.2 of RFC 5322
0055     return QStringLiteral("(?:%1+(?:\r\n%1+)*)").arg(DKIMAuthenticationStatusInfoUtil::wsp_p());
0056 }
0057 
0058 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::quotedPair_p()
0059 {
0060     // quoted-pair as specified in Section 3.2.1 of RFC 5322
0061     // Note: obs-qp is not included, so this pattern matches less then specified!
0062     return QStringLiteral("(?:\\\\(?:%1|%2))").arg(vchar_p(), wsp_p());
0063 }
0064 
0065 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::fws_p()
0066 {
0067     // FWS as specified in Section 3.2.2 of RFC 5322
0068     return QStringLiteral("(?:(?:(?:%1*\r\n)?%1+)|%2)").arg(wsp_p(), obsFws_p());
0069 }
0070 
0071 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::fws_op()
0072 {
0073     return QStringLiteral("%1?").arg(fws_p());
0074 }
0075 
0076 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::ctext_p()
0077 {
0078     // ctext as specified in Section 3.2.2 of RFC 5322
0079     return QStringLiteral("[!-'*-[\\]-~]");
0080 }
0081 
0082 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::ccontent_p()
0083 {
0084     // ccontent as specified in Section 3.2.2 of RFC 5322
0085     // Note: comment is not included, so this pattern matches less then specified!
0086     return QStringLiteral("(?:%1|%2)").arg(ctext_p(), quotedPair_p());
0087 }
0088 
0089 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::comment_p()
0090 {
0091     // comment as specified in Section 3.2.2 of RFC 5322
0092     return QStringLiteral("\\((?:%1%2)*%1\\)").arg(fws_op(), ccontent_p());
0093 }
0094 
0095 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::cfws_p()
0096 {
0097     // CFWS as specified in Section 3.2.2 of RFC 5322 [MAIL]
0098     return QStringLiteral("(?:(?:(?:%1%2)+%1)|%3)").arg(fws_op(), comment_p(), fws_p());
0099 }
0100 
0101 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::cfws_op()
0102 {
0103     return QStringLiteral("%1?").arg(cfws_p());
0104 }
0105 
0106 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::atext()
0107 {
0108     // atext as specified in Section 3.2.3 of RFC 5322
0109     return QStringLiteral("[!#-'*-+/-9=?A-Z^-~-]");
0110 }
0111 
0112 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::dotAtomText_p()
0113 {
0114     // dot-atom-text as specified in Section 3.2.3 of RFC 5322
0115     return QStringLiteral("(?:%1+(?:\\.%1+)*)").arg(atext());
0116 }
0117 
0118 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::dotAtom_p()
0119 {
0120     // dot-atom as specified in Section 3.2.3 of RFC 5322
0121     // dot-atom        =   [CFWS] dot-atom-text [CFWS]
0122     return QStringLiteral("(?:%1%2%1)").arg(cfws_op(), dotAtomText_p());
0123 }
0124 
0125 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::qtext_p()
0126 {
0127     // qtext as specified in Section 3.2.4 of RFC 5322
0128     // Note: obs-qtext is not included, so this pattern matches less then specified!
0129     return QStringLiteral("[!#-[\\]-~]");
0130 }
0131 
0132 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::qcontent_p()
0133 {
0134     // qcontent as specified in Section 3.2.4 of RFC 5322
0135     return QStringLiteral("(?:%1|%2)").arg(qtext_p(), quotedPair_p());
0136 }
0137 
0138 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::quotedString_p()
0139 {
0140     // quoted-string as specified in Section 3.2.4 of RFC 5322
0141     return QStringLiteral("(?:%1\"(?:%2%3)*%2\"%1)").arg(cfws_op(), fws_op(), qcontent_p());
0142 }
0143 
0144 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::quotedString_cp()
0145 {
0146     return QStringLiteral("(?:%1\"((?:%2%3)*)%2\"%1)").arg(cfws_op(), fws_op(), qcontent_p());
0147 }
0148 
0149 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::localPart_p()
0150 {
0151     // local-part as specified in Section 3.4.1 of RFC 5322
0152     // Note: obs-local-part is not included, so this pattern matches less then specified!
0153     return QStringLiteral("(?:%1|%2))").arg(dotAtom_p(), quotedString_p());
0154 }
0155 
0156 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::token_p()
0157 {
0158     // token as specified in Section 5.1 of RFC 2045.
0159     return QStringLiteral("[^ \\x00-\\x1F\\x7F()<>@,;:\\\\\"/[\\]?=]+");
0160 }
0161 
0162 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::value_p()
0163 {
0164     // "value" as specified in Section 5.1 of RFC 2045.
0165     return QStringLiteral("(?:%1|%2)").arg(token_p(), quotedString_p());
0166 }
0167 
0168 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::value_cp()
0169 {
0170     return QStringLiteral("(?:(%1)|%2)").arg(token_p(), quotedString_cp());
0171 }
0172 
0173 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::domainName_p()
0174 {
0175     // domain-name as specified in Section 3.5 of RFC 6376 [DKIM].
0176     return QStringLiteral("(?:%1(?:\\.%1)+)").arg(subDomain_p());
0177 }
0178 
0179 // Tries to matches a pattern to the beginning of str.
0180 //  Adds CFWS_op to the beginning of pattern.
0181 //  pattern must be followed by string end, ";" or CFWS_p.
0182 // If match is found, removes it from str.
0183 QString MessageViewer::DKIMAuthenticationStatusInfoUtil::regexMatchO(const QString &regularExpressionStr)
0184 {
0185     const QString regexp = (QLatin1Char('^') + DKIMAuthenticationStatusInfoUtil::cfws_op() + QStringLiteral("(?:") + regularExpressionStr + QLatin1Char(')')
0186                             + QStringLiteral("(?:(?:") + DKIMAuthenticationStatusInfoUtil::cfws_op() + QStringLiteral("\r\n$)|(?=;)|(?=")
0187                             + DKIMAuthenticationStatusInfoUtil::cfws_p() + QStringLiteral("))"));
0188     return regexp;
0189 }