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

0001 /*
0002    SPDX-FileCopyrightText: 2018-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "dkimmanagerkey.h"
0008 #include "dkimutil.h"
0009 #include <KConfig>
0010 #include <KConfigGroup>
0011 #include <QRegularExpression>
0012 #include <QtCrypto>
0013 using namespace MessageViewer;
0014 DKIMManagerKey::DKIMManagerKey(QObject *parent)
0015     : QObject(parent)
0016     , mQcaInitializer(new QCA::Initializer(QCA::Practical, 64))
0017 {
0018     loadKeys();
0019 }
0020 
0021 DKIMManagerKey::~DKIMManagerKey()
0022 {
0023     delete mQcaInitializer;
0024     saveKeys();
0025 }
0026 
0027 DKIMManagerKey *DKIMManagerKey::self()
0028 {
0029     static DKIMManagerKey s_self;
0030     return &s_self;
0031 }
0032 
0033 QString DKIMManagerKey::keyValue(const QString &selector, const QString &domain)
0034 {
0035     for (const KeyInfo &keyInfo : std::as_const(mKeys)) {
0036         if (keyInfo.selector == selector && keyInfo.domain == domain) {
0037             return keyInfo.keyValue;
0038         }
0039     }
0040     return {};
0041 }
0042 
0043 void DKIMManagerKey::updateLastUsed(const QString &selector, const QString &domain)
0044 {
0045     for (const KeyInfo &keyInfo : std::as_const(mKeys)) {
0046         if (keyInfo.selector == selector && keyInfo.domain == domain) {
0047             KeyInfo newKey = keyInfo;
0048             newKey.lastUsedDateTime = QDateTime::currentDateTime();
0049             addKey(newKey);
0050             return;
0051         }
0052     }
0053 }
0054 
0055 void DKIMManagerKey::addKey(const KeyInfo &key)
0056 {
0057     const QList<KeyInfo> keys = mKeys;
0058     for (const KeyInfo &keyInfo : keys) {
0059         if (keyInfo.selector == key.selector && keyInfo.domain == key.domain) {
0060             mKeys.removeAll(keyInfo);
0061         }
0062     }
0063     mKeys.append(key);
0064 }
0065 
0066 void DKIMManagerKey::removeKey(const QString &key)
0067 {
0068     for (const KeyInfo &keyInfo : std::as_const(mKeys)) {
0069         if (keyInfo.keyValue == key) {
0070             mKeys.removeAll(keyInfo);
0071             break;
0072         }
0073     }
0074 }
0075 
0076 QList<KeyInfo> DKIMManagerKey::keys() const
0077 {
0078     return mKeys;
0079 }
0080 
0081 QStringList DKIMManagerKey::keyRecorderList(KSharedConfig::Ptr &config) const
0082 {
0083     config = KSharedConfig::openConfig(MessageViewer::DKIMUtil::defaultConfigFileName(), KConfig::NoGlobals);
0084     const QStringList keyGroups = config->groupList().filter(QRegularExpression(QStringLiteral("DKIM Key Record #\\d+")));
0085     return keyGroups;
0086 }
0087 
0088 void DKIMManagerKey::loadKeys()
0089 {
0090     KSharedConfig::Ptr config;
0091     const QStringList keyGroups = keyRecorderList(config);
0092 
0093     mKeys.clear();
0094     for (const QString &groupName : keyGroups) {
0095         KConfigGroup group = config->group(groupName);
0096         const QString selector = group.readEntry(QStringLiteral("Selector"), QString());
0097         const QString domain = group.readEntry(QStringLiteral("Domain"), QString());
0098         const QString key = group.readEntry(QStringLiteral("Key"), QString());
0099         const QDateTime storedAt = QDateTime::fromString(group.readEntry(QStringLiteral("StoredAt"), QString()), Qt::ISODate);
0100         QDateTime lastUsed = QDateTime::fromString(group.readEntry(QStringLiteral("LastUsed"), QString()), Qt::ISODate);
0101         if (!lastUsed.isValid()) {
0102             lastUsed = storedAt;
0103         }
0104         mKeys.append(KeyInfo{key, selector, domain, storedAt, lastUsed});
0105     }
0106 }
0107 
0108 void DKIMManagerKey::saveKeys()
0109 {
0110     KSharedConfig::Ptr config;
0111     const QStringList filterGroups = keyRecorderList(config);
0112 
0113     for (const QString &group : filterGroups) {
0114         config->deleteGroup(group);
0115     }
0116     for (int i = 0, total = mKeys.count(); i < total; ++i) {
0117         const QString groupName = QStringLiteral("DKIM Key Record #%1").arg(i);
0118         KConfigGroup group = config->group(groupName);
0119         const KeyInfo &info = mKeys.at(i);
0120         group.writeEntry(QStringLiteral("Selector"), info.selector);
0121         group.writeEntry(QStringLiteral("Domain"), info.domain);
0122         group.writeEntry(QStringLiteral("Key"), info.keyValue);
0123         group.writeEntry(QStringLiteral("StoredAt"), info.storedAtDateTime.toString(Qt::ISODate));
0124         group.writeEntry(QStringLiteral("LastUsed"), info.lastUsedDateTime.toString(Qt::ISODate));
0125     }
0126 }
0127 
0128 void DKIMManagerKey::saveKeys(const QList<MessageViewer::KeyInfo> &lst)
0129 {
0130     mKeys = lst;
0131     saveKeys();
0132 }
0133 
0134 bool KeyInfo::operator==(const KeyInfo &other) const
0135 {
0136     return keyValue == other.keyValue && selector == other.selector && domain == other.domain;
0137 }
0138 
0139 bool KeyInfo::operator!=(const KeyInfo &other) const
0140 {
0141     return !(operator==(other));
0142 }
0143 
0144 QDebug operator<<(QDebug d, const KeyInfo &t)
0145 {
0146     d << " keyvalue " << t.keyValue;
0147     d << " selector " << t.selector;
0148     d << " domain " << t.domain;
0149     d << " storedAtDateTime " << t.storedAtDateTime;
0150     d << " lastUsedDateTime " << t.lastUsedDateTime;
0151     return d;
0152 }
0153 
0154 #include "moc_dkimmanagerkey.cpp"