20 #include <winpr/assert.h>
21 #include <winpr/stream.h>
23 #include <freerdp/log.h>
25 #include "rts_signature.h"
27 #define TAG FREERDP_TAG("core.gateway.rts")
32 { RTS_CMD_VERSION, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_RECEIVE_WINDOW_SIZE, 0, 0, 0, 0 }
34 const RtsPduSignature RTS_PDU_CONN_A2_SIGNATURE = { RTS_FLAG_OUT_CHANNEL,
36 { RTS_CMD_VERSION, RTS_CMD_COOKIE,
37 RTS_CMD_COOKIE, RTS_CMD_CHANNEL_LIFETIME,
38 RTS_CMD_RECEIVE_WINDOW_SIZE, 0, 0, 0 } };
40 RTS_FLAG_NONE, 1, { RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0, 0, 0 }
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 }
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 }
56 RTS_FLAG_NONE, 2, { RTS_CMD_RECEIVE_WINDOW_SIZE, RTS_CMD_VERSION, 0, 0, 0, 0, 0, 0 }
61 { RTS_CMD_VERSION, RTS_CMD_RECEIVE_WINDOW_SIZE,
62 RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0 } };
65 { RTS_CMD_VERSION, RTS_CMD_RECEIVE_WINDOW_SIZE,
66 RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0 } };
69 RTS_FLAG_RECYCLE_CHANNEL,
71 { RTS_CMD_VERSION, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_COOKIE, 0, 0, 0, 0 }
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 }
81 { RTS_CMD_DESTINATION, RTS_CMD_VERSION,
82 RTS_CMD_RECEIVE_WINDOW_SIZE,
83 RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0 } };
86 { RTS_CMD_DESTINATION, RTS_CMD_VERSION,
87 RTS_CMD_RECEIVE_WINDOW_SIZE,
88 RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0 } };
91 { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
94 { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
98 { RTS_CMD_EMPTY, 0, 0, 0, 0, 0, 0, 0 } };
100 RTS_FLAG_NONE, 1, { RTS_CMD_RECEIVE_WINDOW_SIZE, 0, 0, 0, 0, 0, 0, 0 }
104 RTS_FLAG_RECYCLE_CHANNEL,
106 { RTS_CMD_VERSION, RTS_CMD_COOKIE, RTS_CMD_COOKIE, RTS_CMD_COOKIE, 0, 0, 0, 0 }
110 { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
113 { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 } };
116 { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 } };
119 { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
122 RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
125 RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
127 const RtsPduSignature RTS_PDU_OUT_R1_A3_SIGNATURE = { RTS_FLAG_RECYCLE_CHANNEL,
129 { RTS_CMD_VERSION, RTS_CMD_COOKIE,
130 RTS_CMD_COOKIE, RTS_CMD_COOKIE,
131 RTS_CMD_RECEIVE_WINDOW_SIZE, 0, 0, 0 } };
133 RTS_FLAG_RECYCLE_CHANNEL | RTS_FLAG_OUT_CHANNEL,
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 }
139 RTS_FLAG_OUT_CHANNEL,
141 { RTS_CMD_DESTINATION, RTS_CMD_VERSION, RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0 }
144 RTS_FLAG_OUT_CHANNEL,
146 { RTS_CMD_DESTINATION, RTS_CMD_VERSION, RTS_CMD_CONNECTION_TIMEOUT, 0, 0, 0, 0, 0 }
149 RTS_FLAG_OUT_CHANNEL, 2, { RTS_CMD_DESTINATION, RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0 }
152 RTS_FLAG_OUT_CHANNEL, 2, { RTS_CMD_DESTINATION, RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0 }
156 { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
159 { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
162 { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
165 RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
168 RTS_FLAG_RECYCLE_CHANNEL, 1, { RTS_CMD_DESTINATION, 0, 0, 0, 0, 0, 0, 0 }
170 const RtsPduSignature RTS_PDU_OUT_R2_A3_SIGNATURE = { RTS_FLAG_RECYCLE_CHANNEL,
172 { RTS_CMD_VERSION, RTS_CMD_COOKIE,
173 RTS_CMD_COOKIE, RTS_CMD_COOKIE,
174 RTS_CMD_RECEIVE_WINDOW_SIZE, 0, 0, 0 } };
177 { RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0, 0 } };
179 RTS_FLAG_NONE, 2, { RTS_CMD_DESTINATION, RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0 }
182 RTS_FLAG_NONE, 2, { RTS_CMD_DESTINATION, RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0 }
185 RTS_FLAG_NONE, 3, { RTS_CMD_DESTINATION, RTS_CMD_COOKIE, RTS_CMD_VERSION, 0, 0, 0, 0, 0 }
188 RTS_FLAG_OUT_CHANNEL, 2, { RTS_CMD_DESTINATION, RTS_CMD_COOKIE, 0, 0, 0, 0, 0, 0 }
193 { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
195 RTS_FLAG_NONE, 1, { RTS_CMD_NEGATIVE_ANCE, 0, 0, 0, 0, 0, 0, 0 }
199 { RTS_CMD_ANCE, 0, 0, 0, 0, 0, 0, 0 } };
203 { 0, 0, 0, 0, 0, 0, 0, 0 } };
206 RTS_FLAG_OTHER_CMD, 1, { RTS_CMD_CLIENT_KEEPALIVE, 0, 0, 0, 0, 0, 0, 0 }
209 RTS_FLAG_OTHER_CMD, 1, { RTS_CMD_PING_TRAFFIC_SENT_NOTIFY, 0, 0, 0, 0, 0, 0, 0 }
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 } };
214 RTS_FLAG_OTHER_CMD, 1, { RTS_CMD_FLOW_CONTROL_ACK, 0, 0, 0, 0, 0, 0, 0 }
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 }
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
273 { RTS_PDU_OUT_R2_C1, FALSE, &RTS_PDU_OUT_R2_C1_SIGNATURE,
"OUT_R2/C1" },
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" }
288 return rts_match_pdu_signature_ex(signature, src, header, NULL, FALSE);
297 WINPR_ASSERT(signature);
300 if (!rts_extract_pdu_signature_ex(&extracted, src, header, silent))
304 *found_signature = extracted;
305 return memcmp(signature, &extracted,
sizeof(extracted)) == 0;
311 return rts_extract_pdu_signature_ex(signature, src, header, FALSE);
322 WINPR_ASSERT(signature);
325 wStream* s = Stream_StaticInit(&sbuffer, Stream_Pointer(src), Stream_GetRemainingLength(src));
328 if (!rts_read_pdu_header_ex(s, &rheader, silent))
336 signature->Flags = rts->Flags;
337 signature->NumberOfCommands = rts->NumberOfCommands;
339 for (UINT16 i = 0; i < rts->NumberOfCommands; i++)
341 UINT32 CommandType = 0;
342 size_t CommandLength = 0;
344 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 4, silent))
347 Stream_Read_UINT32(s, CommandType);
350 if (i < ARRAYSIZE(signature->CommandTypes))
351 signature->CommandTypes[i] = CommandType;
353 if (!rts_command_length(CommandType, s, &CommandLength, silent))
355 if (!Stream_ConditionalSafeSeek(s, CommandLength, silent))
361 rts_free_pdu_header(&rheader, FALSE);
371 for (
size_t i = 0; i < ARRAYSIZE(RTS_PDU_SIGNATURE_TABLE); i++)
376 if (!current->SignatureClient)
379 if (signature->Flags != pSignature->Flags)
382 if (signature->NumberOfCommands != pSignature->NumberOfCommands)
385 for (
size_t j = 0; j < signature->NumberOfCommands; j++)
387 if (signature->CommandTypes[j] != pSignature->CommandTypes[j])
394 return current->SignatureId;
400 BOOL rts_print_pdu_signature(wLog* log, DWORD level,
const RtsPduSignature* signature)
402 UINT32 SignatureId = 0;
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);
414 WLog_Print(log, level,
"Identified %s RTS PDU", entry->PduName);