mirror of
https://mau.dev/maunium/synapse.git
synced 2024-12-14 18:03:53 +01:00
Validation for events/rooms in fed requests
When we get a federation request which refers to an event id, make sure that said event is in the room the caller claims it is in. (patch supplied by @turt2live)
This commit is contained in:
parent
6284f579bf
commit
0a65450d04
3 changed files with 64 additions and 1 deletions
|
@ -425,6 +425,7 @@ class FederationServer(FederationBase):
|
||||||
ret = yield self.handler.on_query_auth(
|
ret = yield self.handler.on_query_auth(
|
||||||
origin,
|
origin,
|
||||||
event_id,
|
event_id,
|
||||||
|
room_id,
|
||||||
signed_auth,
|
signed_auth,
|
||||||
content.get("rejects", []),
|
content.get("rejects", []),
|
||||||
content.get("missing", []),
|
content.get("missing", []),
|
||||||
|
|
|
@ -1349,6 +1349,9 @@ class FederationHandler(BaseHandler):
|
||||||
def get_state_for_pdu(self, room_id, event_id):
|
def get_state_for_pdu(self, room_id, event_id):
|
||||||
"""Returns the state at the event. i.e. not including said event.
|
"""Returns the state at the event. i.e. not including said event.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
yield self._verify_events_in_room([event_id], room_id)
|
||||||
|
|
||||||
state_groups = yield self.store.get_state_groups(
|
state_groups = yield self.store.get_state_groups(
|
||||||
room_id, [event_id]
|
room_id, [event_id]
|
||||||
)
|
)
|
||||||
|
@ -1391,6 +1394,9 @@ class FederationHandler(BaseHandler):
|
||||||
def get_state_ids_for_pdu(self, room_id, event_id):
|
def get_state_ids_for_pdu(self, room_id, event_id):
|
||||||
"""Returns the state at the event. i.e. not including said event.
|
"""Returns the state at the event. i.e. not including said event.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
yield self._verify_events_in_room([event_id], room_id)
|
||||||
|
|
||||||
state_groups = yield self.store.get_state_groups_ids(
|
state_groups = yield self.store.get_state_groups_ids(
|
||||||
room_id, [event_id]
|
room_id, [event_id]
|
||||||
)
|
)
|
||||||
|
@ -1420,6 +1426,8 @@ class FederationHandler(BaseHandler):
|
||||||
if not in_room:
|
if not in_room:
|
||||||
raise AuthError(403, "Host not in room.")
|
raise AuthError(403, "Host not in room.")
|
||||||
|
|
||||||
|
yield self._verify_events_in_room(pdu_list, room_id)
|
||||||
|
|
||||||
events = yield self.store.get_backfill_events(
|
events = yield self.store.get_backfill_events(
|
||||||
room_id,
|
room_id,
|
||||||
pdu_list,
|
pdu_list,
|
||||||
|
@ -1706,8 +1714,17 @@ class FederationHandler(BaseHandler):
|
||||||
defer.returnValue(context)
|
defer.returnValue(context)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def on_query_auth(self, origin, event_id, remote_auth_chain, rejects,
|
def on_query_auth(self, origin, event_id, room_id, remote_auth_chain, rejects,
|
||||||
missing):
|
missing):
|
||||||
|
in_room = yield self.auth.check_host_in_room(
|
||||||
|
room_id,
|
||||||
|
origin
|
||||||
|
)
|
||||||
|
if not in_room:
|
||||||
|
raise AuthError(403, "Host not in room.")
|
||||||
|
|
||||||
|
yield self._verify_events_in_room([event_id], room_id)
|
||||||
|
|
||||||
# Just go through and process each event in `remote_auth_chain`. We
|
# Just go through and process each event in `remote_auth_chain`. We
|
||||||
# don't want to fall into the trap of `missing` being wrong.
|
# don't want to fall into the trap of `missing` being wrong.
|
||||||
for e in remote_auth_chain:
|
for e in remote_auth_chain:
|
||||||
|
@ -2368,3 +2385,19 @@ class FederationHandler(BaseHandler):
|
||||||
)
|
)
|
||||||
if "valid" not in response or not response["valid"]:
|
if "valid" not in response or not response["valid"]:
|
||||||
raise AuthError(403, "Third party certificate was invalid")
|
raise AuthError(403, "Third party certificate was invalid")
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def _verify_events_in_room(self, pdu_ids, room_id):
|
||||||
|
"""Checks whether the given PDU IDs are in the given room or not.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pdu_ids (list): list of PDU IDs
|
||||||
|
room_id (str): the room ID that the PDUs should be in
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AuthError: if one or more of the PDUs does not belong to the
|
||||||
|
given room.
|
||||||
|
"""
|
||||||
|
room_ids = yield self.store.get_room_ids_for_events(pdu_ids)
|
||||||
|
if len(room_ids) != 1 or room_ids[0] != room_id:
|
||||||
|
raise AuthError(403, "Events must belong to the given room")
|
||||||
|
|
|
@ -295,6 +295,35 @@ class EventFederationWorkerStore(EventsWorkerStore, SignatureWorkerStore,
|
||||||
get_forward_extremeties_for_room_txn
|
get_forward_extremeties_for_room_txn
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_room_ids_for_events(self, event_ids):
|
||||||
|
"""Get a list of room IDs for which the given events belong.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
event_ids (list): the events to look up the room of
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list, the room IDs for the events
|
||||||
|
"""
|
||||||
|
return self.runInteraction(
|
||||||
|
"get_room_ids_for_events",
|
||||||
|
self._get_room_ids_for_events, event_ids
|
||||||
|
)
|
||||||
|
|
||||||
|
def _get_room_ids_for_events(self, txn, event_ids):
|
||||||
|
logger.debug("_get_room_ids_for_events: %s", repr(event_ids))
|
||||||
|
|
||||||
|
base_sql = (
|
||||||
|
"SELECT DISTINCT room_id FROM events"
|
||||||
|
" WHERE event_id IN (%s)"
|
||||||
|
)
|
||||||
|
|
||||||
|
txn.execute(
|
||||||
|
base_sql % (",".join(["?"] * len(event_ids)),),
|
||||||
|
event_ids
|
||||||
|
)
|
||||||
|
|
||||||
|
return [r[0] for r in txn]
|
||||||
|
|
||||||
def get_backfill_events(self, room_id, event_list, limit):
|
def get_backfill_events(self, room_id, event_list, limit):
|
||||||
"""Get a list of Events for a given topic that occurred before (and
|
"""Get a list of Events for a given topic that occurred before (and
|
||||||
including) the events in event_list. Return a list of max size `limit`
|
including) the events in event_list. Return a list of max size `limit`
|
||||||
|
|
Loading…
Reference in a new issue