Verify the mxid_mapping only if it is an actual join event

This commit is contained in:
Till Faelligen 2023-07-03 08:54:45 +02:00
parent dcd28e3614
commit 4bf57a2519
No known key found for this signature in database
GPG key ID: ACCDC9606D472758

View file

@ -167,6 +167,22 @@ func (t *TxnReq) ProcessTransaction(ctx context.Context) (*fclient.RespSend, *ut
} }
continue continue
} }
// If the user is already joined and we receive a new "join" event, we're adding the previous
// content to unsigned, this way VerifyEventSignatures skips the mxid_mapping check
// FIXME: this is not great..
origEvent := event
unsignedUpdated := false
if event.Version() == gomatrixserverlib.RoomVersionPseudoIDs && event.Type() == spec.MRoomMember && event.StateKey() != nil {
unsignedUpdated, err = t.updateUnsignedIfNeeded(ctx, event)
if err != nil {
results[event.EventID()] = fclient.PDUResult{
Error: err.Error(),
}
continue
}
}
if err = gomatrixserverlib.VerifyEventSignatures(ctx, event, t.keys, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { if err = gomatrixserverlib.VerifyEventSignatures(ctx, event, t.keys, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
return t.rsAPI.QueryUserIDForSender(ctx, roomID, senderID) return t.rsAPI.QueryUserIDForSender(ctx, roomID, senderID)
}); err != nil { }); err != nil {
@ -177,6 +193,11 @@ func (t *TxnReq) ProcessTransaction(ctx context.Context) (*fclient.RespSend, *ut
continue continue
} }
// switch the event again, so we don't store a wrong value in the DB
if unsignedUpdated {
event = origEvent
}
// pass the event to the roomserver which will do auth checks // pass the event to the roomserver which will do auth checks
// If the event fail auth checks, gmsl.NotAllowed error will be returned which we be silently // If the event fail auth checks, gmsl.NotAllowed error will be returned which we be silently
// discarded by the caller of this function // discarded by the caller of this function
@ -208,6 +229,47 @@ func (t *TxnReq) ProcessTransaction(ctx context.Context) (*fclient.RespSend, *ut
return &fclient.RespSend{PDUs: results}, nil return &fclient.RespSend{PDUs: results}, nil
} }
// updateUnsignedIfNeeded sets unsigned.prev_content to the previous membership event. This is
// to avoid checking the mxid_mapping on join -> join (e.g. displayname changes) events, which
// wouldn't be present.
func (t *TxnReq) updateUnsignedIfNeeded(ctx context.Context, event gomatrixserverlib.PDU) (updated bool, err error) {
var membership string
membership, err = event.Membership()
if err != nil {
return false, err
}
var validRoomID *spec.RoomID
validRoomID, err = spec.NewRoomID(event.RoomID())
if err != nil {
return false, err
}
// get the current membership event
var currentStateEv gomatrixserverlib.PDU
currentStateEv, err = t.rsAPI.CurrentStateEvent(ctx, *validRoomID, event.Type(), string(event.SenderID()))
if err != nil {
return false, err
}
if currentStateEv != nil {
var currentMembership string
currentMembership, err = currentStateEv.Membership()
if err != nil {
return false, err
}
// if the currentMembership is join and the new membership as well (e.g. displayname change),
// update unsigned so VerifyEventSignatures does not try to validate the mxid_mapping
if currentMembership == spec.Join && currentMembership == membership {
err = event.SetUnsignedField("prev_content", currentStateEv.Content())
if err != nil {
return false, err
}
return true, nil
}
}
return false, nil
}
// nolint:gocyclo // nolint:gocyclo
func (t *TxnReq) processEDUs(ctx context.Context) { func (t *TxnReq) processEDUs(ctx context.Context) {
for _, e := range t.EDUs { for _, e := range t.EDUs {