Wait up to 3 seconds for encryption keys to arrive

This commit is contained in:
Tulir Asokan 2020-09-24 15:25:36 +03:00
parent 0b2fd69bf1
commit d67c3a8c96
8 changed files with 38 additions and 13 deletions

View file

@ -36,6 +36,8 @@ import (
"maunium.net/go/mautrix-whatsapp/database" "maunium.net/go/mautrix-whatsapp/database"
) )
var NoSessionFound = crypto.NoSessionFound
var levelTrace = maulogger.Level{ var levelTrace = maulogger.Level{
Name: "Trace", Name: "Trace",
Severity: -10, Severity: -10,
@ -183,6 +185,10 @@ func (helper *CryptoHelper) Encrypt(roomID id.RoomID, evtType event.Type, conten
return encrypted, nil return encrypted, nil
} }
func (helper *CryptoHelper) WaitForSession(roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID, timeout time.Duration) bool {
return helper.mach.WaitForSession(roomID, senderKey, sessionID, timeout)
}
func (helper *CryptoHelper) HandleMemberEvent(evt *event.Event) { func (helper *CryptoHelper) HandleMemberEvent(evt *event.Event) {
helper.mach.HandleMemberEvent(evt) helper.mach.HandleMemberEvent(evt)
} }

4
go.mod
View file

@ -16,7 +16,7 @@ require (
gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v2 v2.3.0
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.7.4 maunium.net/go/mautrix v0.7.7
) )
replace github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.3.8 replace github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.3.9

4
go.sum
View file

@ -125,6 +125,8 @@ github.com/tulir/go-whatsapp v0.3.7 h1:6YoHsAlO+Y1SnU0bOntDmuvJQziEnBjFKO+1fOH2V
github.com/tulir/go-whatsapp v0.3.7/go.mod h1:7yGOBdWidM6gsmbAFwgkwHEIhzVrm01+6UbImpMWfTM= github.com/tulir/go-whatsapp v0.3.7/go.mod h1:7yGOBdWidM6gsmbAFwgkwHEIhzVrm01+6UbImpMWfTM=
github.com/tulir/go-whatsapp v0.3.8 h1:cRPyYhtgokUyeE2wsSlRpsw9qddi0Giun+kn9fGsl/M= github.com/tulir/go-whatsapp v0.3.8 h1:cRPyYhtgokUyeE2wsSlRpsw9qddi0Giun+kn9fGsl/M=
github.com/tulir/go-whatsapp v0.3.8/go.mod h1:7yGOBdWidM6gsmbAFwgkwHEIhzVrm01+6UbImpMWfTM= github.com/tulir/go-whatsapp v0.3.8/go.mod h1:7yGOBdWidM6gsmbAFwgkwHEIhzVrm01+6UbImpMWfTM=
github.com/tulir/go-whatsapp v0.3.9 h1:fs2G8TMsSJ2y93UxM9pnFHGxMjKrdFAyavqG8MxpNQA=
github.com/tulir/go-whatsapp v0.3.9/go.mod h1:U5+sm33vrv3wz62YyRM/VS7q2ObXkxU4Xqj/3KOmN9o=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
@ -227,3 +229,5 @@ maunium.net/go/mautrix v0.7.2 h1:ru//jj7Y5Xj9CXBpeNyWCoxjq8iT0d+a2lNeSiN9P/o=
maunium.net/go/mautrix v0.7.2/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo= maunium.net/go/mautrix v0.7.2/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo=
maunium.net/go/mautrix v0.7.4 h1:MDjrvDyHcu5ozKAa80ohcXmYAXZTHgHxrhiERtvkEdY= maunium.net/go/mautrix v0.7.4 h1:MDjrvDyHcu5ozKAa80ohcXmYAXZTHgHxrhiERtvkEdY=
maunium.net/go/mautrix v0.7.4/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo= maunium.net/go/mautrix v0.7.4/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo=
maunium.net/go/mautrix v0.7.7 h1:yfpTizagog8NRHcMjxkCyY7Vreb0OEXaessaJBaLQrw=
maunium.net/go/mautrix v0.7.7/go.mod h1:FpsAvwNdG3Zeup7Y2Nlv81Lk0h6iVRPoIy6D7g/7YCE=

View file

@ -153,6 +153,7 @@ type Crypto interface {
HandleMemberEvent(*event.Event) HandleMemberEvent(*event.Event)
Decrypt(*event.Event) (*event.Event, error) Decrypt(*event.Event) (*event.Event, error)
Encrypt(id.RoomID, event.Type, event.Content) (*event.EncryptedEventContent, error) Encrypt(id.RoomID, event.Type, event.Content) (*event.EncryptedEventContent, error)
WaitForSession(id.RoomID, id.SenderKey, id.SessionID, time.Duration) bool
Init() error Init() error
Start() Start()
Stop() Stop()

View file

@ -17,12 +17,14 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"strings" "strings"
"time"
"maunium.net/go/maulogger/v2" "maunium.net/go/maulogger/v2"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/appservice" "maunium.net/go/mautrix/appservice"
"maunium.net/go/mautrix/event" "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/format" "maunium.net/go/mautrix/format"
@ -330,6 +332,8 @@ func (mx *MatrixHandler) shouldIgnoreEvent(evt *event.Event) bool {
return false return false
} }
const sessionWaitTimeout = 3 * time.Second
func (mx *MatrixHandler) HandleEncrypted(evt *event.Event) { func (mx *MatrixHandler) HandleEncrypted(evt *event.Event) {
defer mx.bridge.Metrics.TrackEvent(evt.Type)() defer mx.bridge.Metrics.TrackEvent(evt.Type)()
if mx.shouldIgnoreEvent(evt) || mx.bridge.Crypto == nil { if mx.shouldIgnoreEvent(evt) || mx.bridge.Crypto == nil {
@ -337,6 +341,13 @@ func (mx *MatrixHandler) HandleEncrypted(evt *event.Event) {
} }
decrypted, err := mx.bridge.Crypto.Decrypt(evt) decrypted, err := mx.bridge.Crypto.Decrypt(evt)
if err != nil {
content := evt.Content.AsEncrypted()
if errors.Is(err, NoSessionFound) && mx.bridge.Crypto.WaitForSession(evt.RoomID, content.SenderKey, content.SessionID, sessionWaitTimeout) {
mx.log.Debugfln("Got session %s to decrypt %s after waiting a while, trying to decrypt again", evt.ID, content.SessionID)
decrypted, err = mx.bridge.Crypto.Decrypt(evt)
}
}
if err != nil { if err != nil {
mx.log.Warnfln("Failed to decrypt %s: %v", evt.ID, err) mx.log.Warnfln("Failed to decrypt %s: %v", evt.ID, err)
_, _ = mx.bridge.Bot.SendNotice(evt.RoomID, fmt.Sprintf( _, _ = mx.bridge.Bot.SendNotice(evt.RoomID, fmt.Sprintf(

View file

@ -9,3 +9,5 @@ func NewCryptoHelper(bridge *Bridge) Crypto {
bridge.Log.Debugln("Bridge built without end-to-bridge encryption") bridge.Log.Debugln("Bridge built without end-to-bridge encryption")
return nil return nil
} }
var NoSessionFound = errors.New("nil")

View file

@ -1129,7 +1129,7 @@ func (portal *Portal) HandleMessageRevoke(user *User, message whatsappExt.Messag
msg.Delete() msg.Delete()
} }
func (portal *Portal) HandleFakeMessage(source *User, message FakeMessage) { func (portal *Portal) HandleFakeMessage(_ *User, message FakeMessage) {
if portal.isRecentlyHandled(message.ID) { if portal.isRecentlyHandled(message.ID) {
return return
} }
@ -1465,9 +1465,10 @@ func (portal *Portal) HandleMediaMessage(source *User, msg mediaMessage) {
uploaded, err := intent.UploadBytes(data, uploadMimeType) uploaded, err := intent.UploadBytes(data, uploadMimeType)
if err != nil { if err != nil {
httpErr := err.(mautrix.HTTPError) if errors.Is(err, mautrix.MTooLarge) {
if httpErr.Code == 413 { portal.sendMediaBridgeFailure(source, intent, msg.info, errors.New("homeserver rejected too large file"))
portal.sendMediaBridgeFailure(source, intent, msg.info, errors.New("server rejected too large file")) } else if httpErr := err.(mautrix.HTTPError); httpErr.IsStatus(413) {
portal.sendMediaBridgeFailure(source, intent, msg.info, errors.New("proxy rejected too large file"))
} else { } else {
portal.sendMediaBridgeFailure(source, intent, msg.info, errors.Wrap(err, "failed to upload media")) portal.sendMediaBridgeFailure(source, intent, msg.info, errors.Wrap(err, "failed to upload media"))
} }
@ -2100,7 +2101,7 @@ func (portal *Portal) Cleanup(puppetsOnly bool) {
portal.log.Errorln("Failed to get portal members for cleanup:", err) portal.log.Errorln("Failed to get portal members for cleanup:", err)
return return
} }
for member, _ := range members.Joined { for member := range members.Joined {
if member == intent.UserID { if member == intent.UserID {
continue continue
} }

View file

@ -18,6 +18,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"sort" "sort"
@ -26,7 +27,6 @@ import (
"sync" "sync"
"time" "time"
"github.com/pkg/errors"
"github.com/skip2/go-qrcode" "github.com/skip2/go-qrcode"
log "maunium.net/go/maulogger/v2" log "maunium.net/go/maulogger/v2"
@ -683,7 +683,7 @@ func (user *User) updateLastConnectionIfNecessary() {
} }
func (user *User) HandleError(err error) { func (user *User) HandleError(err error) {
if errors.Cause(err) != whatsapp.ErrInvalidWsData { if !errors.Is(err, whatsapp.ErrInvalidWsData) {
user.log.Errorfln("WhatsApp error: %v", err) user.log.Errorfln("WhatsApp error: %v", err)
} }
if closed, ok := err.(*whatsapp.ErrConnectionClosed); ok { if closed, ok := err.(*whatsapp.ErrConnectionClosed); ok {