transition to LMDBAL

This commit is contained in:
Blue 2023-03-27 21:45:29 +03:00
parent 69d797fe51
commit 81cf0f8d34
Signed by untrusted user: blue
GPG Key ID: 9B203B252A63EE38
18 changed files with 76 additions and 42 deletions

3
.gitmodules vendored
View File

@ -4,3 +4,6 @@
[submodule "external/storage"]
path = external/storage
url = https://git.macaw.me/blue/storage
[submodule "external/lmdbal"]
path = external/lmdbal
url = gitea@git.macaw.me:blue/lmdbal.git

View File

@ -28,6 +28,7 @@ add_executable(squawk ${WIN32_FLAG} ${MACOSX_BUNDLE_FLAG})
target_include_directories(squawk PRIVATE ${CMAKE_SOURCE_DIR})
option(SYSTEM_QXMPP "Use system qxmpp lib" ON)
option(SYSTEM_LMDBAL "Use system lmdbal lib" ON)
option(WITH_KWALLET "Build KWallet support module" ON)
option(WITH_KIO "Build KIO support module" ON)
option(WITH_KCONFIG "Build KConfig support module" ON)
@ -148,14 +149,25 @@ else ()
target_link_libraries(squawk PRIVATE QXmpp::QXmpp)
endif ()
## LMDB
#find_package(LMDB REQUIRED)
## LMDBAL
if (SYSTEM_LMDBAL)
find_package(lmdbal CONFIG)
if (NOT LMDBAL_FOUND)
set(SYSTEM_LMDBAL OFF)
message("LMDBAL package wasn't found, trying to build with bundled LMDBAL")
else ()
message("Building with system LMDBAL")
endif ()
endif()
if (NOT SYSTEM_LMDBAL)
message("Building with bundled LMDBAL")
set(BUILD_STATIC ON)
add_subdirectory(external/lmdbal)
add_library(LMDBAL::LMDBAL ALIAS LMDBAL)
endif()
#TODO conditioning!
add_subdirectory(external/storage)
target_include_directories(squawk PRIVATE external/storage)
target_link_libraries(squawk PRIVATE storage)
target_link_libraries(squawk PRIVATE LMDBAL::LMDBAL)
# Linking
target_link_libraries(squawk

View File

@ -9,9 +9,9 @@
### Prerequisites
- QT 5.12 *(lower versions might work but it wasn't tested)*
- lmdb
- CMake 3.4 or higher
- qxmpp 1.1.0 or higher
- LMDBAL (my own [library](https://git.macaw.me/blue/lmdbal) around lmdb)
- KDE Frameworks: kwallet (optional)
- KDE Frameworks: KIO (optional)
- KDE Frameworks: KConfig (optional)
@ -92,9 +92,11 @@ You can always refer to `appveyor.yml` to see how AppVeyor build squawk.
Here is the list of keys you can pass to configuration phase of `cmake ..`.
- `CMAKE_BUILD_TYPE` - `Debug` just builds showing all warnings, `Release` builds with no warnings and applies optimizations (default is `Debug`)
- `SYSTEM_QXMPP` - `True` tries to link against `qxmpp` installed in the system, `False` builds bundled `qxmpp` library (default is `True`)
- `SYSTEM_LMDBAL` - `True` tries to link against `LMDABL` installed in the system, `False` builds bundled `LMDBAL` library (default is `True`)
- `WITH_KWALLET` - `True` builds the `KWallet` capability module if `KWallet` is installed and if not goes to `False`. `False` disables `KWallet` support (default is `True`)
- `WITH_KIO` - `True` builds the `KIO` capability module if `KIO` is installed and if not goes to `False`. `False` disables `KIO` support (default is `True`)
- `WITH_KCONFIG` - `True` builds the `KConfig` and `KConfigWidgets` capability module if such packages are installed and if not goes to `False`. `False` disables `KConfig` and `KConfigWidgets` support (default is `True`)
- `WITH_OMEMO` - `True` builds the OMEMO encryption, requires `qxmpp` of version >= 1.5.0 built with OMEMO support. `False` disables OMEMO support (default is `True`)
## License

View File

@ -45,11 +45,16 @@ signals:
public slots:
bool checkClient(const Shared::ClientId& id);
bool registerClientInfo(const QString& sourceFullJid, const QString& id, const std::set<Shared::Identity>& identities, const std::set<QString>& features);
bool registerClientInfo(
const QString& sourceFullJid,
const QString& id,
const std::set<Shared::Identity>& identities,
const std::set<QString>& features
);
private:
DataBase db;
DataBase::Cache<QString, Shared::ClientInfo>* cache;
LMDBAL::Base db;
LMDBAL::Cache<QString, Shared::ClientInfo>* cache;
std::map<QString, Shared::ClientInfo> requested;
std::map<QString, Shared::ClientInfo> specific;
};

View File

@ -35,7 +35,7 @@ Core::OmemoHandler::OmemoHandler(Account* account) :
QVariant own = meta->getRecord("ownDevice");
ownDevice = own.value<OwnDevice>();
qDebug() << "Successfully found own device omemo data for account" << acc->getName();
} catch (const DataBase::NotFound& e) {
} catch (const LMDBAL::NotFound& e) {
qDebug() << "No device omemo data was found for account" << acc->getName();
}
}
@ -76,7 +76,7 @@ QXmppTask<void> Core::OmemoHandler::addDevice(const QString& jid, uint32_t devic
bool had = true;
try {
devs = devices->getRecord(jid);
} catch (const DataBase::NotFound& error) {
} catch (const LMDBAL::NotFound& error) {
had = false;
}
@ -127,7 +127,7 @@ QXmppTask<void> Core::OmemoHandler::removePreKeyPair(uint32_t keyId) {
QXmppTask<void> Core::OmemoHandler::removeSignedPreKeyPair(uint32_t keyId) {
try {
signedPreKeyPairs->removeRecord(keyId);
} catch (const DataBase::NotFound& e) {}
} catch (const LMDBAL::NotFound& e) {}
return Core::makeReadyTask();
}
@ -159,7 +159,7 @@ void Core::OmemoHandler::getDevices(const QString& jid, std::list<Shared::KeyInf
QHash<uint32_t, Device> devs;
try {
devs = devices->getRecord(jid);
} catch (const DataBase::NotFound& error) {}
} catch (const LMDBAL::NotFound& error) {}
for (QHash<uint32_t, Device>::const_iterator itr = devs.begin(), end = devs.end(); itr != end; ++itr) {
const Device& dev = itr.value();

View File

@ -73,11 +73,11 @@ private slots:
private:
Account* acc;
std::optional<OwnDevice> ownDevice;
DataBase db;
DataBase::Cache<QString, QVariant>* meta;
DataBase::Cache<QString, QHash<uint32_t, Device>>* devices;
DataBase::Cache<uint32_t, QByteArray>* preKeyPairs;
DataBase::Cache<uint32_t, SignedPreKeyPair>* signedPreKeyPairs;
LMDBAL::Base db;
LMDBAL::Cache<QString, QVariant>* meta;
LMDBAL::Cache<QString, QHash<uint32_t, Device>>* devices;
LMDBAL::Cache<uint32_t, QByteArray>* preKeyPairs;
LMDBAL::Cache<uint32_t, SignedPreKeyPair>* signedPreKeyPairs;
};
}

View File

@ -29,7 +29,7 @@ Core::TrustHandler::TrustHandler(Account* account):
keysByProtocol()
{
if (!protocols.open(QIODevice::ReadWrite | QIODevice::Text)) { //never supposed to happen since I have just created a directory;
throw DataBase::Directory(protocols.fileName().toStdString());
throw LMDBAL::Directory(protocols.fileName().toStdString());
}
QTextStream in(&protocols);
@ -66,7 +66,7 @@ Core::TrustHandler::KeyCache * Core::TrustHandler::createNewCache(const QString&
keysByProtocol.insert(std::make_pair(encryption, cache));
if(!protocols.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
throw DataBase::Directory(protocols.fileName().toStdString());
throw LMDBAL::Directory(protocols.fileName().toStdString());
}
QTextStream out(&protocols);
out << encryption + "\n";
@ -114,7 +114,7 @@ QXmppTask<QXmpp::TrustLevel> Core::TrustHandler::trustLevel(
Keys::const_iterator itr = map.find(keyId);
if (itr != map.end())
level = itr->second;
} catch (const DataBase::NotFound& e) {}
} catch (const LMDBAL::NotFound& e) {}
return Core::makeReadyTask(std::move(convert(level)));
}
@ -176,7 +176,7 @@ QXmppTask<QHash<QString, QMultiHash<QString, QByteArray>>> Core::TrustHandler::s
modifiedJids.insert(keyOwnerJid);
cache->changeRecord(keyOwnerJid, map);
}
} catch (const DataBase::NotFound& e) {
} catch (const LMDBAL::NotFound& e) {
Keys map({{keyId, level}});
modifiedKeys[encryption].insert(keyOwnerJid, keyId);
modifiedJids.insert(keyOwnerJid);
@ -204,7 +204,7 @@ QXmppTask<bool> Core::TrustHandler::hasKey(const QString& encryption,
break;
}
}
} catch (const DataBase::NotFound& e) {}
} catch (const LMDBAL::NotFound& e) {}
return Core::makeReadyTask(std::move(found));
}
@ -226,7 +226,7 @@ QXmppTask<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> Core::TrustHandl
pRes.insert(pair.first, level);
}
}
} catch (const DataBase::NotFound& e) {}
} catch (const LMDBAL::NotFound& e) {}
}
return Core::makeReadyTask(std::move(res));
}
@ -281,7 +281,7 @@ QXmppTask<void> Core::TrustHandler::removeKeys(const QString& encryption, const
try {
cache->removeRecord(keyOwnerJid);
emit trustLevelsChanged(keyOwnerJid, getSummary(keyOwnerJid)); //TODO there is a probability of notification without the actial change
} catch (const DataBase::NotFound& e) {} //if the movin entry was empty or if it consisted of Undecided keys
} catch (const LMDBAL::NotFound& e) {} //if the movin entry was empty or if it consisted of Undecided keys
return Core::makeReadyTask();
@ -334,7 +334,7 @@ QXmppTask<void> Core::TrustHandler::addKeys(
try {
data = cache->getRecord(keyOwnerJid);
had = true;
} catch (const DataBase::NotFound& e) {}
} catch (const LMDBAL::NotFound& e) {}
for (const QByteArray& keyId : keyIds) {
std::pair<Keys::iterator, bool> result = data.insert(std::make_pair(keyId, level));
if (!result.second)
@ -355,14 +355,14 @@ QXmppTask<QByteArray> Core::TrustHandler::ownKey(const QString& encryption) {
QByteArray res;
try {
res = ownKeys->getRecord(encryption);
} catch (const DataBase::NotFound& e) {}
} catch (const LMDBAL::NotFound& e) {}
return Core::makeReadyTask(std::move(res));
}
QXmppTask<void> Core::TrustHandler::resetOwnKey(const QString& encryption) {
try {
ownKeys->removeRecord(encryption);
} catch (const DataBase::NotFound& e) {}
} catch (const LMDBAL::NotFound& e) {}
return Core::makeReadyTask();
}
@ -376,14 +376,14 @@ QXmppTask<QXmpp::TrustSecurityPolicy> Core::TrustHandler::securityPolicy(const Q
QXmpp::TrustSecurityPolicy res;
try {
res = static_cast<QXmpp::TrustSecurityPolicy>(securityPolicies->getRecord(encryption));
} catch (const DataBase::NotFound& e) {}
} catch (const LMDBAL::NotFound& e) {}
return Core::makeReadyTask(std::move(res));
}
QXmppTask<void> Core::TrustHandler::resetSecurityPolicy(const QString& encryption) {
try {
securityPolicies->removeRecord(encryption);
} catch (const DataBase::NotFound& e) {}
} catch (const LMDBAL::NotFound& e) {}
return Core::makeReadyTask();
}
@ -404,7 +404,7 @@ Core::TrustHandler::Keys Core::TrustHandler::getKeys(Shared::EncryptionProtocol
try {
Keys map = itr->second->getRecord(jid);
return map;
} catch (const DataBase::NotFound& e) {
} catch (const LMDBAL::NotFound& e) {
return Keys();
}
} else {
@ -421,7 +421,7 @@ Shared::TrustSummary Core::TrustHandler::getSummary(const QString& jid) const {
for (const std::pair<const QByteArray, Shared::TrustLevel>& trust : keys) {
result.increment(protocol, trust.second);
}
} catch (const DataBase::NotFound& e) {}
} catch (const LMDBAL::NotFound& e) {}
}
return result;

