diff --git a/config/bridge.go b/config/bridge.go index a4e3046..baba694 100644 --- a/config/bridge.go +++ b/config/bridge.go @@ -55,6 +55,7 @@ type BridgeConfig struct { SyncChatMaxAge uint64 `yaml:"sync_max_chat_age"` SyncWithCustomPuppets bool `yaml:"sync_with_custom_puppets"` + LoginSharedSecret string `yaml:"login_shared_secret"` InviteOwnPuppetForBackfilling bool `yaml:"invite_own_puppet_for_backfilling"` PrivateChatPortalMeta bool `yaml:"private_chat_portal_meta"` @@ -91,6 +92,7 @@ func (bc *BridgeConfig) setDefaults() { bc.SyncChatMaxAge = 259200 bc.SyncWithCustomPuppets = true + bc.LoginSharedSecret = "" bc.InviteOwnPuppetForBackfilling = true bc.PrivateChatPortalMeta = false diff --git a/custompuppet.go b/custompuppet.go index 0c43778..f1c335d 100644 --- a/custompuppet.go +++ b/custompuppet.go @@ -17,6 +17,9 @@ package main import ( + "crypto/hmac" + "crypto/sha512" + "encoding/hex" "encoding/json" "fmt" "strings" @@ -58,6 +61,22 @@ func (puppet *Puppet) SwitchCustomMXID(accessToken string, mxid string) error { return nil } +func (puppet *Puppet) loginWithSharedSecret(mxid string) (string, error) { + mac := hmac.New(sha512.New, []byte(puppet.bridge.Config.Bridge.LoginSharedSecret)) + mac.Write([]byte(mxid)) + resp, err := puppet.bridge.AS.BotClient().Login(&mautrix.ReqLogin{ + Type: "m.login.password", + Identifier: mautrix.UserIdentifier{Type: "m.id.user", User: mxid}, + Password: hex.EncodeToString(mac.Sum(nil)), + DeviceID: "WhatsApp Bridge", + InitialDeviceDisplayName: "WhatsApp Bridge", + }) + if err != nil { + return "", err + } + return resp.AccessToken, nil +} + func (puppet *Puppet) newCustomIntent() (*appservice.IntentAPI, error) { if len(puppet.CustomMXID) == 0 { return nil, ErrNoCustomMXID diff --git a/example-config.yaml b/example-config.yaml index 346bda8..98bacc8 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -102,6 +102,12 @@ bridge: # Whether or not to sync with custom puppets to receive EDUs that # are not normally sent to appservices. sync_with_custom_puppets: true + # Shared secret for https://github.com/devture/matrix-synapse-shared-secret-auth + # + # If set, custom puppets will be enabled automatically for local users + # instead of users having to find an access token and run `login-matrix` + # manually. + login_shared_secret: null # Whether or not to invite own WhatsApp user's Matrix puppet into private # chat portals when backfilling if needed. diff --git a/go.mod b/go.mod index 0afaa9f..8564e44 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,8 @@ require ( gopkg.in/yaml.v2 v2.2.2 maunium.net/go/mauflag v1.0.0 maunium.net/go/maulogger/v2 v2.0.0 - maunium.net/go/mautrix v0.1.0-alpha.3.0.20191110191816-178ce1f1561d - maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20191110192030-cd699619a163 + maunium.net/go/mautrix v0.1.0-alpha.3.0.20191230181907-055c3acd81cd + maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20191230181948-bf5d2e16a792 ) replace ( diff --git a/go.sum b/go.sum index f638f9a..2daebd0 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,7 @@ github.com/tulir/go-whatsapp v0.0.2-0.20190830212741-33ca6ee47cf5 h1:0pUczFGOo4s github.com/tulir/go-whatsapp v0.0.2-0.20190830212741-33ca6ee47cf5/go.mod h1:u3Hdptbz3iB5y/NEoSKgsp9hBzUlm0A5OrLMVdENAX8= github.com/tulir/go-whatsapp v0.0.2-0.20190903182221-4e1a838ff3ba h1:exEcedSHn0qEZ1iwNwFF5brEuflhMScjFyyzmxUA+og= github.com/tulir/go-whatsapp v0.0.2-0.20190903182221-4e1a838ff3ba/go.mod h1:u3Hdptbz3iB5y/NEoSKgsp9hBzUlm0A5OrLMVdENAX8= +github.com/tulir/go-whatsapp v0.0.2-0.20191109203156-c477dae1c7e9 h1:WyLOadcpkAvoyaGfUvBgj/mTHetzliBGFioEEtM+Ac8= github.com/tulir/go-whatsapp v0.0.2-0.20191109203156-c477dae1c7e9/go.mod h1:ustkccVUt0hOuKikjFb6b4Eray6At5djkcKYYu4+Lco= golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= @@ -74,6 +75,8 @@ maunium.net/go/mautrix v0.1.0-alpha.3.0.20190622085722-6406f15cb8e3/go.mod h1:O+ maunium.net/go/mautrix v0.1.0-alpha.3.0.20190825132810-9d870654e9d2 h1:0iVxLLAOSBqtJqhIjW9EbblMsaSYoCJRo5mHPZnytUk= maunium.net/go/mautrix v0.1.0-alpha.3.0.20190825132810-9d870654e9d2/go.mod h1:O+QWJP3H7BZEzIBSrECKpnpRnEKBwaoWVEu/yZwVwxg= maunium.net/go/mautrix v0.1.0-alpha.3.0.20191110191816-178ce1f1561d/go.mod h1:O+QWJP3H7BZEzIBSrECKpnpRnEKBwaoWVEu/yZwVwxg= +maunium.net/go/mautrix v0.1.0-alpha.3.0.20191230181907-055c3acd81cd h1:stoHlgxDA3AKrULnJo1Ubmrb/Yk7iz2ucb0JA3YNMDM= +maunium.net/go/mautrix v0.1.0-alpha.3.0.20191230181907-055c3acd81cd/go.mod h1:O+QWJP3H7BZEzIBSrECKpnpRnEKBwaoWVEu/yZwVwxg= maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20190618052224-6e6c9bb47548 h1:ni1nqs+2AOO+g1ND6f2W0pMcb6sIDVqzerXosO+pI2g= maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20190618052224-6e6c9bb47548/go.mod h1:yVWU0gvIHIXClgyVnShiufiDksFbFrBqHG9lDAYcmGI= maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20190822210104-3e49344e186b h1:/03X0PPgtk4pqXcdH86xMzOl891whG5A1hFXQ+xXons= @@ -87,3 +90,5 @@ maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20190830063827-e7dcd7e42e7c/g maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20190901152202-40639f5932be h1:sSBx9AGR4iYHRFwljqNwxXFtbY2bKLJHgI9B4whAU8I= maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20190901152202-40639f5932be/go.mod h1:FJRRpH5+p3wCfEt6u/3kMeu9aGX/pk2PqtvjRDRW74w= maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20191110192030-cd699619a163/go.mod h1:ST7YYCoHtFC4c7/Iga8W5wwKXyxjwVh4DlsnyIU6rYw= +maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20191230181948-bf5d2e16a792 h1:7Lxt/h4TnC6Z9PfnggdD4e7IasxdnYzrXmtTmedbSpU= +maunium.net/go/mautrix-appservice v0.1.0-alpha.3.0.20191230181948-bf5d2e16a792/go.mod h1:ek/PBMaq4AxuI5NP+XAq5Ma2u+ZTjUUaUr6dh4w9zSw= diff --git a/user.go b/user.go index 4d8f7e0..a9821df 100644 --- a/user.go +++ b/user.go @@ -365,9 +365,35 @@ func (user *User) PostLogin() { go user.intPostLogin() } +func (user *User) tryAutomaticDoublePuppeting(){ + if len(user.bridge.Config.Bridge.LoginSharedSecret) == 0 { + // Automatic login not enabled + return + } + + puppet := user.bridge.GetPuppetByJID(user.JID) + if len(puppet.CustomMXID) > 0 { + // Custom puppet already enabled + return + } + accessToken, err := puppet.loginWithSharedSecret(user.MXID) + if err != nil { + user.log.Warnln("Failed to login with shared secret:", err) + return + } + err = puppet.SwitchCustomMXID(accessToken, user.MXID) + if err != nil { + puppet.log.Warnln("Failed to switch to auto-logined custom puppet:", err) + return + } + user.log.Infoln("Successfully automatically enabled custom puppet") +} + func (user *User) intPostLogin() { - user.createCommunity() defer user.syncLock.Unlock() + user.createCommunity() + user.tryAutomaticDoublePuppeting() + select { case <-user.chatListReceived: