diff --git a/qomemo/bundle.cpp b/qomemo/bundle.cpp index aec605a..91f630d 100644 --- a/qomemo/bundle.cpp +++ b/qomemo/bundle.cpp @@ -64,7 +64,9 @@ QXmppIq QXmpp::Omemo::Bundle::toIq(int deviceId) const { item.appendChild(toXml()); auto publish = createElement("publish"); - publish.setAttribute("node", QString("eu.siacs.conversations.axolotl.bundles:%s").arg(deviceId)); + publish.setAttribute( + "node", + QString("eu.siacs.conversations.axolotl.bundles:%s").arg(deviceId)); publish.appendChild(item); auto pubSub = createElement("pubsub", "http://jabber.org/protocol/pubsub"); @@ -116,7 +118,8 @@ void QXmpp::Omemo::Bundle::fromXml(const QXmppElement &element) { QXmppPubSubIq QXmpp::Omemo::Bundle::fetchDeviceBundleIq(int deviceId) { QXmppPubSubIq iq{}; iq.setType(QXmppIq::Get); - iq.setQueryNode(QString("eu.siacs.conversations.axolotl.bundles:%1").arg(deviceId)); + iq.setQueryNode( + QString("eu.siacs.conversations.axolotl.bundles:%1").arg(deviceId)); QXmppPubSubItem item{}; item.setId(QString::number(deviceId)); diff --git a/qomemo/bundle.h b/qomemo/bundle.h index d29bf02..bfa9fff 100644 --- a/qomemo/bundle.h +++ b/qomemo/bundle.h @@ -38,4 +38,4 @@ public: QList prekeys; }; -} +} // namespace QXmpp::Omemo diff --git a/qomemo/database.cpp b/qomemo/database.cpp new file mode 100644 index 0000000..3644522 --- /dev/null +++ b/qomemo/database.cpp @@ -0,0 +1,126 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#include "database.h" + +#include +#include +#include +#include +#include + +using namespace QXmpp::Omemo; + +Database::Database(QString jid) : jid(std::move(jid)) { + auto cacheLocation = + QStandardPaths::writableLocation(QStandardPaths::CacheLocation); + auto path = QString("%1/.omemo/%2").arg(cacheLocation, jid); + QDir cache(path); + + if (!cache.exists() && !cache.mkpath(path)) { + qWarning() << "Could not create:" << path; + throw QException(); + } + + mdb_env_create(&env); + + mdb_env_set_maxdbs(env, 5); + mdb_env_set_mapsize(env, 512UL * 1024UL * 1024UL); + mdb_env_open(env, path.toStdString().c_str(), 0, 0664); + + MDB_txn *txn; + mdb_txn_begin(env, nullptr, 0, &txn); + mdb_dbi_open(txn, "keys", MDB_CREATE, &dbiKeys); + mdb_dbi_open(txn, "devices", MDB_CREATE, &dbiDevices); + mdb_dbi_open(txn, "identity_keys", MDB_CREATE, &dbiIdentityKeys); + mdb_txn_commit(txn); +} + +Database::~Database() { + mdb_dbi_close(env, dbiKeys); + mdb_dbi_close(env, dbiDevices); + mdb_dbi_close(env, dbiIdentityKeys); + mdb_env_close(env); +} + +QBuffer Database::loadIdentityKeySecret(int deviceId) { return QBuffer(); } + +bool Database::saveIdentityKeySecret(int deviceId, + const QBuffer &identityKeySecret) { + MDB_val mdbKey, mdbValue; + auto key = QString("%1/secret").arg(QString::number(deviceId)).toStdString(); + + mdbKey.mv_data = key.data(); + mdbKey.mv_size = key.size(); + + mdbValue.mv_data = const_cast(identityKeySecret.data().data()); + mdbValue.mv_size = identityKeySecret.size(); + + MDB_txn *txn; + mdb_txn_begin(env, nullptr, 0, &txn); + auto err = mdb_put(txn, dbiIdentityKeys, &mdbKey, &mdbValue, MDB_NOOVERWRITE); + if (!err) { + mdb_txn_commit(txn); + return true; + } + + qWarning() << "could not save identity key secret:" << mdb_strerror(err); + mdb_txn_abort(txn); + + return false; +} + +int Database::loadActiveDeviceId() { + MDB_val key, value; + + key.mv_data = (void *)"active"; + key.mv_size = sizeof("active"); + + MDB_txn *txn; + mdb_txn_begin(env, nullptr, 0, &txn); + + auto err = mdb_get(txn, dbiIdentityKeys, &key, &value); + if (err) { + qWarning() << "could not load active device id:" << mdb_strerror(err); + return 0; + } + + if (value.mv_size != sizeof(int)) { + qWarning() << "mv_size is" << value.mv_size << "instead of" << sizeof(int); + return 0; + } + + auto id = *reinterpret_cast(value.mv_data); + + mdb_txn_abort(txn); + + return id; +} + +bool Database::saveActiveDeviceId(int deviceId) { + MDB_val key, value; + + key.mv_data = (void *)"active"; + key.mv_size = sizeof("active"); + + value.mv_data = &deviceId; + value.mv_size = sizeof(deviceId); + + MDB_txn *txn; + mdb_txn_begin(env, nullptr, 0, &txn); + + auto err = mdb_put(txn, dbiIdentityKeys, &key, &value, 0); + if (err) { + qWarning() << "could not save active device id" << mdb_strerror(err); + return false; + } + + err = mdb_txn_commit(txn); + if (err) { + qWarning() << "could not save active device id" << mdb_strerror(err); + return false; + } + + return true; +} diff --git a/qomemo/database.h b/qomemo/database.h new file mode 100644 index 0000000..4584b2e --- /dev/null +++ b/qomemo/database.h @@ -0,0 +1,40 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include +#include +#include + +namespace QXmpp::Omemo { + +class Database { +public: + explicit Database(QString jid); + ~Database(); + Database(const Database &) = delete; + Database(Database &&) = delete; + Database &operator=(const Database &) = delete; + + QBuffer loadIdentityKey(); + bool saveIdentityKey(const QBuffer &identityKey); + + int loadActiveDeviceId(); + bool saveActiveDeviceId(int deviceId); + + QBuffer loadIdentityKeySecret(int deviceId); + bool saveIdentityKeySecret(int deviceId, const QBuffer &identityKeySecret); + + const QString jid; + +private: + MDB_env *env{}; + MDB_dbi dbiDevices{}; + MDB_dbi dbiKeys{}; + MDB_dbi dbiPreKeys{}; + MDB_dbi dbiIdentityKeys{}; +}; + +} // namespace QXmpp::Omemo diff --git a/qomemo/device_service.h b/qomemo/device_service.h index 774b7f4..c4aa04e 100644 --- a/qomemo/device_service.h +++ b/qomemo/device_service.h @@ -20,7 +20,7 @@ public: explicit DeviceService(QObject *parent); public slots: - void onDeviceListReceived(const QString& jid, const DeviceList& list); + void onDeviceListReceived(const QString &jid, const DeviceList &list); private: QMap device_lists{}; diff --git a/qomemo/qxmpp_omemo_manager.cpp b/qomemo/qxmpp_omemo_manager.cpp index f29ec98..062b934 100644 --- a/qomemo/qxmpp_omemo_manager.cpp +++ b/qomemo/qxmpp_omemo_manager.cpp @@ -15,8 +15,11 @@ using namespace QXmpp::Omemo; -Manager::Manager() : deviceService(new DeviceService(this)), omemoVariant(new Variant::Conversations) { - connect(this, &Manager::deviceListReceived, deviceService.get(), &DeviceService::onDeviceListReceived); +Manager::Manager() + : deviceService(new DeviceService(this)), + omemoVariant(new Variant::Conversations) { + connect(this, &Manager::deviceListReceived, deviceService.get(), + &DeviceService::onDeviceListReceived); } bool QXmpp::Omemo::Manager::handleStanza(const QDomElement &stanza) { @@ -31,7 +34,8 @@ bool QXmpp::Omemo::Manager::handleStanza(const QDomElement &stanza) { auto pubsub = stanza.firstChildElement("pubsub"); if (!pubsub.isNull()) { auto items = pubsub.firstChildElement("items"); - if (items.attribute("node") == "eu.siacs.conversations.axolotl.devicelist") { + if (items.attribute("node") == + "eu.siacs.conversations.axolotl.devicelist") { auto item = items.firstChildElement("item"); if (!item.isNull()) { auto list = item.firstChildElement("list"); @@ -56,7 +60,8 @@ void QXmpp::Omemo::Manager::setClient(QXmppClient *client) { if (!client) return; - QObject::connect(client, &QXmppClient::connected, this, &Manager::fetchOwnDevices); + QObject::connect(client, &QXmppClient::connected, this, + &Manager::fetchOwnDevices); } void QXmpp::Omemo::Manager::fetchOwnDevices() { diff --git a/qomemo/sce.h b/qomemo/sce.h index 2cea049..91a7b2c 100644 --- a/qomemo/sce.h +++ b/qomemo/sce.h @@ -4,8 +4,8 @@ #pragma once -#include #include +#include namespace QXmpp::Sce { diff --git a/qomemo/user_device_list.h b/qomemo/user_device_list.h index 26a88ca..27e407a 100644 --- a/qomemo/user_device_list.h +++ b/qomemo/user_device_list.h @@ -5,6 +5,7 @@ #pragma once #include + namespace QXmpp::Omemo { class UserDeviceList { diff --git a/qomemo/variant/omemo_base.h b/qomemo/variant/omemo_base.h index f383a59..fd11f31 100644 --- a/qomemo/variant/omemo_base.h +++ b/qomemo/variant/omemo_base.h @@ -18,12 +18,12 @@ class Base { public: virtual ~Base() = default; - virtual QXmppElement deviceToXml(const Device& device) = 0; - virtual Device deviceFromXml(const QXmppElement& xml) = 0; + virtual QXmppElement deviceToXml(const Device &device) = 0; + virtual Device deviceFromXml(const QXmppElement &xml) = 0; - virtual QXmppElement deviceListToXml(const DeviceList& deviceList) = 0; - virtual DeviceList deviceListFromXml(const QXmppElement& xml) = 0; - virtual QXmppIq deviceListSetIq(const DeviceList& deviceList) = 0; + virtual QXmppElement deviceListToXml(const DeviceList &deviceList) = 0; + virtual DeviceList deviceListFromXml(const QXmppElement &xml) = 0; + virtual QXmppIq deviceListSetIq(const DeviceList &deviceList) = 0; }; } // namespace Variant