View File

@ -45,7 +45,7 @@ public:
typedef QHash<QString, QHash<QByteArray, TL>> HSHBTL;
typedef std::map<QByteArray, Shared::TrustLevel> Keys;
typedef DataBase::Cache<QString, Keys> KeyCache;
typedef LMDBAL::Cache<QString, Keys> KeyCache;
virtual QXmppTask<void> resetAll(CSR encryption) override;
virtual QXmppTask<TL> trustLevel(CSR encryption, CSR keyOwnerJid, const QByteArray& keyId) override;
@ -77,10 +77,10 @@ private:
private:
Account* acc;
DataBase db;
LMDBAL::Base db;
QFile protocols;
DataBase::Cache<QString, uint8_t>* securityPolicies;
DataBase::Cache<QString, QByteArray>* ownKeys;
LMDBAL::Cache<QString, uint8_t>* securityPolicies;
LMDBAL::Cache<QString, QByteArray>* ownKeys;
std::map<QString, KeyCache*> keysByProtocol;
};

1
external/lmdbal vendored Submodule

@ -0,0 +1 @@
Subproject commit c83369f34761e7a053d62312bd07fe5b3db3a519

1
external/storage vendored

@ -1 +0,0 @@
Subproject commit 6a8f67ac34de286588cd89e3218f55b54da47f42

