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:
Richard van der Hoff 2018-08-02 11:53:52 +01:00
parent 6284f579bf
commit 0a65450d04
3 changed files with 64 additions and 1 deletions

View file

@ -1349,6 +1349,9 @@ class FederationHandler(BaseHandler):
def get_state_for_pdu(self, room_id, event_id):
"""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(
room_id, [event_id]
)
@ -1391,6 +1394,9 @@ class FederationHandler(BaseHandler):
def get_state_ids_for_pdu(self, room_id, event_id):
"""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(
room_id, [event_id]
)
@ -1420,6 +1426,8 @@ class FederationHandler(BaseHandler):
if 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(
room_id,
pdu_list,
@ -1706,8 +1714,17 @@ class FederationHandler(BaseHandler):
defer.returnValue(context)
@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):
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
# don't want to fall into the trap of `missing` being wrong.
for e in remote_auth_chain:
@ -2368,3 +2385,19 @@ class FederationHandler(BaseHandler):
)
if "valid" not in response or not response["valid"]:
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")