Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Merge tag 'v1.10.0rc2' into develop
Browse files Browse the repository at this point in the history
Synapse 1.10.0rc2 (2020-02-06)
==============================

Bugfixes
--------

- Fix an issue with cross-signing where device signatures were not sent to remote servers. ([\#6844](#6844))
- Fix to the unknown remote device detection which was introduced in 1.10.rc1. ([\#6848](#6848))

Internal Changes
----------------

- Detect unexpected sender keys on remote encrypted events and resync device lists. ([\#6850](#6850))
  • Loading branch information
erikjohnston committed Feb 6, 2020
2 parents 5e01906 + f663118 commit 2201ef8
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 23 deletions.
18 changes: 17 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
Synapse 1.10.0rc2 (2020-02-06)
==============================

Bugfixes
--------

- Fix an issue with cross-signing where device signatures were not sent to remote servers. ([\#6844](https://github.com/matrix-org/synapse/issues/6844))
- Fix to the unknown remote device detection which was introduced in 1.10.rc1. ([\#6848](https://github.com/matrix-org/synapse/issues/6848))


Internal Changes
----------------

- Detect unexpected sender keys on remote encrypted events and resync device lists. ([\#6850](https://github.com/matrix-org/synapse/issues/6850))


Synapse 1.10.0rc1 (2020-01-31)
==============================

**WARNING**: As of this release Synapse validates `client_secret` parameters in the Client-Server API as per the spec. See [\#6766](https://github.com/matrix-org/synapse/issues/6766) for details.
**WARNING to client developers**: As of this release Synapse validates `client_secret` parameters in the Client-Server API as per the spec. See [\#6766](https://github.com/matrix-org/synapse/issues/6766) for details.


Features
Expand Down
2 changes: 1 addition & 1 deletion synapse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
except ImportError:
pass

__version__ = "1.10.0rc1"
__version__ = "1.10.0rc2"

if bool(os.environ.get("SYNAPSE_TEST_PATCH_LOG_CONTEXTS", False)):
# We import here so that we don't have to install a bunch of deps when
Expand Down
3 changes: 1 addition & 2 deletions synapse/api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,11 @@ class EventTypes(object):
Aliases = "m.room.aliases"
Redaction = "m.room.redaction"
ThirdPartyInvite = "m.room.third_party_invite"
Encryption = "m.room.encryption"
RelatedGroups = "m.room.related_groups"

RoomHistoryVisibility = "m.room.history_visibility"
CanonicalAlias = "m.room.canonical_alias"
Encryption = "m.room.encryption"
Encrypted = "m.room.encrypted"
RoomAvatar = "m.room.avatar"
RoomEncryption = "m.room.encryption"
GuestAccess = "m.room.guest_access"
Expand Down
8 changes: 7 additions & 1 deletion synapse/handlers/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,13 @@ def _handle_device_updates(self, user_id):
# happens if we've missed updates.
resync = yield self._need_to_do_resync(user_id, pending_updates)

logger.debug("Need to re-sync devices for %r? %r", user_id, resync)
if logger.isEnabledFor(logging.INFO):
logger.info(
"Received device list update for %s, requiring resync: %s. Devices: %s",
user_id,
resync,
", ".join(u[0] for u in pending_updates),
)

if resync:
yield self.user_device_resync(user_id)
Expand Down
74 changes: 60 additions & 14 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,29 +752,75 @@ async def _process_received_pdu(

# For encrypted messages we check that we know about the sending device,
# if we don't then we mark the device cache for that user as stale.
if event.type == EventTypes.Encryption:
if event.type == EventTypes.Encrypted:
device_id = event.content.get("device_id")
sender_key = event.content.get("sender_key")

cached_devices = await self.store.get_cached_devices_for_user(event.sender)

resync = False # Whether we should resync device lists.

device = None
if device_id is not None:
cached_devices = await self.store.get_cached_devices_for_user(
event.sender
)
if device_id not in cached_devices:
device = cached_devices.get(device_id)
if device is None:
logger.info(
"Received event from remote device not in our cache: %s %s",
event.sender,
device_id,
)
await self.store.mark_remote_user_device_cache_as_stale(
event.sender
resync = True

# We also check if the `sender_key` matches what we expect.
if sender_key is not None:
# Figure out what sender key we're expecting. If we know the
# device and recognize the algorithm then we can work out the
# exact key to expect. Otherwise check it matches any key we
# have for that device.
if device:
keys = device.get("keys", {}).get("keys", {})

if event.content.get("algorithm") == "m.megolm.v1.aes-sha2":
# For this algorithm we expect a curve25519 key.
key_name = "curve25519:%s" % (device_id,)
current_keys = [keys.get(key_name)]
else:
# We don't know understand the algorithm, so we just
# check it matches a key for the device.
current_keys = keys.values()
elif device_id:
# We don't have any keys for the device ID.
current_keys = []
else:
# The event didn't include a device ID, so we just look for
# keys across all devices.
current_keys = (
key
for device in cached_devices
for key in device.get("keys", {}).get("keys", {}).values()
)

# Immediately attempt a resync in the background
if self.config.worker_app:
return run_in_background(self._user_device_resync, event.sender)
else:
return run_in_background(
self._device_list_updater.user_device_resync, event.sender
)
# We now check that the sender key matches (one of) the expected
# keys.
if sender_key not in current_keys:
logger.info(
"Received event from remote device with unexpected sender key: %s %s: %s",
event.sender,
device_id or "<no device_id>",
sender_key,
)
resync = True

if resync:
await self.store.mark_remote_user_device_cache_as_stale(event.sender)

# Immediately attempt a resync in the background
if self.config.worker_app:
return run_in_background(self._user_device_resync, event.sender)
else:
return run_in_background(
self._device_list_updater.user_device_resync, event.sender
)

@log_function
async def backfill(self, dest, room_id, limit, extremities):
Expand Down
2 changes: 1 addition & 1 deletion synapse/handlers/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ def clone_existing_room(
(EventTypes.RoomHistoryVisibility, ""),
(EventTypes.GuestAccess, ""),
(EventTypes.RoomAvatar, ""),
(EventTypes.Encryption, ""),
(EventTypes.RoomEncryption, ""),
(EventTypes.ServerACL, ""),
(EventTypes.RelatedGroups, ""),
(EventTypes.PowerLevels, ""),
Expand Down
2 changes: 1 addition & 1 deletion synapse/handlers/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def _handle_deltas(self, deltas):
room_state["history_visibility"] = event_content.get(
"history_visibility"
)
elif typ == EventTypes.Encryption:
elif typ == EventTypes.RoomEncryption:
room_state["encryption"] = event_content.get("algorithm")
elif typ == EventTypes.Name:
room_state["name"] = event_content.get("name")
Expand Down
4 changes: 2 additions & 2 deletions synapse/storage/data_stores/main/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ def _fetch_current_state_stats(txn):
EventTypes.Create,
EventTypes.JoinRules,
EventTypes.RoomHistoryVisibility,
EventTypes.Encryption,
EventTypes.RoomEncryption,
EventTypes.Name,
EventTypes.Topic,
EventTypes.RoomAvatar,
Expand Down Expand Up @@ -816,7 +816,7 @@ def _fetch_current_state_stats(txn):
room_state["history_visibility"] = event.content.get(
"history_visibility"
)
elif event.type == EventTypes.Encryption:
elif event.type == EventTypes.RoomEncryption:
room_state["encryption"] = event.content.get("algorithm")
elif event.type == EventTypes.Name:
room_state["name"] = event.content.get("name")
Expand Down

0 comments on commit 2201ef8

Please sign in to comment.