From 50615c76090b670e651d03a3e1590945dc6d39a5 Mon Sep 17 00:00:00 2001 From: Till Faelligen <2353100+S7evinK@users.noreply.github.com> Date: Wed, 14 Jun 2023 09:39:32 +0200 Subject: [PATCH] Sign MXIDMapping for join events --- go.mod | 2 +- go.sum | 4 +- roomserver/api/query.go | 2 + .../internal/perform/perform_create_room.go | 4 +- roomserver/internal/perform/perform_join.go | 48 ++++++++++++++----- roomserver/internal/query/query.go | 3 ++ roomserver/storage/shared/storage.go | 1 + 7 files changed, 46 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 048b0137c..932c16e66 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 - github.com/matrix-org/gomatrixserverlib v0.0.0-20230613155116-96519f6cf88a + github.com/matrix-org/gomatrixserverlib v0.0.0-20230614073341-8d0345fcba4e github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 github.com/mattn/go-sqlite3 v1.14.16 diff --git a/go.sum b/go.sum index daa3a98a5..ce790551a 100644 --- a/go.sum +++ b/go.sum @@ -323,8 +323,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 h1:s7fexw github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo= github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U= github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s= -github.com/matrix-org/gomatrixserverlib v0.0.0-20230613155116-96519f6cf88a h1:wC3e4IAsjhTnHnxfz4LoxO5Q03YCL7TlMa+EKLQqjOs= -github.com/matrix-org/gomatrixserverlib v0.0.0-20230613155116-96519f6cf88a/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU= +github.com/matrix-org/gomatrixserverlib v0.0.0-20230614073341-8d0345fcba4e h1:ZCPgtte0nLiqzS9x7Et4jVAnOGLEszijsH0Xi9h/CJA= +github.com/matrix-org/gomatrixserverlib v0.0.0-20230614073341-8d0345fcba4e/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU= github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a h1:awrPDf9LEFySxTLKYBMCiObelNx/cBuv/wzllvCCH3A= github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a/go.mod h1:HchJX9oKMXaT2xYFs0Ha/6Zs06mxLU8k6F1ODnrGkeQ= github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y= diff --git a/roomserver/api/query.go b/roomserver/api/query.go index 684a5b0e3..b6140afd5 100644 --- a/roomserver/api/query.go +++ b/roomserver/api/query.go @@ -174,6 +174,8 @@ type QueryServerJoinedToRoomResponse struct { RoomExists bool `json:"room_exists"` // True if we still believe that the server is participating in the room IsInRoom bool `json:"is_in_room"` + // The roomversion if joined to room + RoomVersion gomatrixserverlib.RoomVersion } // QueryServerAllowedToSeeEventRequest is a request to QueryServerAllowedToSeeEvent diff --git a/roomserver/internal/perform/perform_create_room.go b/roomserver/internal/perform/perform_create_room.go index d051140bb..02ea6edd5 100644 --- a/roomserver/internal/perform/perform_create_room.go +++ b/roomserver/internal/perform/perform_create_room.go @@ -17,11 +17,9 @@ package perform import ( "context" "crypto/ed25519" - "encoding/base64" "encoding/json" "fmt" "net/http" - "strings" "github.com/getsentry/sentry-go" "github.com/matrix-org/dendrite/internal/eventutil" @@ -174,7 +172,7 @@ func (c *Creator) PerformCreateRoom(ctx context.Context, userID spec.UserID, roo } mapping := &gomatrixserverlib.MXIDMapping{ - UserRoomKey: strings.ToLower(base64.StdEncoding.WithPadding(base64.NoPadding).EncodeToString(pseudoIDKey.Public().(ed25519.PublicKey))), + UserRoomKey: spec.UserRoomKey(pseudoIDKey), UserID: userID.String(), } diff --git a/roomserver/internal/perform/perform_join.go b/roomserver/internal/perform/perform_join.go index 74ed87c74..b99cc56e8 100644 --- a/roomserver/internal/perform/perform_join.go +++ b/roomserver/internal/perform/perform_join.go @@ -16,6 +16,7 @@ package perform import ( "context" + "crypto/ed25519" "database/sql" "errors" "fmt" @@ -24,7 +25,9 @@ import ( "github.com/getsentry/sentry-go" "github.com/matrix-org/gomatrixserverlib" + "github.com/matrix-org/gomatrixserverlib/fclient" "github.com/matrix-org/gomatrixserverlib/spec" + "github.com/matrix-org/util" "github.com/sirupsen/logrus" "github.com/tidwall/gjson" @@ -208,9 +211,6 @@ func (r *Joiner) performJoinRoomByID( } else if authorisedVia != "" { req.Content["join_authorised_via_users_server"] = authorisedVia } - if err = proto.SetContent(req.Content); err != nil { - return "", "", fmt.Errorf("eb.SetContent: %w", err) - } // Force a federated join if we aren't in the room and we've been // given some server names to try joining by. @@ -289,19 +289,43 @@ func (r *Joiner) performJoinRoomByID( if err != nil { return "", "", fmt.Errorf("error joining local room: %q", err) } + + // at this point we know we have an existing room + if inRoomRes.RoomVersion == gomatrixserverlib.RoomVersionPseudoIDs { + var pseudoIDKey ed25519.PrivateKey + pseudoIDKey, err = r.RSAPI.GetOrCreateUserRoomPrivateKey(ctx, *userID, *roomID) + if err != nil { + util.GetLogger(ctx).WithError(err).Error("GetOrCreateUserRoomPrivateKey failed") + return "", "", err + } + + mapping := &gomatrixserverlib.MXIDMapping{ + UserRoomKey: spec.UserRoomKey(pseudoIDKey), + UserID: userID.String(), + } + + // Sign the mapping with the server identity + if err = mapping.Sign(identity.ServerName, identity.KeyID, identity.PrivateKey); err != nil { + return "", "", err + } + req.Content["mxid_mapping"] = mapping + + // sign the event with the pseudo ID key + identity = &fclient.SigningIdentity{ + ServerName: userID.Domain(), + KeyID: "self", + PrivateKey: pseudoIDKey, + } + } + + if err = proto.SetContent(req.Content); err != nil { + return "", "", fmt.Errorf("eb.SetContent: %w", err) + } + event, err := eventutil.QueryAndBuildEvent(ctx, &proto, identity, time.Now(), r.RSAPI, &buildRes) switch err.(type) { case nil: - // create user room key if needed - if buildRes.RoomVersion == gomatrixserverlib.RoomVersionPseudoIDs { - _, err = r.RSAPI.GetOrCreateUserRoomPrivateKey(ctx, *userID, *roomID) - if err != nil { - logrus.WithError(err).Error("GetOrCreateUserRoomPrivateKey failed") - return "", "", fmt.Errorf("failed to get user room private key: %w", err) - } - } - // The room join is local. Send the new join event into the // roomserver. First of all check that the user isn't already // a member of the room. This is best-effort (as in we won't diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go index caea6b526..e7ad214b9 100644 --- a/roomserver/internal/query/query.go +++ b/roomserver/internal/query/query.go @@ -477,6 +477,9 @@ func (r *Queryer) QueryServerJoinedToRoom( if err != nil { return fmt.Errorf("r.DB.RoomInfo: %w", err) } + if info != nil { + response.RoomVersion = info.RoomVersion + } if info == nil || info.IsStub() { return nil } diff --git a/roomserver/storage/shared/storage.go b/roomserver/storage/shared/storage.go index bda51da81..492cd1ab6 100644 --- a/roomserver/storage/shared/storage.go +++ b/roomserver/storage/shared/storage.go @@ -1692,6 +1692,7 @@ func (d *Database) InsertUserRoomPublicKey(ctx context.Context, userID spec.User // SelectUserRoomPrivateKey queries the users room private key. // If no key exists, returns no key and no error. Otherwise returns // the key and a database error, if any. +// TODO: Cache this? func (d *Database) SelectUserRoomPrivateKey(ctx context.Context, userID spec.UserID, roomID spec.RoomID) (key ed25519.PrivateKey, err error) { uID := userID.String() stateKeyNIDMap, sErr := d.eventStateKeyNIDs(ctx, nil, []string{uID})