Skip to content

Commit c93d24d

Browse files
authored
Merge pull request #153 from mautrix/max/be-12207
Add option to delete outdated inbound keys
2 parents 0634700 + ad42ba8 commit c93d24d

File tree

5 files changed

+38
-0
lines changed

5 files changed

+38
-0
lines changed

mautrix/bridge/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ def do_update(self, helper: ConfigUpdateHelper) -> None:
150150
copy("bridge.encryption.delete_keys.delete_prev_on_new_session")
151151
copy("bridge.encryption.delete_keys.delete_on_device_delete")
152152
copy("bridge.encryption.delete_keys.periodically_delete_expired")
153+
copy("bridge.encryption.delete_keys.delete_outdated_inbound")
153154
copy("bridge.encryption.verification_levels.receive")
154155
copy("bridge.encryption.verification_levels.send")
155156
copy("bridge.encryption.verification_levels.share")

mautrix/bridge/e2ee.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class EncryptionManager:
5656
key_sharing_enabled: bool
5757
appservice_mode: bool
5858
periodically_delete_expired_keys: bool
59+
delete_outdated_inbound: bool
5960

6061
bridge: br.Bridge
6162
az: AppService
@@ -113,6 +114,7 @@ def __init__(
113114
self.az.to_device_handler = self.crypto.handle_as_to_device_event
114115

115116
self.periodically_delete_expired_keys = False
117+
self.delete_outdated_inbound = False
116118
self._key_delete_task = None
117119
del_cfg = bridge.config["bridge.encryption.delete_keys"]
118120
if del_cfg:
@@ -123,6 +125,7 @@ def __init__(
123125
self.crypto.delete_fully_used_keys_on_decrypt = del_cfg["delete_fully_used_on_decrypt"]
124126
self.crypto.delete_keys_on_device_delete = del_cfg["delete_on_device_delete"]
125127
self.periodically_delete_expired_keys = del_cfg["periodically_delete_expired"]
128+
self.delete_outdated_inbound = del_cfg["delete_outdated_inbound"]
126129
self.crypto.disable_device_change_key_rotation = bridge.config[
127130
"bridge.encryption.rotation.disable_device_change_key_rotation"
128131
]
@@ -279,6 +282,12 @@ async def start(self) -> None:
279282
else:
280283
_ = self.client.start(self._filter)
281284
self.log.info("End-to-bridge encryption support is enabled (sync mode)")
285+
if self.delete_outdated_inbound:
286+
deleted = await self.crypto_store.redact_outdated_group_sessions()
287+
if len(deleted) > 0:
288+
self.log.debug(
289+
f"Deleted {len(deleted)} inbound keys which lacked expiration metadata"
290+
)
282291
if self.periodically_delete_expired_keys:
283292
self._key_delete_task = background_task.create(self._periodically_delete_keys())
284293
background_task.create(self._resync_encryption_info())

mautrix/crypto/store/abstract.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ async def redact_expired_group_sessions(self) -> list[SessionID]:
237237
The list of session IDs that were deleted.
238238
"""
239239

240+
@abstractmethod
241+
async def redact_outdated_group_sessions(self) -> list[SessionID]:
242+
"""
243+
Remove all Megolm group sessions which lack the metadata to determine when they should
244+
expire.
245+
246+
Returns:
247+
The list of session IDs that were deleted.
248+
"""
249+
240250
@abstractmethod
241251
async def has_group_session(self, room_id: RoomID, session_id: SessionID) -> bool:
242252
"""

mautrix/crypto/store/asyncpg/store.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,21 @@ async def redact_expired_group_sessions(self) -> list[SessionID]:
362362
)
363363
return [row["session_id"] for row in rows]
364364

365+
async def redact_outdated_group_sessions(self) -> list[SessionID]:
366+
q = """
367+
UPDATE crypto_megolm_inbound_session
368+
SET withheld_code=$1, withheld_reason=$2, session=NULL, forwarding_chains=NULL
369+
WHERE account_id=$3 AND session IS NOT NULL AND received_at IS NULL
370+
RETURNING session_id
371+
"""
372+
rows = await self.db.fetch(
373+
q,
374+
RoomKeyWithheldCode.BEEPER_REDACTED.value,
375+
f"Session redacted: outdated",
376+
self.account_id,
377+
)
378+
return [row["session_id"] for row in rows]
379+
365380
async def has_group_session(self, room_id: RoomID, session_id: SessionID) -> bool:
366381
q = """
367382
SELECT COUNT(session) FROM crypto_megolm_inbound_session

mautrix/crypto/store/memory.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ async def redact_group_sessions(
134134
async def redact_expired_group_sessions(self) -> list[SessionID]:
135135
raise NotImplementedError()
136136

137+
async def redact_outdated_group_sessions(self) -> list[SessionID]:
138+
raise NotImplementedError()
139+
137140
async def has_group_session(self, room_id: RoomID, session_id: SessionID) -> bool:
138141
return (room_id, session_id) in self._inbound_sessions
139142

0 commit comments

Comments
 (0)