Skip to content

Commit

Permalink
handlesignal: bridge decryption errors
Browse files Browse the repository at this point in the history
  • Loading branch information
tulir committed Sep 9, 2024
1 parent ea8208b commit 798ebb6
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 18 deletions.
61 changes: 49 additions & 12 deletions pkg/connector/handlesignal.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"maunium.net/go/mautrix/bridgev2"
"maunium.net/go/mautrix/bridgev2/database"
"maunium.net/go/mautrix/bridgev2/networkid"
"maunium.net/go/mautrix/bridgev2/simplevent"
"maunium.net/go/mautrix/event"

"go.mau.fi/mautrix-signal/pkg/signalid"
Expand All @@ -40,6 +41,7 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) {
case *events.ChatEvent:
s.Main.Bridge.QueueRemoteEvent(s.UserLogin, &Bv2ChatEvent{ChatEvent: evt, s: s})
case *events.DecryptionError:
s.Main.Bridge.QueueRemoteEvent(s.UserLogin, s.wrapDecryptionError(evt))
case *events.Receipt:
s.handleSignalReceipt(evt)
case *events.ReadSelf:
Expand All @@ -54,19 +56,22 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) {
}

func (s *SignalClient) wrapCallEvent(evt *events.Call) bridgev2.RemoteMessage {
return &bridgev2.SimpleRemoteEvent[*events.Call]{
Type: bridgev2.RemoteEventMessage,
LogContext: func(c zerolog.Context) zerolog.Context {
c = c.Stringer("sender_id", evt.Info.Sender)
c = c.Uint64("message_ts", evt.Timestamp)
return c
return &simplevent.Message[*events.Call]{
EventMeta: simplevent.EventMeta{
Type: bridgev2.RemoteEventMessage,
LogContext: func(c zerolog.Context) zerolog.Context {
c = c.Stringer("sender_id", evt.Info.Sender)
c = c.Uint64("message_ts", evt.Timestamp)
return c
},
PortalKey: s.makePortalKey(evt.Info.ChatID),
CreatePortal: true,
Sender: s.makeEventSender(evt.Info.Sender),
Timestamp: time.UnixMilli(int64(evt.Timestamp)),
},
PortalKey: s.makePortalKey(evt.Info.ChatID),
Data: evt,
CreatePortal: true,
ID: signalid.MakeMessageID(evt.Info.Sender, evt.Timestamp),
Sender: s.makeEventSender(evt.Info.Sender),
Timestamp: time.UnixMilli(int64(evt.Timestamp)),
Data: evt,
ID: signalid.MakeMessageID(evt.Info.Sender, evt.Timestamp),

ConvertMessageFunc: convertCallEvent,
}
}
Expand All @@ -91,6 +96,38 @@ func convertCallEvent(ctx context.Context, portal *bridgev2.Portal, intent bridg
}, nil
}

func (s *SignalClient) wrapDecryptionError(evt *events.DecryptionError) bridgev2.RemoteMessage {
return &simplevent.Message[*events.DecryptionError]{
EventMeta: simplevent.EventMeta{
Type: bridgev2.RemoteEventMessage,
LogContext: func(c zerolog.Context) zerolog.Context {
c = c.Stringer("sender_id", evt.Sender)
return c
},
PortalKey: s.makePortalKey(evt.Sender.String()),
CreatePortal: true,
Sender: s.makeEventSender(evt.Sender),
Timestamp: time.UnixMilli(int64(evt.Timestamp)),
},
Data: evt,
ID: "decrypterr|" + signalid.MakeMessageID(evt.Sender, evt.Timestamp),

ConvertMessageFunc: convertDecryptionError,
}
}

func convertDecryptionError(_ context.Context, _ *bridgev2.Portal, _ bridgev2.MatrixAPI, _ *events.DecryptionError) (*bridgev2.ConvertedMessage, error) {
return &bridgev2.ConvertedMessage{
Parts: []*bridgev2.ConvertedMessagePart{{
Type: event.EventMessage,
Content: &event.MessageEventContent{
MsgType: event.MsgNotice,
Body: "Message couldn't be decrypted. It may have been in this chat or a group chat. Please check your Signal app.",
},
}},
}, nil
}

type Bv2ChatEvent struct {
*events.ChatEvent
s *SignalClient
Expand Down
5 changes: 3 additions & 2 deletions pkg/signalmeow/events/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ type ChatEvent struct {
}

type DecryptionError struct {
Sender uuid.UUID
Err error
Sender uuid.UUID
Err error
Timestamp uint64
}

type Receipt struct {
Expand Down
11 changes: 7 additions & 4 deletions pkg/signalmeow/receiving.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb.
destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId())
log.Trace().
Uint64("timestamp", envelope.GetTimestamp()).
Uint64("server_timestamp", envelope.GetServerTimestamp()).
Str("destination_service_id", envelope.GetDestinationServiceId()).
Str("source_service_id", envelope.GetSourceServiceId()).
Uint32("source_device_id", envelope.GetSourceDevice()).
Expand All @@ -286,7 +287,7 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb.

result := cli.decryptEnvelope(ctx, envelope)

err = cli.handleDecryptedResult(ctx, result, destinationServiceID)
err = cli.handleDecryptedResult(ctx, result, destinationServiceID, envelope.GetServerTimestamp())
if err != nil {
log.Err(err).Msg("handleDecryptedResult error")
return nil, err
Expand Down Expand Up @@ -613,6 +614,7 @@ func (cli *Client) handleDecryptedResult(
ctx context.Context,
result DecryptionResult,
destinationServiceID libsignalgo.ServiceID,
serverTimestamp uint64,
) error {
log := zerolog.Ctx(ctx)
if result.Content == nil {
Expand All @@ -623,19 +625,20 @@ func (cli *Client) handleDecryptedResult(
// result.Err is set if there was an error during decryption and we
// should notifiy the user that the message could not be decrypted
if result.Err != nil {
log.Err(result.Err).Bool("urgent", result.Urgent).Msg("Decryption error")
theirServiceID, err := result.SenderAddress.NameServiceID()
if err != nil {
log.Err(err).Msg("Name error handling decryption error")
} else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI {
log.Warn().Any("their_service_id", theirServiceID).Msg("Sender ServiceID is not an ACI")
}
log.Err(result.Err).Stringer("sender", theirServiceID).Bool("urgent", result.Urgent).Msg("Decryption error")
// Only send decryption error event if the message was urgent,
// to prevent spamming errors for typing notifications and whatnot
if result.Urgent {
cli.handleEvent(&events.DecryptionError{
Sender: theirServiceID.UUID,
Err: result.Err,
Sender: theirServiceID.UUID,
Err: result.Err,
Timestamp: serverTimestamp,
})
}
// Intentionally not returning here. In most cases there's nothing besides the error so
Expand Down

0 comments on commit 798ebb6

Please sign in to comment.