diff --git a/.gitmodules b/.gitmodules index 098973a..448dae5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 01a9bd1..6cdb712 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/README.md b/README.md index 3e20568..121b640 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/core/components/clientcache.h b/core/components/clientcache.h index 6202af5..b9dba73 100644 --- a/core/components/clientcache.h +++ b/core/components/clientcache.h @@ -45,11 +45,16 @@ signals: public slots: bool checkClient(const Shared::ClientId& id); - bool registerClientInfo(const QString& sourceFullJid, const QString& id, const std::set& identities, const std::set& features); + bool registerClientInfo( + const QString& sourceFullJid, + const QString& id, + const std::set& identities, + const std::set& features + ); private: - DataBase db; - DataBase::Cache* cache; + LMDBAL::Base db; + LMDBAL::Cache* cache; std::map requested; std::map specific; }; diff --git a/core/handlers/omemohandler.cpp b/core/handlers/omemohandler.cpp index c8bcb17..35bca9e 100644 --- a/core/handlers/omemohandler.cpp +++ b/core/handlers/omemohandler.cpp @@ -35,7 +35,7 @@ Core::OmemoHandler::OmemoHandler(Account* account) : QVariant own = meta->getRecord("ownDevice"); ownDevice = own.value(); 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 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 Core::OmemoHandler::removePreKeyPair(uint32_t keyId) { QXmppTask 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 devs; try { devs = devices->getRecord(jid); - } catch (const DataBase::NotFound& error) {} + } catch (const LMDBAL::NotFound& error) {} for (QHash::const_iterator itr = devs.begin(), end = devs.end(); itr != end; ++itr) { const Device& dev = itr.value(); diff --git a/core/handlers/omemohandler.h b/core/handlers/omemohandler.h index 7053450..1ea1f26 100644 --- a/core/handlers/omemohandler.h +++ b/core/handlers/omemohandler.h @@ -73,11 +73,11 @@ private slots: private: Account* acc; std::optional ownDevice; - DataBase db; - DataBase::Cache* meta; - DataBase::Cache>* devices; - DataBase::Cache* preKeyPairs; - DataBase::Cache* signedPreKeyPairs; + LMDBAL::Base db; + LMDBAL::Cache* meta; + LMDBAL::Cache>* devices; + LMDBAL::Cache* preKeyPairs; + LMDBAL::Cache* signedPreKeyPairs; }; } diff --git a/core/handlers/trusthandler.cpp b/core/handlers/trusthandler.cpp index c866d6f..21b3491 100644 --- a/core/handlers/trusthandler.cpp +++ b/core/handlers/trusthandler.cpp @@ -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 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>> 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 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>> 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 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 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 result = data.insert(std::make_pair(keyId, level)); if (!result.second) @@ -355,14 +355,14 @@ QXmppTask 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 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 Core::TrustHandler::securityPolicy(const Q QXmpp::TrustSecurityPolicy res; try { res = static_cast(securityPolicies->getRecord(encryption)); - } catch (const DataBase::NotFound& e) {} + } catch (const LMDBAL::NotFound& e) {} return Core::makeReadyTask(std::move(res)); } QXmppTask 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& trust : keys) { result.increment(protocol, trust.second); } - } catch (const DataBase::NotFound& e) {} + } catch (const LMDBAL::NotFound& e) {} } return result; diff --git a/core/handlers/trusthandler.h b/core/handlers/trusthandler.h index 98d7f1e..68a4aa1 100644 --- a/core/handlers/trusthandler.h +++ b/core/handlers/trusthandler.h @@ -45,7 +45,7 @@ public: typedef QHash> HSHBTL; typedef std::map Keys; - typedef DataBase::Cache KeyCache; + typedef LMDBAL::Cache KeyCache; virtual QXmppTask resetAll(CSR encryption) override; virtual QXmppTask 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* securityPolicies; - DataBase::Cache* ownKeys; + LMDBAL::Cache* securityPolicies; + LMDBAL::Cache* ownKeys; std::map keysByProtocol; }; diff --git a/external/lmdbal b/external/lmdbal new file mode 160000 index 0000000..c83369f --- /dev/null +++ b/external/lmdbal @@ -0,0 +1 @@ +Subproject commit c83369f34761e7a053d62312bd07fe5b3db3a519 diff --git a/external/storage b/external/storage deleted file mode 160000 index 6a8f67a..0000000 --- a/external/storage +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6a8f67ac34de286588cd89e3218f55b54da47f42 diff --git a/main/main.cpp b/main/main.cpp index afe1cf2..ce614b3 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -40,6 +40,7 @@ int main(int argc, char *argv[]) qRegisterMetaType>("QSet"); qRegisterMetaType("Shared::ConnectionState"); qRegisterMetaType("Shared::Availability"); + qRegisterMetaType("Shared::EncryptionProtocol"); qRegisterMetaType("Shared::KeyInfo"); qRegisterMetaType("Shared::Info"); #ifdef WITH_OMEMO diff --git a/packaging/Archlinux/PKGBUILD b/packaging/Archlinux/PKGBUILD index 7db43ff..6e63901 100644 --- a/packaging/Archlinux/PKGBUILD +++ b/packaging/Archlinux/PKGBUILD @@ -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 . } diff --git a/shared/enums.h b/shared/enums.h index aff22b9..c959883 100644 --- a/shared/enums.h +++ b/shared/enums.h @@ -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 diff --git a/shared/global.cpp b/shared/global.cpp index 1b5763b..95168b2 100644 --- a/shared/global.cpp +++ b/shared/global.cpp @@ -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) diff --git a/shared/trustsummary.cpp b/shared/trustsummary.cpp index eae98bf..47abb16 100644 --- a/shared/trustsummary.cpp +++ b/shared/trustsummary.cpp @@ -28,11 +28,13 @@ const std::set Shared::TrustSummary::untrustedLevels({ }); const std::map 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 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} diff --git a/ui/models/contact.cpp b/ui/models/contact.cpp index 8d6def9..c27965b 100644 --- a/ui/models/contact.cpp +++ b/ui/models/contact.cpp @@ -24,6 +24,7 @@ Models::Contact::Contact(const Account* acc, const QString& p_jid ,const QMap presences; QString status; + }; } diff --git a/ui/widgets/chat.cpp b/ui/widgets/chat.cpp index 607fab4..301553b 100644 --- a/ui/widgets/chat.cpp +++ b/ui/widgets/chat.cpp @@ -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()