aboutsummaryrefslogtreecommitdiff
path: root/setup
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2022-11-15 15:05:23 +0000
committerNeil Alexander <neilalexander@users.noreply.github.com>2022-11-15 15:05:23 +0000
commit6650712a1c0dec282b47b7ba14bc8c2e06a385d8 (patch)
tree12ca755c5c33d3489417f9355dda3f1b7983c779 /setup
parentf4ee3977340c84d321767d347795b1dcd05ac459 (diff)
Federation fixes for virtual hosting
Diffstat (limited to 'setup')
-rw-r--r--setup/base/base.go7
-rw-r--r--setup/config/config.go15
-rw-r--r--setup/config/config_global.go82
-rw-r--r--setup/mscs/msc2836/msc2836.go6
-rw-r--r--setup/mscs/msc2946/msc2946.go2
5 files changed, 101 insertions, 11 deletions
diff --git a/setup/base/base.go b/setup/base/base.go
index 2e3a3a19..14edadd9 100644
--- a/setup/base/base.go
+++ b/setup/base/base.go
@@ -364,10 +364,10 @@ func (b *BaseDendrite) CreateClient() *gomatrixserverlib.Client {
// CreateFederationClient creates a new federation client. Should only be called
// once per component.
func (b *BaseDendrite) CreateFederationClient() *gomatrixserverlib.FederationClient {
+ identities := b.Cfg.Global.SigningIdentities()
if b.Cfg.Global.DisableFederation {
return gomatrixserverlib.NewFederationClient(
- b.Cfg.Global.ServerName, b.Cfg.Global.KeyID, b.Cfg.Global.PrivateKey,
- gomatrixserverlib.WithTransport(noOpHTTPTransport),
+ identities, gomatrixserverlib.WithTransport(noOpHTTPTransport),
)
}
opts := []gomatrixserverlib.ClientOption{
@@ -379,8 +379,7 @@ func (b *BaseDendrite) CreateFederationClient() *gomatrixserverlib.FederationCli
opts = append(opts, gomatrixserverlib.WithDNSCache(b.DNSCache))
}
client := gomatrixserverlib.NewFederationClient(
- b.Cfg.Global.ServerName, b.Cfg.Global.KeyID,
- b.Cfg.Global.PrivateKey, opts...,
+ identities, opts...,
)
client.SetUserAgent(fmt.Sprintf("Dendrite/%s", internal.VersionString()))
return client
diff --git a/setup/config/config.go b/setup/config/config.go
index e99852ec..918bcbe3 100644
--- a/setup/config/config.go
+++ b/setup/config/config.go
@@ -231,6 +231,21 @@ func loadConfig(
return nil, err
}
+ for _, v := range c.Global.VirtualHosts {
+ if v.KeyValidityPeriod == 0 {
+ v.KeyValidityPeriod = c.Global.KeyValidityPeriod
+ }
+ if v.PrivateKeyPath == "" {
+ v.KeyID = c.Global.KeyID
+ v.PrivateKey = c.Global.PrivateKey
+ continue
+ }
+ privateKeyPath := absPath(basePath, v.PrivateKeyPath)
+ if v.KeyID, v.PrivateKey, err = LoadMatrixKey(privateKeyPath, readFile); err != nil {
+ return nil, err
+ }
+ }
+
for _, key := range c.Global.OldVerifyKeys {
switch {
case key.PrivateKeyPath != "":
diff --git a/setup/config/config_global.go b/setup/config/config_global.go
index 82577282..f2fdd021 100644
--- a/setup/config/config_global.go
+++ b/setup/config/config_global.go
@@ -1,6 +1,7 @@
package config
import (
+ "fmt"
"math/rand"
"strconv"
"strings"
@@ -15,7 +16,7 @@ type Global struct {
ServerName gomatrixserverlib.ServerName `yaml:"server_name"`
// The secondary server names, used for virtual hosting.
- SecondaryServerNames []gomatrixserverlib.ServerName `yaml:"-"`
+ VirtualHosts []*VirtualHost `yaml:"virtual_hosts"`
// Path to the private key which will be used to sign requests and events.
PrivateKeyPath Path `yaml:"private_key"`
@@ -114,6 +115,10 @@ func (c *Global) Verify(configErrs *ConfigErrors, isMonolith bool) {
checkNotEmpty(configErrs, "global.server_name", string(c.ServerName))
checkNotEmpty(configErrs, "global.private_key", string(c.PrivateKeyPath))
+ for _, v := range c.VirtualHosts {
+ v.Verify(configErrs)
+ }
+
c.JetStream.Verify(configErrs, isMonolith)
c.Metrics.Verify(configErrs, isMonolith)
c.Sentry.Verify(configErrs, isMonolith)
@@ -127,14 +132,85 @@ func (c *Global) IsLocalServerName(serverName gomatrixserverlib.ServerName) bool
if c.ServerName == serverName {
return true
}
- for _, secondaryName := range c.SecondaryServerNames {
- if secondaryName == serverName {
+ for _, v := range c.VirtualHosts {
+ if v.ServerName == serverName {
return true
}
}
return false
}
+func (c *Global) SplitLocalID(sigil byte, id string) (string, gomatrixserverlib.ServerName, error) {
+ u, s, err := gomatrixserverlib.SplitID(sigil, id)
+ if err != nil {
+ return u, s, err
+ }
+ if !c.IsLocalServerName(s) {
+ return u, s, fmt.Errorf("server name %q not known", s)
+ }
+ return u, s, nil
+}
+
+func (c *Global) SigningIdentityFor(serverName gomatrixserverlib.ServerName) (*gomatrixserverlib.SigningIdentity, error) {
+ for _, id := range c.SigningIdentities() {
+ if id.ServerName == serverName {
+ return id, nil
+ }
+ }
+ return nil, fmt.Errorf("no signing identity %q", serverName)
+}
+
+func (c *Global) SigningIdentities() []*gomatrixserverlib.SigningIdentity {
+ identities := make([]*gomatrixserverlib.SigningIdentity, 0, len(c.VirtualHosts)+1)
+ identities = append(identities, &gomatrixserverlib.SigningIdentity{
+ ServerName: c.ServerName,
+ KeyID: c.KeyID,
+ PrivateKey: c.PrivateKey,
+ })
+ for _, v := range c.VirtualHosts {
+ identities = append(identities, v.SigningIdentity())
+ }
+ return identities
+}
+
+type VirtualHost struct {
+ // The server name of the virtual host.
+ ServerName gomatrixserverlib.ServerName `yaml:"server_name"`
+
+ // The key ID of the private key. If not specified, the default global key ID
+ // will be used instead.
+ KeyID gomatrixserverlib.KeyID `yaml:"key_id"`
+
+ // Path to the private key. If not specified, the default global private key
+ // will be used instead.
+ PrivateKeyPath Path `yaml:"private_key"`
+
+ // The private key itself.
+ PrivateKey ed25519.PrivateKey `yaml:"-"`
+
+ // How long a remote server can cache our server key for before requesting it again.
+ // Increasing this number will reduce the number of requests made by remote servers
+ // for our key, but increases the period a compromised key will be considered valid
+ // by remote servers.
+ // Defaults to 24 hours.
+ KeyValidityPeriod time.Duration `yaml:"key_validity_period"`
+
+ // Is registration enabled on this virtual host?
+ AllowRegistration bool `json:"allow_registration"`
+}
+
+func (v *VirtualHost) Verify(configErrs *ConfigErrors) {
+ checkNotEmpty(configErrs, "virtual_host.*.server_name", string(v.ServerName))
+}
+
+func (v *VirtualHost) SigningIdentity() *gomatrixserverlib.SigningIdentity {
+ return &gomatrixserverlib.SigningIdentity{
+ ServerName: v.ServerName,
+ KeyID: v.KeyID,
+ PrivateKey: v.PrivateKey,
+ }
+}
+
type OldVerifyKeys struct {
// Path to the private key.
PrivateKeyPath Path `yaml:"private_key"`
diff --git a/setup/mscs/msc2836/msc2836.go b/setup/mscs/msc2836/msc2836.go
index 98502f5c..bc369c16 100644
--- a/setup/mscs/msc2836/msc2836.go
+++ b/setup/mscs/msc2836/msc2836.go
@@ -397,7 +397,7 @@ func (rc *reqCtx) includeChildren(db Database, parentID string, limit int, recen
serversToQuery := rc.getServersForEventID(parentID)
var result *MSC2836EventRelationshipsResponse
for _, srv := range serversToQuery {
- res, err := rc.fsAPI.MSC2836EventRelationships(rc.ctx, srv, gomatrixserverlib.MSC2836EventRelationshipsRequest{
+ res, err := rc.fsAPI.MSC2836EventRelationships(rc.ctx, rc.serverName, srv, gomatrixserverlib.MSC2836EventRelationshipsRequest{
EventID: parentID,
Direction: "down",
Limit: 100,
@@ -484,7 +484,7 @@ func walkThread(
// MSC2836EventRelationships performs an /event_relationships request to a remote server
func (rc *reqCtx) MSC2836EventRelationships(eventID string, srv gomatrixserverlib.ServerName, ver gomatrixserverlib.RoomVersion) (*MSC2836EventRelationshipsResponse, error) {
- res, err := rc.fsAPI.MSC2836EventRelationships(rc.ctx, srv, gomatrixserverlib.MSC2836EventRelationshipsRequest{
+ res, err := rc.fsAPI.MSC2836EventRelationships(rc.ctx, rc.serverName, srv, gomatrixserverlib.MSC2836EventRelationshipsRequest{
EventID: eventID,
DepthFirst: rc.req.DepthFirst,
Direction: rc.req.Direction,
@@ -665,7 +665,7 @@ func (rc *reqCtx) injectResponseToRoomserver(res *MSC2836EventRelationshipsRespo
})
}
// we've got the data by this point so use a background context
- err := roomserver.SendInputRoomEvents(context.Background(), rc.rsAPI, ires, false)
+ err := roomserver.SendInputRoomEvents(context.Background(), rc.rsAPI, rc.serverName, ires, false)
if err != nil {
util.GetLogger(rc.ctx).WithError(err).Error("failed to inject MSC2836EventRelationshipsResponse into the roomserver")
}
diff --git a/setup/mscs/msc2946/msc2946.go b/setup/mscs/msc2946/msc2946.go
index d7c02254..56c06359 100644
--- a/setup/mscs/msc2946/msc2946.go
+++ b/setup/mscs/msc2946/msc2946.go
@@ -433,7 +433,7 @@ func (w *walker) federatedRoomInfo(roomID string, vias []string) *gomatrixserver
if serverName == string(w.thisServer) {
continue
}
- res, err := w.fsAPI.MSC2946Spaces(ctx, gomatrixserverlib.ServerName(serverName), roomID, w.suggestedOnly)
+ res, err := w.fsAPI.MSC2946Spaces(ctx, w.thisServer, gomatrixserverlib.ServerName(serverName), roomID, w.suggestedOnly)
if err != nil {
util.GetLogger(w.ctx).WithError(err).Warnf("failed to call MSC2946Spaces on server %s", serverName)
continue