Преглед изворни кода

fix missing ICQ 5 authorization message

ICQ 5 hides authorization messages when the message string contains
more than 1 period. This is fixed by removing all periods that
follow the first.

I suspect ICQ 5 encodes additional information in its authorization
message because the authorization dialog displays empty Nick and
Email fields, which might be encoded in the string as a hack or in
undocumented SNAC fields.

The server also throws a spam report upon receiving an authorization,
which crashes the client session because the spam report subquery
is unsupported.

Unsupported subtypes sometimes pop and reset the client's connection.
Because these subtypes are usually for telemetry, it's OK to just
silently ignore them.
Mike пре 1 месец
родитељ
комит
a01f295cf2
4 измењених фајлова са 61 додато и 23 уклоњено
  1. 7 1
      foodgroup/feedbag.go
  2. 49 3
      foodgroup/feedbag_test.go
  3. 4 18
      server/oscar/handler.go
  4. 1 1
      server/oscar/handler_test.go

+ 7 - 1
foodgroup/feedbag.go

@@ -564,12 +564,18 @@ func (s *FeedbagService) RequestAuthorizeToHost(ctx context.Context, instance *s
 	useFeedbag := recipSess != nil && recipSess.UsesFeedbag()
 
 	if useFeedbag {
+		firstDot := strings.IndexByte(inBody.Reason, '.')
+		if firstDot >= 0 {
+			// ICQ 5 ignores authorization requests with multiple periods. Strip
+			// all periods following the first so that the message arrives.
+			inBody.Reason = inBody.Reason[:firstDot+1] + strings.ReplaceAll(inBody.Reason[firstDot+1:], ".", "")
+		}
 		s.messageRelayer.RelayToScreenName(ctx, recipient, wire.SNACMessage{
 			Frame: wire.SNACFrame{
 				FoodGroup: wire.Feedbag,
 				SubGroup:  wire.FeedbagRequestAuthorizeToClient,
 			},
-			Body: wire.SNAC_0x13_0x18_FeedbagRequestAuthorizationToHost{
+			Body: wire.SNAC_0x13_0x19_FeedbagRequestAuthorizeToClient{
 				ScreenName: instance.IdentScreenName().String(),
 				Reason:     inBody.Reason,
 			},

+ 49 - 3
foodgroup/feedbag_test.go

@@ -2983,7 +2983,7 @@ func TestFeedbagService_RequestAuthorizeToHost(t *testing.T) {
 				},
 				Body: wire.SNAC_0x13_0x18_FeedbagRequestAuthorizationToHost{
 					ScreenName: "100002",
-					Reason:     "please add me",
+					Reason:     "please add me.",
 				},
 			},
 			buddySess: func() *state.Session {
@@ -3007,9 +3007,55 @@ func TestFeedbagService_RequestAuthorizeToHost(t *testing.T) {
 									FoodGroup: wire.Feedbag,
 									SubGroup:  wire.FeedbagRequestAuthorizeToClient,
 								},
-								Body: wire.SNAC_0x13_0x18_FeedbagRequestAuthorizationToHost{
+								Body: wire.SNAC_0x13_0x19_FeedbagRequestAuthorizeToClient{
 									ScreenName: "100001",
-									Reason:     "please add me",
+									Reason:     "please add me.",
+								},
+							},
+						},
+					},
+				},
+			},
+			expectICBM: false,
+		},
+		{
+			name:     "ICQ 5 authorization failure workaround: remove periods following first from reason",
+			instance: newTestInstance("100001", sessOptUIN(100001)),
+			inSNAC: wire.SNACMessage{
+				Frame: wire.SNACFrame{
+					FoodGroup: wire.Feedbag,
+					SubGroup:  wire.FeedbagRequestAuthorizeToHost,
+					RequestID: 1234,
+				},
+				Body: wire.SNAC_0x13_0x18_FeedbagRequestAuthorizationToHost{
+					ScreenName: "100002",
+					Reason:     "Please authorize my request and add me to your Contact List. yuki.tanaka ICQ#: 123405",
+				},
+			},
+			buddySess: func() *state.Session {
+				s := state.NewSession()
+				s.SetIdentScreenName(state.NewIdentScreenName("100002"))
+				s.SetUsesFeedbag()
+				return s
+			}(),
+			mockParams: mockParams{
+				sessionRetrieverParams: sessionRetrieverParams{
+					retrieveSessionParams: retrieveSessionParams{
+						{screenName: state.NewIdentScreenName("100002")},
+					},
+				},
+				messageRelayerParams: messageRelayerParams{
+					relayToScreenNameParams: relayToScreenNameParams{
+						{
+							screenName: state.NewIdentScreenName("100002"),
+							message: wire.SNACMessage{
+								Frame: wire.SNACFrame{
+									FoodGroup: wire.Feedbag,
+									SubGroup:  wire.FeedbagRequestAuthorizeToClient,
+								},
+								Body: wire.SNAC_0x13_0x19_FeedbagRequestAuthorizeToClient{
+									ScreenName: "100001",
+									Reason:     "Please authorize my request and add me to your Contact List. yukitanaka ICQ#: 123405",
 								},
 							},
 						},

+ 4 - 18
server/oscar/handler.go

@@ -18,9 +18,8 @@ import (
 var (
 	// ErrRouteNotFound is an error that indicates a failure to find a matching
 	// route for an OSCAR protocol request.
-	ErrRouteNotFound            = errors.New("route not found")
-	errUnknownICQMetaReqType    = errors.New("unknown ICQ request type")
-	errUnknownICQMetaReqSubType = errors.New("unknown ICQ metadata request subtype")
+	ErrRouteNotFound         = errors.New("route not found")
+	errUnknownICQMetaReqType = errors.New("unknown ICQ request type")
 )
 
 // ResponseWriter is the interface for sending a SNAC response to the client
@@ -694,22 +693,9 @@ func (rt Handler) ICQDBQuery(ctx context.Context, instance *state.SessionInstanc
 			if err := rt.SetICQInfo(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
 				return err
 			}
-		case wire.ICQDBQueryMetaReqStat0a8c,
-			wire.ICQDBQueryMetaReqStat0a96,
-			wire.ICQDBQueryMetaReqStat0aaa,
-			wire.ICQDBQueryMetaReqStat0ab4,
-			wire.ICQDBQueryMetaReqStat0ab9,
-			wire.ICQDBQueryMetaReqStat0abe,
-			wire.ICQDBQueryMetaReqStat0ac8,
-			wire.ICQDBQueryMetaReqStat0acd,
-			wire.ICQDBQueryMetaReqStat0ad2,
-			wire.ICQDBQueryMetaReqStat0ad7,
-			wire.ICQDBQueryMetaReqStat0758:
-			rt.Logger.Debug("got a request for stats, not doing anything right now")
-		case wire.ICQDBQueryMetaReqDirectoryQuery, wire.ICQDBQueryMetaReqDirectoryUpdate:
-			rt.Logger.Debug("got a directory query/update request, not implemented yet")
 		default:
-			return fmt.Errorf("%w: %X", errUnknownICQMetaReqSubType, icqMD.Optional.ReqSubType)
+			rt.Logger.Debug("unsupported ICQDBQueryMetaReqType", "type", icqMD.Optional.ReqSubType)
+			return nil
 		}
 	default:
 		return fmt.Errorf("%w: %X", errUnknownICQMetaReqType, icqMD.ReqType)

+ 1 - 1
server/oscar/handler_test.go

@@ -3679,7 +3679,7 @@ func TestHandler_ICQDBQuery(t *testing.T) {
 					},
 				},
 				seq:     1,
-				wantErr: errUnknownICQMetaReqSubType,
+				wantErr: nil,
 			},
 		},
 		{