20 #include <freerdp/config.h>
22 #include <winpr/assert.h>
23 #include <winpr/cast.h>
24 #include <winpr/crt.h>
25 #include <winpr/crypto.h>
27 #include <freerdp/log.h>
29 #include "ncacn_http.h"
30 #include "rpc_client.h"
31 #include "rts_signature.h"
35 #define TAG FREERDP_TAG("core.gateway.rts")
70 static int rts_destination_command_read(rdpRpc* rpc,
wStream* buffer, UINT32* Destination);
72 static const char* rts_command_to_string(UINT32 cmd,
char* buffer,
size_t len)
74 const char* str = NULL;
84 ENTRY(RTS_CMD_RECEIVE_WINDOW_SIZE);
85 ENTRY(RTS_CMD_FLOW_CONTROL_ACK);
86 ENTRY(RTS_CMD_CONNECTION_TIMEOUT);
87 ENTRY(RTS_CMD_COOKIE);
88 ENTRY(RTS_CMD_CHANNEL_LIFETIME);
89 ENTRY(RTS_CMD_CLIENT_KEEPALIVE);
90 ENTRY(RTS_CMD_VERSION);
92 ENTRY(RTS_CMD_PADDING);
93 ENTRY(RTS_CMD_NEGATIVE_ANCE);
95 ENTRY(RTS_CMD_CLIENT_ADDRESS);
96 ENTRY(RTS_CMD_ASSOCIATION_GROUP_ID);
97 ENTRY(RTS_CMD_DESTINATION);
98 ENTRY(RTS_CMD_PING_TRAFFIC_SENT_NOTIFY);
99 ENTRY(RTS_CMD_LAST_ID);
101 str =
"RTS_CMD_UNKNOWN";
107 (void)_snprintf(buffer, len,
"%s [0x%08" PRIx32
"]", str, cmd);
111 static const char* rts_pdu_ptype_to_string(UINT32 ptype)
116 return "PTYPE_REQUEST";
120 return "PTYPE_RESPONSE";
122 return "PTYPE_FAULT";
124 return "PTYPE_WORKING";
126 return "PTYPE_NOCALL";
128 return "PTYPE_REJECT";
131 case PTYPE_CL_CANCEL:
132 return "PTYPE_CL_CANCEL";
135 case PTYPE_CANCEL_ACK:
136 return "PTYPE_CANCEL_ACK";
140 return "PTYPE_BIND_ACK";
142 return "PTYPE_BIND_NAK";
143 case PTYPE_ALTER_CONTEXT:
144 return "PTYPE_ALTER_CONTEXT";
145 case PTYPE_ALTER_CONTEXT_RESP:
146 return "PTYPE_ALTER_CONTEXT_RESP";
147 case PTYPE_RPC_AUTH_3:
148 return "PTYPE_RPC_AUTH_3";
150 return "PTYPE_SHUTDOWN";
151 case PTYPE_CO_CANCEL:
152 return "PTYPE_CO_CANCEL";
154 return "PTYPE_ORPHANED";
165 header.header.rpc_vers = 5;
166 header.header.rpc_vers_minor = 0;
167 header.header.ptype = PTYPE_RTS;
168 header.header.packed_drep[0] = 0x10;
169 header.header.packed_drep[1] = 0x00;
170 header.header.packed_drep[2] = 0x00;
171 header.header.packed_drep[3] = 0x00;
172 header.header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
173 header.header.auth_length = 0;
174 header.header.call_id = 0;
179 static BOOL rts_align_stream(
wStream* s,
size_t alignment, BOOL silent)
185 WINPR_ASSERT(alignment > 0);
187 pos = Stream_GetPosition(s);
188 pad = rpc_offset_align(&pos, alignment);
189 return Stream_ConditionalSafeSeek(s, pad, silent);
192 static char* sdup(
const void* src,
size_t length)
195 WINPR_ASSERT(src || (length == 0));
199 dst = calloc(length + 1,
sizeof(
char));
202 memcpy(dst, src, length);
209 WINPR_ASSERT(header);
213 Stream_Write_UINT8(s, header->rpc_vers);
214 Stream_Write_UINT8(s, header->rpc_vers_minor);
215 Stream_Write_UINT8(s, header->ptype);
216 Stream_Write_UINT8(s, header->pfc_flags);
217 Stream_Write(s, header->packed_drep, ARRAYSIZE(header->packed_drep));
218 Stream_Write_UINT16(s, header->frag_length);
219 Stream_Write_UINT16(s, header->auth_length);
220 Stream_Write_UINT32(s, header->call_id);
227 WINPR_ASSERT(header);
236 const size_t sz = Stream_GetRemainingLength(s);
241 Stream_Read_UINT8(s, header->rpc_vers);
242 Stream_Read_UINT8(s, header->rpc_vers_minor);
243 Stream_Read_UINT8(s, header->ptype);
244 Stream_Read_UINT8(s, header->pfc_flags);
245 Stream_Read(s, header->packed_drep, ARRAYSIZE(header->packed_drep));
246 Stream_Read_UINT16(s, header->frag_length);
247 Stream_Read_UINT16(s, header->auth_length);
248 Stream_Read_UINT32(s, header->call_id);
253 WLog_WARN(TAG,
"Invalid header->frag_length of %" PRIu16
", expected %" PRIuz,
260 if (!Stream_CheckAndLogRequiredLength(TAG, s,
266 const size_t sz2 = Stream_GetRemainingLength(s);
273 static BOOL rts_read_auth_verifier_no_checks(
wStream* s, auth_verifier_co_t* auth,
279 WINPR_ASSERT(header);
281 WINPR_ASSERT(header->frag_length > header->auth_length + 8);
284 *startPos = Stream_GetPosition(s);
288 const size_t expected = header->frag_length - header->auth_length - 8;
290 Stream_SetPosition(s, expected);
291 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 8, silent))
294 Stream_Read_UINT8(s, auth->auth_type);
295 Stream_Read_UINT8(s, auth->auth_level);
296 Stream_Read_UINT8(s, auth->auth_pad_length);
297 Stream_Read_UINT8(s, auth->auth_reserved);
298 Stream_Read_UINT32(s, auth->auth_context_id);
301 if (header->auth_length != 0)
303 const void* ptr = Stream_Pointer(s);
304 if (!Stream_ConditionalSafeSeek(s, header->auth_length, silent))
306 auth->auth_value = (BYTE*)sdup(ptr, header->auth_length);
307 if (auth->auth_value == NULL)
314 static BOOL rts_read_auth_verifier(
wStream* s, auth_verifier_co_t* auth,
320 WINPR_ASSERT(header);
322 if (!rts_read_auth_verifier_no_checks(s, auth, header, &pos, silent))
325 const size_t expected = header->frag_length - header->auth_length - 8;
326 WINPR_ASSERT(pos + auth->auth_pad_length == expected);
327 return pos + auth->auth_pad_length == expected;
330 static BOOL rts_read_auth_verifier_with_stub(
wStream* s, auth_verifier_co_t* auth,
334 size_t alloc_hint = 0;
337 if (!rts_read_auth_verifier_no_checks(s, auth, header, &pos, silent))
340 switch (header->ptype)
345 alloc_hint = hdr->alloc_hint;
346 ptr = &hdr->stub_data;
352 alloc_hint = hdr->alloc_hint;
353 ptr = &hdr->stub_data;
359 alloc_hint = hdr->alloc_hint;
360 ptr = &hdr->stub_data;
369 const size_t off = header->auth_length + 8 + auth->auth_pad_length + pos;
370 const size_t size = header->frag_length - MIN(header->frag_length, off);
371 const void* src = Stream_Buffer(s) + pos;
373 if (off > header->frag_length)
375 "Unexpected alloc_hint(%" PRIuz
") for PDU %s: size %" PRIuz
377 alloc_hint, rts_pdu_ptype_to_string(header->ptype), header->frag_length, off);
378 *ptr = (BYTE*)sdup(src, size);
386 static void rts_free_auth_verifier(auth_verifier_co_t* auth)
390 free(auth->auth_value);
393 static BOOL rts_write_auth_verifier(
wStream* s,
const auth_verifier_co_t* auth,
397 UINT8 auth_pad_length = 0;
401 WINPR_ASSERT(header);
404 pos = Stream_GetPosition(s);
407 auth_pad_length = 4 - (pos % 4);
408 if (!Stream_EnsureRemainingCapacity(s, auth_pad_length))
410 Stream_Zero(s, auth_pad_length);
413 #if defined(WITH_VERBOSE_WINPR_ASSERT) && (WITH_VERBOSE_WINPR_ASSERT != 0)
414 WINPR_ASSERT(header->frag_length + 8ull > header->auth_length);
416 size_t apos = Stream_GetPosition(s);
417 size_t expected = header->frag_length - header->auth_length - 8;
419 WINPR_ASSERT(apos == expected);
423 if (!Stream_EnsureRemainingCapacity(s,
sizeof(auth_verifier_co_t)))
426 Stream_Write_UINT8(s, auth->auth_type);
427 Stream_Write_UINT8(s, auth->auth_level);
428 Stream_Write_UINT8(s, auth_pad_length);
429 Stream_Write_UINT8(s, 0);
430 Stream_Write_UINT32(s, auth->auth_context_id);
432 if (!Stream_EnsureRemainingCapacity(s, header->auth_length))
434 Stream_Write(s, auth->auth_value, header->auth_length);
441 WINPR_ASSERT(version);
443 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 2 *
sizeof(UINT8), silent))
445 Stream_Read_UINT8(s, version->major);
446 Stream_Read_UINT8(s, version->minor);
454 free(versions->p_protocols);
455 versions->p_protocols = NULL;
462 WINPR_ASSERT(versions);
464 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s,
sizeof(UINT8), silent))
467 Stream_Read_UINT8(s, versions->n_protocols);
469 if (versions->n_protocols > 0)
471 versions->p_protocols = calloc(versions->n_protocols,
sizeof(
p_rt_version_t));
472 if (!versions->p_protocols)
475 for (BYTE x = 0; x < versions->n_protocols; x++)
478 if (!rts_read_version(s, version, silent))
480 rts_free_supported_versions(versions);
493 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s,
sizeof(UINT16), silent))
496 Stream_Read_UINT16(s, port->length);
497 if (port->length == 0)
500 const void* ptr = Stream_ConstPointer(s);
501 if (!Stream_ConditionalSafeSeek(s, port->length, silent))
503 port->port_spec = sdup(ptr, port->length);
504 return port->port_spec != NULL;
507 static void rts_free_port_any(
port_any_t* port)
511 free(port->port_spec);
519 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s,
sizeof(
p_uuid_t), silent))
522 Stream_Read_UINT32(s, uuid->time_low);
523 Stream_Read_UINT16(s, uuid->time_mid);
524 Stream_Read_UINT16(s, uuid->time_hi_and_version);
525 Stream_Read_UINT8(s, uuid->clock_seq_hi_and_reserved);
526 Stream_Read_UINT8(s, uuid->clock_seq_low);
527 Stream_Read(s, uuid->node, ARRAYSIZE(uuid->node));
536 if (!Stream_EnsureRemainingCapacity(s,
sizeof(
p_uuid_t)))
539 Stream_Write_UINT32(s, uuid->time_low);
540 Stream_Write_UINT16(s, uuid->time_mid);
541 Stream_Write_UINT16(s, uuid->time_hi_and_version);
542 Stream_Write_UINT8(s, uuid->clock_seq_hi_and_reserved);
543 Stream_Write_UINT8(s, uuid->clock_seq_low);
544 Stream_Write(s, uuid->node, ARRAYSIZE(uuid->node));
561 WINPR_ASSERT(syntax_id);
563 if (!rts_read_uuid(s, &syntax_id->if_uuid, silent))
566 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 4, silent))
569 Stream_Read_UINT32(s, syntax_id->if_version);
576 WINPR_ASSERT(syntax_id);
578 if (!rts_write_uuid(s, &syntax_id->if_uuid))
581 if (!Stream_EnsureRemainingCapacity(s, 4))
584 Stream_Write_UINT32(s, syntax_id->if_version);
598 rts_syntax_id_free(ptr->transfer_syntaxes);
605 WINPR_ASSERT(element);
607 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 4, silent))
610 Stream_Read_UINT16(s, element->p_cont_id);
611 Stream_Read_UINT8(s, element->n_transfer_syn);
612 Stream_Read_UINT8(s, element->reserved);
614 if (!rts_read_syntax_id(s, &element->abstract_syntax, silent))
617 if (element->n_transfer_syn > 0)
619 element->transfer_syntaxes = rts_syntax_id_new(element->n_transfer_syn);
620 if (!element->transfer_syntaxes)
622 for (BYTE x = 0; x < element->n_transfer_syn; x++)
625 if (!rts_read_syntax_id(s, syn, silent))
636 WINPR_ASSERT(element);
638 if (!Stream_EnsureRemainingCapacity(s, 4))
640 Stream_Write_UINT16(s, element->p_cont_id);
641 Stream_Write_UINT8(s, element->n_transfer_syn);
642 Stream_Write_UINT8(s, element->reserved);
643 if (!rts_write_syntax_id(s, &element->abstract_syntax))
646 for (BYTE x = 0; x < element->n_transfer_syn; x++)
649 if (!rts_write_syntax_id(s, syn))
661 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 4, silent))
663 Stream_Read_UINT8(s, list->n_context_elem);
664 Stream_Read_UINT8(s, list->reserved);
665 Stream_Read_UINT16(s, list->reserved2);
667 if (list->n_context_elem > 0)
669 list->p_cont_elem = rts_context_elem_new(list->n_context_elem);
670 if (!list->p_cont_elem)
672 for (BYTE x = 0; x < list->n_context_elem; x++)
675 if (!rts_read_context_elem(s, element, silent))
686 rts_context_elem_free(list->p_cont_elem);
694 if (!Stream_EnsureRemainingCapacity(s, 4))
696 Stream_Write_UINT8(s, list->n_context_elem);
697 Stream_Write_UINT8(s, 0);
698 Stream_Write_UINT16(s, 0);
700 for (BYTE x = 0; x < list->n_context_elem; x++)
703 if (!rts_write_context_elem(s, element))
709 static p_result_t* rts_result_new(
size_t count)
714 static void rts_result_free(
p_result_t* results)
724 WINPR_ASSERT(result);
726 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 2, silent))
728 Stream_Read_UINT16(s, result->result);
729 Stream_Read_UINT16(s, result->reason);
731 return rts_read_syntax_id(s, &result->transfer_syntax, silent);
734 static void rts_free_result(
p_result_t* result)
745 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 4, silent))
747 Stream_Read_UINT8(s, list->n_results);
748 Stream_Read_UINT8(s, list->reserved);
749 Stream_Read_UINT16(s, list->reserved2);
751 if (list->n_results > 0)
753 list->p_results = rts_result_new(list->n_results);
754 if (!list->p_results)
757 for (BYTE x = 0; x < list->n_results; x++)
760 if (!rts_read_result(s, result, silent))
772 for (BYTE x = 0; x < list->n_results; x++)
775 rts_free_result(result);
777 rts_result_free(list->p_results);
785 rts_free_context_list(&ctx->p_context_elem);
786 rts_free_auth_verifier(&ctx->auth_verifier);
794 if (!Stream_ConditionalCheckAndLogRequiredLength(
798 Stream_Read_UINT16(s, ctx->max_xmit_frag);
799 Stream_Read_UINT16(s, ctx->max_recv_frag);
800 Stream_Read_UINT32(s, ctx->assoc_group_id);
802 if (!rts_read_context_list(s, &ctx->p_context_elem, silent))
805 if (!rts_read_auth_verifier(s, &ctx->auth_verifier, &ctx->header, silent))
811 static BOOL rts_read_pdu_alter_context_response(
wStream* s,
818 if (!Stream_ConditionalCheckAndLogRequiredLength(
822 Stream_Read_UINT16(s, ctx->max_xmit_frag);
823 Stream_Read_UINT16(s, ctx->max_recv_frag);
824 Stream_Read_UINT32(s, ctx->assoc_group_id);
826 if (!rts_read_port_any(s, &ctx->sec_addr, silent))
829 if (!rts_align_stream(s, 4, silent))
832 if (!rts_read_result_list(s, &ctx->p_result_list, silent))
835 if (!rts_read_auth_verifier(s, &ctx->auth_verifier, &ctx->header, silent))
846 rts_free_port_any(&ctx->sec_addr);
847 rts_free_result_list(&ctx->p_result_list);
848 rts_free_auth_verifier(&ctx->auth_verifier);
856 if (!Stream_ConditionalCheckAndLogRequiredLength(
859 Stream_Read_UINT16(s, ctx->max_xmit_frag);
860 Stream_Read_UINT16(s, ctx->max_recv_frag);
861 Stream_Read_UINT32(s, ctx->assoc_group_id);
863 if (!rts_read_context_list(s, &ctx->p_context_elem, silent))
866 if (!rts_read_auth_verifier(s, &ctx->auth_verifier, &ctx->header, silent))
876 rts_free_context_list(&ctx->p_context_elem);
877 rts_free_auth_verifier(&ctx->auth_verifier);
885 if (!Stream_CheckAndLogRequiredLength(
888 Stream_Read_UINT16(s, ctx->max_xmit_frag);
889 Stream_Read_UINT16(s, ctx->max_recv_frag);
890 Stream_Read_UINT32(s, ctx->assoc_group_id);
892 if (!rts_read_port_any(s, &ctx->sec_addr, silent))
895 if (!rts_align_stream(s, 4, silent))
898 if (!rts_read_result_list(s, &ctx->p_result_list, silent))
901 return rts_read_auth_verifier(s, &ctx->auth_verifier, &ctx->header, silent);
908 rts_free_port_any(&ctx->sec_addr);
909 rts_free_result_list(&ctx->p_result_list);
910 rts_free_auth_verifier(&ctx->auth_verifier);
918 if (!Stream_ConditionalCheckAndLogRequiredLength(
921 Stream_Read_UINT16(s, ctx->provider_reject_reason);
922 return rts_read_supported_versions(s, &ctx->versions, silent);
930 rts_free_supported_versions(&ctx->versions);
938 if (!Stream_ConditionalCheckAndLogRequiredLength(
941 Stream_Read_UINT16(s, ctx->max_xmit_frag);
942 Stream_Read_UINT16(s, ctx->max_recv_frag);
944 return rts_read_auth_verifier(s, &ctx->auth_verifier, &ctx->header, silent);
951 rts_free_auth_verifier(&ctx->auth_verifier);
959 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 12, silent))
961 Stream_Read_UINT32(s, ctx->alloc_hint);
962 Stream_Read_UINT16(s, ctx->p_cont_id);
963 Stream_Read_UINT8(s, ctx->cancel_count);
964 Stream_Read_UINT8(s, ctx->reserved);
965 Stream_Read_UINT32(s, ctx->status);
967 WLog_WARN(TAG,
"status=%s", Win32ErrorCode2Tag(ctx->status & 0xFFFF));
968 return rts_read_auth_verifier_with_stub(s, &ctx->auth_verifier, &ctx->header, silent);
975 rts_free_auth_verifier(&ctx->auth_verifier);
983 if (!Stream_ConditionalCheckAndLogRequiredLength(
986 return rts_read_auth_verifier(s, &ctx->auth_verifier, &ctx->header, silent);
993 rts_free_auth_verifier(&ctx->auth_verifier);
1001 if (!Stream_ConditionalCheckAndLogRequiredLength(
1004 return rts_read_auth_verifier(s, &ctx->auth_verifier, &ctx->header, silent);
1011 rts_free_auth_verifier(&ctx->auth_verifier);
1019 if (!Stream_ConditionalCheckAndLogRequiredLength(
1022 Stream_Read_UINT32(s, ctx->alloc_hint);
1023 Stream_Read_UINT16(s, ctx->p_cont_id);
1024 Stream_Read_UINT16(s, ctx->opnum);
1025 if (!rts_read_uuid(s, &ctx->object, silent))
1028 return rts_read_auth_verifier_with_stub(s, &ctx->auth_verifier, &ctx->header, silent);
1035 rts_free_auth_verifier(&ctx->auth_verifier);
1043 if (!Stream_ConditionalCheckAndLogRequiredLength(
1046 Stream_Read_UINT32(s, ctx->alloc_hint);
1047 Stream_Read_UINT16(s, ctx->p_cont_id);
1048 Stream_Read_UINT8(s, ctx->cancel_count);
1049 Stream_Read_UINT8(s, ctx->reserved);
1051 if (!rts_align_stream(s, 8, silent))
1054 return rts_read_auth_verifier_with_stub(s, &ctx->auth_verifier, &ctx->header, silent);
1061 free(ctx->stub_data);
1062 rts_free_auth_verifier(&ctx->auth_verifier);
1070 if (!Stream_ConditionalCheckAndLogRequiredLength(
1074 Stream_Read_UINT16(s, ctx->Flags);
1075 Stream_Read_UINT16(s, ctx->NumberOfCommands);
1084 void rts_free_pdu_header(
rpcconn_hdr_t* header, BOOL allocated)
1089 switch (header->common.ptype)
1091 case PTYPE_ALTER_CONTEXT:
1092 rts_free_pdu_alter_context(&header->alter_context);
1094 case PTYPE_ALTER_CONTEXT_RESP:
1095 rts_free_pdu_alter_context_response(&header->alter_context_response);
1098 rts_free_pdu_bind(&header->bind);
1100 case PTYPE_BIND_ACK:
1101 rts_free_pdu_bind_ack(&header->bind_ack);
1103 case PTYPE_BIND_NAK:
1104 rts_free_pdu_bind_nak(&header->bind_nak);
1106 case PTYPE_RPC_AUTH_3:
1107 rts_free_pdu_auth3(&header->rpc_auth_3);
1109 case PTYPE_CANCEL_ACK:
1110 rts_free_pdu_cancel_ack(&header->cancel);
1113 rts_free_pdu_fault(&header->fault);
1115 case PTYPE_ORPHANED:
1116 rts_free_pdu_orphaned(&header->orphaned);
1119 rts_free_pdu_request(&header->request);
1121 case PTYPE_RESPONSE:
1122 rts_free_pdu_response(&header->response);
1125 rts_free_pdu_rts(&header->rts);
1128 case PTYPE_SHUTDOWN:
1137 case PTYPE_CL_CANCEL:
1139 case PTYPE_CO_CANCEL:
1150 return rts_read_pdu_header_ex(s, header, FALSE);
1157 WINPR_ASSERT(header);
1159 if (!rts_read_common_pdu_header(s, &header->common, silent))
1162 WLog_DBG(TAG,
"Reading PDU type %s", rts_pdu_ptype_to_string(header->common.ptype));
1164 switch (header->common.ptype)
1166 case PTYPE_ALTER_CONTEXT:
1167 rc = rts_read_pdu_alter_context(s, &header->alter_context, silent);
1169 case PTYPE_ALTER_CONTEXT_RESP:
1170 rc = rts_read_pdu_alter_context_response(s, &header->alter_context_response, silent);
1173 rc = rts_read_pdu_bind(s, &header->bind, silent);
1175 case PTYPE_BIND_ACK:
1176 rc = rts_read_pdu_bind_ack(s, &header->bind_ack, silent);
1178 case PTYPE_BIND_NAK:
1179 rc = rts_read_pdu_bind_nak(s, &header->bind_nak, silent);
1181 case PTYPE_RPC_AUTH_3:
1182 rc = rts_read_pdu_auth3(s, &header->rpc_auth_3, silent);
1184 case PTYPE_CANCEL_ACK:
1185 rc = rts_read_pdu_cancel_ack(s, &header->cancel, silent);
1188 rc = rts_read_pdu_fault(s, &header->fault, silent);
1190 case PTYPE_ORPHANED:
1191 rc = rts_read_pdu_orphaned(s, &header->orphaned, silent);
1194 rc = rts_read_pdu_request(s, &header->request, silent);
1196 case PTYPE_RESPONSE:
1197 rc = rts_read_pdu_response(s, &header->response, silent);
1200 rc = rts_read_pdu_rts(s, &header->rts, silent);
1202 case PTYPE_SHUTDOWN:
1212 case PTYPE_CL_CANCEL:
1214 case PTYPE_CO_CANCEL:
1225 WINPR_ASSERT(header);
1229 if (!rts_write_common_pdu_header(s, &header->header))
1232 Stream_Write_UINT16(s, header->Flags);
1233 Stream_Write_UINT16(s, header->NumberOfCommands);
1237 static BOOL rts_receive_window_size_command_read(rdpRpc* rpc,
wStream* buffer,
1238 UINT64* ReceiveWindowSize)
1241 WINPR_ASSERT(buffer);
1243 if (!Stream_CheckAndLogRequiredLength(TAG, buffer, 8))
1245 const UINT64 val = Stream_Get_UINT64(buffer);
1246 if (ReceiveWindowSize)
1247 *ReceiveWindowSize = val;
1252 static BOOL rts_receive_window_size_command_write(
wStream* s, UINT32 ReceiveWindowSize)
1256 if (!Stream_EnsureRemainingCapacity(s, 2 *
sizeof(UINT32)))
1259 Stream_Write_UINT32(s, RTS_CMD_RECEIVE_WINDOW_SIZE);
1260 Stream_Write_UINT32(s, ReceiveWindowSize);
1265 static int rts_flow_control_ack_command_read(rdpRpc* rpc,
wStream* buffer, UINT32* BytesReceived,
1266 UINT32* AvailableWindow, BYTE* ChannelCookie)
1272 WINPR_ASSERT(buffer);
1274 int rc = rts_destination_command_read(rpc, buffer, &Command);
1278 if (Command != RTS_CMD_FLOW_CONTROL_ACK)
1280 char buffer1[64] = { 0 };
1281 char buffer2[64] = { 0 };
1282 WLog_Print(rpc->log, WLOG_ERROR,
"got command %s, expected %s",
1283 rts_command_to_string(Command, buffer1,
sizeof(buffer1)),
1284 rts_command_to_string(RTS_CMD_FLOW_CONTROL_ACK, buffer2,
sizeof(buffer2)));
1289 if (!Stream_CheckAndLogRequiredLength(TAG, buffer, 24))
1292 Stream_Read_UINT32(buffer, val);
1294 *BytesReceived = val;
1296 Stream_Read_UINT32(buffer, val);
1297 if (AvailableWindow)
1298 *AvailableWindow = val;
1301 Stream_Read(buffer, ChannelCookie, 16);
1303 Stream_Seek(buffer, 16);
1307 static BOOL rts_flow_control_ack_command_write(
wStream* s, UINT32 BytesReceived,
1308 UINT32 AvailableWindow, BYTE* ChannelCookie)
1312 if (!Stream_EnsureRemainingCapacity(s, 28))
1315 Stream_Write_UINT32(s, RTS_CMD_FLOW_CONTROL_ACK);
1316 Stream_Write_UINT32(s, BytesReceived);
1317 Stream_Write_UINT32(s, AvailableWindow);
1318 Stream_Write(s, ChannelCookie, 16);
1323 static BOOL rts_connection_timeout_command_read(rdpRpc* rpc,
wStream* buffer,
1324 UINT64* ConnectionTimeout)
1327 WINPR_ASSERT(buffer);
1329 if (!Stream_CheckAndLogRequiredLength(TAG, buffer, 8))
1332 UINT64 val = Stream_Get_UINT64(buffer);
1333 if (ConnectionTimeout)
1334 *ConnectionTimeout = val;
1339 static BOOL rts_cookie_command_write(
wStream* s,
const BYTE* Cookie)
1343 if (!Stream_EnsureRemainingCapacity(s, 20))
1346 Stream_Write_UINT32(s, RTS_CMD_COOKIE);
1347 Stream_Write(s, Cookie, 16);
1352 static BOOL rts_channel_lifetime_command_write(
wStream* s, UINT32 ChannelLifetime)
1356 if (!Stream_EnsureRemainingCapacity(s, 8))
1358 Stream_Write_UINT32(s, RTS_CMD_CHANNEL_LIFETIME);
1359 Stream_Write_UINT32(s, ChannelLifetime);
1364 static BOOL rts_client_keepalive_command_write(
wStream* s, UINT32 ClientKeepalive)
1368 if (!Stream_EnsureRemainingCapacity(s, 8))
1376 Stream_Write_UINT32(s, RTS_CMD_CLIENT_KEEPALIVE);
1377 Stream_Write_UINT32(s, ClientKeepalive);
1382 static BOOL rts_version_command_read(rdpRpc* rpc,
wStream* buffer)
1385 WINPR_ASSERT(buffer);
1387 if (!Stream_SafeSeek(buffer, 8))
1395 static BOOL rts_version_command_write(
wStream* buffer)
1397 WINPR_ASSERT(buffer);
1399 if (!Stream_EnsureRemainingCapacity((buffer), 8))
1402 Stream_Write_UINT32(buffer, RTS_CMD_VERSION);
1403 Stream_Write_UINT32(buffer, 1);
1408 static BOOL rts_empty_command_write(
wStream* s)
1412 if (!Stream_EnsureRemainingCapacity(s, 8))
1415 Stream_Write_UINT32(s, RTS_CMD_EMPTY);
1420 static BOOL rts_padding_command_read(
wStream* s,
size_t* length, BOOL silent)
1422 UINT32 ConformanceCount = 0;
1424 WINPR_ASSERT(length);
1425 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 4, silent))
1427 Stream_Read_UINT32(s, ConformanceCount);
1428 *length = ConformanceCount + 4;
1432 static BOOL rts_client_address_command_read(
wStream* s,
size_t* length, BOOL silent)
1434 UINT32 AddressType = 0;
1437 WINPR_ASSERT(length);
1439 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 4, silent))
1441 Stream_Read_UINT32(s, AddressType);
1443 if (AddressType == 0)
1447 *length = 4 + 4 + 12;
1453 *length = 4 + 16 + 12;
1458 static BOOL rts_association_group_id_command_write(
wStream* s,
const BYTE* AssociationGroupId)
1462 if (!Stream_EnsureRemainingCapacity(s, 20))
1465 Stream_Write_UINT32(s, RTS_CMD_ASSOCIATION_GROUP_ID);
1466 Stream_Write(s, AssociationGroupId, 16);
1471 static int rts_destination_command_read(rdpRpc* rpc,
wStream* buffer, UINT32* Destination)
1475 WINPR_ASSERT(buffer);
1477 if (!Stream_CheckAndLogRequiredLength(TAG, buffer, 4))
1479 Stream_Read_UINT32(buffer, val);
1486 static BOOL rts_destination_command_write(
wStream* s, UINT32 Destination)
1490 if (!Stream_EnsureRemainingCapacity(s, 8))
1493 Stream_Write_UINT32(s, RTS_CMD_DESTINATION);
1494 Stream_Write_UINT32(s, Destination);
1499 void rts_generate_cookie(BYTE* cookie)
1501 WINPR_ASSERT(cookie);
1502 winpr_RAND(cookie, 16);
1505 static BOOL rts_send_buffer(
RpcChannel* channel,
wStream* s,
size_t frag_length)
1507 BOOL status = FALSE;
1510 WINPR_ASSERT(channel);
1513 Stream_SealLength(s);
1516 if (Stream_Length(s) != frag_length)
1519 rc = rpc_channel_write(channel, Stream_Buffer(s), Stream_Length(s));
1522 if ((
size_t)rc != Stream_Length(s))
1531 BOOL rts_send_CONN_A1_pdu(rdpRpc* rpc)
1533 BOOL status = FALSE;
1536 UINT32 ReceiveWindowSize = 0;
1537 BYTE* OUTChannelCookie = NULL;
1538 BYTE* VirtualConnectionCookie = NULL;
1544 connection = rpc->VirtualConnection;
1545 WINPR_ASSERT(connection);
1547 outChannel = connection->DefaultOutChannel;
1548 WINPR_ASSERT(outChannel);
1550 header.header.frag_length = 76;
1551 header.Flags = RTS_FLAG_NONE;
1552 header.NumberOfCommands = 4;
1554 WLog_DBG(TAG,
"Sending CONN/A1 RTS PDU");
1555 VirtualConnectionCookie = (BYTE*)&(connection->Cookie);
1556 OUTChannelCookie = (BYTE*)&(outChannel->common.Cookie);
1557 ReceiveWindowSize = outChannel->ReceiveWindow;
1559 buffer = Stream_New(NULL, header.header.frag_length);
1564 if (!rts_write_pdu_header(buffer, &header))
1566 status = rts_version_command_write(buffer);
1569 status = rts_cookie_command_write(
1570 buffer, VirtualConnectionCookie);
1573 status = rts_cookie_command_write(buffer, OUTChannelCookie);
1576 status = rts_receive_window_size_command_write(
1577 buffer, ReceiveWindowSize);
1580 status = rts_send_buffer(&outChannel->common, buffer, header.header.frag_length);
1582 Stream_Free(buffer, TRUE);
1586 BOOL rts_recv_CONN_A3_pdu(rdpRpc* rpc,
wStream* buffer)
1589 UINT64 ConnectionTimeout = 0;
1591 if (!Stream_SafeSeek(buffer, 20))
1594 rc = rts_connection_timeout_command_read(rpc, buffer, &ConnectionTimeout);
1595 if (!rc || (ConnectionTimeout > UINT32_MAX))
1598 WLog_DBG(TAG,
"Receiving CONN/A3 RTS PDU: ConnectionTimeout: %" PRIu64
"", ConnectionTimeout);
1601 WINPR_ASSERT(rpc->VirtualConnection);
1602 WINPR_ASSERT(rpc->VirtualConnection->DefaultInChannel);
1604 rpc->VirtualConnection->DefaultInChannel->PingOriginator.ConnectionTimeout =
1605 (UINT32)ConnectionTimeout;
1611 BOOL rts_send_CONN_B1_pdu(rdpRpc* rpc)
1613 BOOL status = FALSE;
1616 BYTE* INChannelCookie = NULL;
1617 BYTE* AssociationGroupId = NULL;
1618 BYTE* VirtualConnectionCookie = NULL;
1624 connection = rpc->VirtualConnection;
1625 WINPR_ASSERT(connection);
1627 inChannel = connection->DefaultInChannel;
1628 WINPR_ASSERT(inChannel);
1630 header.header.frag_length = 104;
1631 header.Flags = RTS_FLAG_NONE;
1632 header.NumberOfCommands = 6;
1634 WLog_DBG(TAG,
"Sending CONN/B1 RTS PDU");
1636 VirtualConnectionCookie = (BYTE*)&(connection->Cookie);
1637 INChannelCookie = (BYTE*)&(inChannel->common.Cookie);
1638 AssociationGroupId = (BYTE*)&(connection->AssociationGroupId);
1639 buffer = Stream_New(NULL, header.header.frag_length);
1643 if (!rts_write_pdu_header(buffer, &header))
1645 if (!rts_version_command_write(buffer))
1647 if (!rts_cookie_command_write(buffer,
1648 VirtualConnectionCookie))
1650 if (!rts_cookie_command_write(buffer, INChannelCookie))
1652 if (!rts_channel_lifetime_command_write(buffer,
1653 rpc->ChannelLifetime))
1655 if (!rts_client_keepalive_command_write(buffer,
1656 rpc->KeepAliveInterval))
1658 if (!rts_association_group_id_command_write(
1659 buffer, AssociationGroupId))
1661 status = rts_send_buffer(&inChannel->common, buffer, header.header.frag_length);
1663 Stream_Free(buffer, TRUE);
1669 BOOL rts_recv_CONN_C2_pdu(rdpRpc* rpc,
wStream* buffer)
1672 UINT64 ReceiveWindowSize = 0;
1673 UINT64 ConnectionTimeout = 0;
1676 WINPR_ASSERT(buffer);
1678 if (!Stream_SafeSeek(buffer, 20))
1681 rc = rts_version_command_read(rpc, buffer);
1684 rc = rts_receive_window_size_command_read(rpc, buffer, &ReceiveWindowSize);
1685 if (!rc || (ReceiveWindowSize > UINT32_MAX))
1687 rc = rts_connection_timeout_command_read(rpc, buffer, &ConnectionTimeout);
1688 if (!rc || (ConnectionTimeout > UINT32_MAX))
1692 "Receiving CONN/C2 RTS PDU: ConnectionTimeout: %" PRIu64
" ReceiveWindowSize: %" PRIu64
1694 ConnectionTimeout, ReceiveWindowSize);
1697 WINPR_ASSERT(rpc->VirtualConnection);
1698 WINPR_ASSERT(rpc->VirtualConnection->DefaultInChannel);
1700 rpc->VirtualConnection->DefaultInChannel->PingOriginator.ConnectionTimeout =
1701 (UINT32)ConnectionTimeout;
1702 rpc->VirtualConnection->DefaultInChannel->PeerReceiveWindow = (UINT32)ReceiveWindowSize;
1708 BOOL rts_send_flow_control_ack_pdu(rdpRpc* rpc)
1710 BOOL status = FALSE;
1713 UINT32 BytesReceived = 0;
1714 UINT32 AvailableWindow = 0;
1715 BYTE* ChannelCookie = NULL;
1722 connection = rpc->VirtualConnection;
1723 WINPR_ASSERT(connection);
1725 inChannel = connection->DefaultInChannel;
1726 WINPR_ASSERT(inChannel);
1728 outChannel = connection->DefaultOutChannel;
1729 WINPR_ASSERT(outChannel);
1731 header.header.frag_length = 56;
1732 header.Flags = RTS_FLAG_OTHER_CMD;
1733 header.NumberOfCommands = 2;
1735 WLog_DBG(TAG,
"Sending FlowControlAck RTS PDU");
1737 BytesReceived = outChannel->BytesReceived;
1738 AvailableWindow = outChannel->AvailableWindowAdvertised;
1739 ChannelCookie = (BYTE*)&(outChannel->common.Cookie);
1740 outChannel->ReceiverAvailableWindow = outChannel->AvailableWindowAdvertised;
1741 buffer = Stream_New(NULL, header.header.frag_length);
1746 if (!rts_write_pdu_header(buffer, &header))
1748 if (!rts_destination_command_write(buffer, FDOutProxy))
1752 if (!rts_flow_control_ack_command_write(buffer, BytesReceived, AvailableWindow, ChannelCookie))
1755 status = rts_send_buffer(&inChannel->common, buffer, header.header.frag_length);
1757 Stream_Free(buffer, TRUE);
1761 static int rts_recv_flow_control_ack_pdu(rdpRpc* rpc,
wStream* buffer)
1764 UINT32 BytesReceived = 0;
1765 UINT32 AvailableWindow = 0;
1766 BYTE ChannelCookie[16] = { 0 };
1768 rc = rts_flow_control_ack_command_read(rpc, buffer, &BytesReceived, &AvailableWindow,
1769 (BYTE*)&ChannelCookie);
1773 "Receiving FlowControlAck RTS PDU: BytesReceived: %" PRIu32
1774 " AvailableWindow: %" PRIu32
"",
1775 BytesReceived, AvailableWindow);
1777 WINPR_ASSERT(rpc->VirtualConnection);
1778 WINPR_ASSERT(rpc->VirtualConnection->DefaultInChannel);
1780 rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow =
1781 AvailableWindow - (rpc->VirtualConnection->DefaultInChannel->BytesSent - BytesReceived);
1785 static int rts_recv_flow_control_ack_with_destination_pdu(rdpRpc* rpc,
wStream* buffer)
1788 UINT32 Destination = 0;
1789 UINT32 BytesReceived = 0;
1790 UINT32 AvailableWindow = 0;
1791 BYTE ChannelCookie[16] = { 0 };
1809 int rc = rts_destination_command_read(rpc, buffer, &Command);
1813 if (Command != RTS_CMD_DESTINATION)
1815 char buffer1[64] = { 0 };
1816 char buffer2[64] = { 0 };
1817 WLog_Print(rpc->log, WLOG_ERROR,
"got command %s, expected %s",
1818 rts_command_to_string(Command, buffer1,
sizeof(buffer1)),
1819 rts_command_to_string(RTS_CMD_DESTINATION, buffer2,
sizeof(buffer2)));
1823 rc = rts_destination_command_read(rpc, buffer, &Destination);
1827 switch (Destination)
1838 WLog_Print(rpc->log, WLOG_ERROR,
1839 "got destination %" PRIu32
1840 ", expected one of [FDClient[0]|FDInProxy[1]|FDServer[2]|FDOutProxy[3]",
1845 rc = rts_flow_control_ack_command_read(rpc, buffer, &BytesReceived, &AvailableWindow,
1851 "Receiving FlowControlAckWithDestination RTS PDU: BytesReceived: %" PRIu32
1852 " AvailableWindow: %" PRIu32
"",
1853 BytesReceived, AvailableWindow);
1855 WINPR_ASSERT(rpc->VirtualConnection);
1856 WINPR_ASSERT(rpc->VirtualConnection->DefaultInChannel);
1857 rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow =
1858 AvailableWindow - (rpc->VirtualConnection->DefaultInChannel->BytesSent - BytesReceived);
1862 BOOL rts_recv_ping_pdu(rdpRpc* rpc,
wStream* s)
1868 WINPR_ASSERT(rpc->auth);
1871 if (!rts_read_pdu_header(s, &header))
1875 if (header.common.ptype != PTYPE_RTS)
1877 WLog_Print(rpc->log, WLOG_ERROR,
"received invalid ping PDU, type is 0x%" PRIx32,
1878 header.common.ptype);
1881 if (header.rts.Flags != RTS_FLAG_PING)
1883 WLog_Print(rpc->log, WLOG_ERROR,
"received unexpected ping PDU::Flags 0x%" PRIx32,
1888 rts_free_pdu_header(&header, FALSE);
1892 static int rts_send_ping_pdu(rdpRpc* rpc)
1894 BOOL status = FALSE;
1900 WINPR_ASSERT(rpc->VirtualConnection);
1902 inChannel = rpc->VirtualConnection->DefaultInChannel;
1903 WINPR_ASSERT(inChannel);
1905 header.header.frag_length = 20;
1906 header.Flags = RTS_FLAG_PING;
1907 header.NumberOfCommands = 0;
1909 WLog_DBG(TAG,
"Sending Ping RTS PDU");
1910 buffer = Stream_New(NULL, header.header.frag_length);
1915 if (!rts_write_pdu_header(buffer, &header))
1917 status = rts_send_buffer(&inChannel->common, buffer, header.header.frag_length);
1919 Stream_Free(buffer, TRUE);
1920 return (status) ? 1 : -1;
1923 BOOL rts_command_length(UINT32 CommandType,
wStream* s,
size_t* length, BOOL silent)
1926 size_t CommandLength = 0;
1930 switch (CommandType)
1932 case RTS_CMD_RECEIVE_WINDOW_SIZE:
1933 CommandLength = RTS_CMD_RECEIVE_WINDOW_SIZE_LENGTH;
1936 case RTS_CMD_FLOW_CONTROL_ACK:
1937 CommandLength = RTS_CMD_FLOW_CONTROL_ACK_LENGTH;
1940 case RTS_CMD_CONNECTION_TIMEOUT:
1941 CommandLength = RTS_CMD_CONNECTION_TIMEOUT_LENGTH;
1944 case RTS_CMD_COOKIE:
1945 CommandLength = RTS_CMD_COOKIE_LENGTH;
1948 case RTS_CMD_CHANNEL_LIFETIME:
1949 CommandLength = RTS_CMD_CHANNEL_LIFETIME_LENGTH;
1952 case RTS_CMD_CLIENT_KEEPALIVE:
1953 CommandLength = RTS_CMD_CLIENT_KEEPALIVE_LENGTH;
1956 case RTS_CMD_VERSION:
1957 CommandLength = RTS_CMD_VERSION_LENGTH;
1961 CommandLength = RTS_CMD_EMPTY_LENGTH;
1964 case RTS_CMD_PADDING:
1965 if (!rts_padding_command_read(s, &padding, silent))
1969 case RTS_CMD_NEGATIVE_ANCE:
1970 CommandLength = RTS_CMD_NEGATIVE_ANCE_LENGTH;
1974 CommandLength = RTS_CMD_ANCE_LENGTH;
1977 case RTS_CMD_CLIENT_ADDRESS:
1978 if (!rts_client_address_command_read(s, &CommandLength, silent))
1982 case RTS_CMD_ASSOCIATION_GROUP_ID:
1983 CommandLength = RTS_CMD_ASSOCIATION_GROUP_ID_LENGTH;
1986 case RTS_CMD_DESTINATION:
1987 CommandLength = RTS_CMD_DESTINATION_LENGTH;
1990 case RTS_CMD_PING_TRAFFIC_SENT_NOTIFY:
1991 CommandLength = RTS_CMD_PING_TRAFFIC_SENT_NOTIFY_LENGTH;
1995 WLog_ERR(TAG,
"Error: Unknown RTS Command Type: 0x%" PRIx32
"", CommandType);
1999 CommandLength += padding;
2000 if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, CommandLength, silent))
2004 *length = CommandLength;
2008 static int rts_send_OUT_R2_A7_pdu(rdpRpc* rpc)
2010 BOOL status = FALSE;
2013 BYTE* SuccessorChannelCookie = NULL;
2018 WINPR_ASSERT(rpc->VirtualConnection);
2020 inChannel = rpc->VirtualConnection->DefaultInChannel;
2021 WINPR_ASSERT(inChannel);
2023 nextOutChannel = rpc->VirtualConnection->NonDefaultOutChannel;
2024 WINPR_ASSERT(nextOutChannel);
2026 header.header.frag_length = 56;
2027 header.Flags = RTS_FLAG_OUT_CHANNEL;
2028 header.NumberOfCommands = 3;
2030 WLog_DBG(TAG,
"Sending OUT_R2/A7 RTS PDU");
2032 SuccessorChannelCookie = (BYTE*)&(nextOutChannel->common.Cookie);
2033 buffer = Stream_New(NULL, header.header.frag_length);
2038 if (!rts_write_pdu_header(buffer, &header))
2040 if (!rts_destination_command_write(buffer, FDServer))
2042 if (!rts_cookie_command_write(buffer,
2043 SuccessorChannelCookie))
2045 if (!rts_version_command_write(buffer))
2047 status = rts_send_buffer(&inChannel->common, buffer, header.header.frag_length);
2049 Stream_Free(buffer, TRUE);
2050 return (status) ? 1 : -1;
2053 static int rts_send_OUT_R2_C1_pdu(rdpRpc* rpc)
2055 BOOL status = FALSE;
2061 WINPR_ASSERT(rpc->VirtualConnection);
2063 nextOutChannel = rpc->VirtualConnection->NonDefaultOutChannel;
2064 WINPR_ASSERT(nextOutChannel);
2066 header.header.frag_length = 24;
2067 header.Flags = RTS_FLAG_PING;
2068 header.NumberOfCommands = 1;
2070 WLog_DBG(TAG,
"Sending OUT_R2/C1 RTS PDU");
2071 buffer = Stream_New(NULL, header.header.frag_length);
2076 if (!rts_write_pdu_header(buffer, &header))
2079 if (!rts_empty_command_write(buffer))
2081 status = rts_send_buffer(&nextOutChannel->common, buffer, header.header.frag_length);
2083 Stream_Free(buffer, TRUE);
2084 return (status) ? 1 : -1;
2087 BOOL rts_send_OUT_R1_A3_pdu(rdpRpc* rpc)
2089 BOOL status = FALSE;
2092 UINT32 ReceiveWindowSize = 0;
2093 BYTE* VirtualConnectionCookie = NULL;
2094 BYTE* PredecessorChannelCookie = NULL;
2095 BYTE* SuccessorChannelCookie = NULL;
2102 connection = rpc->VirtualConnection;
2103 WINPR_ASSERT(connection);
2105 outChannel = connection->DefaultOutChannel;
2106 WINPR_ASSERT(outChannel);
2108 nextOutChannel = connection->NonDefaultOutChannel;
2109 WINPR_ASSERT(nextOutChannel);
2111 header.header.frag_length = 96;
2112 header.Flags = RTS_FLAG_RECYCLE_CHANNEL;
2113 header.NumberOfCommands = 5;
2115 WLog_DBG(TAG,
"Sending OUT_R1/A3 RTS PDU");
2117 VirtualConnectionCookie = (BYTE*)&(connection->Cookie);
2118 PredecessorChannelCookie = (BYTE*)&(outChannel->common.Cookie);
2119 SuccessorChannelCookie = (BYTE*)&(nextOutChannel->common.Cookie);
2120 ReceiveWindowSize = outChannel->ReceiveWindow;
2121 buffer = Stream_New(NULL, header.header.frag_length);
2126 if (!rts_write_pdu_header(buffer, &header))
2128 if (!rts_version_command_write(buffer))
2130 if (!rts_cookie_command_write(buffer,
2131 VirtualConnectionCookie))
2133 if (!rts_cookie_command_write(
2134 buffer, PredecessorChannelCookie))
2136 if (!rts_cookie_command_write(buffer,
2137 SuccessorChannelCookie))
2139 if (!rts_receive_window_size_command_write(buffer,
2143 status = rts_send_buffer(&nextOutChannel->common, buffer, header.header.frag_length);
2145 Stream_Free(buffer, TRUE);
2149 static int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc,
wStream* buffer)
2152 UINT32 Destination = 0;
2155 WINPR_ASSERT(buffer);
2157 connection = rpc->VirtualConnection;
2158 WINPR_ASSERT(connection);
2160 WLog_DBG(TAG,
"Receiving OUT R1/A2 RTS PDU");
2162 status = rts_destination_command_read(rpc, buffer, &Destination);
2166 connection->NonDefaultOutChannel = rpc_out_channel_new(rpc, &connection->Cookie);
2168 if (!connection->NonDefaultOutChannel)
2171 status = rpc_out_channel_replacement_connect(connection->NonDefaultOutChannel, 5000);
2175 WLog_ERR(TAG,
"rpc_out_channel_replacement_connect failure");
2179 rpc_out_channel_transition_to_state(connection->DefaultOutChannel,
2180 CLIENT_OUT_CHANNEL_STATE_OPENED_A6W);
2184 static int rts_recv_OUT_R2_A6_pdu(rdpRpc* rpc,
wStream* buffer)
2190 WINPR_ASSERT(buffer);
2192 connection = rpc->VirtualConnection;
2193 WINPR_ASSERT(connection);
2195 WLog_DBG(TAG,
"Receiving OUT R2/A6 RTS PDU");
2196 status = rts_send_OUT_R2_C1_pdu(rpc);
2200 WLog_ERR(TAG,
"rts_send_OUT_R2_C1_pdu failure");
2204 status = rts_send_OUT_R2_A7_pdu(rpc);
2208 WLog_ERR(TAG,
"rts_send_OUT_R2_A7_pdu failure");
2212 rpc_out_channel_transition_to_state(connection->NonDefaultOutChannel,
2213 CLIENT_OUT_CHANNEL_STATE_OPENED_B3W);
2214 rpc_out_channel_transition_to_state(connection->DefaultOutChannel,
2215 CLIENT_OUT_CHANNEL_STATE_OPENED_B3W);
2219 static int rts_recv_OUT_R2_B3_pdu(rdpRpc* rpc,
wStream* buffer)
2224 WINPR_ASSERT(buffer);
2226 connection = rpc->VirtualConnection;
2227 WINPR_ASSERT(connection);
2229 WLog_DBG(TAG,
"Receiving OUT R2/B3 RTS PDU");
2230 rpc_out_channel_transition_to_state(connection->DefaultOutChannel,
2231 CLIENT_OUT_CHANNEL_STATE_RECYCLED);
2237 BOOL status = FALSE;
2243 WINPR_ASSERT(buffer);
2244 WINPR_ASSERT(header);
2246 wLog* log = WLog_Get(TAG);
2248 const size_t total = Stream_Length(buffer);
2249 length = header->common.frag_length;
2252 WLog_Print(log, WLOG_ERROR,
"PDU length %" PRIuz
" does not match available data %" PRIuz,
2257 connection = rpc->VirtualConnection;
2261 WLog_Print(log, WLOG_ERROR,
"not connected, aborting");
2265 if (!rts_extract_pdu_signature(&signature, buffer, header))
2268 rts_print_pdu_signature(log, WLOG_TRACE, &signature);
2270 if (memcmp(&signature, &RTS_PDU_FLOW_CONTROL_ACK_SIGNATURE,
sizeof(signature)) == 0)
2272 status = rts_recv_flow_control_ack_pdu(rpc, buffer);
2274 else if (memcmp(&signature, &RTS_PDU_FLOW_CONTROL_ACK_WITH_DESTINATION_SIGNATURE,
2275 sizeof(signature)) == 0)
2277 status = rts_recv_flow_control_ack_with_destination_pdu(rpc, buffer);
2279 else if (memcmp(&signature, &RTS_PDU_PING_SIGNATURE,
sizeof(signature)) == 0)
2281 status = rts_send_ping_pdu(rpc);
2285 if (connection->DefaultOutChannel->State == CLIENT_OUT_CHANNEL_STATE_OPENED)
2287 if (memcmp(&signature, &RTS_PDU_OUT_R1_A2_SIGNATURE,
sizeof(signature)) == 0)
2289 status = rts_recv_OUT_R1_A2_pdu(rpc, buffer);
2292 else if (connection->DefaultOutChannel->State == CLIENT_OUT_CHANNEL_STATE_OPENED_A6W)
2294 if (memcmp(&signature, &RTS_PDU_OUT_R2_A6_SIGNATURE,
sizeof(signature)) == 0)
2296 status = rts_recv_OUT_R2_A6_pdu(rpc, buffer);
2299 else if (connection->DefaultOutChannel->State == CLIENT_OUT_CHANNEL_STATE_OPENED_B3W)
2301 if (memcmp(&signature, &RTS_PDU_OUT_R2_B3_SIGNATURE,
sizeof(signature)) == 0)
2303 status = rts_recv_OUT_R2_B3_pdu(rpc, buffer);
2310 const UINT32 SignatureId = rts_identify_pdu_signature(&signature, NULL);
2311 WLog_Print(log, WLOG_ERROR,
"error parsing RTS PDU with signature id: 0x%08" PRIX32
"",
2313 rts_print_pdu_signature(log, WLOG_ERROR, &signature);
2316 const size_t rem = Stream_GetRemainingLength(buffer);
2319 WLog_Print(log, WLOG_ERROR,
"%" PRIuz
" bytes or %" PRIuz
" total not parsed, aborting",
2321 rts_print_pdu_signature(log, WLOG_ERROR, &signature);
2333 if (!rts_write_common_pdu_header(s, &auth->header))
2336 if (!Stream_EnsureRemainingCapacity(s, 2 *
sizeof(UINT16)))
2339 Stream_Write_UINT16(s, auth->max_xmit_frag);
2340 Stream_Write_UINT16(s, auth->max_recv_frag);
2342 return rts_write_auth_verifier(s, &auth->auth_verifier, &auth->header);
2351 if (!rts_write_common_pdu_header(s, &bind->header))
2354 if (!Stream_EnsureRemainingCapacity(s, 8))
2357 Stream_Write_UINT16(s, bind->max_xmit_frag);
2358 Stream_Write_UINT16(s, bind->max_recv_frag);
2359 Stream_Write_UINT32(s, bind->assoc_group_id);
2361 if (!rts_write_context_list(s, &bind->p_context_elem))
2364 return rts_write_auth_verifier(s, &bind->auth_verifier, &bind->header);
2367 BOOL rts_conditional_check_and_log(
const char* tag,
wStream* s,
size_t size, BOOL silent,
2368 const char* fkt,
const char* file,
size_t line)
2372 const size_t rem = Stream_GetRemainingLength(s);
2378 return Stream_CheckAndLogRequiredLengthEx(tag, WLOG_WARN, s, size, 1,
"%s(%s:%" PRIuz
")", fkt,
2382 BOOL rts_conditional_safe_seek(
wStream* s,
size_t size, BOOL silent,
const char* fkt,
2383 const char* file,
size_t line)
2387 const size_t rem = Stream_GetRemainingLength(s);
2391 return Stream_SafeSeekEx(s, size, file, line, fkt);