Remove outbound session storage

This commit is contained in:
Nicolas Werner 2020-11-27 04:56:44 +01:00
parent c24f9a22a5
commit 2290ebcf78
6 changed files with 44 additions and 101 deletions

View File

@ -361,7 +361,8 @@ Cache::inboundMegolmSessionExists(const MegolmSessionIndex &index)
} }
void void
Cache::updateOutboundMegolmSession(const std::string &room_id, int message_index) Cache::updateOutboundMegolmSession(const std::string &room_id,
mtx::crypto::OutboundGroupSessionPtr &ptr)
{ {
using namespace mtx::crypto; using namespace mtx::crypto;
@ -369,21 +370,14 @@ Cache::updateOutboundMegolmSession(const std::string &room_id, int message_index
return; return;
OutboundGroupSessionData data; OutboundGroupSessionData data;
OlmOutboundGroupSession *session; data.message_index = olm_outbound_group_session_message_index(ptr.get());
{ data.session_id = mtx::crypto::session_id(ptr.get());
std::unique_lock<std::mutex> lock(session_storage.group_outbound_mtx); data.session_key = mtx::crypto::session_key(ptr.get());
data = session_storage.group_outbound_session_data[room_id];
session = session_storage.group_outbound_sessions[room_id].get();
// Update with the current message.
data.message_index = message_index;
session_storage.group_outbound_session_data[room_id] = data;
}
// Save the updated pickled data for the session. // Save the updated pickled data for the session.
json j; json j;
j["data"] = data; j["data"] = data;
j["session"] = pickle<OutboundSessionObject>(session, SECRET); j["session"] = pickle<OutboundSessionObject>(ptr.get(), SECRET);
auto txn = lmdb::txn::begin(env_); auto txn = lmdb::txn::begin(env_);
lmdb::dbi_put(txn, outboundMegolmSessionDb_, lmdb::val(room_id), lmdb::val(j.dump())); lmdb::dbi_put(txn, outboundMegolmSessionDb_, lmdb::val(room_id), lmdb::val(j.dump()));
@ -399,10 +393,6 @@ Cache::dropOutboundMegolmSession(const std::string &room_id)
return; return;
{ {
std::unique_lock<std::mutex> lock(session_storage.group_outbound_mtx);
session_storage.group_outbound_session_data.erase(room_id);
session_storage.group_outbound_sessions.erase(room_id);
auto txn = lmdb::txn::begin(env_); auto txn = lmdb::txn::begin(env_);
lmdb::dbi_del(txn, outboundMegolmSessionDb_, lmdb::val(room_id), nullptr); lmdb::dbi_del(txn, outboundMegolmSessionDb_, lmdb::val(room_id), nullptr);
txn.commit(); txn.commit();
@ -424,30 +414,40 @@ Cache::saveOutboundMegolmSession(const std::string &room_id,
auto txn = lmdb::txn::begin(env_); auto txn = lmdb::txn::begin(env_);
lmdb::dbi_put(txn, outboundMegolmSessionDb_, lmdb::val(room_id), lmdb::val(j.dump())); lmdb::dbi_put(txn, outboundMegolmSessionDb_, lmdb::val(room_id), lmdb::val(j.dump()));
txn.commit(); txn.commit();
{
std::unique_lock<std::mutex> lock(session_storage.group_outbound_mtx);
session_storage.group_outbound_session_data[room_id] = data;
session_storage.group_outbound_sessions[room_id] = std::move(session);
}
} }
bool bool
Cache::outboundMegolmSessionExists(const std::string &room_id) noexcept Cache::outboundMegolmSessionExists(const std::string &room_id) noexcept
{ {
std::unique_lock<std::mutex> lock(session_storage.group_outbound_mtx); try {
return (session_storage.group_outbound_sessions.find(room_id) != auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
session_storage.group_outbound_sessions.end()) && lmdb::val value;
(session_storage.group_outbound_session_data.find(room_id) != return lmdb::dbi_get(txn, outboundMegolmSessionDb_, lmdb::val(room_id), value);
session_storage.group_outbound_session_data.end()); } catch (std::exception &e) {
nhlog::db()->error("Failed to retrieve outbound Megolm Session: {}", e.what());
return false;
}
} }
OutboundGroupSessionDataRef OutboundGroupSessionDataRef
Cache::getOutboundMegolmSession(const std::string &room_id) Cache::getOutboundMegolmSession(const std::string &room_id)
{ {
std::unique_lock<std::mutex> lock(session_storage.group_outbound_mtx); try {
return OutboundGroupSessionDataRef{session_storage.group_outbound_sessions[room_id].get(), using namespace mtx::crypto;
session_storage.group_outbound_session_data[room_id]};
auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
lmdb::val value;
lmdb::dbi_get(txn, outboundMegolmSessionDb_, lmdb::val(room_id), value);
auto obj = json::parse(std::string_view(value.data(), value.size()));
OutboundGroupSessionDataRef ref{};
ref.data = obj.at("data").get<OutboundGroupSessionData>();
ref.session = unpickle<OutboundSessionObject>(obj.at("session"), SECRET);
return ref;
} catch (std::exception &e) {
nhlog::db()->error("Failed to retrieve outbound Megolm Session: {}", e.what());
return {};
}
} }
// //
@ -557,44 +557,6 @@ Cache::saveOlmAccount(const std::string &data)
txn.commit(); txn.commit();
} }
void
Cache::restoreSessions()
{
using namespace mtx::crypto;
auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
std::string key, value;
//
// Outbound Megolm Sessions
//
{
auto cursor = lmdb::cursor::open(txn, outboundMegolmSessionDb_);
while (cursor.get(key, value, MDB_NEXT)) {
json obj;
try {
obj = json::parse(value);
session_storage.group_outbound_session_data[key] =
obj.at("data").get<OutboundGroupSessionData>();
auto session =
unpickle<OutboundSessionObject>(obj.at("session"), SECRET);
session_storage.group_outbound_sessions[key] = std::move(session);
} catch (const nlohmann::json::exception &e) {
nhlog::db()->critical(
"failed to parse outbound megolm session data: {}", e.what());
}
}
cursor.close();
}
txn.commit();
nhlog::db()->info("sessions restored");
}
std::string std::string
Cache::restoreOlmAccount() Cache::restoreOlmAccount()
{ {
@ -4151,9 +4113,10 @@ outboundMegolmSessionExists(const std::string &room_id) noexcept
return instance_->outboundMegolmSessionExists(room_id); return instance_->outboundMegolmSessionExists(room_id);
} }
void void
updateOutboundMegolmSession(const std::string &room_id, int message_index) updateOutboundMegolmSession(const std::string &room_id,
mtx::crypto::OutboundGroupSessionPtr &session)
{ {
instance_->updateOutboundMegolmSession(room_id, message_index); instance_->updateOutboundMegolmSession(room_id, session);
} }
void void
dropOutboundMegolmSession(const std::string &room_id) dropOutboundMegolmSession(const std::string &room_id)
@ -4228,10 +4191,4 @@ restoreOlmAccount()
{ {
return instance_->restoreOlmAccount(); return instance_->restoreOlmAccount();
} }
void
restoreSessions()
{
return instance_->restoreSessions();
}
} // namespace cache } // namespace cache

View File

@ -241,7 +241,8 @@ getOutboundMegolmSession(const std::string &room_id);
bool bool
outboundMegolmSessionExists(const std::string &room_id) noexcept; outboundMegolmSessionExists(const std::string &room_id) noexcept;
void void
updateOutboundMegolmSession(const std::string &room_id, int message_index); updateOutboundMegolmSession(const std::string &room_id,
mtx::crypto::OutboundGroupSessionPtr &session);
void void
dropOutboundMegolmSession(const std::string &room_id); dropOutboundMegolmSession(const std::string &room_id);
@ -277,9 +278,7 @@ getLatestOlmSession(const std::string &curve25519);
void void
saveOlmAccount(const std::string &pickled); saveOlmAccount(const std::string &pickled);
std::string std::string
restoreOlmAccount(); restoreOlmAccount();
void
restoreSessions();
} }

