FreeRDP
rts_signature.c
1 
20 #include <winpr/assert.h>
21 #include <winpr/stream.h>
22 
23 #include <freerdp/log.h>
24 
25 #include "rts_signature.h"
26 
27 #define TAG FREERDP_TAG("core.gateway.rts")
28 
29 const RtsPduSignature RTS_PDU_CONN_A1_SIGNATURE = {
30  RTS_FLAG_NONE,
31  4,
32  { RTS_CMD_VERSION, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_RECEIVE_WINDOW_SIZE, 0, 0, 0, 0 }
33 };
34 const RtsPduSignature RTS_PDU_CONN_A2_SIGNATURE = { RTS_FLAG_OUT_CHANNEL,
35  5,
36  { RTS_CMD_VERSION, RTS_CMD_COOKIE,
37  RTS_CMD_COOKIE, RTS_CMD_CHANNEL_LIFETIME,
38  RTS_CMD_RECEIVE_WINDOW_SIZE, 0, 0, 0 } };
39 const RtsPduSignature RTS_PDU_CONN_A3_SIGNATURE = {
40  RTS_FLAG_NONE, 1, { RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0, 0, 0 }
41 };
42 
43 const RtsPduSignature RTS_PDU_CONN_B1_SIGNATURE = {
44  RTS_FLAG_NONE,
45  6,
46  { RTS_CMD_VERSION, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_CHANNEL_LIFETIME,
47  RTS_CMD_CLIENT_KEEPALIVE, RTS_CMD_ASSOCIATION_GROUP_ID, 0, 0 }
48 };
49 const RtsPduSignature RTS_PDU_CONN_B2_SIGNATURE = {
50  RTS_FLAG_IN_CHANNEL,
51  7,
52  { RTS_CMD_VERSION, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_RECEIVE_WINDOW_SIZE,
53  RTS_CMD_CONNECTION_TIMEOUT, RTS_CMD_ASSOCIATION_GROUP_ID, RTS_CMD_CLIENT_ADDRESS, 0 }
54 };
55 const RtsPduSignature RTS_PDU_CONN_B3_SIGNATURE = {
56  RTS_FLAG_NONE, 2, { RTS_CMD_RECEIVE_WINDOW_SIZE, RTS_CMD_VERSION, 0, 0, 0, 0, 0, 0 }
57 };
58 
59 const RtsPduSignature RTS_PDU_CONN_C1_SIGNATURE = { RTS_FLAG_NONE,
60  3,
61  { RTS_CMD_VERSION, RTS_CMD_RECEIVE_WINDOW_SIZE,
62  RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0 } };
63 const RtsPduSignature RTS_PDU_CONN_C2_SIGNATURE = { RTS_FLAG_NONE,
64  3,
65  { RTS_CMD_VERSION, RTS_CMD_RECEIVE_WINDOW_SIZE,
66  RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0 } };
67 
68 const RtsPduSignature RTS_PDU_IN_R1_A1_SIGNATURE = {
69  RTS_FLAG_RECYCLE_CHANNEL,
70  4,
71  { RTS_CMD_VERSION, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_COOKIE, 0, 0, 0, 0 }
72 };
73 const RtsPduSignature RTS_PDU_IN_R1_A2_SIGNATURE = {
74  RTS_FLAG_NONE,
75  4,
76  { RTS_CMD_VERSION, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_RECEIVE_WINDOW_SIZE,
77  RTS_CMD_CONNECTION_TIMEOUT, 0, 0 }
78 };
79 const RtsPduSignature RTS_PDU_IN_R1_A3_SIGNATURE = { RTS_FLAG_NONE,
80  4,
81  { RTS_CMD_DESTINATION, RTS_CMD_VERSION,
82  RTS_CMD_RECEIVE_WINDOW_SIZE,
83  RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0 } };
84 const RtsPduSignature RTS_PDU_IN_R1_A4_SIGNATURE = { RTS_FLAG_NONE,
85  4,
86  { RTS_CMD_DESTINATION, RTS_CMD_VERSION,
87  RTS_CMD_RECEIVE_WINDOW_SIZE,
88  RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0 } };
89 const RtsPduSignature RTS_PDU_IN_R1_A5_SIGNATURE = { RTS_FLAG_NONE,
90  1,
91  { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
92 const RtsPduSignature RTS_PDU_IN_R1_A6_SIGNATURE = { RTS_FLAG_NONE,
93  1,
94  { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
95 
96 const RtsPduSignature RTS_PDU_IN_R1_B1_SIGNATURE = { RTS_FLAG_NONE,
97  1,
98  { RTS_CMD_EMPTY, 0, 0, 0, 0, 0, 0, 0 } };
99 const RtsPduSignature RTS_PDU_IN_R1_B2_SIGNATURE = {
100  RTS_FLAG_NONE, 1, { RTS_CMD_RECEIVE_WINDOW_SIZE, 0, 0, 0, 0, 0, 0, 0 }
101 };
102 
103 const RtsPduSignature RTS_PDU_IN_R2_A1_SIGNATURE = {
104  RTS_FLAG_RECYCLE_CHANNEL,
105  4,
106  { RTS_CMD_VERSION, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_COOKIE, 0, 0, 0, 0 }
107 };
108 const RtsPduSignature RTS_PDU_IN_R2_A2_SIGNATURE = { RTS_FLAG_NONE,
109  1,
110  { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
111 const RtsPduSignature RTS_PDU_IN_R2_A3_SIGNATURE = { RTS_FLAG_NONE,
112  1,
113  { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 } };
114 const RtsPduSignature RTS_PDU_IN_R2_A4_SIGNATURE = { RTS_FLAG_NONE,
115  1,
116  { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 } };
117 const RtsPduSignature RTS_PDU_IN_R2_A5_SIGNATURE = { RTS_FLAG_NONE,
118  1,
119  { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
120 
121 const RtsPduSignature RTS_PDU_OUT_R1_A1_SIGNATURE = {
122  RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
123 };
124 const RtsPduSignature RTS_PDU_OUT_R1_A2_SIGNATURE = {
125  RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
126 };
127 const RtsPduSignature RTS_PDU_OUT_R1_A3_SIGNATURE = { RTS_FLAG_RECYCLE_CHANNEL,
128  5,
129  { RTS_CMD_VERSION, RTS_CMD_COOKIE,
130  RTS_CMD_COOKIE, RTS_CMD_COOKIE,
131  RTS_CMD_RECEIVE_WINDOW_SIZE, 0, 0, 0 } };
132 const RtsPduSignature RTS_PDU_OUT_R1_A4_SIGNATURE = {
133  RTS_FLAG_RECYCLE_CHANNEL | RTS_FLAG_OUT_CHANNEL,
134  7,
135  { RTS_CMD_VERSION, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_CHANNEL_LIFETIME,
136  RTS_CMD_RECEIVE_WINDOW_SIZE, RTS_CMD_CONNECTION_TIMEOUT, 0 }
137 };
138 const RtsPduSignature RTS_PDU_OUT_R1_A5_SIGNATURE = {
139  RTS_FLAG_OUT_CHANNEL,
140  3,
141  { RTS_CMD_DESTINATION, RTS_CMD_VERSION, RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0 }
142 };
143 const RtsPduSignature RTS_PDU_OUT_R1_A6_SIGNATURE = {
144  RTS_FLAG_OUT_CHANNEL,
145  3,
146  { RTS_CMD_DESTINATION, RTS_CMD_VERSION, RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0 }
147 };
148 const RtsPduSignature RTS_PDU_OUT_R1_A7_SIGNATURE = {
149  RTS_FLAG_OUT_CHANNEL, 2, { RTS_CMD_DESTINATION, RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0 }
150 };
151 const RtsPduSignature RTS_PDU_OUT_R1_A8_SIGNATURE = {
152  RTS_FLAG_OUT_CHANNEL, 2, { RTS_CMD_DESTINATION, RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0 }
153 };
154 const RtsPduSignature RTS_PDU_OUT_R1_A9_SIGNATURE = { RTS_FLAG_NONE,
155  1,
156  { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
157 const RtsPduSignature RTS_PDU_OUT_R1_A10_SIGNATURE = { RTS_FLAG_NONE,
158  1,
159  { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
160 const RtsPduSignature RTS_PDU_OUT_R1_A11_SIGNATURE = { RTS_FLAG_NONE,
161  1,
162  { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
163 
164 const RtsPduSignature RTS_PDU_OUT_R2_A1_SIGNATURE = {
165  RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
166 };
167 const RtsPduSignature RTS_PDU_OUT_R2_A2_SIGNATURE = {
168  RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
169 };
170 const RtsPduSignature RTS_PDU_OUT_R2_A3_SIGNATURE = { RTS_FLAG_RECYCLE_CHANNEL,
171  5,
172  { RTS_CMD_VERSION, RTS_CMD_COOKIE,
173  RTS_CMD_COOKIE, RTS_CMD_COOKIE,
174  RTS_CMD_RECEIVE_WINDOW_SIZE, 0, 0, 0 } };
175 const RtsPduSignature RTS_PDU_OUT_R2_A4_SIGNATURE = { RTS_FLAG_NONE,
176  1,
177  { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
178 const RtsPduSignature RTS_PDU_OUT_R2_A5_SIGNATURE = {
179  RTS_FLAG_NONE, 2, { RTS_CMD_DESTINATION, RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0 }
180 };
181 const RtsPduSignature RTS_PDU_OUT_R2_A6_SIGNATURE = {
182  RTS_FLAG_NONE, 2, { RTS_CMD_DESTINATION, RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0 }
183 };
184 const RtsPduSignature RTS_PDU_OUT_R2_A7_SIGNATURE = {
185  RTS_FLAG_NONE, 3, { RTS_CMD_DESTINATION, RTS_CMD_COOKIE, RTS_CMD_VERSION, 0, 0, 0, 0, 0 }
186 };
187 const RtsPduSignature RTS_PDU_OUT_R2_A8_SIGNATURE = {
188  RTS_FLAG_OUT_CHANNEL, 2, { RTS_CMD_DESTINATION, RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0 }
189 };
190 
191 const RtsPduSignature RTS_PDU_OUT_R2_B1_SIGNATURE = { RTS_FLAG_NONE,
192  1,
193  { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
194 const RtsPduSignature RTS_PDU_OUT_R2_B2_SIGNATURE = {
195  RTS_FLAG_NONE, 1, { RTS_CMD_NEGATIVE_ANCE, 0, 0, 0, 0, 0, 0, 0 }
196 };
197 const RtsPduSignature RTS_PDU_OUT_R2_B3_SIGNATURE = { RTS_FLAG_EOF,
198  1,
199  { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
200 
201 const RtsPduSignature RTS_PDU_OUT_R2_C1_SIGNATURE = { RTS_FLAG_PING,
202  1,
203  { 0, 0, 0, 0, 0, 0, 0, 0 } };
204 
205 const RtsPduSignature RTS_PDU_KEEP_ALIVE_SIGNATURE = {
206  RTS_FLAG_OTHER_CMD, 1, { RTS_CMD_CLIENT_KEEPALIVE, 0, 0, 0, 0, 0, 0, 0 }
207 };
208 const RtsPduSignature RTS_PDU_PING_TRAFFIC_SENT_NOTIFY_SIGNATURE = {
209  RTS_FLAG_OTHER_CMD, 1, { RTS_CMD_PING_TRAFFIC_SENT_NOTIFY, 0, 0, 0, 0, 0, 0, 0 }
210 };
211 const RtsPduSignature RTS_PDU_ECHO_SIGNATURE = { RTS_FLAG_ECHO, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
212 const RtsPduSignature RTS_PDU_PING_SIGNATURE = { RTS_FLAG_PING, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
213 const RtsPduSignature RTS_PDU_FLOW_CONTROL_ACK_SIGNATURE = {
214  RTS_FLAG_OTHER_CMD, 1, { RTS_CMD_FLOW_CONTROL_ACK, 0, 0, 0, 0, 0, 0, 0 }
215 };
216 const RtsPduSignature RTS_PDU_FLOW_CONTROL_ACK_WITH_DESTINATION_SIGNATURE = {
217  RTS_FLAG_OTHER_CMD, 2, { RTS_CMD_DESTINATION, RTS_CMD_FLOW_CONTROL_ACK, 0, 0, 0, 0, 0, 0 }
218 };
219 
220 static const RTS_PDU_SIGNATURE_ENTRY RTS_PDU_SIGNATURE_TABLE[] = {
221  { RTS_PDU_CONN_A1, FALSE, &RTS_PDU_CONN_A1_SIGNATURE, "CONN/A1" },
222  { RTS_PDU_CONN_A2, FALSE, &RTS_PDU_CONN_A2_SIGNATURE, "CONN/A2" },
223  { RTS_PDU_CONN_A3, TRUE, &RTS_PDU_CONN_A3_SIGNATURE, "CONN/A3" },
224 
225  { RTS_PDU_CONN_B1, FALSE, &RTS_PDU_CONN_B1_SIGNATURE, "CONN/B1" },
226  { RTS_PDU_CONN_B2, FALSE, &RTS_PDU_CONN_B2_SIGNATURE, "CONN/B2" },
227  { RTS_PDU_CONN_B3, FALSE, &RTS_PDU_CONN_B3_SIGNATURE, "CONN/B3" },
228 
229  { RTS_PDU_CONN_C1, FALSE, &RTS_PDU_CONN_C1_SIGNATURE, "CONN/C1" },
230  { RTS_PDU_CONN_C2, TRUE, &RTS_PDU_CONN_C2_SIGNATURE, "CONN/C2" },
231 
232  { RTS_PDU_IN_R1_A1, FALSE, &RTS_PDU_IN_R1_A1_SIGNATURE, "IN_R1/A1" },
233  { RTS_PDU_IN_R1_A2, FALSE, &RTS_PDU_IN_R1_A2_SIGNATURE, "IN_R1/A2" },
234  { RTS_PDU_IN_R1_A3, FALSE, &RTS_PDU_IN_R1_A3_SIGNATURE, "IN_R1/A3" },
235  { RTS_PDU_IN_R1_A4, TRUE, &RTS_PDU_IN_R1_A4_SIGNATURE, "IN_R1/A4" },
236  { RTS_PDU_IN_R1_A5, TRUE, &RTS_PDU_IN_R1_A5_SIGNATURE, "IN_R1/A5" },
237  { RTS_PDU_IN_R1_A6, FALSE, &RTS_PDU_IN_R1_A6_SIGNATURE, "IN_R1/A6" },
238 
239  { RTS_PDU_IN_R1_B1, FALSE, &RTS_PDU_IN_R1_B1_SIGNATURE, "IN_R1/B1" },
240  { RTS_PDU_IN_R1_B2, FALSE, &RTS_PDU_IN_R1_B2_SIGNATURE, "IN_R1/B2" },
241 
242  { RTS_PDU_IN_R2_A1, FALSE, &RTS_PDU_IN_R2_A1_SIGNATURE, "IN_R2/A1" },
243  { RTS_PDU_IN_R2_A2, FALSE, &RTS_PDU_IN_R2_A2_SIGNATURE, "IN_R2/A2" },
244  { RTS_PDU_IN_R2_A3, FALSE, &RTS_PDU_IN_R2_A3_SIGNATURE, "IN_R2/A3" },
245  { RTS_PDU_IN_R2_A4, TRUE, &RTS_PDU_IN_R2_A4_SIGNATURE, "IN_R2/A4" },
246  { RTS_PDU_IN_R2_A5, FALSE, &RTS_PDU_IN_R2_A5_SIGNATURE, "IN_R2/A5" },
247 
248  { RTS_PDU_OUT_R1_A1, FALSE, &RTS_PDU_OUT_R1_A1_SIGNATURE, "OUT_R1/A1" },
249  { RTS_PDU_OUT_R1_A2, TRUE, &RTS_PDU_OUT_R1_A2_SIGNATURE, "OUT_R1/A2" },
250  { RTS_PDU_OUT_R1_A3, FALSE, &RTS_PDU_OUT_R1_A3_SIGNATURE, "OUT_R1/A3" },
251  { RTS_PDU_OUT_R1_A4, FALSE, &RTS_PDU_OUT_R1_A4_SIGNATURE, "OUT_R1/A4" },
252  { RTS_PDU_OUT_R1_A5, FALSE, &RTS_PDU_OUT_R1_A5_SIGNATURE, "OUT_R1/A5" },
253  { RTS_PDU_OUT_R1_A6, TRUE, &RTS_PDU_OUT_R1_A6_SIGNATURE, "OUT_R1/A6" },
254  { RTS_PDU_OUT_R1_A7, FALSE, &RTS_PDU_OUT_R1_A7_SIGNATURE, "OUT_R1/A7" },
255  { RTS_PDU_OUT_R1_A8, FALSE, &RTS_PDU_OUT_R1_A8_SIGNATURE, "OUT_R1/A8" },
256  { RTS_PDU_OUT_R1_A9, FALSE, &RTS_PDU_OUT_R1_A9_SIGNATURE, "OUT_R1/A9" },
257  { RTS_PDU_OUT_R1_A10, TRUE, &RTS_PDU_OUT_R1_A10_SIGNATURE, "OUT_R1/A10" },
258  { RTS_PDU_OUT_R1_A11, FALSE, &RTS_PDU_OUT_R1_A11_SIGNATURE, "OUT_R1/A11" },
259 
260  { RTS_PDU_OUT_R2_A1, FALSE, &RTS_PDU_OUT_R2_A1_SIGNATURE, "OUT_R2/A1" },
261  { RTS_PDU_OUT_R2_A2, TRUE, &RTS_PDU_OUT_R2_A2_SIGNATURE, "OUT_R2/A2" },
262  { RTS_PDU_OUT_R2_A3, FALSE, &RTS_PDU_OUT_R2_A3_SIGNATURE, "OUT_R2/A3" },
263  { RTS_PDU_OUT_R2_A4, FALSE, &RTS_PDU_OUT_R2_A4_SIGNATURE, "OUT_R2/A4" },
264  { RTS_PDU_OUT_R2_A5, FALSE, &RTS_PDU_OUT_R2_A5_SIGNATURE, "OUT_R2/A5" },
265  { RTS_PDU_OUT_R2_A6, TRUE, &RTS_PDU_OUT_R2_A6_SIGNATURE, "OUT_R2/A6" },
266  { RTS_PDU_OUT_R2_A7, FALSE, &RTS_PDU_OUT_R2_A7_SIGNATURE, "OUT_R2/A7" },
267  { RTS_PDU_OUT_R2_A8, FALSE, &RTS_PDU_OUT_R2_A8_SIGNATURE, "OUT_R2/A8" },
268 
269  { RTS_PDU_OUT_R2_B1, FALSE, &RTS_PDU_OUT_R2_B1_SIGNATURE, "OUT_R2/B1" },
270  { RTS_PDU_OUT_R2_B2, FALSE, &RTS_PDU_OUT_R2_B2_SIGNATURE, "OUT_R2/B2" },
271  { RTS_PDU_OUT_R2_B3, TRUE, &RTS_PDU_OUT_R2_B3_SIGNATURE, "OUT_R2/B3" },
272 
273  { RTS_PDU_OUT_R2_C1, FALSE, &RTS_PDU_OUT_R2_C1_SIGNATURE, "OUT_R2/C1" },
274 
275  { RTS_PDU_KEEP_ALIVE, TRUE, &RTS_PDU_KEEP_ALIVE_SIGNATURE, "Keep-Alive" },
276  { RTS_PDU_PING_TRAFFIC_SENT_NOTIFY, TRUE, &RTS_PDU_PING_TRAFFIC_SENT_NOTIFY_SIGNATURE,
277  "Ping Traffic Sent Notify" },
278  { RTS_PDU_ECHO, TRUE, &RTS_PDU_ECHO_SIGNATURE, "Echo" },
279  { RTS_PDU_PING, TRUE, &RTS_PDU_PING_SIGNATURE, "Ping" },
280  { RTS_PDU_FLOW_CONTROL_ACK, TRUE, &RTS_PDU_FLOW_CONTROL_ACK_SIGNATURE, "FlowControlAck" },
281  { RTS_PDU_FLOW_CONTROL_ACK_WITH_DESTINATION, TRUE,
282  &RTS_PDU_FLOW_CONTROL_ACK_WITH_DESTINATION_SIGNATURE, "FlowControlAckWithDestination" }
283 };
284 
285 BOOL rts_match_pdu_signature(const RtsPduSignature* signature, wStream* src,
286  const rpcconn_hdr_t* header)
287 {
288  return rts_match_pdu_signature_ex(signature, src, header, NULL, FALSE);
289 }
290 
291 BOOL rts_match_pdu_signature_ex(const RtsPduSignature* signature, wStream* src,
292  const rpcconn_hdr_t* header, RtsPduSignature* found_signature,
293  BOOL silent)
294 {
295  RtsPduSignature extracted = { 0 };
296 
297  WINPR_ASSERT(signature);
298  WINPR_ASSERT(src);
299 
300  if (!rts_extract_pdu_signature_ex(&extracted, src, header, silent))
301  return FALSE;
302 
303  if (found_signature)
304  *found_signature = extracted;
305  return memcmp(signature, &extracted, sizeof(extracted)) == 0;
306 }
307 
308 BOOL rts_extract_pdu_signature(RtsPduSignature* signature, wStream* src,
309  const rpcconn_hdr_t* header)
310 {
311  return rts_extract_pdu_signature_ex(signature, src, header, FALSE);
312 }
313 
314 BOOL rts_extract_pdu_signature_ex(RtsPduSignature* signature, wStream* src,
315  const rpcconn_hdr_t* header, BOOL silent)
316 {
317  BOOL rc = FALSE;
318  wStream sbuffer = { 0 };
319  rpcconn_hdr_t rheader = { 0 };
320  const rpcconn_rts_hdr_t* rts = NULL;
321 
322  WINPR_ASSERT(signature);
323  WINPR_ASSERT(src);
324 
325  wStream* s = Stream_StaticInit(&sbuffer, Stream_Pointer(src), Stream_GetRemainingLength(src));
326  if (!header)
327  {
328  if (!rts_read_pdu_header_ex(s, &rheader, silent))
329  goto fail;
330  header = &rheader;
331  }
332  rts = &header->rts;
333  if (rts->header.frag_length < sizeof(rpcconn_rts_hdr_t))
334  goto fail;
335 
336  signature->Flags = rts->Flags;
337  signature->NumberOfCommands = rts->NumberOfCommands;
338 
339  for (UINT16 i = 0; i < rts->NumberOfCommands; i++)
340  {
341  UINT32 CommandType = 0;
342  size_t CommandLength = 0;
343 
344  if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 4, silent))
345  goto fail;
346 
347  Stream_Read_UINT32(s, CommandType); /* CommandType (4 bytes) */
348 
349  /* We only need this for comparison against known command types */
350  if (i < ARRAYSIZE(signature->CommandTypes))
351  signature->CommandTypes[i] = CommandType;
352 
353  if (!rts_command_length(CommandType, s, &CommandLength, silent))
354  goto fail;
355  if (!Stream_ConditionalSafeSeek(s, CommandLength, silent))
356  goto fail;
357  }
358 
359  rc = TRUE;
360 fail:
361  rts_free_pdu_header(&rheader, FALSE);
362  return rc;
363 }
364 
365 UINT32 rts_identify_pdu_signature(const RtsPduSignature* signature,
366  const RTS_PDU_SIGNATURE_ENTRY** entry)
367 {
368  if (entry)
369  *entry = NULL;
370 
371  for (size_t i = 0; i < ARRAYSIZE(RTS_PDU_SIGNATURE_TABLE); i++)
372  {
373  const RTS_PDU_SIGNATURE_ENTRY* current = &RTS_PDU_SIGNATURE_TABLE[i];
374  const RtsPduSignature* pSignature = current->Signature;
375 
376  if (!current->SignatureClient)
377  continue;
378 
379  if (signature->Flags != pSignature->Flags)
380  continue;
381 
382  if (signature->NumberOfCommands != pSignature->NumberOfCommands)
383  continue;
384 
385  for (size_t j = 0; j < signature->NumberOfCommands; j++)
386  {
387  if (signature->CommandTypes[j] != pSignature->CommandTypes[j])
388  continue;
389  }
390 
391  if (entry)
392  *entry = current;
393 
394  return current->SignatureId;
395  }
396 
397  return 0;
398 }
399 
400 BOOL rts_print_pdu_signature(wLog* log, DWORD level, const RtsPduSignature* signature)
401 {
402  UINT32 SignatureId = 0;
403  const RTS_PDU_SIGNATURE_ENTRY* entry = NULL;
404 
405  if (!signature)
406  return FALSE;
407 
408  WLog_Print(log, level,
409  "RTS PDU Signature: Flags: 0x%04" PRIX16 " NumberOfCommands: %" PRIu16 "",
410  signature->Flags, signature->NumberOfCommands);
411  SignatureId = rts_identify_pdu_signature(signature, &entry);
412 
413  if (SignatureId)
414  WLog_Print(log, level, "Identified %s RTS PDU", entry->PduName);
415 
416  return TRUE;
417 }
Definition: rts_signature.h:36