Validate m.room.create events in send_join responses (#1505)
* Validate m.room.create events in send_join responses For sytest compliance, refs #1315 and #1317 Fixes #1317 * Linting
This commit is contained in:
parent
fe5d1400bf
commit
9096bfcee8
2 changed files with 59 additions and 1 deletions
|
@ -2,6 +2,7 @@ package internal
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
@ -174,8 +175,10 @@ func (r *FederationSenderInternalAPI) performJoinUsingServer(
|
|||
|
||||
// Work out if we support the room version that has been supplied in
|
||||
// the make_join response.
|
||||
// "If not provided, the room version is assumed to be either "1" or "2"."
|
||||
// https://matrix.org/docs/spec/server_server/unstable#get-matrix-federation-v1-make-join-roomid-userid
|
||||
if respMakeJoin.RoomVersion == "" {
|
||||
respMakeJoin.RoomVersion = gomatrixserverlib.RoomVersionV1
|
||||
respMakeJoin.RoomVersion = setDefaultRoomVersionFromJoinEvent(respMakeJoin.JoinEvent)
|
||||
}
|
||||
if _, err = respMakeJoin.RoomVersion.EventFormat(); err != nil {
|
||||
return fmt.Errorf("respMakeJoin.RoomVersion.EventFormat: %w", err)
|
||||
|
@ -205,6 +208,9 @@ func (r *FederationSenderInternalAPI) performJoinUsingServer(
|
|||
return fmt.Errorf("r.federation.SendJoin: %w", err)
|
||||
}
|
||||
r.statistics.ForServer(serverName).Success()
|
||||
if err := sanityCheckSendJoinResponse(respSendJoin); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Process the join response in a goroutine. The idea here is
|
||||
// that we'll try and wait for as long as possible for the work
|
||||
|
@ -424,3 +430,53 @@ func (r *FederationSenderInternalAPI) PerformBroadcastEDU(
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func sanityCheckSendJoinResponse(respSendJoin gomatrixserverlib.RespSendJoin) error {
|
||||
// sanity check we have a create event and it has a known room version
|
||||
for _, ev := range respSendJoin.AuthEvents {
|
||||
if ev.Type() == gomatrixserverlib.MRoomCreate && ev.StateKeyEquals("") {
|
||||
// make sure the room version is known
|
||||
content := ev.Content()
|
||||
verBody := struct {
|
||||
Version string `json:"room_version"`
|
||||
}{}
|
||||
err := json.Unmarshal(content, &verBody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if verBody.Version == "" {
|
||||
// https://matrix.org/docs/spec/client_server/r0.6.0#m-room-create
|
||||
// The version of the room. Defaults to "1" if the key does not exist.
|
||||
verBody.Version = "1"
|
||||
}
|
||||
knownVersions := gomatrixserverlib.RoomVersions()
|
||||
if _, ok := knownVersions[gomatrixserverlib.RoomVersion(verBody.Version)]; !ok {
|
||||
return fmt.Errorf("send_join m.room.create event has an unknown room version: %s", verBody.Version)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("send_join response is missing m.room.create event")
|
||||
}
|
||||
|
||||
func setDefaultRoomVersionFromJoinEvent(joinEvent gomatrixserverlib.EventBuilder) gomatrixserverlib.RoomVersion {
|
||||
// if auth events are not event references we know it must be v3+
|
||||
// we have to do these shenanigans to satisfy sytest, specifically for:
|
||||
// "Outbound federation rejects m.room.create events with an unknown room version"
|
||||
hasEventRefs := true
|
||||
authEvents, ok := joinEvent.AuthEvents.([]interface{})
|
||||
if ok {
|
||||
if len(authEvents) > 0 {
|
||||
_, ok = authEvents[0].(string)
|
||||
if ok {
|
||||
// event refs are objects, not strings, so we know we must be dealing with a v3+ room.
|
||||
hasEventRefs = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if hasEventRefs {
|
||||
return gomatrixserverlib.RoomVersionV1
|
||||
}
|
||||
return gomatrixserverlib.RoomVersionV4
|
||||
}
|
||||
|
|
|
@ -68,6 +68,8 @@ Request to logout with invalid an access token is rejected
|
|||
Request to logout without an access token is rejected
|
||||
Room creation reports m.room.create to myself
|
||||
Room creation reports m.room.member to myself
|
||||
Outbound federation rejects send_join responses with no m.room.create event
|
||||
Outbound federation rejects m.room.create events with an unknown room version
|
||||
Invited user can see room metadata
|
||||
# Blacklisted because these tests call /r0/events which we don't implement
|
||||
# New room members see their own join event
|
||||
|
|
Loading…
Reference in a new issue