mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-31 13:22:46 +00:00
Federation fixes for virtual hosting
This commit is contained in:
parent
f4ee397734
commit
6650712a1c
73 changed files with 736 additions and 420 deletions
|
@ -82,7 +82,8 @@ func Backfill(
|
|||
BackwardsExtremities: map[string][]string{
|
||||
"": eIDs,
|
||||
},
|
||||
ServerName: request.Origin(),
|
||||
ServerName: request.Origin(),
|
||||
VirtualHost: request.Destination(),
|
||||
}
|
||||
if req.Limit, err = strconv.Atoi(limit); err != nil {
|
||||
util.GetLogger(httpReq.Context()).WithError(err).Error("strconv.Atoi failed")
|
||||
|
@ -123,7 +124,7 @@ func Backfill(
|
|||
}
|
||||
|
||||
txn := gomatrixserverlib.Transaction{
|
||||
Origin: cfg.Matrix.ServerName,
|
||||
Origin: request.Destination(),
|
||||
PDUs: eventJSONs,
|
||||
OriginServerTS: gomatrixserverlib.AsTimestamp(time.Now()),
|
||||
}
|
||||
|
|
|
@ -140,6 +140,21 @@ func processInvite(
|
|||
}
|
||||
}
|
||||
|
||||
if event.StateKey() == nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.BadJSON("The invite event has no state key"),
|
||||
}
|
||||
}
|
||||
|
||||
_, domain, err := cfg.Matrix.SplitLocalID('@', *event.StateKey())
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.InvalidArgumentValue(fmt.Sprintf("The user ID is invalid or domain %q does not belong to this server", domain)),
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the event is signed by the server sending the request.
|
||||
redacted, err := gomatrixserverlib.RedactEventJSON(event.JSON(), event.Version())
|
||||
if err != nil {
|
||||
|
@ -175,7 +190,7 @@ func processInvite(
|
|||
|
||||
// Sign the event so that other servers will know that we have received the invite.
|
||||
signedEvent := event.Sign(
|
||||
string(cfg.Matrix.ServerName), cfg.Matrix.KeyID, cfg.Matrix.PrivateKey,
|
||||
string(domain), cfg.Matrix.KeyID, cfg.Matrix.PrivateKey,
|
||||
)
|
||||
|
||||
// Add the invite event to the roomserver.
|
||||
|
|
|
@ -131,10 +131,20 @@ func MakeJoin(
|
|||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
identity, err := cfg.Matrix.SigningIdentityFor(request.Destination())
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusNotFound,
|
||||
JSON: jsonerror.NotFound(
|
||||
fmt.Sprintf("Server name %q does not exist", request.Destination()),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
queryRes := api.QueryLatestEventsAndStateResponse{
|
||||
RoomVersion: verRes.RoomVersion,
|
||||
}
|
||||
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
|
||||
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &builder, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
|
||||
if err == eventutil.ErrRoomNoExists {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusNotFound,
|
||||
|
|
|
@ -16,7 +16,6 @@ package routing
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
@ -136,38 +135,52 @@ func ClaimOneTimeKeys(
|
|||
// LocalKeys returns the local keys for the server.
|
||||
// See https://matrix.org/docs/spec/server_server/unstable.html#publishing-keys
|
||||
func LocalKeys(cfg *config.FederationAPI, serverName gomatrixserverlib.ServerName) util.JSONResponse {
|
||||
keys, err := localKeys(cfg, serverName, time.Now().Add(cfg.Matrix.KeyValidityPeriod))
|
||||
keys, err := localKeys(cfg, serverName)
|
||||
if err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
return util.MessageResponse(http.StatusNotFound, err.Error())
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: keys}
|
||||
}
|
||||
|
||||
func localKeys(cfg *config.FederationAPI, serverName gomatrixserverlib.ServerName, validUntil time.Time) (*gomatrixserverlib.ServerKeys, error) {
|
||||
func localKeys(cfg *config.FederationAPI, serverName gomatrixserverlib.ServerName) (*gomatrixserverlib.ServerKeys, error) {
|
||||
var keys gomatrixserverlib.ServerKeys
|
||||
if !cfg.Matrix.IsLocalServerName(serverName) {
|
||||
return nil, fmt.Errorf("server name not known")
|
||||
}
|
||||
|
||||
keys.ServerName = serverName
|
||||
keys.ValidUntilTS = gomatrixserverlib.AsTimestamp(validUntil)
|
||||
|
||||
publicKey := cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey)
|
||||
|
||||
keys.VerifyKeys = map[gomatrixserverlib.KeyID]gomatrixserverlib.VerifyKey{
|
||||
cfg.Matrix.KeyID: {
|
||||
Key: gomatrixserverlib.Base64Bytes(publicKey),
|
||||
},
|
||||
}
|
||||
|
||||
keys.OldVerifyKeys = map[gomatrixserverlib.KeyID]gomatrixserverlib.OldVerifyKey{}
|
||||
for _, oldVerifyKey := range cfg.Matrix.OldVerifyKeys {
|
||||
keys.OldVerifyKeys[oldVerifyKey.KeyID] = gomatrixserverlib.OldVerifyKey{
|
||||
VerifyKey: gomatrixserverlib.VerifyKey{
|
||||
Key: oldVerifyKey.PublicKey,
|
||||
},
|
||||
ExpiredTS: oldVerifyKey.ExpiredAt,
|
||||
var virtualHost *config.VirtualHost
|
||||
for _, v := range cfg.Matrix.VirtualHosts {
|
||||
if v.ServerName != serverName {
|
||||
continue
|
||||
}
|
||||
virtualHost = v
|
||||
}
|
||||
|
||||
if virtualHost == nil {
|
||||
publicKey := cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey)
|
||||
keys.ServerName = cfg.Matrix.ServerName
|
||||
keys.ValidUntilTS = gomatrixserverlib.AsTimestamp(time.Now().Add(cfg.Matrix.KeyValidityPeriod))
|
||||
keys.VerifyKeys = map[gomatrixserverlib.KeyID]gomatrixserverlib.VerifyKey{
|
||||
cfg.Matrix.KeyID: {
|
||||
Key: gomatrixserverlib.Base64Bytes(publicKey),
|
||||
},
|
||||
}
|
||||
keys.OldVerifyKeys = map[gomatrixserverlib.KeyID]gomatrixserverlib.OldVerifyKey{}
|
||||
for _, oldVerifyKey := range cfg.Matrix.OldVerifyKeys {
|
||||
keys.OldVerifyKeys[oldVerifyKey.KeyID] = gomatrixserverlib.OldVerifyKey{
|
||||
VerifyKey: gomatrixserverlib.VerifyKey{
|
||||
Key: oldVerifyKey.PublicKey,
|
||||
},
|
||||
ExpiredTS: oldVerifyKey.ExpiredAt,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
publicKey := virtualHost.PrivateKey.Public().(ed25519.PublicKey)
|
||||
keys.ServerName = virtualHost.ServerName
|
||||
keys.ValidUntilTS = gomatrixserverlib.AsTimestamp(time.Now().Add(virtualHost.KeyValidityPeriod))
|
||||
keys.VerifyKeys = map[gomatrixserverlib.KeyID]gomatrixserverlib.VerifyKey{
|
||||
virtualHost.KeyID: {
|
||||
Key: gomatrixserverlib.Base64Bytes(publicKey),
|
||||
},
|
||||
}
|
||||
// TODO: Virtual hosts probably want to be able to specify old signing
|
||||
// keys too, just in case
|
||||
}
|
||||
|
||||
toSign, err := json.Marshal(keys.ServerKeyFields)
|
||||
|
@ -213,7 +226,7 @@ func NotaryKeys(
|
|||
for serverName, kidToCriteria := range req.ServerKeys {
|
||||
var keyList []gomatrixserverlib.ServerKeys
|
||||
if serverName == cfg.Matrix.ServerName {
|
||||
if k, err := localKeys(cfg, serverName, time.Now().Add(cfg.Matrix.KeyValidityPeriod)); err == nil {
|
||||
if k, err := localKeys(cfg, serverName); err == nil {
|
||||
keyList = append(keyList, *k)
|
||||
} else {
|
||||
return util.ErrorResponse(err)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
@ -60,8 +61,18 @@ func MakeLeave(
|
|||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
identity, err := cfg.Matrix.SigningIdentityFor(request.Destination())
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusNotFound,
|
||||
JSON: jsonerror.NotFound(
|
||||
fmt.Sprintf("Server name %q does not exist", request.Destination()),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
var queryRes api.QueryLatestEventsAndStateResponse
|
||||
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
|
||||
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &builder, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
|
||||
if err == eventutil.ErrRoomNoExists {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusNotFound,
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
||||
|
@ -42,16 +41,9 @@ func GetProfile(
|
|||
}
|
||||
}
|
||||
|
||||
_, domain, err := gomatrixserverlib.SplitID('@', userID)
|
||||
_, domain, err := cfg.Matrix.SplitLocalID('@', userID)
|
||||
if err != nil {
|
||||
util.GetLogger(httpReq.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed")
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.MissingArgument(fmt.Sprintf("Format of user ID %q is invalid", userID)),
|
||||
}
|
||||
}
|
||||
|
||||
if domain != cfg.Matrix.ServerName {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.InvalidArgumentValue(fmt.Sprintf("Domain %q does not match this server", domain)),
|
||||
|
|
|
@ -83,7 +83,7 @@ func RoomAliasToID(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
resp, err = federation.LookupRoomAlias(httpReq.Context(), domain, roomAlias)
|
||||
resp, err = federation.LookupRoomAlias(httpReq.Context(), domain, cfg.Matrix.ServerName, roomAlias)
|
||||
if err != nil {
|
||||
switch x := err.(type) {
|
||||
case gomatrix.HTTPError:
|
||||
|
|
|
@ -197,12 +197,12 @@ type txnReq struct {
|
|||
|
||||
// A subset of FederationClient functionality that txn requires. Useful for testing.
|
||||
type txnFederationClient interface {
|
||||
LookupState(ctx context.Context, s gomatrixserverlib.ServerName, roomID string, eventID string, roomVersion gomatrixserverlib.RoomVersion) (
|
||||
LookupState(ctx context.Context, origin, s gomatrixserverlib.ServerName, roomID string, eventID string, roomVersion gomatrixserverlib.RoomVersion) (
|
||||
res gomatrixserverlib.RespState, err error,
|
||||
)
|
||||
LookupStateIDs(ctx context.Context, s gomatrixserverlib.ServerName, roomID string, eventID string) (res gomatrixserverlib.RespStateIDs, err error)
|
||||
GetEvent(ctx context.Context, s gomatrixserverlib.ServerName, eventID string) (res gomatrixserverlib.Transaction, err error)
|
||||
LookupMissingEvents(ctx context.Context, s gomatrixserverlib.ServerName, roomID string, missing gomatrixserverlib.MissingEvents,
|
||||
LookupStateIDs(ctx context.Context, origin, s gomatrixserverlib.ServerName, roomID string, eventID string) (res gomatrixserverlib.RespStateIDs, err error)
|
||||
GetEvent(ctx context.Context, origin, s gomatrixserverlib.ServerName, eventID string) (res gomatrixserverlib.Transaction, err error)
|
||||
LookupMissingEvents(ctx context.Context, origin, s gomatrixserverlib.ServerName, roomID string, missing gomatrixserverlib.MissingEvents,
|
||||
roomVersion gomatrixserverlib.RoomVersion) (res gomatrixserverlib.RespMissingEvents, err error)
|
||||
}
|
||||
|
||||
|
@ -287,6 +287,7 @@ func (t *txnReq) processTransaction(ctx context.Context) (*gomatrixserverlib.Res
|
|||
[]*gomatrixserverlib.HeaderedEvent{
|
||||
event.Headered(roomVersion),
|
||||
},
|
||||
t.Destination,
|
||||
t.Origin,
|
||||
api.DoNotSendToOtherServers,
|
||||
nil,
|
||||
|
|
|
@ -147,7 +147,7 @@ type txnFedClient struct {
|
|||
getMissingEvents func(gomatrixserverlib.MissingEvents) (res gomatrixserverlib.RespMissingEvents, err error)
|
||||
}
|
||||
|
||||
func (c *txnFedClient) LookupState(ctx context.Context, s gomatrixserverlib.ServerName, roomID string, eventID string, roomVersion gomatrixserverlib.RoomVersion) (
|
||||
func (c *txnFedClient) LookupState(ctx context.Context, origin, s gomatrixserverlib.ServerName, roomID string, eventID string, roomVersion gomatrixserverlib.RoomVersion) (
|
||||
res gomatrixserverlib.RespState, err error,
|
||||
) {
|
||||
fmt.Println("testFederationClient.LookupState", eventID)
|
||||
|
@ -159,7 +159,7 @@ func (c *txnFedClient) LookupState(ctx context.Context, s gomatrixserverlib.Serv
|
|||
res = r
|
||||
return
|
||||
}
|
||||
func (c *txnFedClient) LookupStateIDs(ctx context.Context, s gomatrixserverlib.ServerName, roomID string, eventID string) (res gomatrixserverlib.RespStateIDs, err error) {
|
||||
func (c *txnFedClient) LookupStateIDs(ctx context.Context, origin, s gomatrixserverlib.ServerName, roomID string, eventID string) (res gomatrixserverlib.RespStateIDs, err error) {
|
||||
fmt.Println("testFederationClient.LookupStateIDs", eventID)
|
||||
r, ok := c.stateIDs[eventID]
|
||||
if !ok {
|
||||
|
@ -169,7 +169,7 @@ func (c *txnFedClient) LookupStateIDs(ctx context.Context, s gomatrixserverlib.S
|
|||
res = r
|
||||
return
|
||||
}
|
||||
func (c *txnFedClient) GetEvent(ctx context.Context, s gomatrixserverlib.ServerName, eventID string) (res gomatrixserverlib.Transaction, err error) {
|
||||
func (c *txnFedClient) GetEvent(ctx context.Context, origin, s gomatrixserverlib.ServerName, eventID string) (res gomatrixserverlib.Transaction, err error) {
|
||||
fmt.Println("testFederationClient.GetEvent", eventID)
|
||||
r, ok := c.getEvent[eventID]
|
||||
if !ok {
|
||||
|
@ -179,7 +179,7 @@ func (c *txnFedClient) GetEvent(ctx context.Context, s gomatrixserverlib.ServerN
|
|||
res = r
|
||||
return
|
||||
}
|
||||
func (c *txnFedClient) LookupMissingEvents(ctx context.Context, s gomatrixserverlib.ServerName, roomID string, missing gomatrixserverlib.MissingEvents,
|
||||
func (c *txnFedClient) LookupMissingEvents(ctx context.Context, origin, s gomatrixserverlib.ServerName, roomID string, missing gomatrixserverlib.MissingEvents,
|
||||
roomVersion gomatrixserverlib.RoomVersion) (res gomatrixserverlib.RespMissingEvents, err error) {
|
||||
return c.getMissingEvents(missing)
|
||||
}
|
||||
|
|
|
@ -90,7 +90,17 @@ func CreateInvitesFrom3PIDInvites(
|
|||
}
|
||||
|
||||
// Send all the events
|
||||
if err := api.SendEvents(req.Context(), rsAPI, api.KindNew, evs, "TODO", cfg.Matrix.ServerName, nil, false); err != nil {
|
||||
if err := api.SendEvents(
|
||||
req.Context(),
|
||||
rsAPI,
|
||||
api.KindNew,
|
||||
evs,
|
||||
cfg.Matrix.ServerName, // TODO: which virtual host?
|
||||
"TODO",
|
||||
cfg.Matrix.ServerName,
|
||||
nil,
|
||||
false,
|
||||
); err != nil {
|
||||
util.GetLogger(req.Context()).WithError(err).Error("SendEvents failed")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
@ -126,6 +136,14 @@ func ExchangeThirdPartyInvite(
|
|||
}
|
||||
}
|
||||
|
||||
_, senderDomain, err := cfg.Matrix.SplitLocalID('@', builder.Sender)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.BadJSON("Invalid sender ID: " + err.Error()),
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the state key is correct.
|
||||
_, targetDomain, err := gomatrixserverlib.SplitID('@', *builder.StateKey)
|
||||
if err != nil {
|
||||
|
@ -171,7 +189,7 @@ func ExchangeThirdPartyInvite(
|
|||
util.GetLogger(httpReq.Context()).WithError(err).Error("failed to make invite v2 request")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
signedEvent, err := federation.SendInviteV2(httpReq.Context(), request.Origin(), inviteReq)
|
||||
signedEvent, err := federation.SendInviteV2(httpReq.Context(), senderDomain, request.Origin(), inviteReq)
|
||||
if err != nil {
|
||||
util.GetLogger(httpReq.Context()).WithError(err).Error("federation.SendInvite failed")
|
||||
return jsonerror.InternalServerError()
|
||||
|
@ -189,6 +207,7 @@ func ExchangeThirdPartyInvite(
|
|||
[]*gomatrixserverlib.HeaderedEvent{
|
||||
inviteEvent.Headered(verRes.RoomVersion),
|
||||
},
|
||||
request.Destination(),
|
||||
request.Origin(),
|
||||
cfg.Matrix.ServerName,
|
||||
nil,
|
||||
|
@ -341,7 +360,7 @@ func buildMembershipEvent(
|
|||
// them responded with an error.
|
||||
func sendToRemoteServer(
|
||||
ctx context.Context, inv invite,
|
||||
federation federationAPI.FederationClient, _ *config.FederationAPI,
|
||||
federation federationAPI.FederationClient, cfg *config.FederationAPI,
|
||||
builder gomatrixserverlib.EventBuilder,
|
||||
) (err error) {
|
||||
remoteServers := make([]gomatrixserverlib.ServerName, 2)
|
||||
|
@ -357,7 +376,7 @@ func sendToRemoteServer(
|
|||
}
|
||||
|
||||
for _, server := range remoteServers {
|
||||
err = federation.ExchangeThirdPartyInvite(ctx, server, builder)
|
||||
err = federation.ExchangeThirdPartyInvite(ctx, cfg.Matrix.ServerName, server, builder)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue