Skip to content

Commit

Permalink
signalmeow/receiving: handle sync messages sent to PNIs properly
Browse files Browse the repository at this point in the history
* store destination E.164 numbers received in sync messages
* fetch PNI identity from server if it isn't found in database when handling
  PNI signature message
  • Loading branch information
tulir committed Jul 14, 2024
1 parent 41a7187 commit e627ad8
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
12 changes: 2 additions & 10 deletions pkg/connector/chatinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (
return s.contactToUserInfo(contact), nil
}

func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.PortalInfo, error) {
func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.ChatInfo, error) {
userID, groupID, err := parsePortalID(portal.ID)
if err != nil {
return nil, err
}
if groupID != "" {
return s.getGroupInfo(ctx, groupID, 0)
} else {
aci, pni := serviceIDToACIAndPNI(userID)
aci, pni := userID.ToACIAndPNI()
contact, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil)
if err != nil {
return nil, err
Expand Down Expand Up @@ -251,11 +251,3 @@ func makeAvatarPathID(avatarPath string) networkid.AvatarID {
}
return networkid.AvatarID("path:" + avatarPath)
}

func serviceIDToACIAndPNI(serviceID libsignalgo.ServiceID) (aci, pni uuid.UUID) {
if serviceID.Type == libsignalgo.ServiceIDTypeACI {
return serviceID.UUID, uuid.Nil
} else {
return uuid.Nil, serviceID.UUID
}
}
8 changes: 8 additions & 0 deletions pkg/libsignalgo/serviceid.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ func NewACIServiceID(uuid uuid.UUID) ServiceID {
}
}

func (s ServiceID) ToACIAndPNI() (aci, pni uuid.UUID) {
if s.Type == ServiceIDTypeACI {
return s.UUID, uuid.Nil
} else {
return uuid.Nil, s.UUID
}
}

func (s ServiceID) IsEmpty() bool {
return s.UUID == uuid.Nil
}
Expand Down
20 changes: 19 additions & 1 deletion pkg/signalmeow/receiving.go
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,13 @@ func (cli *Client) handleDecryptedResult(
log.Err(err).Msg("Sync message destination parse error")
return err
}
if syncSent.GetDestinationE164() != "" {
aci, pni := syncDestinationServiceID.ToACIAndPNI()
_, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, syncSent.GetDestinationE164())
if err != nil {
log.Err(err).Msg("Failed to update recipient E164 after receiving sync message")
}
}
}
if destination == nil && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil {
log.Warn().Msg("sync message sent destination is nil")
Expand Down Expand Up @@ -913,7 +920,18 @@ func (cli *Client) handlePNISignatureMessage(ctx context.Context, sender libsign
if err != nil {
return fmt.Errorf("failed to get identity for PNI %s: %w", pni, err)
} else if pniIdentity == nil {
return fmt.Errorf("identity not found for PNI %s", pni)
zerolog.Ctx(ctx).Debug().
Stringer("aci", sender.UUID).
Stringer("pni", pni).
Msg("Fetching PNI identity for signature verification as it wasn't found in store")
err = cli.FetchAndProcessPreKey(ctx, pniServiceID, 0)
if err != nil {
return fmt.Errorf("failed to fetch prekey for PNI %s after identity wasn't found in store: %w", pni, err)
} else if pniIdentity, err = cli.Store.IdentityKeyStore.GetIdentityKey(ctx, pniServiceID); err != nil {
return fmt.Errorf("failed to get identity for PNI %s after fetching: %w", pni, err)
} else if pniIdentity == nil {
return fmt.Errorf("identity not found for PNI %s even after fetching", pni)
}
}
aciIdentity, err := cli.Store.IdentityKeyStore.GetIdentityKey(ctx, sender)
if err != nil {
Expand Down

0 comments on commit e627ad8

Please sign in to comment.