View File

@ -40,6 +40,7 @@ int main(int argc, char *argv[])
qRegisterMetaType<QSet<QString>>("QSet<QString>");
qRegisterMetaType<Shared::ConnectionState>("Shared::ConnectionState");
qRegisterMetaType<Shared::Availability>("Shared::Availability");
qRegisterMetaType<Shared::EncryptionProtocol>("Shared::EncryptionProtocol");
qRegisterMetaType<Shared::KeyInfo>("Shared::KeyInfo");
qRegisterMetaType<Shared::Info>("Shared::Info");
#ifdef WITH_OMEMO

View File

@ -6,7 +6,7 @@ pkgdesc="An XMPP desktop messenger, written on pure c++ (qt)"
arch=('i686' 'x86_64')
url="https://git.macaw.me/blue/squawk"
license=('GPL3')
depends=('hicolor-icon-theme' 'desktop-file-utils' 'lmdb' 'qxmpp>=1.1.0')
depends=('hicolor-icon-theme' 'desktop-file-utils' 'lmdbal' 'qxmpp>=1.1.0')
makedepends=('cmake>=3.3' 'imagemagick' 'qt5-tools' 'boost')
optdepends=('kwallet: secure password storage (requires rebuild)'
'kconfig: system themes support (requires rebuild)'
@ -18,9 +18,9 @@ sha256sums=('e4fa2174a3ba95159cc3b0bac3f00550c9e0ce971c55334e2662696a4543fc7e')
build() {
cd "$srcdir/squawk"
cmake . -D CMAKE_INSTALL_PREFIX=/usr -D CMAKE_BUILD_TYPE=Release
cmake --build . -j $nproc
cmake --build .
}
package() {
cd "$srcdir/squawk"
DESTDIR="$pkgdir/" cmake --build . --target install
DESTDIR="$pkgdir/" cmake --install .
}

View File

@ -160,11 +160,14 @@ static const TrustLevel TrustLevelHighest = TrustLevel::undecided;
static const TrustLevel TrustLevelLowest = TrustLevel::authenticated;
enum class EncryptionProtocol {
none,
omemo,
omemo1,
omemo2
};
Q_ENUM_NS(EncryptionProtocol)
static const EncryptionProtocol EncryptionProtocolHighest = EncryptionProtocol::none;
static const EncryptionProtocol EncryptionProtocolLowest = EncryptionProtocol::omemo2;
}
#endif // SHARED_ENUMS_H

