From 313a5d528c0eb6c6c0246c6325199d0605b7c344 Mon Sep 17 00:00:00 2001 From: Igor Artemenko Date: Thu, 12 Jan 2023 16:26:24 +0000 Subject: [PATCH] Decrypt initial message after joining new DM Suppose that Alice logs in using Element. Before this change, when Bob would send a DM to Alice through Pantalaimon, Alice would not be able to decrypt Bob's initial message. Instead, she would see "Unable to decrypt: The sender's device has not sent us the keys for this message." and Pantalaimon's olmsessions table would have no associated records. Any future messages would be visible however. On the other hand, when Alice (using Element) is the one to send the first DM to Bob, he can decrypt the initial message. For Pantalaimon to execute /keys/claim, get_missing_sessions must return the invitee's device (and log "Missing session for device"). If Pantalaimon calls this method too soon, then self.device_store will not have the device. To populate self.device_store before Pantalaimon calls get_missing_sessions, it must execute /keys/query (and invoke _handle_key_query) earlier, during the /createRoom request. Pantalaimon does execute the /keys/query request during a sync after the server finishes creating the DM (and logs "Adding new device to the device store for user"), but only after checking unsuccessfully for the device in self.device_store. After this change, Pantalaimon executes /keys/claim, there is one record in olmsessions, and Alice can decrypt Bob's initial message. --- pantalaimon/daemon.py | 21 +++++++++++++++++++++ pantalaimon/main.py | 2 ++ 2 files changed, 23 insertions(+) diff --git a/pantalaimon/daemon.py b/pantalaimon/daemon.py index 3264cab..d241aff 100755 --- a/pantalaimon/daemon.py +++ b/pantalaimon/daemon.py @@ -793,6 +793,27 @@ class ProxyDaemon: body=await response.read(), ) + async def createRoom(self, request): + try: + content = await request.json() + except (JSONDecodeError, ContentTypeError): + return self._not_json + + invite = content.get("invite", ()) + if invite: + access_token = self.get_access_token(request) + + if not access_token: + return self._missing_token + + client = await self._find_client(access_token) + if not client: + return self._unknown_token + + client.users_for_key_query.update(invite) + + return await self.forward_to_web(request) + async def messages(self, request): access_token = self.get_access_token(request) diff --git a/pantalaimon/main.py b/pantalaimon/main.py index 0ab42d6..cd27170 100644 --- a/pantalaimon/main.py +++ b/pantalaimon/main.py @@ -71,6 +71,8 @@ async def init(data_dir, server_conf, send_queue, recv_queue): web.post("/_matrix/client/v3/login", proxy.login), web.get("/_matrix/client/r0/sync", proxy.sync), web.get("/_matrix/client/v3/sync", proxy.sync), + web.post("/_matrix/client/r0/createRoom", proxy.createRoom), + web.post("/_matrix/client/v3/createRoom", proxy.createRoom), web.get("/_matrix/client/r0/rooms/{room_id}/messages", proxy.messages), web.get("/_matrix/client/v3/rooms/{room_id}/messages", proxy.messages), web.put(