Allow invites via 3pid to bypass sender sig check
When a server sends a third party invite another server may be the one that the inviting user registers with. In this case it is that remote server that will issue an actual invitation, and wants to do it "in the name of" the original invitee. However, the new proper invite will not be signed by the original server, and thus other servers would reject the invite if it was seen as coming from the original user. To fix this, a special case has been added to the auth rules whereby another server can send an invite "in the name of" another server's user, so long as that user had previously issued a third party invite that is now being accepted.
This commit is contained in:
parent
bbc0d9617f
commit
1168cbd54d
|
@ -72,7 +72,7 @@ class Auth(object):
|
||||||
auth_events = {
|
auth_events = {
|
||||||
(e.type, e.state_key): e for e in auth_events.values()
|
(e.type, e.state_key): e for e in auth_events.values()
|
||||||
}
|
}
|
||||||
self.check(event, auth_events=auth_events, do_sig_check=False)
|
self.check(event, auth_events=auth_events, do_sig_check=do_sig_check)
|
||||||
|
|
||||||
def check(self, event, auth_events, do_sig_check=True):
|
def check(self, event, auth_events, do_sig_check=True):
|
||||||
""" Checks if this event is correctly authed.
|
""" Checks if this event is correctly authed.
|
||||||
|
@ -92,9 +92,21 @@ class Auth(object):
|
||||||
raise AuthError(500, "Event has no room_id: %s" % event)
|
raise AuthError(500, "Event has no room_id: %s" % event)
|
||||||
|
|
||||||
sender_domain = get_domain_from_id(event.sender)
|
sender_domain = get_domain_from_id(event.sender)
|
||||||
|
event_id_domain = get_domain_from_id(event.event_id)
|
||||||
|
|
||||||
|
is_invite_via_3pid = (
|
||||||
|
event.type == EventTypes.Member
|
||||||
|
and event.membership == Membership.INVITE
|
||||||
|
and "third_party_invite" in event.content
|
||||||
|
)
|
||||||
|
|
||||||
# Check the sender's domain has signed the event
|
# Check the sender's domain has signed the event
|
||||||
if do_sig_check and not event.signatures.get(sender_domain):
|
if do_sig_check and not event.signatures.get(sender_domain):
|
||||||
|
if not is_invite_via_3pid:
|
||||||
|
raise AuthError(403, "Event not signed by sender's server")
|
||||||
|
|
||||||
|
# Check the event_id's domain has signed the event
|
||||||
|
if do_sig_check and not event.signatures.get(event_id_domain):
|
||||||
raise AuthError(403, "Event not signed by sending server")
|
raise AuthError(403, "Event not signed by sending server")
|
||||||
|
|
||||||
if auth_events is None:
|
if auth_events is None:
|
||||||
|
@ -491,6 +503,9 @@ class Auth(object):
|
||||||
if not invite_event:
|
if not invite_event:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if invite_event.sender != event.sender:
|
||||||
|
return False
|
||||||
|
|
||||||
if event.user_id != invite_event.user_id:
|
if event.user_id != invite_event.user_id:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -1922,15 +1922,15 @@ class FederationHandler(BaseHandler):
|
||||||
original_invite = yield self.store.get_event(
|
original_invite = yield self.store.get_event(
|
||||||
original_invite_id, allow_none=True
|
original_invite_id, allow_none=True
|
||||||
)
|
)
|
||||||
if not original_invite:
|
if original_invite:
|
||||||
|
display_name = original_invite.content["display_name"]
|
||||||
|
event_dict["content"]["third_party_invite"]["display_name"] = display_name
|
||||||
|
else:
|
||||||
logger.info(
|
logger.info(
|
||||||
"Could not find invite event for third_party_invite - "
|
"Could not find invite event for third_party_invite: %r",
|
||||||
"discarding: %s" % (event_dict,)
|
event_dict
|
||||||
)
|
)
|
||||||
return
|
|
||||||
|
|
||||||
display_name = original_invite.content["display_name"]
|
|
||||||
event_dict["content"]["third_party_invite"]["display_name"] = display_name
|
|
||||||
builder = self.event_builder_factory.new(event_dict)
|
builder = self.event_builder_factory.new(event_dict)
|
||||||
EventValidator().validate_new(builder)
|
EventValidator().validate_new(builder)
|
||||||
message_handler = self.hs.get_handlers().message_handler
|
message_handler = self.hs.get_handlers().message_handler
|
||||||
|
|
Loading…
Reference in New Issue