aboutsummaryrefslogtreecommitdiff
path: root/trust_db.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trust_db.cpp')
-rw-r--r--trust_db.cpp376
1 files changed, 272 insertions, 104 deletions
diff --git a/trust_db.cpp b/trust_db.cpp
index 138c028..0d8073b 100644
--- a/trust_db.cpp
+++ b/trust_db.cpp
@@ -1,8 +1,9 @@
#include "trust_db.h"
+#include <QXmppTrustLevel.h>
+#include <QXmppTrustSecurityPolicy.h>
#include <QXmppConfiguration.h>
#include <QXmppFutureUtils_p.h>
#include <QXmppPromise.h>
-#include <qt5keychain/keychain.h>
#include <QEventLoop>
#include <QtConcurrent>
#include <iostream>
@@ -13,16 +14,44 @@ TrustDb::TrustDb(const QString &jid, const JidDb &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)
{
- switch (securityPolicy)
- {
- case QXmpp::NoSecurityPolicy:
- return "NoSecurityPolicy";
+ for (const auto &t : tsp_levels)
+ if (t.policy == securityPolicy)
+ return t.str;
- case QXmpp::Toakafa:
- return "Toakafa";
- }
+ return "unknown";
+}
+
+static QString toString(const QXmpp::TrustLevel &trustLevel)
+{
+ for (const auto &t : trustlevels)
+ if (t.level == trustLevel)
+ return t.str;
return "unknown";
}
@@ -30,16 +59,24 @@ static QString toString(const QXmpp::TrustSecurityPolicy securityPolicy)
static int toSecurityPolicy(const QString &s,
QXmpp::TrustSecurityPolicy &securityPolicy)
{
- if (s == "NoSecurityPolicy")
- {
- securityPolicy = QXmpp::NoSecurityPolicy;
- return 0;
- }
- else if (s == "Toakafa")
- {
- securityPolicy = QXmpp::Toakafa;
- return 0;
- }
+ 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;
}
@@ -52,35 +89,18 @@ QString TrustDb::service() const
QXmppTask<void> TrustDb::setSecurityPolicy(const QString &encryption,
const QXmpp::TrustSecurityPolicy securityPolicy)
{
- QKeychain::WritePasswordJob job(service());
- QEventLoop loop;
-
- job.setKey("securityPolicy/" + encryption);
- job.setTextData(toString(securityPolicy));
- job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
- job.start();
- loop.exec();
-
- if (job.error())
- std::cerr << "Failed to store security policy: "
- << qPrintable(job.errorString()) << std::endl;
+ 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)
{
- QKeychain::DeletePasswordJob job(service());
- QEventLoop loop;
-
- job.setKey("securityPolicy/" + encryption);
- job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
- job.start();
- loop.exec();
-
- if (job.error())
- std::cerr << "Failed to reset security policy: "
- << qPrintable(job.errorString()) << std::endl;
+ if (db.store(encryption, QString()))
+ std::cerr << "TrustDb::resetSecurityPolicy: store failed"
+ << std::endl;
return QXmpp::Private::makeReadyTask();
}
@@ -88,23 +108,11 @@ QXmppTask<void> TrustDb::resetSecurityPolicy(const QString &encryption)
QXmppTask<QXmpp::TrustSecurityPolicy> TrustDb::securityPolicy(
const QString &encryption)
{
- QKeychain::ReadPasswordJob job(service());
- QEventLoop loop;
-
- job.setKey("securityPolicy/" + encryption);
- job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
- job.start();
- loop.exec();
+ const auto s = db.securityPolicy(encryption);
+ QXmpp::TrustSecurityPolicy policy;
- if (job.error())
- std::cerr << "Failed to read security policy: "
- << qPrintable(job.errorString()) << std::endl;
-
- QXmpp::TrustSecurityPolicy policy = QXmpp::Toakafa;
- const QString data = job.textData();
-
- if (toSecurityPolicy(data, policy))
- std::cerr << "Invalid security policy " << qPrintable(data)
+ if (toSecurityPolicy(s, policy))
+ std::cerr << "TrustDb::securityPolicy: toSecurityPolicy failed"
<< std::endl;
return QXmpp::Private::makeReadyTask(QXmpp::TrustSecurityPolicy(policy));
@@ -113,81 +121,80 @@ QXmppTask<QXmpp::TrustSecurityPolicy> TrustDb::securityPolicy(
QXmppTask<void> TrustDb::setOwnKey(const QString &encryption,
const QByteArray &keyId)
{
- QKeychain::WritePasswordJob job(service());
- QEventLoop loop;
-
- job.setKey("key/" + encryption);
- job.setBinaryData(keyId);
- job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
- job.start();
- loop.exec();
-
- if (job.error())
- std::cerr << "Failed to store own key: "
- << qPrintable(job.errorString()) << std::endl;
+ 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)
{
- QKeychain::DeletePasswordJob job(service());
- QEventLoop loop;
-
- job.setKey("key/" + encryption);
- job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
- job.start();
- loop.exec();
-
- if (job.error())
- std::cerr << "Failed to reset own key: "
- << qPrintable(job.errorString()) << std::endl;
-
return QXmpp::Private::makeReadyTask();
}
QXmppTask<QByteArray> TrustDb::ownKey(const QString &encryption)
{
- QKeychain::ReadPasswordJob job(service());
- QEventLoop loop;
-
- job.setKey("key/" + encryption);
- job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
- job.start();
- loop.exec();
-
- QByteArray ret;
-
- if (job.error())
- std::cerr << "Failed to read own key: "
- << qPrintable(job.errorString()) << std::endl;
- else
- ret = job.binaryData();
-
- return QXmpp::Private::makeReadyTask(QByteArray(ret));
+ 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();
}
@@ -195,8 +202,32 @@ 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>>());
+ QMultiHash<QString, QByteArray>>(ret));
}
QXmppTask<QHash<QString,
@@ -204,14 +235,66 @@ QXmppTask<QHash<QString,
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>>());
+ QHash<QByteArray, QXmpp::TrustLevel>>(ret));
}
QXmppTask<bool> TrustDb::hasKey(const QString &encryption,
const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels)
{
- return QXmpp::Private::makeReadyTask(bool());
+ 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,
@@ -220,8 +303,33 @@ QXmppTask<QHash<QString,
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>>());
+ QMultiHash<QString, QByteArray>>(ret));
}
QXmppTask<QHash<QString,
@@ -231,17 +339,77 @@ QXmppTask<QHash<QString,
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>>());
+ QMultiHash<QString, QByteArray>>(ret));
}
QXmppTask<QXmpp::TrustLevel> TrustDb::trustLevel(const QString &encryption,
const QString &keyOwnerJid, const QByteArray &keyId)
{
- return QXmpp::Private::makeReadyTask(QXmpp::TrustLevel());
+ 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);
+}
+
+}