浏览代码

Add support for automatic key sharing

Tulir Asokan 4 年之前
父节点
当前提交
aefe63cba5
共有 7 个文件被更改,包括 60 次插入2 次删除
  1. 6 0
      config/bridge.go
  2. 25 0
      crypto.go
  3. 13 0
      database/upgrades/2020-08-03-update-crypto-store.go
  4. 1 1
      database/upgrades/upgrades.go
  5. 12 0
      example-config.yaml
  6. 1 1
      go.mod
  7. 2 0
      go.sum

+ 6 - 0
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"`

+ 25 - 0
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 {

+ 13 - 0
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())
+	}}
+}

+ 1 - 1
database/upgrades/upgrades.go

@@ -39,7 +39,7 @@ type upgrade struct {
 	fn      upgradeFunc
 }
 
-const NumberOfUpgrades = 18
+const NumberOfUpgrades = 19
 
 var upgrades [NumberOfUpgrades]upgrade
 

+ 12 - 0
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:

+ 1 - 1
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

+ 2 - 0
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=