Maybe support e2be by default and fix some bugs

This commit is contained in:
Tulir Asokan 2020-05-12 22:25:55 +03:00
parent db5c1a3f61
commit 1c3de877db
8 changed files with 52 additions and 11 deletions

View file

@ -22,6 +22,7 @@ import (
"crypto/hmac" "crypto/hmac"
"crypto/sha512" "crypto/sha512"
"encoding/hex" "encoding/hex"
"fmt"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -78,7 +79,7 @@ func (helper *CryptoHelper) Init() error {
stateStore := &cryptoStateStore{helper.bridge} stateStore := &cryptoStateStore{helper.bridge}
helper.store = database.NewSQLCryptoStore(helper.bridge.DB, helper.client.DeviceID) helper.store = database.NewSQLCryptoStore(helper.bridge.DB, helper.client.DeviceID)
helper.store.UserID = helper.client.UserID helper.store.UserID = helper.client.UserID
helper.store.GhostIDFormat = helper.bridge.Config.Bridge.FormatUsername("%") helper.store.GhostIDFormat = fmt.Sprintf("@%s:%s", helper.bridge.Config.Bridge.FormatUsername("%"), helper.bridge.AS.HomeserverDomain)
helper.mach = crypto.NewOlmMachine(helper.client, logger, helper.store, stateStore) helper.mach = crypto.NewOlmMachine(helper.client, logger, helper.store, stateStore)
helper.client.Logger = logger.int.Sub("Bot") helper.client.Logger = logger.int.Sub("Bot")

View file

@ -211,6 +211,13 @@ func (store *SQLCryptoStore) AddSession(key id.SenderKey, session *crypto.OlmSes
return err return err
} }
func (store *SQLCryptoStore) UpdateSession(key id.SenderKey, session *crypto.OlmSession) error {
sessionBytes := session.Internal.Pickle(store.PickleKey)
_, err := store.db.Exec("UPDATE crypto_olm_session SET session=$1, last_used=$2 WHERE session_id=$3",
sessionBytes, session.UseTime, session.ID())
return err
}
func (store *SQLCryptoStore) PutGroupSession(roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID, session *crypto.InboundGroupSession) error { func (store *SQLCryptoStore) PutGroupSession(roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID, session *crypto.InboundGroupSession) error {
sessionBytes := session.Internal.Pickle(store.PickleKey) sessionBytes := session.Internal.Pickle(store.PickleKey)
forwardingChains := strings.Join(session.ForwardingChains, ",") forwardingChains := strings.Join(session.ForwardingChains, ",")

View file

@ -18,7 +18,7 @@ func init() {
} }
_, err = tx.Exec(`CREATE TABLE crypto_message_index ( _, err = tx.Exec(`CREATE TABLE crypto_message_index (
sender_key CHAR(43), sender_key CHAR(43),
session_id VARCHAR(255), session_id CHAR(43),
"index" INTEGER, "index" INTEGER,
event_id VARCHAR(255) NOT NULL, event_id VARCHAR(255) NOT NULL,
timestamp BIGINT NOT NULL, timestamp BIGINT NOT NULL,
@ -49,11 +49,11 @@ func init() {
return err return err
} }
_, err = tx.Exec(`CREATE TABLE crypto_olm_session ( _, err = tx.Exec(`CREATE TABLE crypto_olm_session (
session_id CHAR(43) PRIMARY KEY, session_id CHAR(43) PRIMARY KEY,
sender_key VARCHAR(255) NOT NULL, sender_key CHAR(43) NOT NULL,
session bytea NOT NULL, session bytea NOT NULL,
created_at timestamp NOT NULL, created_at timestamp NOT NULL,
last_used timestamp NOT NULL last_used timestamp NOT NULL
)`) )`)
if err != nil { if err != nil {
return err return err

View file

@ -148,6 +148,7 @@ bridge:
allow: false allow: false
# Default to encryption, force-enable encryption in all portals the bridge creates # Default to encryption, force-enable encryption in all portals the bridge creates
# This will cause the bridge bot to be in private chats for the encryption to work properly. # 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 default: false
# Permissions for using the bridge. # Permissions for using the bridge.

2
go.mod
View file

@ -15,7 +15,7 @@ require (
gopkg.in/yaml.v2 v2.2.8 gopkg.in/yaml.v2 v2.2.8
maunium.net/go/mauflag v1.0.0 maunium.net/go/mauflag v1.0.0
maunium.net/go/maulogger/v2 v2.1.1 maunium.net/go/maulogger/v2 v2.1.1
maunium.net/go/mautrix v0.4.1 maunium.net/go/mautrix v0.4.3
) )
replace github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.2.6 replace github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.2.6

4
go.sum
View file

@ -88,3 +88,7 @@ maunium.net/go/mautrix v0.4.0 h1:IYfmxCoxR/6UMi92IncsSZeKQbZm8Xa35XIRX814KJ4=
maunium.net/go/mautrix v0.4.0/go.mod h1:8Y+NqmROJyWYvvP4yPfX9tLM59VCfgE/kcQ0SeX68ho= maunium.net/go/mautrix v0.4.0/go.mod h1:8Y+NqmROJyWYvvP4yPfX9tLM59VCfgE/kcQ0SeX68ho=
maunium.net/go/mautrix v0.4.1 h1:i2lJNT+TE4AAL3cVKUN4jKVRkujCE/oS8aIsj8+7iNE= maunium.net/go/mautrix v0.4.1 h1:i2lJNT+TE4AAL3cVKUN4jKVRkujCE/oS8aIsj8+7iNE=
maunium.net/go/mautrix v0.4.1/go.mod h1:8Y+NqmROJyWYvvP4yPfX9tLM59VCfgE/kcQ0SeX68ho= maunium.net/go/mautrix v0.4.1/go.mod h1:8Y+NqmROJyWYvvP4yPfX9tLM59VCfgE/kcQ0SeX68ho=
maunium.net/go/mautrix v0.4.2 h1:GBU++Z7o/fLPcEsNMkNOUsnDknwV/MGPQ0BN4ikK6tw=
maunium.net/go/mautrix v0.4.2/go.mod h1:8Y+NqmROJyWYvvP4yPfX9tLM59VCfgE/kcQ0SeX68ho=
maunium.net/go/mautrix v0.4.3 h1:fVoJy992TjBEvuK5NeO9fpBh+9JuSFsxaEdGjFp/7h4=
maunium.net/go/mautrix v0.4.3/go.mod h1:8Y+NqmROJyWYvvP4yPfX9tLM59VCfgE/kcQ0SeX68ho=

View file

@ -130,6 +130,10 @@ func (mx *MatrixHandler) HandleBotInvite(evt *event.Event) {
} }
func (mx *MatrixHandler) HandleMembership(evt *event.Event) { func (mx *MatrixHandler) HandleMembership(evt *event.Event) {
if _, isPuppet := mx.bridge.ParsePuppetMXID(evt.Sender); evt.Sender == mx.bridge.Bot.UserID || isPuppet {
return
}
if mx.bridge.Crypto != nil { if mx.bridge.Crypto != nil {
mx.bridge.Crypto.HandleMemberEvent(evt) mx.bridge.Crypto.HandleMemberEvent(evt)
} }

View file

@ -725,7 +725,6 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
portal.log.Infoln("Creating Matrix room. Info source:", user.MXID) portal.log.Infoln("Creating Matrix room. Info source:", user.MXID)
var metadata *whatsappExt.GroupInfo var metadata *whatsappExt.GroupInfo
isPrivateChat := false
if portal.IsPrivateChat() { if portal.IsPrivateChat() {
puppet := portal.bridge.GetPuppetByJID(portal.Key.JID) puppet := portal.bridge.GetPuppetByJID(portal.Key.JID)
if portal.bridge.Config.Bridge.PrivateChatPortalMeta { if portal.bridge.Config.Bridge.PrivateChatPortalMeta {
@ -736,7 +735,6 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
portal.Name = "" portal.Name = ""
} }
portal.Topic = "WhatsApp private chat" portal.Topic = "WhatsApp private chat"
isPrivateChat = true
} else if portal.IsStatusBroadcastRoom() { } else if portal.IsStatusBroadcastRoom() {
portal.Name = "WhatsApp Status Broadcast" portal.Name = "WhatsApp Status Broadcast"
portal.Topic = "WhatsApp status updates from your contacts" portal.Topic = "WhatsApp status updates from your contacts"
@ -770,13 +768,26 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
invite = portal.bridge.Config.Bridge.Relaybot.InviteUsers invite = portal.bridge.Config.Bridge.Relaybot.InviteUsers
} }
if portal.bridge.Config.Bridge.Encryption.Default {
initialState = append(initialState, &event.Event{
Type: event.StateEncryption,
Content: event.Content{
Parsed: event.EncryptionEventContent{Algorithm: id.AlgorithmMegolmV1},
},
})
portal.Encrypted = true
if portal.IsPrivateChat() {
invite = append(invite, portal.bridge.Bot.UserID)
}
}
resp, err := intent.CreateRoom(&mautrix.ReqCreateRoom{ resp, err := intent.CreateRoom(&mautrix.ReqCreateRoom{
Visibility: "private", Visibility: "private",
Name: portal.Name, Name: portal.Name,
Topic: portal.Topic, Topic: portal.Topic,
Invite: invite, Invite: invite,
Preset: "private_chat", Preset: "private_chat",
IsDirect: isPrivateChat, IsDirect: portal.IsPrivateChat(),
InitialState: initialState, InitialState: initialState,
}) })
if err != nil { if err != nil {
@ -784,6 +795,12 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
} }
portal.MXID = resp.RoomID portal.MXID = resp.RoomID
portal.Update() portal.Update()
// We set the memberships beforehand to make sure the encryption key exchange in initial backfill knows the users are here.
for _, user := range invite {
portal.bridge.StateStore.SetMembership(portal.MXID, user, event.MembershipInvite)
}
if metadata != nil { if metadata != nil {
portal.SyncParticipants(metadata) portal.SyncParticipants(metadata)
} else { } else {
@ -796,6 +813,13 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
if portal.IsPrivateChat() { if portal.IsPrivateChat() {
puppet := user.bridge.GetPuppetByJID(portal.Key.JID) puppet := user.bridge.GetPuppetByJID(portal.Key.JID)
user.addPuppetToCommunity(puppet) user.addPuppetToCommunity(puppet)
if portal.bridge.Config.Bridge.Encryption.Default {
err = portal.bridge.Bot.EnsureJoined(portal.MXID)
if err != nil {
portal.log.Errorln("Failed to join created portal with bridge bot for e2be:", err)
}
}
} }
err = portal.FillInitialHistory(user) err = portal.FillInitialHistory(user)
if err != nil { if err != nil {