Compare commits
2 Commits
c6273dd637
...
d213a7297b
Author | SHA1 | Date |
---|---|---|
Xavier Del Campo Romero | d213a7297b | |
Xavier Del Campo Romero | 39dcbc9e2c |
175
jiddb.cpp
175
jiddb.cpp
|
@ -70,7 +70,7 @@ QStringList JidDb::roster() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
int JidDb::ensureContactDb(const QString &jid) const
|
||||
int JidDb::ensureContactTable(const QString &jid) const
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
|
||||
|
@ -84,12 +84,57 @@ int JidDb::ensureContactDb(const QString &jid) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
static QString securityPolicyTableName(const QString &encryption)
|
||||
{
|
||||
return "securityPolicy/" + encryption;;
|
||||
}
|
||||
|
||||
int JidDb::ensureSecurityPolicyTable(const QString &encryption,
|
||||
QString &table) const
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
|
||||
table = securityPolicyTableName(encryption);
|
||||
|
||||
if (!q.exec("create table if not exists '" + table
|
||||
+ "' (policy TEXT unique) strict;"))
|
||||
{
|
||||
std::cerr << "JidDb::ensureSecurityPolicyTable: query exec failed"
|
||||
<< std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static QString keysTableName(const QString &encryption)
|
||||
{
|
||||
return "keys/" + encryption;
|
||||
}
|
||||
|
||||
int JidDb::ensureKeysTable(const QString &encryption, QString &table) const
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
|
||||
table = keysTableName(encryption);
|
||||
|
||||
if (!q.exec("create table if not exists '" + table
|
||||
+ "' (owner TEXT, trustlevel TEXT, key TEXT) strict;"))
|
||||
{
|
||||
std::cerr << "JidDb::ensureKeysTable: query exec failed"
|
||||
<< std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QList<JidDb::Message> JidDb::messages(const QString &jid,
|
||||
const int tail) const
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
|
||||
if (ensureContactDb(jid))
|
||||
if (ensureContactTable(jid))
|
||||
return QList<Message>();
|
||||
else if (tail < 0)
|
||||
{
|
||||
|
@ -159,7 +204,7 @@ int JidDb::storeMessage(const JidDb::Message &msg) const
|
|||
break;
|
||||
}
|
||||
|
||||
ensureContactDb(msg.contact);
|
||||
ensureContactTable(msg.contact);
|
||||
|
||||
if (!q.exec("insert into '" + msg.contact
|
||||
+ "' (direction, time, body) values "
|
||||
|
@ -213,3 +258,127 @@ QList<JidDb::Conversation> JidDb::conversations() const
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString JidDb::securityPolicy(const QString &encryption) const
|
||||
{
|
||||
const auto tb = tables();
|
||||
const auto name = securityPolicyTableName(encryption);
|
||||
|
||||
for (const auto &t : tb)
|
||||
{
|
||||
if (t == name)
|
||||
{
|
||||
QStringList ret;
|
||||
QSqlQuery q(db);
|
||||
|
||||
if (!q.exec("select policy from '" + name + "';"))
|
||||
std::cerr << "query exec failed" << std::endl;
|
||||
else
|
||||
while (q.next())
|
||||
return q.value("policy").toString();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
int JidDb::storeSecurityPolicy(const QString &encryption,
|
||||
const QString &policy) const
|
||||
{
|
||||
QString table;
|
||||
|
||||
if (ensureSecurityPolicyTable(encryption, table))
|
||||
return -1;
|
||||
|
||||
QSqlQuery q(db);
|
||||
|
||||
if (!q.exec("insert or ignore into '" + table
|
||||
+ "' (policy) values ('" + policy + "');"))
|
||||
{
|
||||
std::cerr << "JidDb::storeSecurityPolicy: query exec failed"
|
||||
<< std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QList<JidDb::Keys> JidDb::keys(const QString &encryption) const
|
||||
{
|
||||
QList<Keys> ret;
|
||||
QString table;
|
||||
|
||||
if (ensureKeysTable(encryption, table))
|
||||
{
|
||||
std::cerr << "JidDb::keys: ensureKeysTable failed" << std::endl;
|
||||
return QList<Keys>();
|
||||
}
|
||||
|
||||
QSqlQuery q(db);
|
||||
|
||||
if (!q.exec("select owner, trustlevel, key from '" + table + "';"))
|
||||
std::cerr << "JidDb::keys: query exec failed" << std::endl;
|
||||
else
|
||||
while (q.next())
|
||||
{
|
||||
const auto owner = q.value("owner").toString();
|
||||
const auto trust_level = q.value("trustlevel").toString();
|
||||
const auto key_b64 = q.value("key").toString();
|
||||
const auto key = QByteArray::fromBase64(key_b64.toLatin1());
|
||||
bool found = false;
|
||||
|
||||
for (auto &k : ret)
|
||||
if (k.owner == owner)
|
||||
{
|
||||
k.keys.append(key);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
Keys keys;
|
||||
|
||||
keys.owner = owner;
|
||||
keys.trust_level = trust_level;
|
||||
keys.keys.append(key);
|
||||
ret.append(keys);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int JidDb::storeKeys(const QString &encryption, const JidDb::Keys &keys) const
|
||||
{
|
||||
QString table;
|
||||
|
||||
if (ensureKeysTable(encryption, table))
|
||||
{
|
||||
std::cerr << "JidDb::storeKeys: ensureKeysTable failed" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (const auto &k : keys.keys)
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
|
||||
if (!q.exec("insert or replace into '" + table
|
||||
+ "' (owner, trustlevel, key) values ('"
|
||||
+ keys.owner + ", " + keys.trust_level + ","
|
||||
+ k.toBase64() + "');"))
|
||||
{
|
||||
std::cerr << "JidDb::storeKeys: query exec failed"
|
||||
<< std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JidDb::removeKeys() const
|
||||
{
|
||||
}
|
||||
|
|
32
jiddb.h
32
jiddb.h
|
@ -2,12 +2,15 @@
|
|||
#define JID_DB_H
|
||||
|
||||
#include "direction.h"
|
||||
#include <QByteArray>
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QPair>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QSqlDatabase>
|
||||
#include <QVariant>
|
||||
|
||||
class JidDb : public QObject
|
||||
{
|
||||
|
@ -30,6 +33,24 @@ public:
|
|||
QDateTime dt;
|
||||
};
|
||||
|
||||
struct Trust
|
||||
{
|
||||
QString security_policy;
|
||||
};
|
||||
|
||||
struct Keys
|
||||
{
|
||||
Keys() {}
|
||||
Keys(const QString &owner, const QString &trust_level,
|
||||
const QList<QByteArray> &keys) :
|
||||
owner(owner),
|
||||
trust_level(trust_level),
|
||||
keys(keys)
|
||||
{}
|
||||
QString owner, trust_level;
|
||||
QList<QByteArray> keys;
|
||||
};
|
||||
|
||||
JidDb(const QString &jid);
|
||||
QStringList roster() const;
|
||||
const QString &jid;
|
||||
|
@ -38,16 +59,25 @@ public Q_SLOTS:
|
|||
QList<Conversation> conversations() const;
|
||||
QList<Message> messages(const QString &jid,
|
||||
int tail = -1) const;
|
||||
QString securityPolicy(const QString &encryption) const;
|
||||
QList<Keys> keys(const QString &encryption) const;
|
||||
int storeMessage(const Message &msg) const;
|
||||
int addToRoster(const QString &jid);
|
||||
int addToRoster(const QStringList &roster);
|
||||
int storeSecurityPolicy(const QString &encryption,
|
||||
const QString &policy) const;
|
||||
int storeKeys(const QString &encryption, const Keys &keys) const;
|
||||
void removeKeys() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void addedToRoster(QString jid);
|
||||
|
||||
private:
|
||||
QSqlDatabase db;
|
||||
int ensureContactDb(const QString &jid) const;
|
||||
int ensureSecurityPolicyTable(const QString &encryption,
|
||||
QString &table) const;
|
||||
int ensureContactTable(const QString &jid) const;
|
||||
int ensureKeysTable(const QString &encryption, QString &table) const;
|
||||
QStringList tables() const;
|
||||
};
|
||||
|
||||
|
|
277
trust_db.cpp
277
trust_db.cpp
|
@ -1,4 +1,6 @@
|
|||
#include "trust_db.h"
|
||||
#include <QXmppTrustLevel.h>
|
||||
#include <QXmppTrustSecurityPolicy.h>
|
||||
#include <QXmppConfiguration.h>
|
||||
#include <QXmppFutureUtils_p.h>
|
||||
#include <QXmppPromise.h>
|
||||
|
@ -13,16 +15,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 +60,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 +90,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.storeSecurityPolicy(encryption, toString(securityPolicy)))
|
||||
std::cerr << "TrustDb::setSecurityPolicy: storeSecurityPolicy 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.storeSecurityPolicy(encryption, QString()))
|
||||
std::cerr << "TrustDb::resetSecurityPolicy: storeSecurityPolicy failed"
|
||||
<< std::endl;
|
||||
|
||||
return QXmpp::Private::makeReadyTask();
|
||||
}
|
||||
|
@ -88,23 +109,11 @@ QXmppTask<void> TrustDb::resetSecurityPolicy(const QString &encryption)
|
|||
QXmppTask<QXmpp::TrustSecurityPolicy> TrustDb::securityPolicy(
|
||||
const QString &encryption)
|
||||
{
|
||||
QKeychain::ReadPasswordJob job(service());
|
||||
QEventLoop loop;
|
||||
const auto s = db.securityPolicy(encryption);
|
||||
QXmpp::TrustSecurityPolicy policy;
|
||||
|
||||
job.setKey("securityPolicy/" + encryption);
|
||||
job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
|
||||
job.start();
|
||||
loop.exec();
|
||||
|
||||
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));
|
||||
|
@ -171,23 +180,60 @@ 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.storeKeys(encryption, keys))
|
||||
std::cerr << "TrustDb::addKeys: storeKeys 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.storeKeys(encryption, k))
|
||||
std::cerr << "TrustDb::removeKeys: storeKeys 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.storeKeys(encryption, k))
|
||||
std::cerr << "TrustDb::removeKeys: storeKeys failed" << std::endl;
|
||||
|
||||
return QXmpp::Private::makeReadyTask();
|
||||
}
|
||||
|
||||
QXmppTask<void> TrustDb::removeKeys(const QString &encryption)
|
||||
{
|
||||
db.removeKeys();
|
||||
return QXmpp::Private::makeReadyTask();
|
||||
}
|
||||
|
||||
|
@ -195,8 +241,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 +274,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 +342,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.storeKeys(encryption, key))
|
||||
std::cerr << "TrustDb::setTrustLevel: storeKeys failed"
|
||||
<< std::endl;
|
||||
|
||||
return QXmpp::Private::makeReadyTask(QHash<QString,
|
||||
QMultiHash<QString, QByteArray>>());
|
||||
QMultiHash<QString, QByteArray>>(ret));
|
||||
}
|
||||
|
||||
QXmppTask<QHash<QString,
|
||||
|
@ -245,3 +392,13 @@ QXmppTask<void> TrustDb::resetAll(const QString &encryption)
|
|||
{
|
||||
return QXmpp::Private::makeReadyTask();
|
||||
}
|
||||
|
||||
namespace QXmpp
|
||||
{
|
||||
|
||||
uint qHash(const TrustLevel &key, uint seed)
|
||||
{
|
||||
return qHash(key, seed);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
12
xxcc.cpp
12
xxcc.cpp
|
@ -6,6 +6,7 @@
|
|||
#include "conversation.h"
|
||||
#include "message.h"
|
||||
#include <QXmppMessage.h>
|
||||
#include <QXmppOmemoElement_p.h>
|
||||
#include <QXmppRosterManager.h>
|
||||
#include <QXmppUtils.h>
|
||||
#include <QKeyEvent>
|
||||
|
@ -201,8 +202,17 @@ void xxcc::send(void)
|
|||
|
||||
const auto from = selected->jidBare(),
|
||||
to = ui.jid->text(), msg = ui.chatinput->toPlainText();
|
||||
const bool enc = ui.omemo->isChecked();
|
||||
static const auto encmsg = "This is an OMEMO-encrypted message.";
|
||||
|
||||
QXmppMessage out(from, to, msg);
|
||||
QXmppMessage out(from, to, enc ? encmsg : msg);
|
||||
QXmppOmemoElement omemo;
|
||||
|
||||
if (enc)
|
||||
{
|
||||
omemo.setPayload(msg.toUtf8());
|
||||
out.setOmemoElement(omemo);
|
||||
}
|
||||
|
||||
out.setStamp(QDateTime::currentDateTimeUtc());
|
||||
selected->sendPacket(out);
|
||||
|
|
5
xxcc.ui
5
xxcc.ui
|
@ -226,10 +226,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="QCheckBox" name="omemo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
|
|
Loading…
Reference in New Issue