View File

@ -21,7 +21,7 @@ from_json(const nlohmann::json &obj, OutboundGroupSessionData &msg);
struct OutboundGroupSessionDataRef struct OutboundGroupSessionDataRef
{ {
OlmOutboundGroupSession *session; mtx::crypto::OutboundGroupSessionPtr session;
OutboundGroupSessionData data; OutboundGroupSessionData data;
}; };
@ -52,16 +52,6 @@ to_json(nlohmann::json &obj, const MegolmSessionIndex &msg);
void void
from_json(const nlohmann::json &obj, MegolmSessionIndex &msg); from_json(const nlohmann::json &obj, MegolmSessionIndex &msg);
struct OlmSessionStorage
{
// Megolm sessions
std::map<std::string, mtx::crypto::OutboundGroupSessionPtr> group_outbound_sessions;
std::map<std::string, OutboundGroupSessionData> group_outbound_session_data;
// Guards for accessing megolm sessions.
std::mutex group_outbound_mtx;
};
struct StoredOlmSession struct StoredOlmSession
{ {
std::uint64_t last_message_ts = 0; std::uint64_t last_message_ts = 0;

View File

@ -235,7 +235,8 @@ public:
mtx::crypto::OutboundGroupSessionPtr session); mtx::crypto::OutboundGroupSessionPtr session);
OutboundGroupSessionDataRef getOutboundMegolmSession(const std::string &room_id); OutboundGroupSessionDataRef getOutboundMegolmSession(const std::string &room_id);
bool outboundMegolmSessionExists(const std::string &room_id) noexcept; bool outboundMegolmSessionExists(const std::string &room_id) noexcept;
void updateOutboundMegolmSession(const std::string &room_id, int message_index); void updateOutboundMegolmSession(const std::string &room_id,
mtx::crypto::OutboundGroupSessionPtr &session);
void dropOutboundMegolmSession(const std::string &room_id); void dropOutboundMegolmSession(const std::string &room_id);
void importSessionKeys(const mtx::crypto::ExportedSessionKeys &keys); void importSessionKeys(const mtx::crypto::ExportedSessionKeys &keys);
@ -265,8 +266,6 @@ public:
void saveOlmAccount(const std::string &pickled); void saveOlmAccount(const std::string &pickled);
std::string restoreOlmAccount(); std::string restoreOlmAccount();
void restoreSessions();
signals: signals:
void newReadReceipts(const QString &room_id, const std::vector<QString> &event_ids); void newReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
void roomReadStatus(const std::map<QString, bool> &status); void roomReadStatus(const std::map<QString, bool> &status);
@ -578,7 +577,6 @@ private:
QString localUserId_; QString localUserId_;
QString cacheDirectory_; QString cacheDirectory_;
OlmSessionStorage session_storage;
VerificationStorage verification_storage; VerificationStorage verification_storage;
}; };

