24 #include <freerdp/config.h>
28 #include <winpr/crt.h>
29 #include <winpr/crypto.h>
30 #include <winpr/assert.h>
31 #include <winpr/cast.h>
33 #include <freerdp/log.h>
34 #include <freerdp/utils/string.h>
35 #include <freerdp/crypto/certificate.h>
41 #include "../crypto/certificate.h"
43 #define TAG FREERDP_TAG("core.gcc")
47 HIGH_COLOR_4BPP = 0x04,
48 HIGH_COLOR_8BPP = 0x08,
49 HIGH_COLOR_15BPP = 0x0F,
50 HIGH_COLOR_16BPP = 0x10,
51 HIGH_COLOR_24BPP = 0x18,
54 static const char* HighColorToString(HIGH_COLOR_DEPTH color)
59 return "HIGH_COLOR_4BPP";
61 return "HIGH_COLOR_8BPP";
62 case HIGH_COLOR_15BPP:
63 return "HIGH_COLOR_15BPP";
64 case HIGH_COLOR_16BPP:
65 return "HIGH_COLOR_16BPP";
66 case HIGH_COLOR_24BPP:
67 return "HIGH_COLOR_24BPP";
69 return "HIGH_COLOR_UNKNOWN";
73 static HIGH_COLOR_DEPTH ColorDepthToHighColor(UINT32 bpp)
78 return HIGH_COLOR_4BPP;
80 return HIGH_COLOR_8BPP;
82 return HIGH_COLOR_15BPP;
84 return HIGH_COLOR_16BPP;
86 return HIGH_COLOR_24BPP;
90 static char* gcc_block_type_string(UINT16 type,
char* buffer,
size_t size);
91 static BOOL gcc_read_client_cluster_data(
wStream* s, rdpMcs* mcs);
92 static BOOL gcc_read_client_core_data(
wStream* s, rdpMcs* mcs);
93 static BOOL gcc_read_client_data_blocks(
wStream* s, rdpMcs* mcs, UINT16 length);
94 static BOOL gcc_read_server_data_blocks(
wStream* s, rdpMcs* mcs, UINT16 length);
95 static BOOL gcc_read_user_data_header(
wStream* s, UINT16* type, UINT16* length);
96 static BOOL gcc_write_user_data_header(
wStream* s, UINT16 type, UINT16 length);
98 static BOOL gcc_write_client_core_data(
wStream* s,
const rdpMcs* mcs);
99 static BOOL gcc_read_server_core_data(
wStream* s, rdpMcs* mcs);
100 static BOOL gcc_write_server_core_data(
wStream* s, rdpMcs* mcs);
101 static BOOL gcc_read_client_security_data(
wStream* s, rdpMcs* mcs);
102 static BOOL gcc_write_client_security_data(
wStream* s,
const rdpMcs* mcs);
103 static BOOL gcc_read_server_security_data(
wStream* s, rdpMcs* mcs);
104 static BOOL gcc_write_server_security_data(
wStream* s, rdpMcs* mcs);
105 static BOOL gcc_read_client_network_data(
wStream* s, rdpMcs* mcs);
106 static BOOL gcc_write_client_network_data(
wStream* s,
const rdpMcs* mcs);
107 static BOOL gcc_read_server_network_data(
wStream* s, rdpMcs* mcs);
108 static BOOL gcc_write_server_network_data(
wStream* s,
const rdpMcs* mcs);
109 static BOOL gcc_write_client_cluster_data(
wStream* s,
const rdpMcs* mcs);
110 static BOOL gcc_read_client_monitor_data(
wStream* s, rdpMcs* mcs);
111 static BOOL gcc_write_client_monitor_data(
wStream* s,
const rdpMcs* mcs);
112 static BOOL gcc_read_client_monitor_extended_data(
wStream* s, rdpMcs* mcs);
113 static BOOL gcc_write_client_monitor_extended_data(
wStream* s,
const rdpMcs* mcs);
114 static BOOL gcc_read_client_message_channel_data(
wStream* s, rdpMcs* mcs);
115 static BOOL gcc_write_client_message_channel_data(
wStream* s,
const rdpMcs* mcs);
116 static BOOL gcc_read_server_message_channel_data(
wStream* s, rdpMcs* mcs);
117 static BOOL gcc_write_server_message_channel_data(
wStream* s,
const rdpMcs* mcs);
118 static BOOL gcc_read_client_multitransport_channel_data(
wStream* s, rdpMcs* mcs);
119 static BOOL gcc_write_client_multitransport_channel_data(
wStream* s,
const rdpMcs* mcs);
120 static BOOL gcc_read_server_multitransport_channel_data(
wStream* s, rdpMcs* mcs);
121 static BOOL gcc_write_server_multitransport_channel_data(
wStream* s,
const rdpMcs* mcs);
123 static rdpSettings* mcs_get_settings(rdpMcs* mcs)
127 rdpContext* context = transport_get_context(mcs->transport);
128 WINPR_ASSERT(context);
130 return context->settings;
133 static const rdpSettings* mcs_get_const_settings(
const rdpMcs* mcs)
137 const rdpContext* context = transport_get_context(mcs->transport);
138 WINPR_ASSERT(context);
140 return context->settings;
143 static char* rdp_early_server_caps_string(UINT32 flags,
char* buffer,
size_t size)
145 char msg[32] = { 0 };
146 const UINT32 mask = RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1 | RNS_UD_SC_DYNAMIC_DST_SUPPORTED |
147 RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2 | RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED;
148 const UINT32 unknown = flags & (~mask);
150 if (flags & RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1)
151 winpr_str_append(
"RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1", buffer, size,
"|");
152 if (flags & RNS_UD_SC_DYNAMIC_DST_SUPPORTED)
153 winpr_str_append(
"RNS_UD_SC_DYNAMIC_DST_SUPPORTED", buffer, size,
"|");
154 if (flags & RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2)
155 winpr_str_append(
"RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2", buffer, size,
"|");
156 if (flags & RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED)
157 winpr_str_append(
"RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED", buffer, size,
"|");
161 (void)_snprintf(msg,
sizeof(msg),
"RNS_UD_SC_UNKNOWN[0x%08" PRIx32
"]", unknown);
162 winpr_str_append(msg, buffer, size,
"|");
164 (void)_snprintf(msg,
sizeof(msg),
"[0x%08" PRIx32
"]", flags);
165 winpr_str_append(msg, buffer, size,
"|");
169 static const char* rdp_early_client_caps_string(UINT32 flags,
char* buffer,
size_t size)
171 char msg[32] = { 0 };
172 const UINT32 mask = RNS_UD_CS_SUPPORT_ERRINFO_PDU | RNS_UD_CS_WANT_32BPP_SESSION |
173 RNS_UD_CS_SUPPORT_STATUSINFO_PDU | RNS_UD_CS_STRONG_ASYMMETRIC_KEYS |
174 RNS_UD_CS_RELATIVE_MOUSE_INPUT | RNS_UD_CS_VALID_CONNECTION_TYPE |
175 RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU |
176 RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT |
177 RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL | RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE |
178 RNS_UD_CS_SUPPORT_HEARTBEAT_PDU | RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN;
179 const UINT32 unknown = flags & (~mask);
181 if (flags & RNS_UD_CS_SUPPORT_ERRINFO_PDU)
182 winpr_str_append(
"RNS_UD_CS_SUPPORT_ERRINFO_PDU", buffer, size,
"|");
183 if (flags & RNS_UD_CS_WANT_32BPP_SESSION)
184 winpr_str_append(
"RNS_UD_CS_WANT_32BPP_SESSION", buffer, size,
"|");
185 if (flags & RNS_UD_CS_SUPPORT_STATUSINFO_PDU)
186 winpr_str_append(
"RNS_UD_CS_SUPPORT_STATUSINFO_PDU", buffer, size,
"|");
187 if (flags & RNS_UD_CS_STRONG_ASYMMETRIC_KEYS)
188 winpr_str_append(
"RNS_UD_CS_STRONG_ASYMMETRIC_KEYS", buffer, size,
"|");
189 if (flags & RNS_UD_CS_RELATIVE_MOUSE_INPUT)
190 winpr_str_append(
"RNS_UD_CS_RELATIVE_MOUSE_INPUT", buffer, size,
"|");
191 if (flags & RNS_UD_CS_VALID_CONNECTION_TYPE)
192 winpr_str_append(
"RNS_UD_CS_VALID_CONNECTION_TYPE", buffer, size,
"|");
193 if (flags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU)
194 winpr_str_append(
"RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU", buffer, size,
"|");
195 if (flags & RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT)
196 winpr_str_append(
"RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT", buffer, size,
"|");
197 if (flags & RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL)
198 winpr_str_append(
"RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL", buffer, size,
"|");
199 if (flags & RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE)
200 winpr_str_append(
"RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE", buffer, size,
"|");
201 if (flags & RNS_UD_CS_SUPPORT_HEARTBEAT_PDU)
202 winpr_str_append(
"RNS_UD_CS_SUPPORT_HEARTBEAT_PDU", buffer, size,
"|");
203 if (flags & RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN)
204 winpr_str_append(
"RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN", buffer, size,
"|");
208 (void)_snprintf(msg,
sizeof(msg),
"RNS_UD_CS_UNKNOWN[0x%08" PRIx32
"]", unknown);
209 winpr_str_append(msg, buffer, size,
"|");
211 (void)_snprintf(msg,
sizeof(msg),
"[0x%08" PRIx32
"]", flags);
212 winpr_str_append(msg, buffer, size,
"|");
216 static DWORD rdp_version_common(DWORD serverVersion, DWORD clientVersion)
218 DWORD version = MIN(serverVersion, clientVersion);
223 case RDP_VERSION_5_PLUS:
224 case RDP_VERSION_10_0:
225 case RDP_VERSION_10_1:
226 case RDP_VERSION_10_2:
227 case RDP_VERSION_10_3:
228 case RDP_VERSION_10_4:
229 case RDP_VERSION_10_5:
230 case RDP_VERSION_10_6:
231 case RDP_VERSION_10_7:
232 case RDP_VERSION_10_8:
233 case RDP_VERSION_10_9:
234 case RDP_VERSION_10_10:
235 case RDP_VERSION_10_11:
236 case RDP_VERSION_10_12:
240 WLog_ERR(TAG,
"Invalid client [%" PRId32
"] and server [%" PRId32
"] versions",
241 serverVersion, clientVersion);
345 static const BYTE t124_02_98_oid[6] = { 0, 0, 20, 124, 0, 1 };
347 static const BYTE h221_cs_key[4] =
"Duca";
348 static const BYTE h221_sc_key[4] =
"McDn";
360 BOOL gcc_read_conference_create_request(
wStream* s, rdpMcs* mcs)
370 if (!per_read_choice(s, &choice))
373 if (!per_read_object_identifier(s, t124_02_98_oid))
377 if (!per_read_length(s, &length))
381 if (!per_read_choice(s, &choice))
384 if (!per_read_selection(s, &selection))
388 if (!per_read_numeric_string(s, 1))
391 if (!per_read_padding(s, 1))
395 if (!per_read_number_of_sets(s, &number) || number != 1)
398 if (!per_read_choice(s, &choice) ||
403 if (!per_read_octet_string(s, h221_cs_key, 4,
408 if (!per_read_length(s, &length))
411 if (!Stream_CheckAndLogRequiredLength(TAG, s, length))
414 if (!gcc_read_client_data_blocks(s, mcs, length))
430 BOOL gcc_write_conference_create_request(
wStream* s,
wStream* userData)
433 WINPR_ASSERT(userData);
435 if (!per_write_choice(s, 0))
437 if (!per_write_object_identifier(s, t124_02_98_oid))
440 const size_t pos = Stream_GetPosition(userData);
441 WINPR_ASSERT(pos <= UINT16_MAX - 14);
442 if (!per_write_length(s, (UINT16)pos + 14))
445 if (!per_write_choice(s, 0))
448 if (!per_write_selection(s, 0x08))
451 if (!per_write_numeric_string(s, (BYTE*)
"1", 1, 1))
453 if (!per_write_padding(s, 1))
456 if (!per_write_number_of_sets(s, 1))
458 if (!per_write_choice(s, 0xC0))
461 if (!per_write_octet_string(s, h221_cs_key, 4,
465 const size_t upos = Stream_GetPosition(userData);
466 WINPR_ASSERT(upos <= UINT16_MAX);
467 return per_write_octet_string(s, Stream_Buffer(userData), (UINT16)upos,
471 BOOL gcc_read_conference_create_response(
wStream* s, rdpMcs* mcs)
482 if (!per_read_choice(s, &choice) || !per_read_object_identifier(s, t124_02_98_oid))
486 if (!per_read_length(s, &length))
490 if (!per_read_choice(s, &choice))
494 if (!per_read_integer16(s, &nodeID, 1001))
498 if (!per_read_integer(s, &tag))
502 if (!per_read_enumerated(s, &result, MCS_Result_enum_length))
506 if (!per_read_number_of_sets(s, &number))
510 if (!per_read_choice(s, &choice))
514 if (!per_read_octet_string(s, h221_sc_key, 4,
519 if (!per_read_length(s, &length))
522 if (!gcc_read_server_data_blocks(s, mcs, length))
524 WLog_ERR(TAG,
"gcc_read_conference_create_response: gcc_read_server_data_blocks failed");
531 BOOL gcc_write_conference_create_response(
wStream* s,
wStream* userData)
534 WINPR_ASSERT(userData);
536 if (!per_write_choice(s, 0))
538 if (!per_write_object_identifier(s, t124_02_98_oid))
542 if (!per_write_length(s, 0x2A))
545 if (!per_write_choice(s, 0x14))
548 if (!per_write_integer16(s, 0x79F3, 1001))
551 if (!per_write_integer(s, 1))
554 if (!per_write_enumerated(s, 0, MCS_Result_enum_length))
557 if (!per_write_number_of_sets(s, 1))
560 if (!per_write_choice(s, 0xC0))
563 if (!per_write_octet_string(s, h221_sc_key, 4,
567 const size_t pos = Stream_GetPosition(userData);
568 WINPR_ASSERT(pos <= UINT16_MAX);
569 return per_write_octet_string(s, Stream_Buffer(userData), (UINT16)pos,
573 static BOOL gcc_read_client_unused1_data(
wStream* s)
575 return Stream_SafeSeek(s, 2);
578 BOOL gcc_read_client_data_blocks(
wStream* s, rdpMcs* mcs, UINT16 length)
583 BOOL gotMultitransport = FALSE;
589 UINT16 blockLength = 0;
591 if (!gcc_read_user_data_header(s, &type, &blockLength))
594 if (!Stream_CheckAndLogRequiredLength(TAG, s, (
size_t)(blockLength - 4)))
597 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), blockLength - 4);
600 Stream_Seek(s, blockLength - 4);
605 if (!gcc_read_client_core_data(sub, mcs))
611 if (!gcc_read_client_security_data(sub, mcs))
617 if (!gcc_read_client_network_data(sub, mcs))
623 if (!gcc_read_client_cluster_data(sub, mcs))
629 if (!gcc_read_client_monitor_data(sub, mcs))
634 case CS_MCS_MSGCHANNEL:
635 if (!gcc_read_client_message_channel_data(sub, mcs))
641 if (!gcc_read_client_monitor_extended_data(sub, mcs))
647 if (!gcc_read_client_unused1_data(sub))
653 case CS_MULTITRANSPORT:
654 gotMultitransport = TRUE;
655 if (!gcc_read_client_multitransport_channel_data(sub, mcs))
661 WLog_ERR(TAG,
"Unknown GCC client data block: 0x%04" PRIX16
"", type);
662 winpr_HexDump(TAG, WLOG_TRACE, Stream_Pointer(sub), Stream_GetRemainingLength(sub));
666 const size_t rem = Stream_GetRemainingLength(sub);
669 char buffer[128] = { 0 };
670 const size_t total = Stream_Length(sub);
672 "Error parsing GCC client data block %s: Actual Offset: %" PRIuz
673 " Expected Offset: %" PRIuz,
674 gcc_block_type_string(type, buffer,
sizeof(buffer)), total - rem, total);
677 if (blockLength > length)
679 char buffer[128] = { 0 };
681 "Error parsing GCC client data block %s: got blockLength 0x%04" PRIx16
682 ", but only 0x%04" PRIx16
"remaining",
683 gcc_block_type_string(type, buffer,
sizeof(buffer)), blockLength, length);
687 length -= blockLength;
690 if (!gotMultitransport)
692 rdpSettings* settings = mcs_get_settings(mcs);
701 BOOL gcc_write_client_data_blocks(
wStream* s,
const rdpMcs* mcs)
703 const rdpSettings* settings = mcs_get_const_settings(mcs);
706 WINPR_ASSERT(settings);
708 if (!gcc_write_client_core_data(s, mcs) || !gcc_write_client_cluster_data(s, mcs) ||
709 !gcc_write_client_security_data(s, mcs) || !gcc_write_client_network_data(s, mcs))
714 if (settings->NegotiationFlags & EXTENDED_CLIENT_DATA_SUPPORTED)
716 if (settings->UseMultimon && !settings->SpanMonitors)
718 if (!gcc_write_client_monitor_data(s, mcs) ||
719 !gcc_write_client_monitor_extended_data(s, mcs))
723 if (!gcc_write_client_message_channel_data(s, mcs) ||
724 !gcc_write_client_multitransport_channel_data(s, mcs))
729 if (settings->UseMultimon && !settings->SpanMonitors)
731 WLog_ERR(TAG,
"WARNING: true multi monitor support was not advertised by server!");
733 if (settings->ForceMultimon)
735 WLog_ERR(TAG,
"Sending multi monitor information anyway (may break connectivity!)");
736 if (!gcc_write_client_monitor_data(s, mcs) ||
737 !gcc_write_client_monitor_extended_data(s, mcs))
742 WLog_ERR(TAG,
"Use /multimon:force to force sending multi monitor information");
749 char* gcc_block_type_string(UINT16 type,
char* buffer,
size_t size)
754 (void)_snprintf(buffer, size,
"CS_CORE [0x%04" PRIx16
"]", type);
757 (void)_snprintf(buffer, size,
"CS_SECURITY [0x%04" PRIx16
"]", type);
760 (void)_snprintf(buffer, size,
"CS_NET [0x%04" PRIx16
"]", type);
763 (void)_snprintf(buffer, size,
"CS_CLUSTER [0x%04" PRIx16
"]", type);
766 (void)_snprintf(buffer, size,
"CS_MONITOR [0x%04" PRIx16
"]", type);
768 case CS_MCS_MSGCHANNEL:
769 (void)_snprintf(buffer, size,
"CS_MONITOR [0x%04" PRIx16
"]", type);
772 (void)_snprintf(buffer, size,
"CS_MONITOR_EX [0x%04" PRIx16
"]", type);
775 (void)_snprintf(buffer, size,
"CS_UNUSED1 [0x%04" PRIx16
"]", type);
777 case CS_MULTITRANSPORT:
778 (void)_snprintf(buffer, size,
"CS_MONITOR_EX [0x%04" PRIx16
"]", type);
781 (void)_snprintf(buffer, size,
"SC_CORE [0x%04" PRIx16
"]", type);
784 (void)_snprintf(buffer, size,
"SC_SECURITY [0x%04" PRIx16
"]", type);
787 (void)_snprintf(buffer, size,
"SC_NET [0x%04" PRIx16
"]", type);
789 case SC_MCS_MSGCHANNEL:
790 (void)_snprintf(buffer, size,
"SC_MCS_MSGCHANNEL [0x%04" PRIx16
"]", type);
792 case SC_MULTITRANSPORT:
793 (void)_snprintf(buffer, size,
"SC_MULTITRANSPORT [0x%04" PRIx16
"]", type);
796 (void)_snprintf(buffer, size,
"UNKNOWN [0x%04" PRIx16
"]", type);
802 BOOL gcc_read_server_data_blocks(
wStream* s, rdpMcs* mcs, UINT16 length)
806 UINT16 blockLength = 0;
812 while (offset < length)
814 char buffer[64] = { 0 };
819 if (!gcc_read_user_data_header(s, &type, &blockLength))
821 WLog_ERR(TAG,
"gcc_read_server_data_blocks: gcc_read_user_data_header failed");
824 holdp = Stream_Pointer(s);
825 sub = Stream_StaticInit(&subbuffer, holdp, blockLength - 4);
826 if (!Stream_SafeSeek(s, blockLength - 4))
828 WLog_ERR(TAG,
"gcc_read_server_data_blocks: stream too short");
831 offset += blockLength;
836 if (!gcc_read_server_core_data(sub, mcs))
838 WLog_ERR(TAG,
"gcc_read_server_data_blocks: gcc_read_server_core_data failed");
845 if (!gcc_read_server_security_data(sub, mcs))
850 if (!gcc_read_server_network_data(sub, mcs))
853 "gcc_read_server_data_blocks: gcc_read_server_network_data failed");
859 case SC_MCS_MSGCHANNEL:
860 if (!gcc_read_server_message_channel_data(sub, mcs))
864 "gcc_read_server_data_blocks: gcc_read_server_message_channel_data failed");
870 case SC_MULTITRANSPORT:
871 if (!gcc_read_server_multitransport_channel_data(sub, mcs))
873 WLog_ERR(TAG,
"gcc_read_server_data_blocks: "
874 "gcc_read_server_multitransport_channel_data failed");
881 WLog_ERR(TAG,
"gcc_read_server_data_blocks: ignoring type=%s",
882 gcc_block_type_string(type, buffer,
sizeof(buffer)));
883 winpr_HexDump(TAG, WLOG_TRACE, Stream_Pointer(sub), Stream_GetRemainingLength(sub));
887 rest = Stream_GetRemainingLength(sub);
890 WLog_WARN(TAG,
"gcc_read_server_data_blocks: ignoring %" PRIuz
" bytes with type=%s",
891 rest, gcc_block_type_string(type, buffer,
sizeof(buffer)));
898 BOOL gcc_write_server_data_blocks(
wStream* s, rdpMcs* mcs)
903 if (!gcc_write_server_core_data(s, mcs) ||
904 !gcc_write_server_network_data(s, mcs) ||
905 !gcc_write_server_security_data(s, mcs) ||
906 !gcc_write_server_message_channel_data(s, mcs))
909 const rdpSettings* settings = mcs_get_const_settings(mcs);
910 WINPR_ASSERT(settings);
912 if (settings->SupportMultitransport && (settings->MultitransportFlags != 0))
914 return gcc_write_server_multitransport_channel_data(s, mcs);
919 BOOL gcc_read_user_data_header(
wStream* s, UINT16* type, UINT16* length)
922 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
925 Stream_Read_UINT16(s, *type);
926 Stream_Read_UINT16(s, *length);
928 if ((*length < 4) || (!Stream_CheckAndLogRequiredLength(TAG, s, (
size_t)(*length - 4))))
945 BOOL gcc_write_user_data_header(
wStream* s, UINT16 type, UINT16 length)
949 if (!Stream_EnsureRemainingCapacity(s, 4 + length))
951 Stream_Write_UINT16(s, type);
952 Stream_Write_UINT16(s, length);
956 static UINT32 filterAndLogEarlyServerCapabilityFlags(UINT32 flags)
959 (RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1 | RNS_UD_SC_DYNAMIC_DST_SUPPORTED |
960 RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2 | RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED);
961 const UINT32 filtered = flags & mask;
962 const UINT32 unknown = flags & (~mask);
965 char buffer[256] = { 0 };
967 "TS_UD_SC_CORE::EarlyCapabilityFlags [0x%08" PRIx32
" & 0x%08" PRIx32
968 " --> 0x%08" PRIx32
"] filtering %s, feature not implemented",
969 flags, ~mask, unknown,
970 rdp_early_server_caps_string(unknown, buffer,
sizeof(buffer)));
975 static UINT32 earlyServerCapsFromSettings(
const rdpSettings* settings)
977 UINT32 EarlyCapabilityFlags = 0;
979 if (settings->SupportEdgeActionV1)
980 EarlyCapabilityFlags |= RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1;
981 if (settings->SupportDynamicTimeZone)
982 EarlyCapabilityFlags |= RNS_UD_SC_DYNAMIC_DST_SUPPORTED;
983 if (settings->SupportEdgeActionV2)
984 EarlyCapabilityFlags |= RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2;
985 if (settings->SupportSkipChannelJoin)
986 EarlyCapabilityFlags |= RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED;
988 return filterAndLogEarlyServerCapabilityFlags(EarlyCapabilityFlags);
991 static UINT16 filterAndLogEarlyClientCapabilityFlags(UINT32 flags)
994 (RNS_UD_CS_SUPPORT_ERRINFO_PDU | RNS_UD_CS_WANT_32BPP_SESSION |
995 RNS_UD_CS_SUPPORT_STATUSINFO_PDU | RNS_UD_CS_STRONG_ASYMMETRIC_KEYS |
996 RNS_UD_CS_RELATIVE_MOUSE_INPUT | RNS_UD_CS_VALID_CONNECTION_TYPE |
997 RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU | RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT |
998 RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL | RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE |
999 RNS_UD_CS_SUPPORT_HEARTBEAT_PDU | RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN);
1000 const UINT32 filtered = flags & mask;
1001 const UINT32 unknown = flags & ~mask;
1004 char buffer[256] = { 0 };
1006 "(TS_UD_CS_CORE)::EarlyCapabilityFlags [0x%08" PRIx32
" & 0x%08" PRIx32
1007 " --> 0x%08" PRIx32
"] filtering %s, feature not implemented",
1008 flags, ~mask, unknown,
1009 rdp_early_client_caps_string(unknown, buffer,
sizeof(buffer)));
1012 WINPR_ASSERT(filtered <= UINT16_MAX);
1013 return (UINT16)filtered;
1016 static UINT16 earlyClientCapsFromSettings(
const rdpSettings* settings)
1018 UINT32 earlyCapabilityFlags = 0;
1020 WINPR_ASSERT(settings);
1021 if (settings->SupportErrorInfoPdu)
1022 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_ERRINFO_PDU;
1025 earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION;
1027 if (settings->SupportStatusInfoPdu)
1028 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_STATUSINFO_PDU;
1030 if (settings->ConnectionType)
1031 earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE;
1033 if (settings->SupportMonitorLayoutPdu)
1034 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU;
1037 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT;
1039 if (settings->SupportGraphicsPipeline)
1040 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL;
1042 if (settings->SupportDynamicTimeZone)
1043 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE;
1045 if (settings->SupportHeartbeatPdu)
1046 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_HEARTBEAT_PDU;
1048 if (settings->SupportAsymetricKeys)
1049 earlyCapabilityFlags |= RNS_UD_CS_STRONG_ASYMMETRIC_KEYS;
1051 if (settings->HasRelativeMouseEvent)
1052 earlyCapabilityFlags |= RNS_UD_CS_RELATIVE_MOUSE_INPUT;
1054 if (settings->SupportSkipChannelJoin)
1055 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN;
1057 return filterAndLogEarlyClientCapabilityFlags(earlyCapabilityFlags);
1060 static BOOL updateEarlyClientCaps(rdpSettings* settings, UINT32 earlyCapabilityFlags,
1061 UINT32 connectionType)
1063 WINPR_ASSERT(settings);
1065 if (settings->SupportErrorInfoPdu)
1066 settings->SupportErrorInfoPdu =
1067 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_ERRINFO_PDU) ? TRUE : FALSE;
1075 if (settings->SupportStatusInfoPdu)
1076 settings->SupportStatusInfoPdu =
1077 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_STATUSINFO_PDU) ? TRUE : FALSE;
1079 if (settings->SupportAsymetricKeys)
1080 settings->SupportAsymetricKeys =
1081 (earlyCapabilityFlags & RNS_UD_CS_STRONG_ASYMMETRIC_KEYS) ? TRUE : FALSE;
1083 if (settings->HasRelativeMouseEvent)
1084 settings->HasRelativeMouseEvent =
1085 (earlyCapabilityFlags & RNS_UD_CS_RELATIVE_MOUSE_INPUT) ? TRUE : FALSE;
1087 if (settings->NetworkAutoDetect)
1088 settings->NetworkAutoDetect =
1089 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT) ? TRUE : FALSE;
1091 if (settings->SupportSkipChannelJoin)
1092 settings->SupportSkipChannelJoin =
1093 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN) ? TRUE : FALSE;
1095 if (settings->SupportMonitorLayoutPdu)
1096 settings->SupportMonitorLayoutPdu =
1097 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU) ? TRUE : FALSE;
1099 if (settings->SupportHeartbeatPdu)
1100 settings->SupportHeartbeatPdu =
1101 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_HEARTBEAT_PDU) ? TRUE : FALSE;
1103 if (settings->SupportGraphicsPipeline)
1104 settings->SupportGraphicsPipeline =
1105 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL) ? TRUE : FALSE;
1107 if (settings->SupportDynamicTimeZone)
1108 settings->SupportDynamicTimeZone =
1109 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE) ? TRUE : FALSE;
1111 if ((earlyCapabilityFlags & RNS_UD_CS_VALID_CONNECTION_TYPE) == 0)
1113 settings->ConnectionType = connectionType;
1115 filterAndLogEarlyClientCapabilityFlags(earlyCapabilityFlags);
1119 static BOOL updateEarlyServerCaps(rdpSettings* settings, UINT32 earlyCapabilityFlags,
1120 UINT32 connectionType)
1122 WINPR_ASSERT(settings);
1124 settings->SupportEdgeActionV1 =
1125 settings->SupportEdgeActionV1 &&
1126 (earlyCapabilityFlags & RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1)
1129 settings->SupportDynamicTimeZone =
1130 settings->SupportDynamicTimeZone && (earlyCapabilityFlags & RNS_UD_SC_DYNAMIC_DST_SUPPORTED)
1133 settings->SupportEdgeActionV2 =
1134 settings->SupportEdgeActionV2 &&
1135 (earlyCapabilityFlags & RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2)
1138 settings->SupportSkipChannelJoin =
1139 settings->SupportSkipChannelJoin &&
1140 (earlyCapabilityFlags & RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED)
1144 filterAndLogEarlyServerCapabilityFlags(earlyCapabilityFlags);
1157 BOOL gcc_read_client_core_data(
wStream* s, rdpMcs* mcs)
1159 char buffer[2048] = { 0 };
1160 char strbuffer[130] = { 0 };
1162 BYTE connectionType = 0;
1163 UINT32 clientColorDepth = 0;
1164 UINT16 colorDepth = 0;
1165 UINT16 postBeta2ColorDepth = 0;
1166 UINT16 highColorDepth = 0;
1167 UINT32 serverSelectedProtocol = 0;
1168 rdpSettings* settings = mcs_get_settings(mcs);
1171 WINPR_ASSERT(settings);
1173 size_t blockLength = Stream_GetRemainingLength(s);
1175 if (blockLength < 128)
1178 Stream_Read_UINT32(s, version);
1179 settings->RdpVersion = rdp_version_common(version, settings->RdpVersion);
1180 Stream_Read_UINT16(s, settings->DesktopWidth);
1181 Stream_Read_UINT16(s, settings->DesktopHeight);
1182 Stream_Read_UINT16(s, colorDepth);
1183 Stream_Seek_UINT16(s);
1184 Stream_Read_UINT32(s, settings->KeyboardLayout);
1185 Stream_Read_UINT32(s, settings->ClientBuild);
1188 if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, 32 /
sizeof(WCHAR), strbuffer,
1189 ARRAYSIZE(strbuffer)) < 0)
1191 WLog_ERR(TAG,
"failed to convert client host name");
1198 Stream_Read_UINT32(s, settings->KeyboardType);
1199 Stream_Read_UINT32(s, settings->KeyboardSubType);
1200 Stream_Read_UINT32(s, settings->KeyboardFunctionKey);
1213 UINT16 clientProductIdLen = 0;
1214 if (blockLength < 2)
1217 Stream_Read_UINT16(s, postBeta2ColorDepth);
1220 if (blockLength < 2)
1223 Stream_Read_UINT16(s, clientProductIdLen);
1226 if (blockLength < 4)
1229 Stream_Seek_UINT32(s);
1232 if (blockLength < 2)
1235 Stream_Read_UINT16(s, highColorDepth);
1238 if (blockLength < 2)
1241 Stream_Read_UINT16(s, settings->SupportedColorDepths);
1244 if (blockLength < 2)
1247 Stream_Read_UINT16(s, settings->EarlyCapabilityFlags);
1252 if (blockLength < 64)
1255 if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, 64 /
sizeof(WCHAR), strbuffer,
1256 ARRAYSIZE(strbuffer)) < 0)
1258 WLog_ERR(TAG,
"failed to convert the client product identifier");
1266 if (blockLength < 1)
1269 Stream_Read_UINT8(s, connectionType);
1272 if (blockLength < 1)
1275 Stream_Seek_UINT8(s);
1278 if (blockLength < 4)
1281 Stream_Read_UINT32(s, serverSelectedProtocol);
1284 if (blockLength < 4)
1287 Stream_Read_UINT32(s, settings->DesktopPhysicalWidth);
1290 if (blockLength < 4)
1293 Stream_Read_UINT32(s,
1294 settings->DesktopPhysicalHeight);
1297 if (blockLength < 2)
1300 Stream_Read_UINT16(s, settings->DesktopOrientation);
1303 if (blockLength < 4)
1306 Stream_Read_UINT32(s, settings->DesktopScaleFactor);
1309 if (blockLength < 4)
1312 Stream_Read_UINT32(s, settings->DeviceScaleFactor);
1315 settings->SelectedProtocol = serverSelectedProtocol;
1316 else if (settings->SelectedProtocol != serverSelectedProtocol)
1320 if (highColorDepth > 0)
1322 if (settings->EarlyCapabilityFlags & RNS_UD_CS_WANT_32BPP_SESSION)
1323 clientColorDepth = 32;
1325 clientColorDepth = highColorDepth;
1327 else if (postBeta2ColorDepth > 0)
1329 switch (postBeta2ColorDepth)
1331 case RNS_UD_COLOR_4BPP:
1332 clientColorDepth = 4;
1335 case RNS_UD_COLOR_8BPP:
1336 clientColorDepth = 8;
1339 case RNS_UD_COLOR_16BPP_555:
1340 clientColorDepth = 15;
1343 case RNS_UD_COLOR_16BPP_565:
1344 clientColorDepth = 16;
1347 case RNS_UD_COLOR_24BPP:
1348 clientColorDepth = 24;
1359 case RNS_UD_COLOR_4BPP:
1360 clientColorDepth = 4;
1363 case RNS_UD_COLOR_8BPP:
1364 clientColorDepth = 8;
1377 !settings->ServerMode)
1383 WLog_DBG(TAG,
"Received EarlyCapabilityFlags=%s",
1384 rdp_early_client_caps_string(settings->EarlyCapabilityFlags, buffer,
sizeof(buffer)));
1386 return updateEarlyClientCaps(settings, settings->EarlyCapabilityFlags, connectionType);
1398 BOOL gcc_write_client_core_data(
wStream* s,
const rdpMcs* mcs)
1400 char buffer[2048] = { 0 };
1401 char dbuffer[2048] = { 0 };
1402 BYTE connectionType = 0;
1403 HIGH_COLOR_DEPTH highColorDepth = HIGH_COLOR_4BPP;
1405 UINT16 earlyCapabilityFlags = 0;
1406 const rdpSettings* settings = mcs_get_const_settings(mcs);
1409 WINPR_ASSERT(settings);
1411 const UINT16 SupportedColorDepths =
1415 if (!gcc_write_user_data_header(s, CS_CORE, 234))
1418 Stream_Write_UINT32(s, settings->RdpVersion);
1419 Stream_Write_UINT16(
1420 s, WINPR_ASSERTING_INT_CAST(uint16_t, settings->DesktopWidth));
1421 Stream_Write_UINT16(
1422 s, WINPR_ASSERTING_INT_CAST(uint16_t, settings->DesktopHeight));
1423 Stream_Write_UINT16(s,
1425 Stream_Write_UINT16(s, RNS_UD_SAS_DEL);
1426 Stream_Write_UINT32(s, settings->KeyboardLayout);
1427 Stream_Write_UINT32(s, settings->ClientBuild);
1429 if (!Stream_EnsureRemainingCapacity(s, 32 + 12 + 64 + 8))
1433 size_t clientNameLength = 0;
1434 WCHAR* clientName = ConvertUtf8ToWCharAlloc(settings->ClientHostname, &clientNameLength);
1435 if (clientNameLength >= 16)
1437 clientNameLength = 16;
1438 clientName[clientNameLength - 1] = 0;
1441 Stream_Write(s, clientName, (clientNameLength * 2));
1442 Stream_Zero(s, 32 - (clientNameLength * 2));
1444 Stream_Write_UINT32(s, settings->KeyboardType);
1445 Stream_Write_UINT32(s, settings->KeyboardSubType);
1446 Stream_Write_UINT32(s, settings->KeyboardFunctionKey);
1448 Stream_Write_UINT16(s, RNS_UD_COLOR_8BPP);
1449 Stream_Write_UINT16(s, 1);
1450 Stream_Write_UINT32(s, 0);
1451 highColorDepth = ColorDepthToHighColor(ColorDepth);
1452 earlyCapabilityFlags = earlyClientCapsFromSettings(settings);
1454 WINPR_ASSERT(settings->ConnectionType <= UINT8_MAX);
1455 connectionType = (UINT8)settings->ConnectionType;
1457 if (!Stream_EnsureRemainingCapacity(s, 6))
1460 WLog_DBG(TAG,
"Sending highColorDepth=%s, supportedColorDepths=%s, earlyCapabilityFlags=%s",
1461 HighColorToString(highColorDepth),
1463 rdp_early_client_caps_string(earlyCapabilityFlags, buffer,
sizeof(buffer)));
1464 Stream_Write_UINT16(s, WINPR_ASSERTING_INT_CAST(uint16_t, highColorDepth));
1465 Stream_Write_UINT16(s, SupportedColorDepths);
1466 Stream_Write_UINT16(s, earlyCapabilityFlags);
1468 if (!Stream_EnsureRemainingCapacity(s, 64 + 24))
1472 size_t clientDigProductIdLength = 0;
1473 WCHAR* clientDigProductId =
1474 ConvertUtf8ToWCharAlloc(settings->ClientProductId, &clientDigProductIdLength);
1475 if (clientDigProductIdLength >= 32)
1477 clientDigProductIdLength = 32;
1478 clientDigProductId[clientDigProductIdLength - 1] = 0;
1481 Stream_Write(s, clientDigProductId, (clientDigProductIdLength * 2));
1482 Stream_Zero(s, 64 - (clientDigProductIdLength * 2));
1483 free(clientDigProductId);
1484 Stream_Write_UINT8(s, connectionType);
1485 Stream_Write_UINT8(s, 0);
1486 Stream_Write_UINT32(s, settings->SelectedProtocol);
1487 Stream_Write_UINT32(s, settings->DesktopPhysicalWidth);
1488 Stream_Write_UINT32(s, settings->DesktopPhysicalHeight);
1489 Stream_Write_UINT16(s, settings->DesktopOrientation);
1490 Stream_Write_UINT32(s, settings->DesktopScaleFactor);
1491 Stream_Write_UINT32(s, settings->DeviceScaleFactor);
1495 BOOL gcc_read_server_core_data(
wStream* s, rdpMcs* mcs)
1497 UINT32 serverVersion = 0;
1498 rdpSettings* settings = mcs_get_settings(mcs);
1501 WINPR_ASSERT(settings);
1503 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1506 Stream_Read_UINT32(s, serverVersion);
1507 settings->RdpVersion = rdp_version_common(serverVersion, settings->RdpVersion);
1509 if (Stream_GetRemainingLength(s) >= 4)
1511 Stream_Read_UINT32(s, settings->RequestedProtocols);
1514 if (Stream_GetRemainingLength(s) >= 4)
1516 char buffer[2048] = { 0 };
1518 Stream_Read_UINT32(s, settings->EarlyCapabilityFlags);
1520 TAG,
"Received EarlyCapabilityFlags=%s",
1521 rdp_early_client_caps_string(settings->EarlyCapabilityFlags, buffer,
sizeof(buffer)));
1524 return updateEarlyServerCaps(settings, settings->EarlyCapabilityFlags,
1525 settings->ConnectionType);
1531 BOOL gcc_write_server_core_data(
wStream* s, rdpMcs* mcs)
1533 const rdpSettings* settings = mcs_get_const_settings(mcs);
1536 WINPR_ASSERT(settings);
1538 if (!gcc_write_user_data_header(s, SC_CORE, 16))
1541 const UINT32 EarlyCapabilityFlags = earlyServerCapsFromSettings(settings);
1542 Stream_Write_UINT32(s, settings->RdpVersion);
1543 Stream_Write_UINT32(s, settings->RequestedProtocols);
1544 Stream_Write_UINT32(s, EarlyCapabilityFlags);
1557 BOOL gcc_read_client_security_data(
wStream* s, rdpMcs* mcs)
1559 rdpSettings* settings = mcs_get_settings(mcs);
1562 WINPR_ASSERT(settings);
1564 const size_t blockLength = Stream_GetRemainingLength(s);
1565 if (blockLength < 8)
1568 if (settings->UseRdpSecurityLayer)
1570 Stream_Read_UINT32(s, settings->EncryptionMethods);
1572 if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE)
1573 Stream_Read_UINT32(s, settings->EncryptionMethods);
1594 BOOL gcc_write_client_security_data(
wStream* s,
const rdpMcs* mcs)
1596 const rdpSettings* settings = mcs_get_const_settings(mcs);
1599 WINPR_ASSERT(settings);
1601 if (!gcc_write_user_data_header(s, CS_SECURITY, 12))
1604 if (settings->UseRdpSecurityLayer)
1606 Stream_Write_UINT32(s, settings->EncryptionMethods);
1607 Stream_Write_UINT32(s, 0);
1612 Stream_Write_UINT32(s, 0);
1613 Stream_Write_UINT32(s, settings->EncryptionMethods);
1618 BOOL gcc_read_server_security_data(
wStream* s, rdpMcs* mcs)
1620 const BYTE* data = NULL;
1622 BOOL validCryptoConfig = FALSE;
1623 UINT32 EncryptionMethod = 0;
1624 UINT32 EncryptionLevel = 0;
1625 rdpSettings* settings = mcs_get_settings(mcs);
1628 WINPR_ASSERT(settings);
1630 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1633 Stream_Read_UINT32(s, EncryptionMethod);
1634 Stream_Read_UINT32(s, EncryptionLevel);
1637 switch (EncryptionMethod)
1639 case ENCRYPTION_METHOD_NONE:
1640 WLog_DBG(TAG,
"Server rdp encryption method: NONE");
1643 case ENCRYPTION_METHOD_40BIT:
1644 WLog_DBG(TAG,
"Server rdp encryption method: 40BIT");
1647 case ENCRYPTION_METHOD_56BIT:
1648 WLog_DBG(TAG,
"Server rdp encryption method: 56BIT");
1651 case ENCRYPTION_METHOD_128BIT:
1652 WLog_DBG(TAG,
"Server rdp encryption method: 128BIT");
1655 case ENCRYPTION_METHOD_FIPS:
1656 WLog_DBG(TAG,
"Server rdp encryption method: FIPS");
1660 WLog_ERR(TAG,
"Received unknown encryption method %08" PRIX32
"", EncryptionMethod);
1664 if (settings->UseRdpSecurityLayer && !(settings->EncryptionMethods & EncryptionMethod))
1666 WLog_WARN(TAG,
"Server uses non-advertised encryption method 0x%08" PRIX32
"",
1671 settings->EncryptionMethods = EncryptionMethod;
1672 settings->EncryptionLevel = EncryptionLevel;
1674 switch (settings->EncryptionLevel)
1676 case ENCRYPTION_LEVEL_NONE:
1677 if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE)
1679 validCryptoConfig = TRUE;
1684 case ENCRYPTION_LEVEL_FIPS:
1685 if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
1687 validCryptoConfig = TRUE;
1692 case ENCRYPTION_LEVEL_LOW:
1693 case ENCRYPTION_LEVEL_HIGH:
1694 case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE:
1695 if (settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT ||
1696 settings->EncryptionMethods == ENCRYPTION_METHOD_56BIT ||
1697 settings->EncryptionMethods == ENCRYPTION_METHOD_128BIT ||
1698 settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
1700 validCryptoConfig = TRUE;
1706 WLog_ERR(TAG,
"Received unknown encryption level 0x%08" PRIX32
"",
1707 settings->EncryptionLevel);
1710 if (!validCryptoConfig)
1713 "Received invalid cryptographic configuration (level=0x%08" PRIX32
1714 " method=0x%08" PRIX32
")",
1715 settings->EncryptionLevel, settings->EncryptionMethods);
1719 if (settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE)
1722 settings->UseRdpSecurityLayer = FALSE;
1726 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1729 Stream_Read_UINT32(s, settings->ServerRandomLength);
1730 Stream_Read_UINT32(s, settings->ServerCertificateLength);
1732 if ((settings->ServerRandomLength == 0) || (settings->ServerCertificateLength == 0))
1735 "Invalid ServerRandom (length=%" PRIu32
") or ServerCertificate (length=%" PRIu32
1737 settings->ServerRandomLength, settings->ServerCertificateLength);
1741 if (!Stream_CheckAndLogRequiredLength(TAG, s, settings->ServerRandomLength))
1746 settings->ServerRandomLength))
1749 Stream_Read(s, settings->ServerRandom, settings->ServerRandomLength);
1751 if (!Stream_CheckAndLogRequiredLength(TAG, s, settings->ServerCertificateLength))
1756 settings->ServerCertificateLength))
1759 Stream_Read(s, settings->ServerCertificate, settings->ServerCertificateLength);
1761 data = settings->ServerCertificate;
1762 length = settings->ServerCertificateLength;
1764 if (!freerdp_certificate_read_server_cert(settings->RdpServerCertificate, data, length))
1769 free(settings->ServerRandom);
1770 free(settings->ServerCertificate);
1771 settings->ServerRandom = NULL;
1772 settings->ServerCertificate = NULL;
1776 static BOOL gcc_update_server_random(rdpSettings* settings)
1778 const size_t length = 32;
1779 WINPR_ASSERT(settings);
1785 winpr_RAND(data, length);
1792 BOOL gcc_write_server_security_data(
wStream* s, rdpMcs* mcs)
1794 if (!gcc_update_server_random(mcs_get_settings(mcs)))
1797 const rdpSettings* settings = mcs_get_const_settings(mcs);
1800 WINPR_ASSERT(settings);
1802 const size_t posHeader = Stream_GetPosition(s);
1803 if (!gcc_write_user_data_header(s, SC_SECURITY, 12))
1806 Stream_Write_UINT32(s, settings->EncryptionMethods);
1807 Stream_Write_UINT32(s, settings->EncryptionLevel);
1809 if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE)
1812 if (!Stream_EnsureRemainingCapacity(s,
sizeof(UINT32) + settings->ServerRandomLength))
1814 Stream_Write_UINT32(s, settings->ServerRandomLength);
1815 const size_t posCertLen = Stream_GetPosition(s);
1816 Stream_Seek_UINT32(s);
1817 Stream_Write(s, settings->ServerRandom, settings->ServerRandomLength);
1819 const SSIZE_T len = freerdp_certificate_write_server_cert(
1820 settings->RdpServerCertificate, CERT_TEMPORARILY_ISSUED | CERT_CHAIN_VERSION_1, s);
1823 const size_t end = Stream_GetPosition(s);
1825 WINPR_ASSERT(end >= posHeader);
1826 const size_t diff = end - posHeader;
1827 WINPR_ASSERT(diff <= UINT16_MAX);
1828 Stream_SetPosition(s, posHeader);
1829 if (!gcc_write_user_data_header(s, SC_SECURITY, (UINT16)diff))
1831 Stream_SetPosition(s, posCertLen);
1832 WINPR_ASSERT(len <= UINT32_MAX);
1833 Stream_Write_UINT32(s, (UINT32)len);
1834 Stream_SetPosition(s, end);
1848 BOOL gcc_read_client_network_data(
wStream* s, rdpMcs* mcs)
1853 const size_t blockLength = Stream_GetRemainingLength(s);
1854 if (blockLength < 4)
1857 Stream_Read_UINT32(s, mcs->channelCount);
1859 if (blockLength < 4 + mcs->channelCount * 12)
1862 if (mcs->channelCount > CHANNEL_MAX_COUNT)
1866 for (UINT32 i = 0; i < mcs->channelCount; i++)
1874 rdpMcsChannel* channel = &mcs->channels[i];
1875 Stream_Read(s, channel->Name, CHANNEL_NAME_LEN + 1);
1877 if (!memchr(channel->Name, 0, CHANNEL_NAME_LEN + 1))
1881 "protocol violation: received a static channel name with missing null-termination");
1885 Stream_Read_UINT32(s, channel->options);
1886 channel->ChannelId = mcs->baseChannelId++;
1901 BOOL gcc_write_client_network_data(
wStream* s,
const rdpMcs* mcs)
1905 if (mcs->channelCount > 0)
1907 const size_t length = mcs->channelCount * 12 + 8;
1908 WINPR_ASSERT(length <= UINT16_MAX);
1909 if (!gcc_write_user_data_header(s, CS_NET, (UINT16)length))
1911 Stream_Write_UINT32(s, mcs->channelCount);
1914 for (UINT32 i = 0; i < mcs->channelCount; i++)
1917 rdpMcsChannel* channel = &mcs->channels[i];
1918 Stream_Write(s, channel->Name, CHANNEL_NAME_LEN + 1);
1919 Stream_Write_UINT32(s, channel->options);
1925 BOOL gcc_read_server_network_data(
wStream* s, rdpMcs* mcs)
1927 UINT16 channelId = 0;
1928 UINT16 MCSChannelId = 0;
1929 UINT16 channelCount = 0;
1930 UINT32 parsedChannelCount = 0;
1933 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1936 Stream_Read_UINT16(s, MCSChannelId);
1937 Stream_Read_UINT16(s, channelCount);
1938 parsedChannelCount = channelCount;
1940 if (channelCount != mcs->channelCount)
1942 WLog_ERR(TAG,
"requested %" PRIu32
" channels, got %" PRIu16
" instead", mcs->channelCount,
1947 mcs->channelCount = channelCount;
1950 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, channelCount, 2ull))
1953 if (mcs->channelMaxCount < parsedChannelCount)
1955 WLog_ERR(TAG,
"requested %" PRIu32
" channels > channelMaxCount %" PRIu16,
1956 mcs->channelCount, mcs->channelMaxCount);
1960 for (UINT32 i = 0; i < parsedChannelCount; i++)
1962 rdpMcsChannel* channel = &mcs->channels[i];
1963 Stream_Read_UINT16(s, channelId);
1964 channel->ChannelId = channelId;
1967 if (channelCount % 2 == 1)
1968 return Stream_SafeSeek(s, 2);
1973 BOOL gcc_write_server_network_data(
wStream* s,
const rdpMcs* mcs)
1977 const size_t payloadLen = 8 + mcs->channelCount * 2 + (mcs->channelCount % 2 == 1 ? 2 : 0);
1979 WINPR_ASSERT(payloadLen <= UINT16_MAX);
1980 if (!gcc_write_user_data_header(s, SC_NET, (UINT16)payloadLen))
1983 Stream_Write_UINT16(s, MCS_GLOBAL_CHANNEL_ID);
1984 Stream_Write_UINT16(s,
1985 WINPR_ASSERTING_INT_CAST(uint16_t, mcs->channelCount));
1987 for (UINT32 i = 0; i < mcs->channelCount; i++)
1989 const rdpMcsChannel* channel = &mcs->channels[i];
1990 Stream_Write_UINT16(s, channel->ChannelId);
1993 if (mcs->channelCount % 2 == 1)
1994 Stream_Write_UINT16(s, 0);
2008 BOOL gcc_read_client_cluster_data(
wStream* s, rdpMcs* mcs)
2010 char buffer[128] = { 0 };
2011 UINT32 redirectedSessionId = 0;
2012 rdpSettings* settings = mcs_get_settings(mcs);
2015 WINPR_ASSERT(settings);
2017 const size_t blockLength = Stream_GetRemainingLength(s);
2018 if (blockLength < 8)
2021 Stream_Read_UINT32(s, settings->ClusterInfoFlags);
2022 Stream_Read_UINT32(s, redirectedSessionId);
2024 WLog_VRB(TAG,
"read ClusterInfoFlags=%s, RedirectedSessionId=0x%08" PRIx32,
2025 rdp_cluster_info_flags_to_string(settings->ClusterInfoFlags, buffer,
sizeof(buffer)),
2026 redirectedSessionId);
2027 if (settings->ClusterInfoFlags & REDIRECTED_SESSIONID_FIELD_VALID)
2028 settings->RedirectedSessionId = redirectedSessionId;
2030 settings->ConsoleSession =
2031 (settings->ClusterInfoFlags & REDIRECTED_SESSIONID_FIELD_VALID) ? TRUE : FALSE;
2032 settings->RedirectSmartCards =
2033 (settings->ClusterInfoFlags & REDIRECTED_SMARTCARD) ? TRUE : FALSE;
2035 if (blockLength > 8ULL)
2037 if (Stream_GetRemainingLength(s) >= (blockLength - 8ULL))
2040 Stream_Seek(s, (blockLength - 8));
2056 BOOL gcc_write_client_cluster_data(
wStream* s,
const rdpMcs* mcs)
2058 char buffer[128] = { 0 };
2060 const rdpSettings* settings = mcs_get_const_settings(mcs);
2063 WINPR_ASSERT(settings);
2065 if (!gcc_write_user_data_header(s, CS_CLUSTER, 12))
2067 flags = settings->ClusterInfoFlags;
2069 if (settings->ConsoleSession || settings->RedirectedSessionId)
2070 flags |= REDIRECTED_SESSIONID_FIELD_VALID;
2072 if (settings->RedirectSmartCards && settings->SmartcardLogon)
2073 flags |= REDIRECTED_SMARTCARD;
2075 if (flags & REDIRECTION_SUPPORTED)
2080 flags |= (REDIRECTION_VERSION6 << 2);
2082 flags |= (REDIRECTION_VERSION5 << 2);
2085 WLog_VRB(TAG,
"write ClusterInfoFlags=%s, RedirectedSessionId=0x%08" PRIx32,
2086 rdp_cluster_info_flags_to_string(flags, buffer,
sizeof(buffer)),
2087 settings->RedirectedSessionId);
2088 Stream_Write_UINT32(s, flags);
2089 Stream_Write_UINT32(s, settings->RedirectedSessionId);
2102 BOOL gcc_read_client_monitor_data(
wStream* s, rdpMcs* mcs)
2104 UINT32 monitorCount = 0;
2105 rdpSettings* settings = mcs_get_settings(mcs);
2108 WINPR_ASSERT(settings);
2110 const size_t blockLength = Stream_GetRemainingLength(s);
2111 if (blockLength < 8)
2114 Stream_Read_UINT32(s, settings->MonitorFlags);
2115 Stream_Read_UINT32(s, monitorCount);
2121 if (monitorCount > 16)
2123 WLog_ERR(TAG,
"announced monitors(%" PRIu32
") exceed the 16 limit", monitorCount);
2127 if (monitorCount > settings->MonitorDefArraySize)
2129 WLog_ERR(TAG,
"too many announced monitors(%" PRIu32
"), clamping to %" PRIu32
"",
2130 monitorCount, settings->MonitorDefArraySize);
2131 monitorCount = settings->MonitorDefArraySize;
2134 if ((UINT32)((blockLength - 8) / 20) < monitorCount)
2137 settings->MonitorCount = monitorCount;
2139 for (UINT32 index = 0; index < monitorCount; index++)
2146 rdpMonitor* current = &settings->MonitorDefArray[index];
2148 Stream_Read_INT32(s, left);
2149 Stream_Read_INT32(s, top);
2150 Stream_Read_INT32(s, right);
2151 Stream_Read_INT32(s, bottom);
2152 Stream_Read_INT32(s, flags);
2155 current->width = right - left + 1;
2156 current->height = bottom - top + 1;
2157 current->is_primary = (flags & MONITOR_PRIMARY) ? TRUE : FALSE;
2172 BOOL gcc_write_client_monitor_data(
wStream* s,
const rdpMcs* mcs)
2176 const rdpSettings* settings = mcs_get_const_settings(mcs);
2179 WINPR_ASSERT(settings);
2181 WLog_DBG(TAG,
"MonitorCount=%" PRIu32, settings->MonitorCount);
2182 if (settings->MonitorCount > 1)
2184 const size_t len = (20 * settings->MonitorCount) + 12;
2185 WINPR_ASSERT(len <= UINT16_MAX);
2186 const UINT16 length = (UINT16)len;
2187 if (!gcc_write_user_data_header(s, CS_MONITOR, length))
2189 Stream_Write_UINT32(s, settings->MonitorFlags);
2190 Stream_Write_UINT32(s, settings->MonitorCount);
2194 for (UINT32 i = 0; i < settings->MonitorCount; i++)
2196 const rdpMonitor* current = &settings->MonitorDefArray[i];
2197 if (current->is_primary)
2205 for (UINT32 i = 0; i < settings->MonitorCount; i++)
2207 const rdpMonitor* current = &settings->MonitorDefArray[i];
2208 const UINT32 left = WINPR_ASSERTING_INT_CAST(uint32_t, current->x - baseX);
2209 const UINT32 top = WINPR_ASSERTING_INT_CAST(uint32_t, current->y - baseY);
2210 const UINT32 right = left + WINPR_ASSERTING_INT_CAST(uint32_t, current->width - 1);
2211 const UINT32 bottom = top + WINPR_ASSERTING_INT_CAST(uint32_t, current->height - 1);
2212 const UINT32 flags = current->is_primary ? MONITOR_PRIMARY : 0;
2214 "Monitor[%" PRIu32
"]: top=%" PRIu32
", left=%" PRIu32
", bottom=%" PRIu32
2215 ", right=%" PRIu32
", flags=%" PRIu32,
2216 i, top, left, bottom, right, flags);
2217 Stream_Write_UINT32(s, left);
2218 Stream_Write_UINT32(s, top);
2219 Stream_Write_UINT32(s, right);
2220 Stream_Write_UINT32(s, bottom);
2221 Stream_Write_UINT32(s, flags);
2224 WLog_DBG(TAG,
"FINISHED");
2228 BOOL gcc_read_client_monitor_extended_data(
wStream* s, rdpMcs* mcs)
2230 UINT32 monitorCount = 0;
2231 UINT32 monitorAttributeSize = 0;
2232 rdpSettings* settings = mcs_get_settings(mcs);
2235 WINPR_ASSERT(settings);
2237 const size_t blockLength = Stream_GetRemainingLength(s);
2238 if (blockLength < 12)
2241 Stream_Read_UINT32(s, settings->MonitorAttributeFlags);
2242 Stream_Read_UINT32(s, monitorAttributeSize);
2243 Stream_Read_UINT32(s, monitorCount);
2245 if (monitorAttributeSize != 20)
2248 if ((blockLength - 12) / monitorAttributeSize < monitorCount)
2251 if (settings->MonitorCount != monitorCount)
2254 settings->HasMonitorAttributes = TRUE;
2256 for (UINT32 index = 0; index < monitorCount; index++)
2258 rdpMonitor* current = &settings->MonitorDefArray[index];
2259 Stream_Read_UINT32(s, current->attributes.physicalWidth);
2260 Stream_Read_UINT32(s, current->attributes.physicalHeight);
2261 Stream_Read_UINT32(s, current->attributes.orientation);
2262 Stream_Read_UINT32(s, current->attributes.desktopScaleFactor);
2263 Stream_Read_UINT32(s, current->attributes.deviceScaleFactor);
2269 BOOL gcc_write_client_monitor_extended_data(
wStream* s,
const rdpMcs* mcs)
2271 const rdpSettings* settings = mcs_get_const_settings(mcs);
2274 WINPR_ASSERT(settings);
2276 if (settings->HasMonitorAttributes)
2278 const size_t length = (20 * settings->MonitorCount) + 16;
2279 WINPR_ASSERT(length <= UINT16_MAX);
2280 if (!gcc_write_user_data_header(s, CS_MONITOR_EX, (UINT16)length))
2282 Stream_Write_UINT32(s, settings->MonitorAttributeFlags);
2283 Stream_Write_UINT32(s, 20);
2284 Stream_Write_UINT32(s, settings->MonitorCount);
2286 for (UINT32 i = 0; i < settings->MonitorCount; i++)
2288 const rdpMonitor* current = &settings->MonitorDefArray[i];
2289 Stream_Write_UINT32(s, current->attributes.physicalWidth);
2290 Stream_Write_UINT32(s, current->attributes.physicalHeight);
2291 Stream_Write_UINT32(s, current->attributes.orientation);
2292 Stream_Write_UINT32(s, current->attributes.desktopScaleFactor);
2293 Stream_Write_UINT32(s, current->attributes.deviceScaleFactor);
2308 BOOL gcc_read_client_message_channel_data(
wStream* s, rdpMcs* mcs)
2313 const size_t blockLength = Stream_GetRemainingLength(s);
2314 if (blockLength < 4)
2317 Stream_Read_UINT32(s, mcs->flags);
2318 mcs->messageChannelId = mcs->baseChannelId++;
2331 BOOL gcc_write_client_message_channel_data(
wStream* s,
const rdpMcs* mcs)
2333 const rdpSettings* settings = mcs_get_const_settings(mcs);
2337 WINPR_ASSERT(settings);
2339 settings->SupportHeartbeatPdu || settings->SupportMultitransport)
2341 if (!gcc_write_user_data_header(s, CS_MCS_MSGCHANNEL, 8))
2343 Stream_Write_UINT32(s, mcs->flags);
2348 BOOL gcc_read_server_message_channel_data(
wStream* s, rdpMcs* mcs)
2350 UINT16 MCSChannelId = 0;
2353 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
2356 Stream_Read_UINT16(s, MCSChannelId);
2358 mcs->messageChannelId = MCSChannelId;
2362 BOOL gcc_write_server_message_channel_data(
wStream* s,
const rdpMcs* mcs)
2366 if (mcs->messageChannelId == 0)
2369 if (!gcc_write_user_data_header(s, SC_MCS_MSGCHANNEL, 6))
2372 Stream_Write_UINT16(s, mcs->messageChannelId);
2385 BOOL gcc_read_client_multitransport_channel_data(
wStream* s, rdpMcs* mcs)
2387 rdpSettings* settings = mcs_get_settings(mcs);
2390 WINPR_ASSERT(settings);
2392 const size_t blockLength = Stream_GetRemainingLength(s);
2393 if (blockLength < 4)
2396 UINT32 remoteFlags = 0;
2397 Stream_Read_UINT32(s, remoteFlags);
2398 settings->MultitransportFlags &= remoteFlags;
2412 BOOL gcc_write_client_multitransport_channel_data(
wStream* s,
const rdpMcs* mcs)
2414 const rdpSettings* settings = mcs_get_const_settings(mcs);
2417 WINPR_ASSERT(settings);
2418 if (!gcc_write_user_data_header(s, CS_MULTITRANSPORT, 8))
2420 Stream_Write_UINT32(s, settings->MultitransportFlags);
2424 BOOL gcc_read_server_multitransport_channel_data(
wStream* s, rdpMcs* mcs)
2426 rdpSettings* settings = mcs_get_settings(mcs);
2427 UINT32 remoteFlags = 0;
2430 WINPR_ASSERT(settings);
2431 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2434 Stream_Read_UINT32(s, remoteFlags);
2435 settings->MultitransportFlags &= remoteFlags;
2439 BOOL gcc_write_server_multitransport_channel_data(
wStream* s,
const rdpMcs* mcs)
2441 const rdpSettings* settings = mcs_get_const_settings(mcs);
2444 WINPR_ASSERT(settings);
2446 if (!gcc_write_user_data_header(s, SC_MULTITRANSPORT, 8))
2449 Stream_Write_UINT32(s, settings->MultitransportFlags);
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
FREERDP_API const char * freerdp_supported_color_depths_string(UINT16 mask, char *buffer, size_t size)
returns a string representation of RNS_UD_XXBPP_SUPPORT values
FREERDP_API UINT16 freerdp_settings_get_uint16(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt16 id)
Returns a UINT16 settings value.
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.
FREERDP_API void * freerdp_settings_get_pointer_writable(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a mutable pointer settings value.