From 340dbf2eb6d2c3f3a20f985bdd25cca0934bec78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 14 Jul 2021 10:44:03 +0200 Subject: [PATCH 1/3] pantalaimon: Prevent the sending of messages if the client didn't sync Pantalaimon depends on the room state to be present to decide correctly if a message should be encrypted or now. The room state is fetched from the server every time we restart, this means that failure to fetch room states from the server would hinder us from doing the correct decision. This patch prevents a downgrade to sending unencrypted messages if we're unable to sync at least once with the server. --- pantalaimon/client.py | 5 ++++- pantalaimon/daemon.py | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/pantalaimon/client.py b/pantalaimon/client.py index 76d31a2..e0188f2 100644 --- a/pantalaimon/client.py +++ b/pantalaimon/client.py @@ -410,6 +410,10 @@ class PanClient(AsyncClient): except (asyncio.CancelledError, KeyboardInterrupt): return + @property + def has_been_synced(self) -> bool: + self.last_sync_token is not None + async def sync_tasks(self, response): if self.index: await self.index.commit_events() @@ -540,7 +544,6 @@ class PanClient(AsyncClient): timeout = 30000 sync_filter = {"room": {"state": {"lazy_load_members": True}}} next_batch = self.pan_store.load_token(self.server_name, self.user_id) - self.last_sync_token = next_batch # We don't store any room state so initial sync needs to be with the # full_state parameter. Subsequent ones are normal. diff --git a/pantalaimon/daemon.py b/pantalaimon/daemon.py index a2f5a37..bb9b8e5 100755 --- a/pantalaimon/daemon.py +++ b/pantalaimon/daemon.py @@ -902,7 +902,22 @@ class ProxyDaemon: room = client.rooms[room_id] encrypt = room.encrypted except KeyError: - return await self.forward_to_web(request, token=client.access_token) + if client.has_been_synced: + return await self.forward_to_web(request, token=client.access_token) + else: + logger.error( + "The internal Pantalaimon client did not manage " + "to sync with the server." + ) + return web.json_response( + { + "errcode": "M_UNKNOWN", + "error": "The pantalaimon client did not manage to sync with " + "the server", + }, + headers=CORS_HEADERS, + status=500, + ) # Don't encrypt reactions for now - they are weird and clients # need to support them like this. From f875499d6b0a9d968270872a4a81527517dd703e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 14 Jul 2021 11:05:02 +0200 Subject: [PATCH 2/3] pantalaimon: Fix some formatting issues --- pantalaimon/daemon.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pantalaimon/daemon.py b/pantalaimon/daemon.py index bb9b8e5..bdba6a8 100755 --- a/pantalaimon/daemon.py +++ b/pantalaimon/daemon.py @@ -942,7 +942,9 @@ class ProxyDaemon: try: content["url"] = await self._decrypt_uri(content["url"], client) if "info" in content and "thumbnail_url" in content["info"]: - content["info"]["thumbnail_url"] = await self._decrypt_uri(content["info"]["thumbnail_url"], client) + content["info"]["thumbnail_url"] = await self._decrypt_uri( + content["info"]["thumbnail_url"], client + ) return await self.forward_to_web( request, data=json.dumps(content), token=client.access_token ) @@ -962,7 +964,9 @@ class ProxyDaemon: content_msgtype in ["m.image", "m.video", "m.audio", "m.file"] or msgtype == "m.room.avatar" ): - upload_info, media_info = self._get_upload_and_media_info(content["url"]) + upload_info, media_info = self._get_upload_and_media_info( + content["url"] + ) if not upload_info or not media_info: response = await client.room_send( room_id, msgtype, content, txnid, ignore_unverified @@ -1280,7 +1284,9 @@ class ProxyDaemon: return self._not_json try: - content["avatar_url"] = await self._decrypt_uri(content["avatar_url"], client) + content["avatar_url"] = await self._decrypt_uri( + content["avatar_url"], client + ) return await self.forward_to_web( request, data=json.dumps(content), token=client.access_token ) From a9f6ad2c7e08c72e8274a6bdf2954edf1c2d6b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 14 Jul 2021 12:25:39 +0200 Subject: [PATCH 3/3] pantalaimon: Don't forward messages if we think the room isn't joined --- pantalaimon/daemon.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pantalaimon/daemon.py b/pantalaimon/daemon.py index bdba6a8..bbec91a 100755 --- a/pantalaimon/daemon.py +++ b/pantalaimon/daemon.py @@ -897,13 +897,22 @@ class ProxyDaemon: room_id = request.match_info["room_id"] - # The room is not in the joined rooms list, just forward it. try: room = client.rooms[room_id] encrypt = room.encrypted except KeyError: + # The room is not in the joined rooms list, either the pan client + # didn't manage to sync the state or we're not joined, in either + # case send an error response. if client.has_been_synced: - return await self.forward_to_web(request, token=client.access_token) + return web.json_response( + { + "errcode": "M_FORBIDDEN", + "error": "You do not have permission to send the event." + }, + headers=CORS_HEADERS, + status=403, + ) else: logger.error( "The internal Pantalaimon client did not manage "