From fdb64c59865e4db76addfb8222f6421443e25240 Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Tue, 3 Feb 2026 15:59:29 +0100 Subject: Import files from xxcc --- trust_db.cpp | 415 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 trust_db.cpp (limited to 'trust_db.cpp') 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 +#include +#include +#include +#include +#include +#include +#include + +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 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 TrustDb::resetSecurityPolicy(const QString &encryption) +{ + if (db.store(encryption, QString())) + std::cerr << "TrustDb::resetSecurityPolicy: store failed" + << std::endl; + + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask 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 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 TrustDb::resetOwnKey(const QString &encryption) +{ + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask TrustDb::ownKey(const QString &encryption) +{ + return QXmpp::Private::makeReadyTask(db.ownKeyId(encryption)); +} + +QXmppTask TrustDb::addKeys(const QString &encryption, + const QString &keyOwnerJid, const QList &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 TrustDb::removeKeys(const QString &encryption, + const QList &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 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 TrustDb::removeKeys(const QString &encryption) +{ + db.removeKeys(encryption); + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask>> TrustDb::keys(const QString &encryption, + const QXmpp::TrustLevels trustLevels) +{ + QHash> 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 mh; + + for (const auto &key : k.keys) + mh.insert(k.owner, key); + + ret.insert(level, mh); + } + + return QXmpp::Private::makeReadyTask(QHash>(ret)); +} + +QXmppTask>> TrustDb::keys(const QString &encryption, + const QList &keyOwnerJids, + const QXmpp::TrustLevels trustLevels) +{ + QHash> 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 h; + + for (const auto &key : k.keys) + h.insert(key, level); + + ret.insert(jid, h); + break; + } + + return QXmpp::Private::makeReadyTask(QHash>(ret)); +} + +QXmppTask 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>> TrustDb::setTrustLevel( + const QString &encryption, + const QMultiHash &keyIds, + const QXmpp::TrustLevel trustLevel) +{ + QHash> 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 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>(ret)); +} + +QXmppTask>> TrustDb::setTrustLevel( + const QString &encryption, + const QList &keyOwnerJids, + const QXmpp::TrustLevel oldTrustLevel, + const QXmpp::TrustLevel newTrustLevel) +{ + QHash> 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 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>(ret)); +} + +QXmppTask 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 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); +} + +} -- cgit v1.2.3