FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
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
29const 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};
34const 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 } };
39const RtsPduSignature RTS_PDU_CONN_A3_SIGNATURE = {
40 RTS_FLAG_NONE, 1, { RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0, 0, 0 }
41};
42
43const 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};
49const 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};
55const 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
59const 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 } };
63const 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
68const 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};
73const 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};
79const 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 } };
84const 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 } };
89const RtsPduSignature RTS_PDU_IN_R1_A5_SIGNATURE = { RTS_FLAG_NONE,
90 1,
91 { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
92const RtsPduSignature RTS_PDU_IN_R1_A6_SIGNATURE = { RTS_FLAG_NONE,
93 1,
94 { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
95
96const RtsPduSignature RTS_PDU_IN_R1_B1_SIGNATURE = { RTS_FLAG_NONE,
97 1,
98 { RTS_CMD_EMPTY, 0, 0, 0, 0, 0, 0, 0 } };
99const 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
103const 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};
108const RtsPduSignature RTS_PDU_IN_R2_A2_SIGNATURE = { RTS_FLAG_NONE,
109 1,
110 { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
111const RtsPduSignature RTS_PDU_IN_R2_A3_SIGNATURE = { RTS_FLAG_NONE,
112 1,
113 { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 } };
114const RtsPduSignature RTS_PDU_IN_R2_A4_SIGNATURE = { RTS_FLAG_NONE,
115 1,
116 { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 } };
117const RtsPduSignature RTS_PDU_IN_R2_A5_SIGNATURE = { RTS_FLAG_NONE,
118 1,
119 { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
120
121const RtsPduSignature RTS_PDU_OUT_R1_A1_SIGNATURE = {
122 RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
123};
124const RtsPduSignature RTS_PDU_OUT_R1_A2_SIGNATURE = {
125 RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
126};
127const 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 } };
132const 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};
138const 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};
143const 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};
148const 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};
151const 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};
154const RtsPduSignature RTS_PDU_OUT_R1_A9_SIGNATURE = { RTS_FLAG_NONE,
155 1,
156 { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
157const RtsPduSignature RTS_PDU_OUT_R1_A10_SIGNATURE = { RTS_FLAG_NONE,
158 1,
159 { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
160const RtsPduSignature RTS_PDU_OUT_R1_A11_SIGNATURE = { RTS_FLAG_NONE,
161 1,
162 { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
163
164const RtsPduSignature RTS_PDU_OUT_R2_A1_SIGNATURE = {
165 RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
166};
167const RtsPduSignature RTS_PDU_OUT_R2_A2_SIGNATURE = {
168 RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
169};
170const 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 } };
175const RtsPduSignature RTS_PDU_OUT_R2_A4_SIGNATURE = { RTS_FLAG_NONE,
176 1,
177 { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
178const 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};
181const 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};
184const 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};
187const 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
191const RtsPduSignature RTS_PDU_OUT_R2_B1_SIGNATURE = { RTS_FLAG_NONE,
192 1,
193 { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
194const RtsPduSignature RTS_PDU_OUT_R2_B2_SIGNATURE = {
195 RTS_FLAG_NONE, 1, { RTS_CMD_NEGATIVE_ANCE, 0, 0, 0, 0, 0, 0, 0 }
196};
197const RtsPduSignature RTS_PDU_OUT_R2_B3_SIGNATURE = { RTS_FLAG_EOF,
198 1,
199 { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
200
201const RtsPduSignature RTS_PDU_OUT_R2_C1_SIGNATURE = { RTS_FLAG_PING,
202 1,
203 { 0, 0, 0, 0, 0, 0, 0, 0 } };
204
205const RtsPduSignature RTS_PDU_KEEP_ALIVE_SIGNATURE = {
206 RTS_FLAG_OTHER_CMD, 1, { RTS_CMD_CLIENT_KEEPALIVE, 0, 0, 0, 0, 0, 0, 0 }
207};
208const 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};
211const RtsPduSignature RTS_PDU_ECHO_SIGNATURE = { RTS_FLAG_ECHO, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
212const RtsPduSignature RTS_PDU_PING_SIGNATURE = { RTS_FLAG_PING, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
213const 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};
216const 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
220static 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
285BOOL 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
291BOOL 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
308BOOL 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
314BOOL 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;
360fail:
361 rts_free_pdu_header(&rheader, FALSE);
362 return rc;
363}
364
365UINT32 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
400BOOL 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}