File indexing completed on 2025-01-26 04:57:22
0001 /* 0002 SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "hashcachemanager.h" 0008 #include "checkphishingurlutil.h" 0009 #include "webengineviewer_debug.h" 0010 #include <KConfig> 0011 #include <KConfigGroup> 0012 0013 using namespace WebEngineViewer; 0014 0015 struct HashCacheInfo { 0016 HashCacheInfo() = default; 0017 0018 [[nodiscard]] bool isValid() const; 0019 HashCacheManager::UrlStatus status = HashCacheManager::Unknown; 0020 uint verifyCacheAfterThisTime = 0; 0021 }; 0022 0023 bool HashCacheInfo::isValid() const 0024 { 0025 return status != HashCacheManager::Unknown; 0026 } 0027 0028 class WebEngineViewer::HashCacheManagerPrivate 0029 { 0030 public: 0031 HashCacheManagerPrivate() 0032 { 0033 load(); 0034 } 0035 0036 void clearCache(); 0037 void save(); 0038 void load(); 0039 void addHashStatus(const QByteArray &hash, HashCacheManager::UrlStatus status, uint cacheDuration); 0040 [[nodiscard]] HashCacheManager::UrlStatus hashStatus(const QByteArray &hash); 0041 0042 private: 0043 void clear(); 0044 0045 QMap<QByteArray, HashCacheInfo> mHashList; 0046 }; 0047 0048 void HashCacheManagerPrivate::clear() 0049 { 0050 mHashList.clear(); 0051 } 0052 0053 void HashCacheManagerPrivate::clearCache() 0054 { 0055 clear(); 0056 save(); 0057 } 0058 0059 void HashCacheManagerPrivate::save() 0060 { 0061 KConfig phishingurlKConfig(WebEngineViewer::CheckPhishingUrlUtil::configFileName()); 0062 KConfigGroup grp = phishingurlKConfig.group(QStringLiteral("Hash")); 0063 0064 QList<QByteArray> lstMalware; 0065 QList<double> lstMalwareDuration; 0066 0067 QList<QByteArray> lstOk; 0068 QList<double> lstOkDuration; 0069 0070 QMapIterator<QByteArray, HashCacheInfo> i(mHashList); 0071 while (i.hasNext()) { 0072 i.next(); 0073 switch (i.value().status) { 0074 case HashCacheManager::UrlOk: 0075 lstOk << i.key(); 0076 lstOkDuration << i.value().verifyCacheAfterThisTime; 0077 break; 0078 case HashCacheManager::MalWare: 0079 lstMalware << i.key(); 0080 lstMalwareDuration << i.value().verifyCacheAfterThisTime; 0081 break; 0082 case HashCacheManager::Unknown: 0083 break; 0084 } 0085 } 0086 grp.writeEntry("malware", lstMalware); 0087 grp.writeEntry("malwareCacheDuration", lstMalwareDuration); 0088 0089 grp.writeEntry("safe", lstOk); 0090 grp.writeEntry("safeCacheDuration", lstOkDuration); 0091 grp.sync(); 0092 } 0093 0094 void HashCacheManagerPrivate::load() 0095 { 0096 clear(); 0097 KConfig phishingurlKConfig(WebEngineViewer::CheckPhishingUrlUtil::configFileName()); 0098 KConfigGroup grp = phishingurlKConfig.group(QStringLiteral("Hash")); 0099 QList<QByteArray> lstMalware = grp.readEntry("malware", QList<QByteArray>()); 0100 QList<double> lstMalwareDuration = grp.readEntry("malwareCacheDuration", QList<double>()); 0101 0102 QList<QByteArray> lstOk = grp.readEntry("safe", QList<QByteArray>()); 0103 QList<double> lstOkDuration = grp.readEntry("safeCacheDuration", QList<double>()); 0104 if (lstMalware.count() != lstMalwareDuration.count()) { 0105 qCWarning(WEBENGINEVIEWER_LOG) << "unsafe url: HashCacheManagerPrivate invalid number of data stored"; 0106 return; 0107 } 0108 if (lstOk.count() != lstOkDuration.count()) { 0109 qCWarning(WEBENGINEVIEWER_LOG) << "safe url: HashCacheManagerPrivate invalid number of data stored"; 0110 return; 0111 } 0112 0113 const int nb(lstOk.count()); 0114 for (int i = 0; i < nb; ++i) { 0115 HashCacheInfo info; 0116 info.status = HashCacheManager::UrlOk; 0117 info.verifyCacheAfterThisTime = lstOkDuration.at(i); 0118 if (info.isValid()) { 0119 mHashList.insert(lstOk.at(i), info); 0120 } 0121 } 0122 0123 const int nb2(lstMalware.count()); 0124 for (int i = 0; i < nb2; ++i) { 0125 HashCacheInfo info; 0126 info.status = HashCacheManager::MalWare; 0127 info.verifyCacheAfterThisTime = lstMalwareDuration.at(i); 0128 if (info.isValid()) { 0129 mHashList.insert(lstMalware.at(i), info); 0130 } 0131 } 0132 } 0133 0134 HashCacheManager::UrlStatus HashCacheManagerPrivate::hashStatus(const QByteArray &hash) 0135 { 0136 const HashCacheInfo info = mHashList.value(hash, HashCacheInfo()); 0137 if (info.isValid()) { 0138 if (CheckPhishingUrlUtil::cachedValueStillValid(info.verifyCacheAfterThisTime)) { 0139 return info.status; 0140 } else { 0141 return HashCacheManager::Unknown; 0142 } 0143 } else { 0144 return HashCacheManager::Unknown; 0145 } 0146 } 0147 0148 void HashCacheManagerPrivate::addHashStatus(const QByteArray &hash, HashCacheManager::UrlStatus status, uint cacheDuration) 0149 { 0150 HashCacheInfo info; 0151 info.status = status; 0152 info.verifyCacheAfterThisTime = cacheDuration; 0153 switch (status) { 0154 case HashCacheManager::UrlOk: 0155 mHashList.insert(hash, info); 0156 break; 0157 case HashCacheManager::MalWare: 0158 mHashList.insert(hash, info); 0159 break; 0160 case HashCacheManager::Unknown: 0161 qCWarning(WEBENGINEVIEWER_LOG()) << "HashCacheManagerPrivate::addHashStatus unknown status detected!"; 0162 return; 0163 } 0164 save(); 0165 } 0166 0167 HashCacheManager *HashCacheManager::self() 0168 { 0169 static HashCacheManager s_self; 0170 return &s_self; 0171 } 0172 0173 HashCacheManager::HashCacheManager(QObject *parent) 0174 : QObject(parent) 0175 , d(new HashCacheManagerPrivate) 0176 { 0177 } 0178 0179 HashCacheManager::~HashCacheManager() = default; 0180 0181 void HashCacheManager::clearCache() 0182 { 0183 d->clearCache(); 0184 } 0185 0186 void HashCacheManager::addHashStatus(const QByteArray &hash, HashCacheManager::UrlStatus status, uint cacheDuration) 0187 { 0188 d->addHashStatus(hash, status, cacheDuration); 0189 } 0190 0191 HashCacheManager::UrlStatus HashCacheManager::hashStatus(const QByteArray &hash) 0192 { 0193 return d->hashStatus(hash); 0194 } 0195 0196 #include "moc_hashcachemanager.cpp"