View File

@ -526,7 +526,6 @@ ChatPage::loadStateFromCache()
nhlog::db()->info("restoring state from cache"); nhlog::db()->info("restoring state from cache");
try { try {
cache::restoreSessions();
olm::client()->load(cache::restoreOlmAccount(), STORAGE_SECRET_KEY); olm::client()->load(cache::restoreOlmAccount(), STORAGE_SECRET_KEY);
emit initializeEmptyViews(cache::client()->roomIds()); emit initializeEmptyViews(cache::client()->roomIds());

View File

@ -294,23 +294,23 @@ encrypt_group_message(const std::string &room_id, const std::string &device_id,
// Always check before for existence. // Always check before for existence.
auto res = cache::getOutboundMegolmSession(room_id); auto res = cache::getOutboundMegolmSession(room_id);
auto payload = olm::client()->encrypt_group_message(res.session, body.dump()); auto payload = olm::client()->encrypt_group_message(res.session.get(), body.dump());
// Prepare the m.room.encrypted event. // Prepare the m.room.encrypted event.
msg::Encrypted data; msg::Encrypted data;
data.ciphertext = std::string((char *)payload.data(), payload.size()); data.ciphertext = std::string((char *)payload.data(), payload.size());
data.sender_key = olm::client()->identity_keys().curve25519; data.sender_key = olm::client()->identity_keys().curve25519;
data.session_id = res.data.session_id; data.session_id = mtx::crypto::session_id(res.session.get());
data.device_id = device_id; data.device_id = device_id;
data.algorithm = MEGOLM_ALGO; data.algorithm = MEGOLM_ALGO;
data.relates_to = relation; data.relates_to = relation;
data.r_relates_to = r_relation; data.r_relates_to = r_relation;
auto message_index = olm_outbound_group_session_message_index(res.session); res.data.message_index = olm_outbound_group_session_message_index(res.session.get());
nhlog::crypto()->debug("next message_index {}", message_index); nhlog::crypto()->debug("next message_index {}", res.data.message_index);
// We need to re-pickle the session after we send a message to save the new message_index. // We need to re-pickle the session after we send a message to save the new message_index.
cache::updateOutboundMegolmSession(room_id, message_index); cache::updateOutboundMegolmSession(room_id, res.session);
return data; return data;
} }