From 5ca1fb18bbf9789a65eaf3113ee1ff65449ff086 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 7 Nov 2021 03:38:48 +0100 Subject: Move away from using an event loop to access secrets Fixes messages in room flickering and being stuck fixes #760 relates to #770 relates to #789 --- src/ChatPage.cpp | 117 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 57 deletions(-) (limited to 'src/ChatPage.cpp') diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index d262387c..eec8a4d1 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -316,6 +316,65 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token) try { cache::init(userid); + connect(cache::client(), &Cache::databaseReady, this, [this]() { + nhlog::db()->info("database ready"); + + const bool isInitialized = cache::isInitialized(); + const auto cacheVersion = cache::formatVersion(); + + try { + if (!isInitialized) { + cache::setCurrentFormat(); + } else { + if (cacheVersion == cache::CacheVersion::Current) { + loadStateFromCache(); + return; + } else if (cacheVersion == cache::CacheVersion::Older) { + if (!cache::runMigrations()) { + QMessageBox::critical( + this, + tr("Cache migration failed!"), + tr("Migrating the cache to the current version failed. " + "This can have different reasons. Please open an " + "issue and try to use an older version in the mean " + "time. Alternatively you can try deleting the cache " + "manually.")); + QCoreApplication::quit(); + } + loadStateFromCache(); + return; + } else if (cacheVersion == cache::CacheVersion::Newer) { + QMessageBox::critical( + this, + tr("Incompatible cache version"), + tr("The cache on your disk is newer than this version of Nheko " + "supports. Please update Nheko or clear your cache.")); + QCoreApplication::quit(); + return; + } + } + + // It's the first time syncing with this device + // There isn't a saved olm account to restore. + nhlog::crypto()->info("creating new olm account"); + olm::client()->create_new_account(); + cache::saveOlmAccount(olm::client()->save(cache::client()->pickleSecret())); + } catch (const lmdb::error &e) { + nhlog::crypto()->critical("failed to save olm account {}", e.what()); + emit dropToLoginPageCb(QString::fromStdString(e.what())); + return; + } catch (const mtx::crypto::olm_exception &e) { + nhlog::crypto()->critical("failed to create new olm account {}", e.what()); + emit dropToLoginPageCb(QString::fromStdString(e.what())); + return; + } + + getProfileInfo(); + getBackupVersion(); + tryInitialSync(); + callManager_->refreshTurnServer(); + }); + connect(cache::client(), &Cache::newReadReceipts, view_manager_, @@ -326,66 +385,10 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token) ¬ificationsManager, &NotificationsManager::removeNotification); - const bool isInitialized = cache::isInitialized(); - const auto cacheVersion = cache::formatVersion(); - - callManager_->refreshTurnServer(); - - if (!isInitialized) { - cache::setCurrentFormat(); - } else { - if (cacheVersion == cache::CacheVersion::Current) { - loadStateFromCache(); - return; - } else if (cacheVersion == cache::CacheVersion::Older) { - if (!cache::runMigrations()) { - QMessageBox::critical(this, - tr("Cache migration failed!"), - tr("Migrating the cache to the current version failed. " - "This can have different reasons. Please open an " - "issue and try to use an older version in the mean " - "time. Alternatively you can try deleting the cache " - "manually.")); - QCoreApplication::quit(); - } - loadStateFromCache(); - return; - } else if (cacheVersion == cache::CacheVersion::Newer) { - QMessageBox::critical( - this, - tr("Incompatible cache version"), - tr("The cache on your disk is newer than this version of Nheko " - "supports. Please update or clear your cache.")); - QCoreApplication::quit(); - return; - } - } - } catch (const lmdb::error &e) { nhlog::db()->critical("failure during boot: {}", e.what()); - cache::deleteData(); - nhlog::net()->info("falling back to initial sync"); + emit dropToLoginPageCb(tr("Failed to open database, logging out!")); } - - try { - // It's the first time syncing with this device - // There isn't a saved olm account to restore. - nhlog::crypto()->info("creating new olm account"); - olm::client()->create_new_account(); - cache::saveOlmAccount(olm::client()->save(cache::client()->pickleSecret())); - } catch (const lmdb::error &e) { - nhlog::crypto()->critical("failed to save olm account {}", e.what()); - emit dropToLoginPageCb(QString::fromStdString(e.what())); - return; - } catch (const mtx::crypto::olm_exception &e) { - nhlog::crypto()->critical("failed to create new olm account {}", e.what()); - emit dropToLoginPageCb(QString::fromStdString(e.what())); - return; - } - - getProfileInfo(); - getBackupVersion(); - tryInitialSync(); } void -- cgit 1.5.1 From 809be93e206e9ab75ab1f3e6c083a0b6ea37ce6e Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 7 Nov 2021 21:27:58 +0100 Subject: Fix self verification status never updating --- src/ChatPage.cpp | 1 + src/encryption/SelfVerificationStatus.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/ChatPage.cpp') diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index eec8a4d1..0b8f2301 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -373,6 +373,7 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token) getBackupVersion(); tryInitialSync(); callManager_->refreshTurnServer(); + emit MainWindow::instance()->reload(); }); connect(cache::client(), diff --git a/src/encryption/SelfVerificationStatus.cpp b/src/encryption/SelfVerificationStatus.cpp index 5fa8d831..3ddbc7e6 100644 --- a/src/encryption/SelfVerificationStatus.cpp +++ b/src/encryption/SelfVerificationStatus.cpp @@ -258,7 +258,8 @@ SelfVerificationStatus::invalidate() using namespace mtx::secret_storage; nhlog::db()->info("Invalidating self verification status"); - if (cache::isInitialized()) { + if (!cache::isInitialized()) { + nhlog::db()->warn("SelfVerificationStatus: cache not initialized"); return; } -- cgit 1.5.1 From ff560a09f57964ac97efffe9ee2a6be8dea527b7 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 8 Nov 2021 16:26:16 +0100 Subject: Improve fetching of device keys after login --- src/Cache.cpp | 6 ++++-- src/ChatPage.cpp | 4 +++- src/encryption/SelfVerificationStatus.cpp | 17 ++++++++++++++--- src/ui/UserProfile.cpp | 2 ++ 4 files changed, 23 insertions(+), 6 deletions(-) (limited to 'src/ChatPage.cpp') diff --git a/src/Cache.cpp b/src/Cache.cpp index 280e00ed..0fdf8dd3 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -4101,8 +4101,9 @@ Cache::updateUserKeys(const std::string &sync_token, const mtx::responses::Query (void)status; emit verificationStatusChanged(user); } + } else { + emit verificationStatusChanged(user_id); } - emit verificationStatusChanged(user_id); } } @@ -4311,8 +4312,9 @@ Cache::markDeviceVerified(const std::string &user_id, const std::string &key) (void)status; emit verificationStatusChanged(user); } + } else { + emit verificationStatusChanged(user_id); } - emit verificationStatusChanged(user_id); } void diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 0b8f2301..77a8edcf 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -526,6 +526,8 @@ ChatPage::tryInitialSync() for (const auto &entry : res.one_time_key_counts) nhlog::net()->info("uploaded {} {} one-time keys", entry.second, entry.first); + cache::client()->markUserKeysOutOfDate({http::client()->user_id().to_string()}); + startInitialSync(); }); } @@ -1143,7 +1145,7 @@ ChatPage::decryptDownloadedSecrets(mtx::secret_storage::AesHmacSha2KeyDescriptio if (!decrypted.empty()) { cache::storeSecret(secretName, decrypted); - if (deviceKeys && + if (deviceKeys && deviceKeys->device_keys.count(http::client()->device_id()) && secretName == mtx::secret_storage::secrets::cross_signing_self_signing) { auto myKey = deviceKeys->device_keys.at(http::client()->device_id()); if (myKey.user_id == http::client()->user_id().to_string() && diff --git a/src/encryption/SelfVerificationStatus.cpp b/src/encryption/SelfVerificationStatus.cpp index 3ddbc7e6..c4f4f196 100644 --- a/src/encryption/SelfVerificationStatus.cpp +++ b/src/encryption/SelfVerificationStatus.cpp @@ -4,6 +4,8 @@ #include "SelfVerificationStatus.h" +#include + #include "Cache_p.h" #include "ChatPage.h" #include "Logging.h" @@ -18,12 +20,13 @@ SelfVerificationStatus::SelfVerificationStatus(QObject *o) : QObject(o) { - connect(MainWindow::instance(), &MainWindow::reload, this, [this] { + connect(ChatPage::instance(), &ChatPage::contentLoaded, this, [this] { connect(cache::client(), &Cache::selfVerificationStatusChanged, this, &SelfVerificationStatus::invalidate, Qt::UniqueConnection); + cache::client()->markUserKeysOutOfDate({http::client()->user_id().to_string()}); }); } @@ -268,8 +271,16 @@ SelfVerificationStatus::invalidate() auto keys = cache::client()->userKeys(http::client()->user_id().to_string()); if (!keys || keys->device_keys.find(http::client()->device_id()) == keys->device_keys.end()) { - QTimer::singleShot(500, [] { - cache::client()->markUserKeysOutOfDate({http::client()->user_id().to_string()}); + if (keys && (keys->seen_device_ids.count(http::client()->device_id()) || + keys->seen_device_keys.count(olm::client()->identity_keys().curve25519))) { + emit ChatPage::instance()->dropToLoginPageCb( + tr("Identity key changed. This breaks E2EE, so logging out.")); + return; + } + + cache::client()->markUserKeysOutOfDate({http::client()->user_id().to_string()}); + + QTimer::singleShot(1'000, [] { cache::client()->query_keys(http::client()->user_id().to_string(), [](const UserKeyCache &, mtx::http::RequestErr) {}); }); diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp index b5a16f43..72b1d8e6 100644 --- a/src/ui/UserProfile.cpp +++ b/src/ui/UserProfile.cpp @@ -188,6 +188,7 @@ UserProfile::fetchDeviceList(const QString &userID) nhlog::net()->warn("failed to query device keys: {},{}", mtx::errors::to_string(err->matrix_error.errcode), static_cast(err->status_code)); + return; } // Ensure local key cache is up to date @@ -201,6 +202,7 @@ UserProfile::fetchDeviceList(const QString &userID) nhlog::net()->warn("failed to query device keys: {},{}", mtx::errors::to_string(err->matrix_error.errcode), static_cast(err->status_code)); + return; } emit verificationStatiChanged(); -- cgit 1.5.1