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

Commit

Permalink
Do not perform a local join if the local server is not authorized.
Browse files Browse the repository at this point in the history
  • Loading branch information
clokep committed Jul 1, 2021
1 parent 1f59459 commit 15074d2
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 9 deletions.
30 changes: 22 additions & 8 deletions synapse/event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,14 +373,9 @@ def _is_membership_change_allowed(
# not need to meet the allow rules.
if do_sig_check and not caller_in_room and not caller_invited:
# Find the servers of any users who could issue invites.
authorised_users = get_users_which_can_issue_invite(auth_events)
# Attempt to pull out the domain from each authorised user.
authorised_servers = set()
for user in authorised_users:
try:
authorised_servers.add(UserID.from_string(user).domain)
except SynapseError:
pass
authorised_servers = get_servers_from_users(
get_users_which_can_issue_invite(auth_events)
)

# Ensure one of the signatures is from one of the authorised servers.
# Note that it was previously checked that the signatures are
Expand Down Expand Up @@ -717,6 +712,25 @@ def get_users_which_can_issue_invite(auth_events: StateMap[EventBase]) -> List[s
return result


def get_servers_from_users(users: List[str]) -> Set[str]:
"""
Resolve a list of users into their servers.
Args:
users: A list of users.
Returns:
A set of servers.
"""
servers = set()
for user in users:
try:
servers.add(UserID.from_string(user).domain)
except SynapseError:
pass
return servers


def _get_named_level(auth_events: StateMap[EventBase], name: str, default: int) -> int:
power_level_event = _get_power_level_event(auth_events)

Expand Down
32 changes: 31 additions & 1 deletion synapse/handlers/room_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
SynapseError,
)
from synapse.api.ratelimiting import Ratelimiter
from synapse.event_auth import get_servers_from_users, get_users_which_can_issue_invite
from synapse.events import EventBase
from synapse.events.snapshot import EventContext
from synapse.types import (
Expand Down Expand Up @@ -701,7 +702,36 @@ async def update_membership_locked(
# so don't really fit into the general auth process.
raise AuthError(403, "Guest access not allowed")

if not is_host_in_room:
# Check if a remote join should be performed.
remote_join = not is_host_in_room
if not remote_join:
# If the host is in the room, but not one of the authorised hosts
# for restricted join rules, a remote join must be used.
room_version = await self.store.get_room_version(room_id)
current_state_ids = await self.store.get_current_state_ids(room_id)

# Otherwise, check if they should be allowed access via membership in a space.
if await self.event_auth_handler.has_restricted_join_rules(
current_state_ids, room_version
):
current_state_map = await self.store.get_events(
current_state_ids.values()
)
current_state = {
state_key: current_state_map[event_id]
for state_key, event_id in current_state_ids.items()
}
allowed_servers = get_servers_from_users(
get_users_which_can_issue_invite(current_state)
)

# If the local server is not one of allowed servers, use
# another server to join (and override the list of servers
# with those that can issue the join).
remote_room_hosts = list(allowed_servers)
remote_join = self.hs.hostname not in allowed_servers

if remote_join:
if ratelimit:
time_now_s = self.clock.time()
(
Expand Down

0 comments on commit 15074d2

Please sign in to comment.