diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-02-03 15:59:29 +0100 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-02-03 16:26:52 +0100 |
| commit | fdb64c59865e4db76addfb8222f6421443e25240 (patch) | |
| tree | 0de2bad9f758c69b7fb9ba2670653c8515a3a70d /trust_db.cpp | |
| parent | 207176de48d5e44c8d3e6318b526db5d772dd008 (diff) | |
| download | yachat6-fdb64c59865e4db76addfb8222f6421443e25240.tar.gz | |
Import files from xxcc
Diffstat (limited to 'trust_db.cpp')
| -rw-r--r-- | trust_db.cpp | 415 |
1 files changed, 415 insertions, 0 deletions
diff --git a/trust_db.cpp b/trust_db.cpp new file mode 100644 index 0000000..3dfd906 --- /dev/null +++ b/trust_db.cpp @@ -0,0 +1,415 @@ +#include "trust_db.h" +#include <QXmppTrustLevel.h> +#include <QXmppTrustSecurityPolicy.h> +#include <QXmppConfiguration.h> +#include <QXmppFutureUtils_p.h> +#include <QXmppPromise.h> +#include <QEventLoop> +#include <QtConcurrent/QtConcurrent> +#include <iostream> + +TrustDb::TrustDb(const QString &jid, const JidDb &db) : + jid(jid), + db(db) +{ +} + +static const struct +{ + QXmpp::TrustLevel level; + const char *str; +} trustlevels[] = +{ + {QXmpp::TrustLevel::Undecided, "Undecided"}, + {QXmpp::TrustLevel::AutomaticallyDistrusted, "AutomaticallyDistrusted"}, + {QXmpp::TrustLevel::ManuallyDistrusted, "ManuallyDistrusted"}, + {QXmpp::TrustLevel::AutomaticallyTrusted, "AutomaticallyTrusted"}, + {QXmpp::TrustLevel::ManuallyTrusted, "ManuallyTrusted"}, + {QXmpp::TrustLevel::Authenticated, "Authenticated"} +}; + +static const struct +{ + QXmpp::TrustSecurityPolicy policy; + const char *str; +} tsp_levels[] = +{ + {QXmpp::NoSecurityPolicy, "NoSecurityPolicy"}, + {QXmpp::Toakafa, "Toakafa"} +}; + +static QString toString(const QXmpp::TrustSecurityPolicy securityPolicy) +{ + for (const auto &t : tsp_levels) + if (t.policy == securityPolicy) + return t.str; + + return "unknown"; +} + +static QString toString(const QXmpp::TrustLevel &trustLevel) +{ + for (const auto &t : trustlevels) + if (t.level == trustLevel) + return t.str; + + return "unknown"; +} + +static int toSecurityPolicy(const QString &s, + QXmpp::TrustSecurityPolicy &securityPolicy) +{ + for (const auto &t : tsp_levels) + if (t.str == s) + { + securityPolicy = t.policy; + return 0; + } + + return -1; +} + +static int toTrustLevel(const QString &tstr, QXmpp::TrustLevel &trustLevel) +{ + for (const auto &t : trustlevels) + if (t.str == tstr) + { + trustLevel = t.level; + return 0; + } + + return -1; +} + +QString TrustDb::service() const +{ + return "xxcc/trust/" + jid; +} + +QXmppTask<void> TrustDb::setSecurityPolicy(const QString &encryption, + const QXmpp::TrustSecurityPolicy securityPolicy) +{ + if (db.store(encryption, toString(securityPolicy))) + std::cerr << "TrustDb::setSecurityPolicy: store failed" + << std::endl; + + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<void> TrustDb::resetSecurityPolicy(const QString &encryption) +{ + if (db.store(encryption, QString())) + std::cerr << "TrustDb::resetSecurityPolicy: store failed" + << std::endl; + + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<QXmpp::TrustSecurityPolicy> TrustDb::securityPolicy( + const QString &encryption) +{ + const auto s = db.securityPolicy(encryption); + QXmpp::TrustSecurityPolicy policy; + + if (toSecurityPolicy(s, policy)) + std::cerr << "TrustDb::securityPolicy: toSecurityPolicy failed" + << std::endl; + + return QXmpp::Private::makeReadyTask(QXmpp::TrustSecurityPolicy(policy)); +} + +QXmppTask<void> TrustDb::setOwnKey(const QString &encryption, + const QByteArray &keyId) +{ + if (db.store(encryption, keyId)) + std::cerr << "TrustDb::setOwnKey: db.store failed" << std::endl; + + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<void> TrustDb::resetOwnKey(const QString &encryption) +{ + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<QByteArray> TrustDb::ownKey(const QString &encryption) +{ + return QXmpp::Private::makeReadyTask(db.ownKeyId(encryption)); +} + +QXmppTask<void> TrustDb::addKeys(const QString &encryption, + const QString &keyOwnerJid, const QList<QByteArray> &keyIds, + const QXmpp::TrustLevel trustLevel) +{ + const struct JidDb::Keys keys(keyOwnerJid, toString(trustLevel), keyIds); + + if (db.store(encryption, keys)) + std::cerr << "TrustDb::addKeys: store failed" << std::endl; + + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<void> TrustDb::removeKeys(const QString &encryption, + const QList<QByteArray> &keyIds) +{ + auto keys = db.keys(encryption); + + for (const auto &id : keyIds) + for (auto &k : keys) + { + const auto i = k.keys.indexOf(id); + + if (i != -1) + { + k.keys.removeAt(i); + break; + } + } + + for (const auto &k : keys) + if (db.store(encryption, k)) + std::cerr << "TrustDb::removeKeys: store failed" << std::endl; + + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<void> TrustDb::removeKeys(const QString &encryption, + const QString &keyOwnerJid) +{ + auto keys = db.keys(encryption); + + for (int i = 0; i < keys.count(); i++) + if (keys[i].owner == keyOwnerJid) + { + keys.removeAt(i); + break; + } + + for (const auto &k : keys) + if (db.store(encryption, k)) + std::cerr << "TrustDb::removeKeys: store failed" << std::endl; + + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<void> TrustDb::removeKeys(const QString &encryption) +{ + db.removeKeys(encryption); + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<QHash<QXmpp::TrustLevel, + QMultiHash<QString, QByteArray>>> TrustDb::keys(const QString &encryption, + const QXmpp::TrustLevels trustLevels) +{ + QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>> ret; + const auto keys = db.keys(encryption); + + for (const auto &k : keys) + { + QXmpp::TrustLevel level; + + if (toTrustLevel(k.trust_level, level)) + { + std::cerr << "TrustDb::keys: invalid trust level: " + << qPrintable(k.trust_level) << std::endl; + continue; + } + else if (!trustLevels.testFlag(level)) + continue; + + QMultiHash<QString, QByteArray> mh; + + for (const auto &key : k.keys) + mh.insert(k.owner, key); + + ret.insert(level, mh); + } + + return QXmpp::Private::makeReadyTask(QHash<QXmpp::TrustLevel, + QMultiHash<QString, QByteArray>>(ret)); +} + +QXmppTask<QHash<QString, + QHash<QByteArray, QXmpp::TrustLevel>>> TrustDb::keys(const QString &encryption, + const QList<QString> &keyOwnerJids, + const QXmpp::TrustLevels trustLevels) +{ + QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>> ret; + const auto keys = db.keys(encryption); + + for (const auto &jid : keyOwnerJids) + for (const auto &k : keys) + { + if (k.owner != jid) + continue; + + QXmpp::TrustLevel level; + + if (toTrustLevel(k.trust_level, level)) + { + std::cerr << "TrustDb::keys: invalid trust level: " + << qPrintable(k.trust_level) << std::endl; + continue; + } + else if (!trustLevels.testFlag(level)) + continue; + + QHash<QByteArray, QXmpp::TrustLevel> h; + + for (const auto &key : k.keys) + h.insert(key, level); + + ret.insert(jid, h); + break; + } + + return QXmpp::Private::makeReadyTask(QHash<QString, + QHash<QByteArray, QXmpp::TrustLevel>>(ret)); +} + +QXmppTask<bool> TrustDb::hasKey(const QString &encryption, + const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels) +{ + bool ret = false; + const auto keys = db.keys(encryption); + + for (const auto &k : keys) + { + if (k.owner != keyOwnerJid) + continue; + + QXmpp::TrustLevel level; + + if (toTrustLevel(k.trust_level, level)) + { + std::cerr << "TrustDb::keys: invalid trust level: " + << qPrintable(k.trust_level) << std::endl; + break; + } + else if (!trustLevels.testFlag(level)) + break; + + ret = true; + break; + } + + return QXmpp::Private::makeReadyTask(bool(ret)); +} + +QXmppTask<QHash<QString, + QMultiHash<QString, QByteArray>>> TrustDb::setTrustLevel( + const QString &encryption, + const QMultiHash<QString, QByteArray> &keyIds, + const QXmpp::TrustLevel trustLevel) +{ + QHash<QString, QMultiHash<QString, QByteArray>> ret; + auto keys = db.keys(encryption); + const auto str = toString(trustLevel); + + for (const auto &owner : keyIds.keys()) + for (auto &k : keys) + { + if (k.owner != owner) + continue; + + k.trust_level = str; + QMultiHash<QString, QByteArray> mh; + + for (const auto &id : k.keys) + mh.insert(owner, id); + + ret.insert(owner, mh); + break; + } + + for (const auto &key : keys) + if (db.store(encryption, key)) + std::cerr << "TrustDb::setTrustLevel: store failed" + << std::endl; + + return QXmpp::Private::makeReadyTask(QHash<QString, + QMultiHash<QString, QByteArray>>(ret)); +} + +QXmppTask<QHash<QString, + QMultiHash<QString, QByteArray>>> TrustDb::setTrustLevel( + const QString &encryption, + const QList<QString> &keyOwnerJids, + const QXmpp::TrustLevel oldTrustLevel, + const QXmpp::TrustLevel newTrustLevel) +{ + QHash<QString, QMultiHash<QString, QByteArray>> ret; + auto keys = db.keys(encryption); + const auto str = toString(newTrustLevel); + + for (const auto &owner : keyOwnerJids) + for (auto &k : keys) + { + QXmpp::TrustLevel trust_level; + + if (k.owner != owner + || toTrustLevel(k.trust_level, trust_level) + || trust_level != oldTrustLevel) + continue; + + k.trust_level = str; + QMultiHash<QString, QByteArray> mh; + + for (const auto &id : k.keys) + mh.insert(owner, id); + + ret.insert(owner, mh); + break; + } + + for (const auto &key : keys) + if (db.store(encryption, key)) + std::cerr << "TrustDb::setTrustLevel: store failed" << std::endl; + + return QXmpp::Private::makeReadyTask(QHash<QString, + QMultiHash<QString, QByteArray>>(ret)); +} + +QXmppTask<QXmpp::TrustLevel> TrustDb::trustLevel(const QString &encryption, + const QString &keyOwnerJid, const QByteArray &keyId) +{ + const auto keys = db.keys(encryption); + + for (const auto &k : keys) + { + if (k.owner != keyOwnerJid) + continue; + + for (const auto &id : k.keys) + if (id == keyId) + { + QXmpp::TrustLevel ret(QXmpp::TrustLevel::Undecided); + + if (toTrustLevel(k.trust_level, ret)) + std::cerr << "toTrustLevel failed" << std::endl; + + return QXmpp::Private::makeReadyTask( QXmpp::TrustLevel(ret)); + } + } + + return QXmpp::Private::makeReadyTask(QXmpp::TrustLevel( + QXmpp::TrustLevel::Undecided)); +} + +QXmppTask<void> TrustDb::resetAll(const QString &encryption) +{ + db.removeKeys(encryption); + + return QXmpp::Private::makeReadyTask(); +} + +namespace QXmpp +{ + +uint qHash(const TrustLevel &key, uint seed) +{ + return qHash(key, seed); +} + +} |
