diff --git a/config/bridge.go b/config/bridge.go index 4621f02..625e860 100644 --- a/config/bridge.go +++ b/config/bridge.go @@ -77,6 +77,12 @@ type BridgeConfig struct { Encryption struct { Allow bool `yaml:"allow"` Default bool `yaml:"default"` + + KeySharing struct { + Allow bool `yaml:"allow"` + RequireCrossSigning bool `yaml:"require_cross_signing"` + RequireVerification bool `yaml:"require_verification"` + } `yaml:"key_sharing"` } `yaml:"encryption"` Permissions PermissionConfig `yaml:"permissions"` diff --git a/crypto.go b/crypto.go index 2d3808e..e2d6157 100644 --- a/crypto.go +++ b/crypto.go @@ -83,6 +83,7 @@ func (helper *CryptoHelper) Init() error { logger := &cryptoLogger{helper.baseLog} stateStore := &cryptoStateStore{helper.bridge} helper.mach = crypto.NewOlmMachine(helper.client, logger, helper.store, stateStore) + helper.mach.AllowKeyShare = helper.allowKeyShare helper.client.Logger = logger.int.Sub("Bot") helper.client.Syncer = &cryptoSyncer{helper.mach} @@ -91,6 +92,30 @@ func (helper *CryptoHelper) Init() error { return helper.mach.Load() } +func (helper *CryptoHelper) allowKeyShare(device *crypto.DeviceIdentity, info event.RequestedKeyInfo) *crypto.KeyShareRejection { + cfg := helper.bridge.Config.Bridge.Encryption.KeySharing + if !cfg.Allow { + return &crypto.KeyShareRejectNoResponse + } else if device.Trust == crypto.TrustStateBlacklisted { + return &crypto.KeyShareRejectBlacklisted + } else if device.Trust == crypto.TrustStateVerified || !cfg.RequireVerification { + portal := helper.bridge.GetPortalByMXID(info.RoomID) + if portal == nil { + helper.log.Debugfln("Rejecting key request for %s from %s/%s: room is not a portal", info.SessionID, device.UserID, device.DeviceID) + return &crypto.KeyShareRejection{Code: event.RoomKeyWithheldUnavailable, Reason: "Requested room is not a portal room"} + } + user := helper.bridge.GetUserByMXID(device.UserID) + if !user.IsInPortal(portal.Key) { + helper.log.Debugfln("Rejecting key request for %s from %s/%s: user is not in portal", info.SessionID, device.UserID, device.DeviceID) + return &crypto.KeyShareRejection{Code: event.RoomKeyWithheldUnauthorized, Reason: "You're not in that portal"} + } + helper.log.Debugfln("Accepting key request for %s from %s/%s", info.SessionID, device.UserID, device.DeviceID) + return nil + } else { + return &crypto.KeyShareRejectUnverified + } +} + func (helper *CryptoHelper) loginBot() (*mautrix.Client, error) { deviceID := helper.store.FindDeviceID() if len(deviceID) > 0 { diff --git a/database/upgrades/2020-08-03-update-crypto-store.go b/database/upgrades/2020-08-03-update-crypto-store.go new file mode 100644 index 0000000..859c250 --- /dev/null +++ b/database/upgrades/2020-08-03-update-crypto-store.go @@ -0,0 +1,13 @@ +package upgrades + +import ( + "database/sql" + + "maunium.net/go/mautrix/crypto/sql_store_upgrade" +) + +func init() { + upgrades[18] = upgrade{"Add megolm withheld data to crypto store", func(tx *sql.Tx, c context) error { + return sql_store_upgrade.Upgrades[2](tx, c.dialect.String()) + }} +} diff --git a/database/upgrades/upgrades.go b/database/upgrades/upgrades.go index f020d94..a870745 100644 --- a/database/upgrades/upgrades.go +++ b/database/upgrades/upgrades.go @@ -39,7 +39,7 @@ type upgrade struct { fn upgradeFunc } -const NumberOfUpgrades = 18 +const NumberOfUpgrades = 19 var upgrades [NumberOfUpgrades]upgrade diff --git a/example-config.yaml b/example-config.yaml index 039eff1..0f5da51 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -187,6 +187,18 @@ bridge: # This will cause the bridge bot to be in private chats for the encryption to work properly. # It is recommended to also set private_chat_portal_meta to true when using this. default: false + # Options for automatic key sharing. + key_sharing: + # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. + # You must use a client that supports requesting keys from other users to use this feature. + allow: false + # Require the requesting device to have a valid cross-signing signature? + # This doesn't require that the bridge has verified the device, only that the user has verified it. + # Not yet implemented. + require_cross_signing: false + # Require devices to be verified by the bridge? + # Verification by the bridge is not yet implemented. + require_verification: true # Permissions for using the bridge. # Permitted values: diff --git a/go.mod b/go.mod index d6bb7c0..fac1f93 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( gopkg.in/yaml.v2 v2.3.0 maunium.net/go/mauflag v1.0.0 maunium.net/go/maulogger/v2 v2.1.1 - maunium.net/go/mautrix v0.7.0-rc.3 + maunium.net/go/mautrix v0.7.0 ) replace github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.3.7 diff --git a/go.sum b/go.sum index ed26aa2..d7771d7 100644 --- a/go.sum +++ b/go.sum @@ -219,3 +219,5 @@ maunium.net/go/mautrix v0.7.0-rc.2 h1:139raRbbLft9i+g0zGVOT8rrHKRQmeo0SsZnFpZDEX maunium.net/go/mautrix v0.7.0-rc.2/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo= maunium.net/go/mautrix v0.7.0-rc.3 h1:GVmrVvY5vDASMyZ2xJ9kNynWsgqKl1yerKP7c6RsM7o= maunium.net/go/mautrix v0.7.0-rc.3/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo= +maunium.net/go/mautrix v0.7.0 h1:9Wxs5S4Wl4S99dbBwfLZYAe/sP7VKaFikw9Ocf88kfk= +maunium.net/go/mautrix v0.7.0/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo=