diff options
Diffstat (limited to 'vendor/go.mau.fi/whatsmeow/message.go')
-rw-r--r-- | vendor/go.mau.fi/whatsmeow/message.go | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/vendor/go.mau.fi/whatsmeow/message.go b/vendor/go.mau.fi/whatsmeow/message.go index 3238ba90..85ccb12b 100644 --- a/vendor/go.mau.fi/whatsmeow/message.go +++ b/vendor/go.mau.fi/whatsmeow/message.go @@ -13,7 +13,9 @@ import ( "errors" "fmt" "io" + "runtime/debug" "strconv" + "sync/atomic" "time" "go.mau.fi/libsignal/signalerror" @@ -162,6 +164,18 @@ func (cli *Client) decryptMessages(info *types.MessageInfo, node *waBinary.Node) } } +func (cli *Client) clearUntrustedIdentity(target types.JID) { + err := cli.Store.Identities.DeleteIdentity(target.SignalAddress().String()) + if err != nil { + cli.Log.Warnf("Failed to delete untrusted identity of %s from store: %v", target, err) + } + err = cli.Store.Sessions.DeleteSession(target.SignalAddress().String()) + if err != nil { + cli.Log.Warnf("Failed to delete session with %s (untrusted identity) from store: %v", target, err) + } + cli.dispatchEvent(&events.IdentityChange{JID: target, Timestamp: time.Now(), Implicit: true}) +} + func (cli *Client) decryptDM(child *waBinary.Node, from types.JID, isPreKey bool) ([]byte, error) { content, _ := child.Content.([]byte) @@ -174,17 +188,9 @@ func (cli *Client) decryptDM(child *waBinary.Node, from types.JID, isPreKey bool return nil, fmt.Errorf("failed to parse prekey message: %w", err) } plaintext, _, err = cipher.DecryptMessageReturnKey(preKeyMsg) - if errors.Is(err, signalerror.ErrUntrustedIdentity) { + if cli.AutoTrustIdentity && errors.Is(err, signalerror.ErrUntrustedIdentity) { cli.Log.Warnf("Got %v error while trying to decrypt prekey message from %s, clearing stored identity and retrying", err, from) - err = cli.Store.Identities.DeleteIdentity(from.SignalAddress().String()) - if err != nil { - cli.Log.Warnf("Failed to delete identity of %s from store after decryption error: %v", from, err) - } - err = cli.Store.Sessions.DeleteSession(from.SignalAddress().String()) - if err != nil { - cli.Log.Warnf("Failed to delete session with %s from store after decryption error: %v", from, err) - } - cli.dispatchEvent(&events.IdentityChange{JID: from, Timestamp: time.Now(), Implicit: true}) + cli.clearUntrustedIdentity(from) plaintext, _, err = cipher.DecryptMessageReturnKey(preKeyMsg) } if err != nil { @@ -261,6 +267,26 @@ func (cli *Client) handleSenderKeyDistributionMessage(chat, from types.JID, rawS cli.Log.Debugf("Processed sender key distribution message from %s in %s", senderKeyName.Sender().String(), senderKeyName.GroupID()) } +func (cli *Client) handleHistorySyncNotificationLoop() { + defer func() { + atomic.StoreUint32(&cli.historySyncHandlerStarted, 0) + err := recover() + if err != nil { + cli.Log.Errorf("History sync handler panicked: %v\n%s", err, debug.Stack()) + } + + // Check in case something new appeared in the channel between the loop stopping + // and the atomic variable being updated. If yes, restart the loop. + if len(cli.historySyncNotifications) > 0 && atomic.CompareAndSwapUint32(&cli.historySyncHandlerStarted, 0, 1) { + cli.Log.Warnf("New history sync notifications appeared after loop stopped, restarting loop...") + go cli.handleHistorySyncNotificationLoop() + } + }() + for notif := range cli.historySyncNotifications { + cli.handleHistorySyncNotification(notif) + } +} + func (cli *Client) handleHistorySyncNotification(notif *waProto.HistorySyncNotification) { var historySync waProto.HistorySync if data, err := cli.Download(notif); err != nil { @@ -272,7 +298,7 @@ func (cli *Client) handleHistorySyncNotification(notif *waProto.HistorySyncNotif } else if err = proto.Unmarshal(rawData, &historySync); err != nil { cli.Log.Errorf("Failed to unmarshal history sync data: %v", err) } else { - cli.Log.Debugf("Received history sync") + cli.Log.Debugf("Received history sync (type %s, chunk %d)", historySync.GetSyncType(), historySync.GetChunkOrder()) if historySync.GetSyncType() == waProto.HistorySync_PUSH_NAME { go cli.handleHistoricalPushNames(historySync.GetPushnames()) } @@ -314,16 +340,19 @@ func (cli *Client) handleProtocolMessage(info *types.MessageInfo, msg *waProto.M protoMsg := msg.GetProtocolMessage() if protoMsg.GetHistorySyncNotification() != nil && info.IsFromMe { - cli.handleHistorySyncNotification(protoMsg.HistorySyncNotification) - cli.sendProtocolMessageReceipt(info.ID, "hist_sync") + cli.historySyncNotifications <- protoMsg.HistorySyncNotification + if atomic.CompareAndSwapUint32(&cli.historySyncHandlerStarted, 0, 1) { + go cli.handleHistorySyncNotificationLoop() + } + go cli.sendProtocolMessageReceipt(info.ID, "hist_sync") } if protoMsg.GetAppStateSyncKeyShare() != nil && info.IsFromMe { - cli.handleAppStateSyncKeyShare(protoMsg.AppStateSyncKeyShare) + go cli.handleAppStateSyncKeyShare(protoMsg.AppStateSyncKeyShare) } if info.Category == "peer" { - cli.sendProtocolMessageReceipt(info.ID, "peer_msg") + go cli.sendProtocolMessageReceipt(info.ID, "peer_msg") } } @@ -347,7 +376,7 @@ func (cli *Client) handleDecryptedMessage(info *types.MessageInfo, msg *waProto. } } if msg.GetProtocolMessage() != nil { - go cli.handleProtocolMessage(info, msg) + cli.handleProtocolMessage(info, msg) } // Unwrap ephemeral and view-once messages |