From 9ddd62925c5c06209923cb86829161ba9e56966b Mon Sep 17 00:00:00 2001 From: Till Faelligen <2353100+S7evinK@users.noreply.github.com> Date: Wed, 5 Jul 2023 10:57:41 +0200 Subject: [PATCH] Use a MembershipQuerier to get the current membership --- federationapi/api/api.go | 1 + federationapi/internal/api.go | 5 +++++ federationapi/internal/perform.go | 9 ++++---- internal/transactionrequest.go | 22 +------------------ roomserver/api/api.go | 1 + roomserver/internal/input/input_events.go | 2 +- roomserver/internal/input/input_missing.go | 6 ++--- roomserver/internal/perform/perform_admin.go | 4 ++-- .../internal/perform/perform_backfill.go | 6 +++++ roomserver/internal/query/query.go | 11 ++++++++++ 10 files changed, 36 insertions(+), 31 deletions(-) diff --git a/federationapi/api/api.go b/federationapi/api/api.go index 5b49e509e..d07ed541c 100644 --- a/federationapi/api/api.go +++ b/federationapi/api/api.go @@ -73,6 +73,7 @@ type RoomserverFederationAPI interface { GetEventAuth(ctx context.Context, origin, s spec.ServerName, roomVersion gomatrixserverlib.RoomVersion, roomID, eventID string) (res fclient.RespEventAuth, err error) GetEvent(ctx context.Context, origin, s spec.ServerName, eventID string) (res gomatrixserverlib.Transaction, err error) LookupMissingEvents(ctx context.Context, origin, s spec.ServerName, roomID string, missing fclient.MissingEvents, roomVersion gomatrixserverlib.RoomVersion) (res fclient.RespMissingEvents, err error) + CurrentMembership(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (string, error) } type P2PFederationAPI interface { diff --git a/federationapi/internal/api.go b/federationapi/internal/api.go index aa501f63c..da3efd5b2 100644 --- a/federationapi/internal/api.go +++ b/federationapi/internal/api.go @@ -1,6 +1,7 @@ package internal import ( + "context" "crypto/ed25519" "encoding/base64" "fmt" @@ -182,3 +183,7 @@ func (a *FederationInternalAPI) doRequestIfNotBlacklisted( } return request() } + +func (a *FederationInternalAPI) CurrentMembership(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (string, error) { + return a.rsAPI.CurrentMembership(ctx, roomID, senderID) +} diff --git a/federationapi/internal/perform.go b/federationapi/internal/perform.go index 515b3377d..ac5c1dc44 100644 --- a/federationapi/internal/perform.go +++ b/federationapi/internal/perform.go @@ -167,7 +167,7 @@ func (r *FederationInternalAPI) performJoinUsingServer( KeyRing: r.keyRing, EventProvider: federatedEventProvider(ctx, r.federation, r.keyRing, user.Domain(), serverName, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { return r.rsAPI.QueryUserIDForSender(ctx, roomID, senderID) - }), + }, r.rsAPI), UserIDQuerier: func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { return r.rsAPI.QueryUserIDForSender(ctx, roomID, senderID) }, @@ -190,6 +190,7 @@ func (r *FederationInternalAPI) performJoinUsingServer( } return r.rsAPI.StoreUserRoomPublicKey(ctx, senderID, *storeUserID, roomID) }, + MembershipQuerier: r.rsAPI, } response, joinErr := gomatrixserverlib.PerformJoin(ctx, r, joinInput) @@ -387,7 +388,7 @@ func (r *FederationInternalAPI) performOutboundPeekUsingServer( return r.rsAPI.QueryUserIDForSender(ctx, roomID, senderID) } authEvents, stateEvents, err := gomatrixserverlib.CheckStateResponse( - ctx, &respPeek, respPeek.RoomVersion, r.keyRing, federatedEventProvider(ctx, r.federation, r.keyRing, r.cfg.Matrix.ServerName, serverName, userIDProvider), userIDProvider, + ctx, &respPeek, respPeek.RoomVersion, r.keyRing, federatedEventProvider(ctx, r.federation, r.keyRing, r.cfg.Matrix.ServerName, serverName, userIDProvider, r.rsAPI), userIDProvider, r.rsAPI, ) if err != nil { return fmt.Errorf("error checking state returned from peeking: %w", err) @@ -676,7 +677,7 @@ func checkEventsContainCreateEvent(events []gomatrixserverlib.PDU) error { func federatedEventProvider( ctx context.Context, federation fclient.FederationClient, keyRing gomatrixserverlib.JSONVerifier, origin, server spec.ServerName, - userIDForSender spec.UserIDForSender, + userIDForSender spec.UserIDForSender, rsAPI gomatrixserverlib.MembershipQuerier, ) gomatrixserverlib.EventProvider { // A list of events that we have retried, if they were not included in // the auth events supplied in the send_join. @@ -726,7 +727,7 @@ func federatedEventProvider( } // Check the signatures of the event. - if err := gomatrixserverlib.VerifyEventSignatures(ctx, ev, keyRing, userIDForSender); err != nil { + if err := gomatrixserverlib.VerifyEventSignatures(ctx, ev, keyRing, userIDForSender, rsAPI); err != nil { return nil, fmt.Errorf("missingAuth VerifyEventSignatures: %w", err) } diff --git a/internal/transactionrequest.go b/internal/transactionrequest.go index e7b2d98f2..121c72138 100644 --- a/internal/transactionrequest.go +++ b/internal/transactionrequest.go @@ -168,24 +168,9 @@ func (t *TxnReq) ProcessTransaction(ctx context.Context) (*fclient.RespSend, *ut 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) { return t.rsAPI.QueryUserIDForSender(ctx, roomID, senderID) - }); err != nil { + }, t.rsAPI); err != nil { util.GetLogger(ctx).WithError(err).Debugf("Transaction: Couldn't validate signature of event %q", event.EventID()) results[event.EventID()] = fclient.PDUResult{ Error: err.Error(), @@ -193,11 +178,6 @@ func (t *TxnReq) ProcessTransaction(ctx context.Context) (*fclient.RespSend, *ut 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 // If the event fail auth checks, gmsl.NotAllowed error will be returned which we be silently // discarded by the caller of this function diff --git a/roomserver/api/api.go b/roomserver/api/api.go index ab56529c5..8534018b5 100644 --- a/roomserver/api/api.go +++ b/roomserver/api/api.go @@ -236,6 +236,7 @@ type FederationRoomserverAPI interface { QueryBulkStateContentAPI QuerySenderIDAPI UserRoomPrivateKeyCreator + CurrentMembership(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (string, error) AssignRoomNID(ctx context.Context, roomID spec.RoomID, roomVersion gomatrixserverlib.RoomVersion) (roomNID types.RoomNID, err error) SigningIdentityFor(ctx context.Context, roomID spec.RoomID, senderID spec.UserID) (fclient.SigningIdentity, error) // QueryServerBannedFromRoom returns whether a server is banned from a room by server ACLs. diff --git a/roomserver/internal/input/input_events.go b/roomserver/internal/input/input_events.go index 0d79a54db..d15ad4508 100644 --- a/roomserver/internal/input/input_events.go +++ b/roomserver/internal/input/input_events.go @@ -780,7 +780,7 @@ nextAuthEvent: // if a critical event is missing anyway. if err := gomatrixserverlib.VerifyEventSignatures(ctx, authEvent, r.FSAPI.KeyRing(), func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { return r.Queryer.QueryUserIDForSender(ctx, roomID, senderID) - }); err != nil { + }, r.Queryer); err != nil { continue nextAuthEvent } diff --git a/roomserver/internal/input/input_missing.go b/roomserver/internal/input/input_missing.go index 7ee84e4c0..0a60027d3 100644 --- a/roomserver/internal/input/input_missing.go +++ b/roomserver/internal/input/input_missing.go @@ -571,7 +571,7 @@ func (t *missingStateReq) getMissingEvents(ctx context.Context, e gomatrixserver for _, ev := range missingResp.Events.UntrustedEvents(roomVersion) { if err = gomatrixserverlib.VerifyEventSignatures(ctx, ev, t.keys, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { return t.inputer.Queryer.QueryUserIDForSender(ctx, roomID, senderID) - }); err != nil { + }, t.inputer.Queryer); err != nil { continue } missingEvents = append(missingEvents, t.cacheAndReturn(ev)) @@ -662,7 +662,7 @@ func (t *missingStateReq) lookupMissingStateViaState( AuthEvents: state.GetAuthEvents(), }, roomVersion, t.keys, nil, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { return t.inputer.Queryer.QueryUserIDForSender(ctx, roomID, senderID) - }) + }, t.inputer.Queryer) if err != nil { return nil, err } @@ -899,7 +899,7 @@ func (t *missingStateReq) lookupEvent(ctx context.Context, roomVersion gomatrixs } if err := gomatrixserverlib.VerifyEventSignatures(ctx, event, t.keys, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { return t.inputer.Queryer.QueryUserIDForSender(ctx, roomID, senderID) - }); err != nil { + }, t.inputer.Queryer); err != nil { t.log.WithError(err).Warnf("Couldn't validate signature of event %q from /event", event.EventID()) return nil, verifySigError{event.EventID(), err} } diff --git a/roomserver/internal/perform/perform_admin.go b/roomserver/internal/perform/perform_admin.go index 12b557f51..212760da3 100644 --- a/roomserver/internal/perform/perform_admin.go +++ b/roomserver/internal/perform/perform_admin.go @@ -270,7 +270,7 @@ func (r *Admin) PerformAdminDownloadState( for _, authEvent := range state.GetAuthEvents().UntrustedEvents(roomInfo.RoomVersion) { if err = gomatrixserverlib.VerifyEventSignatures(ctx, authEvent, r.Inputer.KeyRing, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { return r.Queryer.QueryUserIDForSender(ctx, roomID, senderID) - }); err != nil { + }, r.Queryer); err != nil { continue } authEventMap[authEvent.EventID()] = authEvent @@ -278,7 +278,7 @@ func (r *Admin) PerformAdminDownloadState( for _, stateEvent := range state.GetStateEvents().UntrustedEvents(roomInfo.RoomVersion) { if err = gomatrixserverlib.VerifyEventSignatures(ctx, stateEvent, r.Inputer.KeyRing, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { return r.Queryer.QueryUserIDForSender(ctx, roomID, senderID) - }); err != nil { + }, r.Queryer); err != nil { continue } stateEventMap[stateEvent.EventID()] = stateEvent diff --git a/roomserver/internal/perform/perform_backfill.go b/roomserver/internal/perform/perform_backfill.go index ef56e0cee..2f146e630 100644 --- a/roomserver/internal/perform/perform_backfill.go +++ b/roomserver/internal/perform/perform_backfill.go @@ -266,6 +266,7 @@ type backfillRequester struct { eventIDMap map[string]gomatrixserverlib.PDU historyVisiblity gomatrixserverlib.HistoryVisibility roomVersion gomatrixserverlib.RoomVersion + membershipQuerier gomatrixserverlib.MembershipQuerier } func newBackfillRequester( @@ -292,9 +293,14 @@ func newBackfillRequester( preferServer: preferServer, historyVisiblity: gomatrixserverlib.HistoryVisibilityShared, roomVersion: roomVersion, + membershipQuerier: fsAPI, } } +func (b *backfillRequester) CurrentMembership(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (string, error) { + return b.fsAPI.CurrentMembership(ctx, roomID, senderID) +} + func (b *backfillRequester) StateIDsBeforeEvent(ctx context.Context, targetEvent gomatrixserverlib.PDU) ([]string, error) { b.eventIDMap[targetEvent.EventID()] = targetEvent if ids, ok := b.eventIDToBeforeStateIDs[targetEvent.EventID()]; ok { diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go index 626d3c13e..404e5148d 100644 --- a/roomserver/internal/query/query.go +++ b/roomserver/internal/query/query.go @@ -1036,3 +1036,14 @@ func (r *Queryer) QueryUserIDForSender(ctx context.Context, roomID spec.RoomID, return nil, nil } + +func (r *Queryer) CurrentMembership(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (string, error) { + res := api.QueryMembershipForUserResponse{} + err := r.QueryMembershipForSenderID(ctx, roomID, senderID, &res) + + membership := "" + if err == nil { + membership = res.Membership + } + return membership, err +}