View File

@ -405,3 +405,4 @@ FROM_INT_INPL(Shared::AccountPassword)
FROM_INT_INPL(Shared::Avatar)
FROM_INT_INPL(Shared::Availability)
FROM_INT_INPL(Shared::TrustLevel)
FROM_INT_INPL(Shared::EncryptionProtocol)

View File

@ -28,11 +28,13 @@ const std::set<Shared::TrustLevel> Shared::TrustSummary::untrustedLevels({
});
const std::map<Shared::EncryptionProtocol, QString> Shared::TrustSummary::protocolKeys({
{Shared::EncryptionProtocol::none, "none"},
{Shared::EncryptionProtocol::omemo, "eu.siacs.conversations.axolotl"},
{Shared::EncryptionProtocol::omemo1, "urn:xmpp:omemo:1"},
{Shared::EncryptionProtocol::omemo2, "urn:xmpp:omemo:2"}
});
const std::map<QString, Shared::EncryptionProtocol> Shared::TrustSummary::protocolValues({
{"none", Shared::EncryptionProtocol::none},
{"eu.siacs.conversations.axolotl", Shared::EncryptionProtocol::omemo},
{"urn:xmpp:omemo:1", Shared::EncryptionProtocol::omemo1},
{"urn:xmpp:omemo:2", Shared::EncryptionProtocol::omemo2}

View File

@ -24,6 +24,7 @@ Models::Contact::Contact(const Account* acc, const QString& p_jid ,const QMap<QS
Element(Item::contact, acc, p_jid, data, parentItem),
availability(Shared::Availability::offline),
state(Shared::SubscriptionState::none),
encryption(Shared::EncryptionProtocol::none),
trust(),
presences(),
status()

View File

@ -82,9 +82,11 @@ protected:
private:
Shared::Availability availability;
Shared::SubscriptionState state;
Shared::EncryptionProtocol encryption;
Shared::TrustSummary trust;
QMap<QString, Presence*> presences;
QString status;
};
}

View File

@ -29,8 +29,10 @@ Chat::Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent):
setAvatar(p_contact->getAvatarPath());
connect(contact, &Models::Contact::childChanged, this, &Chat::onContactChanged);
if (p_contact->hasKeys(Shared::EncryptionProtocol::omemo2))
if (p_contact->hasKeys(Shared::EncryptionProtocol::omemo2)) {
m_ui->encryptionButton->setVisible(true);
//if ()
}
}
Chat::~Chat()