mirror of
https://github.com/hoernschen/dendrite.git
synced 2024-12-27 07:28:27 +00:00
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
@ -174,8 +175,10 @@ func (r *FederationSenderInternalAPI) performJoinUsingServer(
|
||||||
|
|
||||||
// Work out if we support the room version that has been supplied in
|
// Work out if we support the room version that has been supplied in
|
||||||
// the make_join response.
|
// 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 == "" {
|
if respMakeJoin.RoomVersion == "" {
|
||||||
respMakeJoin.RoomVersion = gomatrixserverlib.RoomVersionV1
|
respMakeJoin.RoomVersion = setDefaultRoomVersionFromJoinEvent(respMakeJoin.JoinEvent)
|
||||||
}
|
}
|
||||||
if _, err = respMakeJoin.RoomVersion.EventFormat(); err != nil {
|
if _, err = respMakeJoin.RoomVersion.EventFormat(); err != nil {
|
||||||
return fmt.Errorf("respMakeJoin.RoomVersion.EventFormat: %w", err)
|
return fmt.Errorf("respMakeJoin.RoomVersion.EventFormat: %w", err)
|
||||||
|
@ -205,6 +208,9 @@ func (r *FederationSenderInternalAPI) performJoinUsingServer(
|
||||||
return fmt.Errorf("r.federation.SendJoin: %w", err)
|
return fmt.Errorf("r.federation.SendJoin: %w", err)
|
||||||
}
|
}
|
||||||
r.statistics.ForServer(serverName).Success()
|
r.statistics.ForServer(serverName).Success()
|
||||||
|
if err := sanityCheckSendJoinResponse(respSendJoin); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Process the join response in a goroutine. The idea here is
|
// 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
|
// that we'll try and wait for as long as possible for the work
|
||||||
|
@ -424,3 +430,53 @@ func (r *FederationSenderInternalAPI) PerformBroadcastEDU(
|
||||||
|
|
||||||
return nil
|
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
|
Request to logout without an access token is rejected
|
||||||
Room creation reports m.room.create to myself
|
Room creation reports m.room.create to myself
|
||||||
Room creation reports m.room.member 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
|
Invited user can see room metadata
|
||||||
# Blacklisted because these tests call /r0/events which we don't implement
|
# Blacklisted because these tests call /r0/events which we don't implement
|
||||||
# New room members see their own join event
|
# New room members see their own join event
|
||||||
|
|
Loading…
Reference in a new issue