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

Strip "join_authorised_via_users_server" from join events which do not need it. #10933

Merged
merged 5 commits into from
Sep 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/10933.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug introduced in Synapse v1.40.0 where changing a user's display name or avatar in a restricted room would cause an authentication error.
3 changes: 3 additions & 0 deletions synapse/api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ class EventContentFields:
# For "marker" events
MSC2716_MARKER_INSERTION = "org.matrix.msc2716.marker.insertion"

# The authorising user for joining a restricted room.
AUTHORISING_USER = "join_authorised_via_users_server"


class RoomTypes:
"""Understood values of the room_type field of m.room.create events."""
Expand Down
12 changes: 7 additions & 5 deletions synapse/event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ def validate_event_for_room_version(
room_version_obj.msc3083_join_rules
and event.type == EventTypes.Member
and event.membership == Membership.JOIN
and "join_authorised_via_users_server" in event.content
and EventContentFields.AUTHORISING_USER in event.content
)
if is_invite_via_allow_rule:
authoriser_domain = get_domain_from_id(
event.content["join_authorised_via_users_server"]
event.content[EventContentFields.AUTHORISING_USER]
)
if not event.signatures.get(authoriser_domain):
raise AuthError(403, "Event not signed by authorising server")
Expand Down Expand Up @@ -413,7 +413,9 @@ def _is_membership_change_allowed(
# Note that if the caller is in the room or invited, then they do
# not need to meet the allow rules.
if not caller_in_room and not caller_invited:
authorising_user = event.content.get("join_authorised_via_users_server")
authorising_user = event.content.get(
EventContentFields.AUTHORISING_USER
)

if authorising_user is None:
raise AuthError(403, "Join event is missing authorising user.")
Expand Down Expand Up @@ -868,10 +870,10 @@ def auth_types_for_event(
auth_types.add(key)

if room_version.msc3083_join_rules and membership == Membership.JOIN:
if "join_authorised_via_users_server" in event.content:
if EventContentFields.AUTHORISING_USER in event.content:
key = (
EventTypes.Member,
event.content["join_authorised_via_users_server"],
event.content[EventContentFields.AUTHORISING_USER],
)
auth_types.add(key)

Expand Down
2 changes: 1 addition & 1 deletion synapse/events/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def add_fields(*fields):
if event_type == EventTypes.Member:
add_fields("membership")
if room_version.msc3375_redaction_rules:
add_fields("join_authorised_via_users_server")
add_fields(EventContentFields.AUTHORISING_USER)
elif event_type == EventTypes.Create:
# MSC2176 rules state that create events cannot be redacted.
if room_version.msc2176_redaction_rules:
Expand Down
6 changes: 3 additions & 3 deletions synapse/federation/federation_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import logging
from collections import namedtuple

from synapse.api.constants import MAX_DEPTH, EventTypes, Membership
from synapse.api.constants import MAX_DEPTH, EventContentFields, EventTypes, Membership
from synapse.api.errors import Codes, SynapseError
from synapse.api.room_versions import EventFormatVersions, RoomVersion
from synapse.crypto.event_signing import check_event_content_hash
Expand Down Expand Up @@ -184,10 +184,10 @@ async def _check_sigs_on_pdu(
room_version.msc3083_join_rules
and pdu.type == EventTypes.Member
and pdu.membership == Membership.JOIN
and "join_authorised_via_users_server" in pdu.content
and EventContentFields.AUTHORISING_USER in pdu.content
):
authorising_server = get_domain_from_id(
pdu.content["join_authorised_via_users_server"]
pdu.content[EventContentFields.AUTHORISING_USER]
)
try:
await keyring.verify_event_for_server(
Expand Down
6 changes: 3 additions & 3 deletions synapse/federation/federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import attr
from prometheus_client import Counter

from synapse.api.constants import EventTypes, Membership
from synapse.api.constants import EventContentFields, EventTypes, Membership
from synapse.api.errors import (
CodeMessageException,
Codes,
Expand Down Expand Up @@ -875,9 +875,9 @@ async def _execute(pdu: EventBase) -> None:
# If the join is being authorised via allow rules, we need to send
# the /send_join back to the same server that was originally used
# with /make_join.
if "join_authorised_via_users_server" in pdu.content:
if EventContentFields.AUTHORISING_USER in pdu.content:
destinations = [
get_domain_from_id(pdu.content["join_authorised_via_users_server"])
get_domain_from_id(pdu.content[EventContentFields.AUTHORISING_USER])
]

return await self._try_destination_list(
Expand Down
6 changes: 3 additions & 3 deletions synapse/federation/federation_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from twisted.internet.abstract import isIPAddress
from twisted.python import failure

from synapse.api.constants import EduTypes, EventTypes, Membership
from synapse.api.constants import EduTypes, EventContentFields, EventTypes, Membership
from synapse.api.errors import (
AuthError,
Codes,
Expand Down Expand Up @@ -765,11 +765,11 @@ async def _on_send_membership_event(
if (
room_version.msc3083_join_rules
and event.membership == Membership.JOIN
and "join_authorised_via_users_server" in event.content
and EventContentFields.AUTHORISING_USER in event.content
):
# We can only authorise our own users.
authorising_server = get_domain_from_id(
event.content["join_authorised_via_users_server"]
event.content[EventContentFields.AUTHORISING_USER]
)
if authorising_server != self.server_name:
raise SynapseError(
Expand Down
9 changes: 7 additions & 2 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@
from twisted.internet import defer

from synapse import event_auth
from synapse.api.constants import EventTypes, Membership, RejectedReason
from synapse.api.constants import (
EventContentFields,
EventTypes,
Membership,
RejectedReason,
)
from synapse.api.errors import (
AuthError,
CodeMessageException,
Expand Down Expand Up @@ -716,7 +721,7 @@ async def on_make_join_request(

if include_auth_user_id:
event_content[
"join_authorised_via_users_server"
EventContentFields.AUTHORISING_USER
] = await self._event_auth_handler.get_user_which_could_invite(
room_id,
state_ids,
Expand Down
10 changes: 9 additions & 1 deletion synapse/handlers/room_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,14 @@ async def update_membership_locked(
errcode=Codes.BAD_JSON,
)

# The event content should *not* include the authorising user as
# it won't be properly signed. Strip it out since it might come
# back from a client updating a display name / avatar.
#
# This only applies to restricted rooms, but there should be no reason
# for a client to include it. Unconditionally remove it.
content.pop(EventContentFields.AUTHORISING_USER, None)

effective_membership_state = action
if action in ["kick", "unban"]:
effective_membership_state = "leave"
Expand Down Expand Up @@ -939,7 +947,7 @@ async def _should_perform_remote_join(
# be included in the event content in order to efficiently validate
# the event.
content[
"join_authorised_via_users_server"
EventContentFields.AUTHORISING_USER
] = await self.event_auth_handler.get_user_which_could_invite(
room_id,
current_state_ids,
Expand Down
7 changes: 4 additions & 3 deletions tests/events/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from synapse.api.constants import EventContentFields
from synapse.api.room_versions import RoomVersions
from synapse.events import make_event_from_dict
from synapse.events.utils import (
Expand Down Expand Up @@ -352,7 +353,7 @@ def test_member(self):
"event_id": "$test:domain",
"content": {
"membership": "join",
"join_authorised_via_users_server": "@user:domain",
EventContentFields.AUTHORISING_USER: "@user:domain",
"other_key": "stripped",
},
},
Expand All @@ -372,15 +373,15 @@ def test_member(self):
"type": "m.room.member",
"content": {
"membership": "join",
"join_authorised_via_users_server": "@user:domain",
EventContentFields.AUTHORISING_USER: "@user:domain",
"other_key": "stripped",
},
},
{
"type": "m.room.member",
"content": {
"membership": "join",
"join_authorised_via_users_server": "@user:domain",
EventContentFields.AUTHORISING_USER: "@user:domain",
},
"signatures": {},
"unsigned": {},
Expand Down
9 changes: 5 additions & 4 deletions tests/test_event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from typing import Optional

from synapse import event_auth
from synapse.api.constants import EventContentFields
from synapse.api.errors import AuthError
from synapse.api.room_versions import RoomVersions
from synapse.events import EventBase, make_event_from_dict
Expand Down Expand Up @@ -353,7 +354,7 @@ def test_join_rules_msc3083_restricted(self):
authorised_join_event = _join_event(
pleb,
additional_content={
"join_authorised_via_users_server": "@creator:example.com"
EventContentFields.AUTHORISING_USER: "@creator:example.com"
},
)
event_auth.check_auth_rules_for_event(
Expand All @@ -376,7 +377,7 @@ def test_join_rules_msc3083_restricted(self):
_join_event(
pleb,
additional_content={
"join_authorised_via_users_server": "@inviter:foo.test"
EventContentFields.AUTHORISING_USER: "@inviter:foo.test"
},
),
pl_auth_events,
Expand All @@ -401,7 +402,7 @@ def test_join_rules_msc3083_restricted(self):
_join_event(
pleb,
additional_content={
"join_authorised_via_users_server": "@other:example.com"
EventContentFields.AUTHORISING_USER: "@other:example.com"
},
),
auth_events,
Expand All @@ -417,7 +418,7 @@ def test_join_rules_msc3083_restricted(self):
"join",
sender=creator,
additional_content={
"join_authorised_via_users_server": "@inviter:foo.test"
EventContentFields.AUTHORISING_USER: "@inviter:foo.test"
},
),
auth_events,
Expand Down