armadillomessage.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright (c) 2024 Tulir Asokan
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. package whatsmeow
  7. import (
  8. "context"
  9. "fmt"
  10. "google.golang.org/protobuf/proto"
  11. armadillo "go.mau.fi/whatsmeow/proto"
  12. "go.mau.fi/whatsmeow/proto/armadilloutil"
  13. "go.mau.fi/whatsmeow/proto/instamadilloTransportPayload"
  14. "go.mau.fi/whatsmeow/proto/waCommon"
  15. "go.mau.fi/whatsmeow/proto/waMsgApplication"
  16. "go.mau.fi/whatsmeow/proto/waMsgTransport"
  17. "go.mau.fi/whatsmeow/types"
  18. "go.mau.fi/whatsmeow/types/events"
  19. )
  20. func (cli *Client) handleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handlerFailed, protobufFailed bool) {
  21. dec, err := decodeArmadillo(decrypted)
  22. if err != nil {
  23. cli.Log.Warnf("Failed to decode armadillo message from %s: %v", info.SourceString(), err)
  24. protobufFailed = true
  25. return
  26. }
  27. dec.Info = *info
  28. dec.RetryCount = retryCount
  29. if dec.Transport.GetProtocol().GetAncillary().GetSkdm() != nil {
  30. if !info.IsGroup {
  31. cli.Log.Warnf("Got sender key distribution message in non-group chat from %s", info.Sender)
  32. } else {
  33. skdm := dec.Transport.GetProtocol().GetAncillary().GetSkdm()
  34. cli.handleSenderKeyDistributionMessage(ctx, info.Chat, info.Sender, skdm.AxolotlSenderKeyDistributionMessage)
  35. }
  36. }
  37. if dec.Message != nil || dec.FBApplication != nil {
  38. handlerFailed = cli.dispatchEvent(&dec)
  39. }
  40. return
  41. }
  42. func decodeArmadillo(data []byte) (dec events.FBMessage, err error) {
  43. var transport waMsgTransport.MessageTransport
  44. err = proto.Unmarshal(data, &transport)
  45. if err != nil {
  46. return dec, fmt.Errorf("failed to unmarshal transport: %w", err)
  47. }
  48. dec.Transport = &transport
  49. if transport.GetPayload() == nil {
  50. return
  51. }
  52. appPayloadVer := transport.GetPayload().GetApplicationPayload().GetVersion()
  53. switch appPayloadVer {
  54. case waMsgTransport.FBMessageApplicationVersion:
  55. return decodeFBArmadillo(&transport)
  56. case waMsgTransport.IGMessageApplicationVersion:
  57. return decodeIGArmadillo(&transport)
  58. default:
  59. return dec, fmt.Errorf("%w %d in MessageTransport", armadilloutil.ErrUnsupportedVersion, appPayloadVer)
  60. }
  61. }
  62. func decodeFBArmadillo(transport *waMsgTransport.MessageTransport) (dec events.FBMessage, err error) {
  63. var application *waMsgApplication.MessageApplication
  64. application, err = transport.GetPayload().DecodeFB()
  65. if err != nil {
  66. return dec, fmt.Errorf("failed to unmarshal application: %w", err)
  67. }
  68. dec.FBApplication = application
  69. if application.GetPayload() == nil {
  70. return
  71. }
  72. switch typedContent := application.GetPayload().GetContent().(type) {
  73. case *waMsgApplication.MessageApplication_Payload_CoreContent:
  74. err = fmt.Errorf("unsupported core content payload")
  75. case *waMsgApplication.MessageApplication_Payload_Signal:
  76. err = fmt.Errorf("unsupported signal payload")
  77. case *waMsgApplication.MessageApplication_Payload_ApplicationData:
  78. err = fmt.Errorf("unsupported application data payload")
  79. case *waMsgApplication.MessageApplication_Payload_SubProtocol:
  80. var protoMsg proto.Message
  81. var subData *waCommon.SubProtocol
  82. switch subProtocol := typedContent.SubProtocol.GetSubProtocol().(type) {
  83. case *waMsgApplication.MessageApplication_SubProtocolPayload_ConsumerMessage:
  84. dec.Message, err = subProtocol.Decode()
  85. case *waMsgApplication.MessageApplication_SubProtocolPayload_BusinessMessage:
  86. dec.Message = (*armadillo.Unsupported_BusinessApplication)(subProtocol.BusinessMessage)
  87. case *waMsgApplication.MessageApplication_SubProtocolPayload_PaymentMessage:
  88. dec.Message = (*armadillo.Unsupported_PaymentApplication)(subProtocol.PaymentMessage)
  89. case *waMsgApplication.MessageApplication_SubProtocolPayload_MultiDevice:
  90. dec.Message, err = subProtocol.Decode()
  91. case *waMsgApplication.MessageApplication_SubProtocolPayload_Voip:
  92. dec.Message = (*armadillo.Unsupported_Voip)(subProtocol.Voip)
  93. case *waMsgApplication.MessageApplication_SubProtocolPayload_Armadillo:
  94. dec.Message, err = subProtocol.Decode()
  95. default:
  96. return dec, fmt.Errorf("unsupported subprotocol type: %T", subProtocol)
  97. }
  98. if protoMsg != nil {
  99. err = proto.Unmarshal(subData.GetPayload(), protoMsg)
  100. if err != nil {
  101. return dec, fmt.Errorf("failed to unmarshal application subprotocol payload (%T v%d): %w", protoMsg, subData.GetVersion(), err)
  102. }
  103. }
  104. default:
  105. err = fmt.Errorf("unsupported application payload content type: %T", typedContent)
  106. }
  107. return
  108. }
  109. func decodeIGArmadillo(transport *waMsgTransport.MessageTransport) (dec events.FBMessage, err error) {
  110. innerTransport, err := transport.GetPayload().DecodeIG()
  111. if err != nil {
  112. return dec, fmt.Errorf("failed to unmarshal IG transport: %w", err)
  113. }
  114. dec.IGTransport = innerTransport
  115. switch typedContent := innerTransport.GetTransportPayload().(type) {
  116. case *instamadilloTransportPayload.TransportPayload_Add:
  117. dec.Message = typedContent.Add
  118. case *instamadilloTransportPayload.TransportPayload_Supplement:
  119. dec.Message = typedContent.Supplement
  120. case *instamadilloTransportPayload.TransportPayload_Delete:
  121. dec.Message = typedContent.Delete
  122. }
  123. return
  124. }