24 #include <freerdp/config.h>
28 #include <winpr/crt.h>
29 #include <winpr/crypto.h>
30 #include <winpr/assert.h>
32 #include <freerdp/log.h>
33 #include <freerdp/utils/string.h>
34 #include <freerdp/crypto/certificate.h>
40 #include "../crypto/certificate.h"
42 #define TAG FREERDP_TAG("core.gcc")
46 HIGH_COLOR_4BPP = 0x04,
47 HIGH_COLOR_8BPP = 0x08,
48 HIGH_COLOR_15BPP = 0x0F,
49 HIGH_COLOR_16BPP = 0x10,
50 HIGH_COLOR_24BPP = 0x18,
53 static const char* HighColorToString(HIGH_COLOR_DEPTH color)
58 return "HIGH_COLOR_4BPP";
60 return "HIGH_COLOR_8BPP";
61 case HIGH_COLOR_15BPP:
62 return "HIGH_COLOR_15BPP";
63 case HIGH_COLOR_16BPP:
64 return "HIGH_COLOR_16BPP";
65 case HIGH_COLOR_24BPP:
66 return "HIGH_COLOR_24BPP";
68 return "HIGH_COLOR_UNKNOWN";
72 static HIGH_COLOR_DEPTH ColorDepthToHighColor(UINT32 bpp)
77 return HIGH_COLOR_4BPP;
79 return HIGH_COLOR_8BPP;
81 return HIGH_COLOR_15BPP;
83 return HIGH_COLOR_16BPP;
85 return HIGH_COLOR_24BPP;
89 static char* gcc_block_type_string(UINT16 type,
char* buffer,
size_t size);
90 static BOOL gcc_read_client_cluster_data(
wStream* s, rdpMcs* mcs);
91 static BOOL gcc_read_client_core_data(
wStream* s, rdpMcs* mcs);
92 static BOOL gcc_read_client_data_blocks(
wStream* s, rdpMcs* mcs, UINT16 length);
93 static BOOL gcc_read_server_data_blocks(
wStream* s, rdpMcs* mcs, UINT16 length);
94 static BOOL gcc_read_user_data_header(
wStream* s, UINT16* type, UINT16* length);
95 static BOOL gcc_write_user_data_header(
wStream* s, UINT16 type, UINT16 length);
97 static BOOL gcc_write_client_core_data(
wStream* s,
const rdpMcs* mcs);
98 static BOOL gcc_read_server_core_data(
wStream* s, rdpMcs* mcs);
99 static BOOL gcc_write_server_core_data(
wStream* s, rdpMcs* mcs);
100 static BOOL gcc_read_client_security_data(
wStream* s, rdpMcs* mcs);
101 static BOOL gcc_write_client_security_data(
wStream* s,
const rdpMcs* mcs);
102 static BOOL gcc_read_server_security_data(
wStream* s, rdpMcs* mcs);
103 static BOOL gcc_write_server_security_data(
wStream* s, rdpMcs* mcs);
104 static BOOL gcc_read_client_network_data(
wStream* s, rdpMcs* mcs);
105 static BOOL gcc_write_client_network_data(
wStream* s,
const rdpMcs* mcs);
106 static BOOL gcc_read_server_network_data(
wStream* s, rdpMcs* mcs);
107 static BOOL gcc_write_server_network_data(
wStream* s,
const rdpMcs* mcs);
108 static BOOL gcc_write_client_cluster_data(
wStream* s,
const rdpMcs* mcs);
109 static BOOL gcc_read_client_monitor_data(
wStream* s, rdpMcs* mcs);
110 static BOOL gcc_write_client_monitor_data(
wStream* s,
const rdpMcs* mcs);
111 static BOOL gcc_read_client_monitor_extended_data(
wStream* s, rdpMcs* mcs);
112 static BOOL gcc_write_client_monitor_extended_data(
wStream* s,
const rdpMcs* mcs);
113 static BOOL gcc_read_client_message_channel_data(
wStream* s, rdpMcs* mcs);
114 static BOOL gcc_write_client_message_channel_data(
wStream* s,
const rdpMcs* mcs);
115 static BOOL gcc_read_server_message_channel_data(
wStream* s, rdpMcs* mcs);
116 static BOOL gcc_write_server_message_channel_data(
wStream* s,
const rdpMcs* mcs);
117 static BOOL gcc_read_client_multitransport_channel_data(
wStream* s, rdpMcs* mcs);
118 static BOOL gcc_write_client_multitransport_channel_data(
wStream* s,
const rdpMcs* mcs);
119 static BOOL gcc_read_server_multitransport_channel_data(
wStream* s, rdpMcs* mcs);
120 static BOOL gcc_write_server_multitransport_channel_data(
wStream* s,
const rdpMcs* mcs);
122 static rdpSettings* mcs_get_settings(rdpMcs* mcs)
126 rdpContext* context = transport_get_context(mcs->transport);
127 WINPR_ASSERT(context);
129 return context->settings;
132 static const rdpSettings* mcs_get_const_settings(
const rdpMcs* mcs)
136 const rdpContext* context = transport_get_context(mcs->transport);
137 WINPR_ASSERT(context);
139 return context->settings;
142 static char* rdp_early_server_caps_string(UINT32 flags,
char* buffer,
size_t size)
144 char msg[32] = { 0 };
145 const UINT32 mask = RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1 | RNS_UD_SC_DYNAMIC_DST_SUPPORTED |
146 RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2 | RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED;
147 const UINT32 unknown = flags & (~mask);
149 if (flags & RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1)
150 winpr_str_append(
"RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1", buffer, size,
"|");
151 if (flags & RNS_UD_SC_DYNAMIC_DST_SUPPORTED)
152 winpr_str_append(
"RNS_UD_SC_DYNAMIC_DST_SUPPORTED", buffer, size,
"|");
153 if (flags & RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2)
154 winpr_str_append(
"RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2", buffer, size,
"|");
155 if (flags & RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED)
156 winpr_str_append(
"RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED", buffer, size,
"|");
160 (void)_snprintf(msg,
sizeof(msg),
"RNS_UD_SC_UNKNOWN[0x%08" PRIx32
"]", unknown);
161 winpr_str_append(msg, buffer, size,
"|");
163 (void)_snprintf(msg,
sizeof(msg),
"[0x%08" PRIx32
"]", flags);
164 winpr_str_append(msg, buffer, size,
"|");
168 static const char* rdp_early_client_caps_string(UINT32 flags,
char* buffer,
size_t size)
170 char msg[32] = { 0 };
171 const UINT32 mask = RNS_UD_CS_SUPPORT_ERRINFO_PDU | RNS_UD_CS_WANT_32BPP_SESSION |
172 RNS_UD_CS_SUPPORT_STATUSINFO_PDU | RNS_UD_CS_STRONG_ASYMMETRIC_KEYS |
173 RNS_UD_CS_RELATIVE_MOUSE_INPUT | RNS_UD_CS_VALID_CONNECTION_TYPE |
174 RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU |
175 RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT |
176 RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL | RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE |
177 RNS_UD_CS_SUPPORT_HEARTBEAT_PDU | RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN;
178 const UINT32 unknown = flags & (~mask);
180 if (flags & RNS_UD_CS_SUPPORT_ERRINFO_PDU)
181 winpr_str_append(
"RNS_UD_CS_SUPPORT_ERRINFO_PDU", buffer, size,
"|");
182 if (flags & RNS_UD_CS_WANT_32BPP_SESSION)
183 winpr_str_append(
"RNS_UD_CS_WANT_32BPP_SESSION", buffer, size,
"|");
184 if (flags & RNS_UD_CS_SUPPORT_STATUSINFO_PDU)
185 winpr_str_append(
"RNS_UD_CS_SUPPORT_STATUSINFO_PDU", buffer, size,
"|");
186 if (flags & RNS_UD_CS_STRONG_ASYMMETRIC_KEYS)
187 winpr_str_append(
"RNS_UD_CS_STRONG_ASYMMETRIC_KEYS", buffer, size,
"|");
188 if (flags & RNS_UD_CS_RELATIVE_MOUSE_INPUT)
189 winpr_str_append(
"RNS_UD_CS_RELATIVE_MOUSE_INPUT", buffer, size,
"|");
190 if (flags & RNS_UD_CS_VALID_CONNECTION_TYPE)
191 winpr_str_append(
"RNS_UD_CS_VALID_CONNECTION_TYPE", buffer, size,
"|");
192 if (flags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU)
193 winpr_str_append(
"RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU", buffer, size,
"|");
194 if (flags & RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT)
195 winpr_str_append(
"RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT", buffer, size,
"|");
196 if (flags & RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL)
197 winpr_str_append(
"RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL", buffer, size,
"|");
198 if (flags & RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE)
199 winpr_str_append(
"RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE", buffer, size,
"|");
200 if (flags & RNS_UD_CS_SUPPORT_HEARTBEAT_PDU)
201 winpr_str_append(
"RNS_UD_CS_SUPPORT_HEARTBEAT_PDU", buffer, size,
"|");
202 if (flags & RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN)
203 winpr_str_append(
"RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN", buffer, size,
"|");
207 (void)_snprintf(msg,
sizeof(msg),
"RNS_UD_CS_UNKNOWN[0x%08" PRIx32
"]", unknown);
208 winpr_str_append(msg, buffer, size,
"|");
210 (void)_snprintf(msg,
sizeof(msg),
"[0x%08" PRIx32
"]", flags);
211 winpr_str_append(msg, buffer, size,
"|");
215 static DWORD rdp_version_common(DWORD serverVersion, DWORD clientVersion)
217 DWORD version = MIN(serverVersion, clientVersion);
222 case RDP_VERSION_5_PLUS:
223 case RDP_VERSION_10_0:
224 case RDP_VERSION_10_1:
225 case RDP_VERSION_10_2:
226 case RDP_VERSION_10_3:
227 case RDP_VERSION_10_4:
228 case RDP_VERSION_10_5:
229 case RDP_VERSION_10_6:
230 case RDP_VERSION_10_7:
231 case RDP_VERSION_10_8:
232 case RDP_VERSION_10_9:
233 case RDP_VERSION_10_10:
234 case RDP_VERSION_10_11:
235 case RDP_VERSION_10_12:
239 WLog_ERR(TAG,
"Invalid client [%" PRId32
"] and server [%" PRId32
"] versions",
240 serverVersion, clientVersion);
344 static const BYTE t124_02_98_oid[6] = { 0, 0, 20, 124, 0, 1 };
346 static const BYTE h221_cs_key[4] =
"Duca";
347 static const BYTE h221_sc_key[4] =
"McDn";
359 BOOL gcc_read_conference_create_request(
wStream* s, rdpMcs* mcs)
369 if (!per_read_choice(s, &choice))
372 if (!per_read_object_identifier(s, t124_02_98_oid))
376 if (!per_read_length(s, &length))
380 if (!per_read_choice(s, &choice))
383 if (!per_read_selection(s, &selection))
387 if (!per_read_numeric_string(s, 1))
390 if (!per_read_padding(s, 1))
394 if (!per_read_number_of_sets(s, &number) || number != 1)
397 if (!per_read_choice(s, &choice) ||
402 if (!per_read_octet_string(s, h221_cs_key, 4,
407 if (!per_read_length(s, &length))
410 if (!Stream_CheckAndLogRequiredLength(TAG, s, length))
413 if (!gcc_read_client_data_blocks(s, mcs, length))
429 BOOL gcc_write_conference_create_request(
wStream* s,
wStream* userData)
432 WINPR_ASSERT(userData);
434 if (!per_write_choice(s, 0))
436 if (!per_write_object_identifier(s, t124_02_98_oid))
439 if (!per_write_length(s, Stream_GetPosition(userData) + 14))
442 if (!per_write_choice(s, 0))
445 if (!per_write_selection(s, 0x08))
448 if (!per_write_numeric_string(s, (BYTE*)
"1", 1, 1))
450 if (!per_write_padding(s, 1))
453 if (!per_write_number_of_sets(s, 1))
455 if (!per_write_choice(s, 0xC0))
458 if (!per_write_octet_string(s, h221_cs_key, 4,
462 return per_write_octet_string(s, Stream_Buffer(userData), Stream_GetPosition(userData),
466 BOOL gcc_read_conference_create_response(
wStream* s, rdpMcs* mcs)
477 if (!per_read_choice(s, &choice) || !per_read_object_identifier(s, t124_02_98_oid))
481 if (!per_read_length(s, &length))
485 if (!per_read_choice(s, &choice))
489 if (!per_read_integer16(s, &nodeID, 1001))
493 if (!per_read_integer(s, &tag))
497 if (!per_read_enumerated(s, &result, MCS_Result_enum_length))
501 if (!per_read_number_of_sets(s, &number))
505 if (!per_read_choice(s, &choice))
509 if (!per_read_octet_string(s, h221_sc_key, 4,
514 if (!per_read_length(s, &length))
517 if (!gcc_read_server_data_blocks(s, mcs, length))
519 WLog_ERR(TAG,
"gcc_read_conference_create_response: gcc_read_server_data_blocks failed");
526 BOOL gcc_write_conference_create_response(
wStream* s,
wStream* userData)
529 WINPR_ASSERT(userData);
531 if (!per_write_choice(s, 0))
533 if (!per_write_object_identifier(s, t124_02_98_oid))
537 if (!per_write_length(s, 0x2A))
540 if (!per_write_choice(s, 0x14))
543 if (!per_write_integer16(s, 0x79F3, 1001))
546 if (!per_write_integer(s, 1))
549 if (!per_write_enumerated(s, 0, MCS_Result_enum_length))
552 if (!per_write_number_of_sets(s, 1))
555 if (!per_write_choice(s, 0xC0))
558 if (!per_write_octet_string(s, h221_sc_key, 4,
562 return per_write_octet_string(s, Stream_Buffer(userData), Stream_GetPosition(userData),
566 static BOOL gcc_read_client_unused1_data(
wStream* s)
568 return Stream_SafeSeek(s, 2);
571 BOOL gcc_read_client_data_blocks(
wStream* s, rdpMcs* mcs, UINT16 length)
576 BOOL gotMultitransport = FALSE;
582 UINT16 blockLength = 0;
584 if (!gcc_read_user_data_header(s, &type, &blockLength))
587 if (!Stream_CheckAndLogRequiredLength(TAG, s, (
size_t)(blockLength - 4)))
590 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), blockLength - 4);
593 Stream_Seek(s, blockLength - 4);
598 if (!gcc_read_client_core_data(sub, mcs))
604 if (!gcc_read_client_security_data(sub, mcs))
610 if (!gcc_read_client_network_data(sub, mcs))
616 if (!gcc_read_client_cluster_data(sub, mcs))
622 if (!gcc_read_client_monitor_data(sub, mcs))
627 case CS_MCS_MSGCHANNEL:
628 if (!gcc_read_client_message_channel_data(sub, mcs))
634 if (!gcc_read_client_monitor_extended_data(sub, mcs))
640 if (!gcc_read_client_unused1_data(sub))
646 case CS_MULTITRANSPORT:
647 gotMultitransport = TRUE;
648 if (!gcc_read_client_multitransport_channel_data(sub, mcs))
654 WLog_ERR(TAG,
"Unknown GCC client data block: 0x%04" PRIX16
"", type);
655 winpr_HexDump(TAG, WLOG_TRACE, Stream_Pointer(sub), Stream_GetRemainingLength(sub));
659 const size_t rem = Stream_GetRemainingLength(sub);
662 char buffer[128] = { 0 };
663 const size_t total = Stream_Length(sub);
665 "Error parsing GCC client data block %s: Actual Offset: %" PRIuz
666 " Expected Offset: %" PRIuz,
667 gcc_block_type_string(type, buffer,
sizeof(buffer)), total - rem, total);
670 if (blockLength > length)
672 char buffer[128] = { 0 };
674 "Error parsing GCC client data block %s: got blockLength 0x%04" PRIx16
675 ", but only 0x%04" PRIx16
"remaining",
676 gcc_block_type_string(type, buffer,
sizeof(buffer)), blockLength, length);
680 length -= blockLength;
683 if (!gotMultitransport)
685 rdpSettings* settings = mcs_get_settings(mcs);
694 BOOL gcc_write_client_data_blocks(
wStream* s,
const rdpMcs* mcs)
696 const rdpSettings* settings = mcs_get_const_settings(mcs);
699 WINPR_ASSERT(settings);
701 if (!gcc_write_client_core_data(s, mcs) || !gcc_write_client_cluster_data(s, mcs) ||
702 !gcc_write_client_security_data(s, mcs) || !gcc_write_client_network_data(s, mcs))
707 if (settings->NegotiationFlags & EXTENDED_CLIENT_DATA_SUPPORTED)
709 if (settings->UseMultimon && !settings->SpanMonitors)
711 if (!gcc_write_client_monitor_data(s, mcs) ||
712 !gcc_write_client_monitor_extended_data(s, mcs))
716 if (!gcc_write_client_message_channel_data(s, mcs) ||
717 !gcc_write_client_multitransport_channel_data(s, mcs))
722 if (settings->UseMultimon && !settings->SpanMonitors)
724 WLog_ERR(TAG,
"WARNING: true multi monitor support was not advertised by server!");
726 if (settings->ForceMultimon)
728 WLog_ERR(TAG,
"Sending multi monitor information anyway (may break connectivity!)");
729 if (!gcc_write_client_monitor_data(s, mcs) ||
730 !gcc_write_client_monitor_extended_data(s, mcs))
735 WLog_ERR(TAG,
"Use /multimon:force to force sending multi monitor information");
742 char* gcc_block_type_string(UINT16 type,
char* buffer,
size_t size)
747 (void)_snprintf(buffer, size,
"CS_CORE [0x%04" PRIx16
"]", type);
750 (void)_snprintf(buffer, size,
"CS_SECURITY [0x%04" PRIx16
"]", type);
753 (void)_snprintf(buffer, size,
"CS_NET [0x%04" PRIx16
"]", type);
756 (void)_snprintf(buffer, size,
"CS_CLUSTER [0x%04" PRIx16
"]", type);
759 (void)_snprintf(buffer, size,
"CS_MONITOR [0x%04" PRIx16
"]", type);
761 case CS_MCS_MSGCHANNEL:
762 (void)_snprintf(buffer, size,
"CS_MONITOR [0x%04" PRIx16
"]", type);
765 (void)_snprintf(buffer, size,
"CS_MONITOR_EX [0x%04" PRIx16
"]", type);
768 (void)_snprintf(buffer, size,
"CS_UNUSED1 [0x%04" PRIx16
"]", type);
770 case CS_MULTITRANSPORT:
771 (void)_snprintf(buffer, size,
"CS_MONITOR_EX [0x%04" PRIx16
"]", type);
774 (void)_snprintf(buffer, size,
"SC_CORE [0x%04" PRIx16
"]", type);
777 (void)_snprintf(buffer, size,
"SC_SECURITY [0x%04" PRIx16
"]", type);
780 (void)_snprintf(buffer, size,
"SC_NET [0x%04" PRIx16
"]", type);
782 case SC_MCS_MSGCHANNEL:
783 (void)_snprintf(buffer, size,
"SC_MCS_MSGCHANNEL [0x%04" PRIx16
"]", type);
785 case SC_MULTITRANSPORT:
786 (void)_snprintf(buffer, size,
"SC_MULTITRANSPORT [0x%04" PRIx16
"]", type);
789 (void)_snprintf(buffer, size,
"UNKNOWN [0x%04" PRIx16
"]", type);
795 BOOL gcc_read_server_data_blocks(
wStream* s, rdpMcs* mcs, UINT16 length)
799 UINT16 blockLength = 0;
805 while (offset < length)
807 char buffer[64] = { 0 };
812 if (!gcc_read_user_data_header(s, &type, &blockLength))
814 WLog_ERR(TAG,
"gcc_read_server_data_blocks: gcc_read_user_data_header failed");
817 holdp = Stream_Pointer(s);
818 sub = Stream_StaticInit(&subbuffer, holdp, blockLength - 4);
819 if (!Stream_SafeSeek(s, blockLength - 4))
821 WLog_ERR(TAG,
"gcc_read_server_data_blocks: stream too short");
824 offset += blockLength;
829 if (!gcc_read_server_core_data(sub, mcs))
831 WLog_ERR(TAG,
"gcc_read_server_data_blocks: gcc_read_server_core_data failed");
838 if (!gcc_read_server_security_data(sub, mcs))
843 if (!gcc_read_server_network_data(sub, mcs))
846 "gcc_read_server_data_blocks: gcc_read_server_network_data failed");
852 case SC_MCS_MSGCHANNEL:
853 if (!gcc_read_server_message_channel_data(sub, mcs))
857 "gcc_read_server_data_blocks: gcc_read_server_message_channel_data failed");
863 case SC_MULTITRANSPORT:
864 if (!gcc_read_server_multitransport_channel_data(sub, mcs))
866 WLog_ERR(TAG,
"gcc_read_server_data_blocks: "
867 "gcc_read_server_multitransport_channel_data failed");
874 WLog_ERR(TAG,
"gcc_read_server_data_blocks: ignoring type=%s",
875 gcc_block_type_string(type, buffer,
sizeof(buffer)));
876 winpr_HexDump(TAG, WLOG_TRACE, Stream_Pointer(sub), Stream_GetRemainingLength(sub));
880 rest = Stream_GetRemainingLength(sub);
883 WLog_WARN(TAG,
"gcc_read_server_data_blocks: ignoring %" PRIuz
" bytes with type=%s",
884 rest, gcc_block_type_string(type, buffer,
sizeof(buffer)));
891 BOOL gcc_write_server_data_blocks(
wStream* s, rdpMcs* mcs)
896 if (!gcc_write_server_core_data(s, mcs) ||
897 !gcc_write_server_network_data(s, mcs) ||
898 !gcc_write_server_security_data(s, mcs) ||
899 !gcc_write_server_message_channel_data(s, mcs))
902 const rdpSettings* settings = mcs_get_const_settings(mcs);
903 WINPR_ASSERT(settings);
905 if (settings->SupportMultitransport && (settings->MultitransportFlags != 0))
907 return gcc_write_server_multitransport_channel_data(s, mcs);
912 BOOL gcc_read_user_data_header(
wStream* s, UINT16* type, UINT16* length)
915 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
918 Stream_Read_UINT16(s, *type);
919 Stream_Read_UINT16(s, *length);
921 if ((*length < 4) || (!Stream_CheckAndLogRequiredLength(TAG, s, (
size_t)(*length - 4))))
938 BOOL gcc_write_user_data_header(
wStream* s, UINT16 type, UINT16 length)
942 if (!Stream_EnsureRemainingCapacity(s, 4 + length))
944 Stream_Write_UINT16(s, type);
945 Stream_Write_UINT16(s, length);
949 static UINT32 filterAndLogEarlyServerCapabilityFlags(UINT32 flags)
952 (RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1 | RNS_UD_SC_DYNAMIC_DST_SUPPORTED |
953 RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2 | RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED);
954 const UINT32 filtered = flags & mask;
955 const UINT32 unknown = flags & (~mask);
958 char buffer[256] = { 0 };
960 "TS_UD_SC_CORE::EarlyCapabilityFlags [0x%08" PRIx32
" & 0x%08" PRIx32
961 " --> 0x%08" PRIx32
"] filtering %s, feature not implemented",
962 flags, ~mask, unknown,
963 rdp_early_server_caps_string(unknown, buffer,
sizeof(buffer)));
968 static UINT32 earlyServerCapsFromSettings(
const rdpSettings* settings)
970 UINT32 EarlyCapabilityFlags = 0;
972 if (settings->SupportEdgeActionV1)
973 EarlyCapabilityFlags |= RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1;
974 if (settings->SupportDynamicTimeZone)
975 EarlyCapabilityFlags |= RNS_UD_SC_DYNAMIC_DST_SUPPORTED;
976 if (settings->SupportEdgeActionV2)
977 EarlyCapabilityFlags |= RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2;
978 if (settings->SupportSkipChannelJoin)
979 EarlyCapabilityFlags |= RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED;
981 return filterAndLogEarlyServerCapabilityFlags(EarlyCapabilityFlags);
984 static UINT16 filterAndLogEarlyClientCapabilityFlags(UINT32 flags)
987 (RNS_UD_CS_SUPPORT_ERRINFO_PDU | RNS_UD_CS_WANT_32BPP_SESSION |
988 RNS_UD_CS_SUPPORT_STATUSINFO_PDU | RNS_UD_CS_STRONG_ASYMMETRIC_KEYS |
989 RNS_UD_CS_RELATIVE_MOUSE_INPUT | RNS_UD_CS_VALID_CONNECTION_TYPE |
990 RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU | RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT |
991 RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL | RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE |
992 RNS_UD_CS_SUPPORT_HEARTBEAT_PDU | RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN);
993 const UINT32 filtered = flags & mask;
994 const UINT32 unknown = flags & ~mask;
997 char buffer[256] = { 0 };
999 "(TS_UD_CS_CORE)::EarlyCapabilityFlags [0x%08" PRIx32
" & 0x%08" PRIx32
1000 " --> 0x%08" PRIx32
"] filtering %s, feature not implemented",
1001 flags, ~mask, unknown,
1002 rdp_early_client_caps_string(unknown, buffer,
sizeof(buffer)));
1007 static UINT16 earlyClientCapsFromSettings(
const rdpSettings* settings)
1009 UINT32 earlyCapabilityFlags = 0;
1011 WINPR_ASSERT(settings);
1012 if (settings->SupportErrorInfoPdu)
1013 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_ERRINFO_PDU;
1016 earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION;
1018 if (settings->SupportStatusInfoPdu)
1019 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_STATUSINFO_PDU;
1021 if (settings->ConnectionType)
1022 earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE;
1024 if (settings->SupportMonitorLayoutPdu)
1025 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU;
1028 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT;
1030 if (settings->SupportGraphicsPipeline)
1031 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL;
1033 if (settings->SupportDynamicTimeZone)
1034 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE;
1036 if (settings->SupportHeartbeatPdu)
1037 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_HEARTBEAT_PDU;
1039 if (settings->SupportAsymetricKeys)
1040 earlyCapabilityFlags |= RNS_UD_CS_STRONG_ASYMMETRIC_KEYS;
1042 if (settings->HasRelativeMouseEvent)
1043 earlyCapabilityFlags |= RNS_UD_CS_RELATIVE_MOUSE_INPUT;
1045 if (settings->SupportSkipChannelJoin)
1046 earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN;
1048 return filterAndLogEarlyClientCapabilityFlags(earlyCapabilityFlags);
1051 static BOOL updateEarlyClientCaps(rdpSettings* settings, UINT32 earlyCapabilityFlags,
1052 UINT32 connectionType)
1054 WINPR_ASSERT(settings);
1056 if (settings->SupportErrorInfoPdu)
1057 settings->SupportErrorInfoPdu =
1058 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_ERRINFO_PDU) ? TRUE : FALSE;
1066 if (settings->SupportStatusInfoPdu)
1067 settings->SupportStatusInfoPdu =
1068 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_STATUSINFO_PDU) ? TRUE : FALSE;
1070 if (settings->SupportAsymetricKeys)
1071 settings->SupportAsymetricKeys =
1072 (earlyCapabilityFlags & RNS_UD_CS_STRONG_ASYMMETRIC_KEYS) ? TRUE : FALSE;
1074 if (settings->HasRelativeMouseEvent)
1075 settings->HasRelativeMouseEvent =
1076 (earlyCapabilityFlags & RNS_UD_CS_RELATIVE_MOUSE_INPUT) ? TRUE : FALSE;
1078 if (settings->NetworkAutoDetect)
1079 settings->NetworkAutoDetect =
1080 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT) ? TRUE : FALSE;
1082 if (settings->SupportSkipChannelJoin)
1083 settings->SupportSkipChannelJoin =
1084 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN) ? TRUE : FALSE;
1086 if (settings->SupportMonitorLayoutPdu)
1087 settings->SupportMonitorLayoutPdu =
1088 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU) ? TRUE : FALSE;
1090 if (settings->SupportHeartbeatPdu)
1091 settings->SupportHeartbeatPdu =
1092 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_HEARTBEAT_PDU) ? TRUE : FALSE;
1094 if (settings->SupportGraphicsPipeline)
1095 settings->SupportGraphicsPipeline =
1096 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL) ? TRUE : FALSE;
1098 if (settings->SupportDynamicTimeZone)
1099 settings->SupportDynamicTimeZone =
1100 (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE) ? TRUE : FALSE;
1102 if ((earlyCapabilityFlags & RNS_UD_CS_VALID_CONNECTION_TYPE) == 0)
1104 settings->ConnectionType = connectionType;
1106 filterAndLogEarlyClientCapabilityFlags(earlyCapabilityFlags);
1110 static BOOL updateEarlyServerCaps(rdpSettings* settings, UINT32 earlyCapabilityFlags,
1111 UINT32 connectionType)
1113 WINPR_ASSERT(settings);
1115 settings->SupportEdgeActionV1 =
1116 settings->SupportEdgeActionV1 &&
1117 (earlyCapabilityFlags & RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1)
1120 settings->SupportDynamicTimeZone =
1121 settings->SupportDynamicTimeZone && (earlyCapabilityFlags & RNS_UD_SC_DYNAMIC_DST_SUPPORTED)
1124 settings->SupportEdgeActionV2 =
1125 settings->SupportEdgeActionV2 &&
1126 (earlyCapabilityFlags & RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2)
1129 settings->SupportSkipChannelJoin =
1130 settings->SupportSkipChannelJoin &&
1131 (earlyCapabilityFlags & RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED)
1135 filterAndLogEarlyServerCapabilityFlags(earlyCapabilityFlags);
1148 BOOL gcc_read_client_core_data(
wStream* s, rdpMcs* mcs)
1150 char buffer[2048] = { 0 };
1151 char strbuffer[130] = { 0 };
1153 BYTE connectionType = 0;
1154 UINT32 clientColorDepth = 0;
1155 UINT16 colorDepth = 0;
1156 UINT16 postBeta2ColorDepth = 0;
1157 UINT16 highColorDepth = 0;
1158 UINT32 serverSelectedProtocol = 0;
1159 rdpSettings* settings = mcs_get_settings(mcs);
1162 WINPR_ASSERT(settings);
1164 size_t blockLength = Stream_GetRemainingLength(s);
1166 if (blockLength < 128)
1169 Stream_Read_UINT32(s, version);
1170 settings->RdpVersion = rdp_version_common(version, settings->RdpVersion);
1171 Stream_Read_UINT16(s, settings->DesktopWidth);
1172 Stream_Read_UINT16(s, settings->DesktopHeight);
1173 Stream_Read_UINT16(s, colorDepth);
1174 Stream_Seek_UINT16(s);
1175 Stream_Read_UINT32(s, settings->KeyboardLayout);
1176 Stream_Read_UINT32(s, settings->ClientBuild);
1179 if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, 32 /
sizeof(WCHAR), strbuffer,
1180 ARRAYSIZE(strbuffer)) < 0)
1182 WLog_ERR(TAG,
"failed to convert client host name");
1189 Stream_Read_UINT32(s, settings->KeyboardType);
1190 Stream_Read_UINT32(s, settings->KeyboardSubType);
1191 Stream_Read_UINT32(s, settings->KeyboardFunctionKey);
1204 UINT16 clientProductIdLen = 0;
1205 if (blockLength < 2)
1208 Stream_Read_UINT16(s, postBeta2ColorDepth);
1211 if (blockLength < 2)
1214 Stream_Read_UINT16(s, clientProductIdLen);
1217 if (blockLength < 4)
1220 Stream_Seek_UINT32(s);
1223 if (blockLength < 2)
1226 Stream_Read_UINT16(s, highColorDepth);
1229 if (blockLength < 2)
1232 Stream_Read_UINT16(s, settings->SupportedColorDepths);
1235 if (blockLength < 2)
1238 Stream_Read_UINT16(s, settings->EarlyCapabilityFlags);
1243 if (blockLength < 64)
1246 if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, 64 /
sizeof(WCHAR), strbuffer,
1247 ARRAYSIZE(strbuffer)) < 0)
1249 WLog_ERR(TAG,
"failed to convert the client product identifier");
1257 if (blockLength < 1)
1260 Stream_Read_UINT8(s, connectionType);
1263 if (blockLength < 1)
1266 Stream_Seek_UINT8(s);
1269 if (blockLength < 4)
1272 Stream_Read_UINT32(s, serverSelectedProtocol);
1275 if (blockLength < 4)
1278 Stream_Read_UINT32(s, settings->DesktopPhysicalWidth);
1281 if (blockLength < 4)
1284 Stream_Read_UINT32(s,
1285 settings->DesktopPhysicalHeight);
1288 if (blockLength < 2)
1291 Stream_Read_UINT16(s, settings->DesktopOrientation);
1294 if (blockLength < 4)
1297 Stream_Read_UINT32(s, settings->DesktopScaleFactor);
1300 if (blockLength < 4)
1303 Stream_Read_UINT32(s, settings->DeviceScaleFactor);
1306 settings->SelectedProtocol = serverSelectedProtocol;
1307 else if (settings->SelectedProtocol != serverSelectedProtocol)
1311 if (highColorDepth > 0)
1313 if (settings->EarlyCapabilityFlags & RNS_UD_CS_WANT_32BPP_SESSION)
1314 clientColorDepth = 32;
1316 clientColorDepth = highColorDepth;
1318 else if (postBeta2ColorDepth > 0)
1320 switch (postBeta2ColorDepth)
1322 case RNS_UD_COLOR_4BPP:
1323 clientColorDepth = 4;
1326 case RNS_UD_COLOR_8BPP:
1327 clientColorDepth = 8;
1330 case RNS_UD_COLOR_16BPP_555:
1331 clientColorDepth = 15;
1334 case RNS_UD_COLOR_16BPP_565:
1335 clientColorDepth = 16;
1338 case RNS_UD_COLOR_24BPP:
1339 clientColorDepth = 24;
1350 case RNS_UD_COLOR_4BPP:
1351 clientColorDepth = 4;
1354 case RNS_UD_COLOR_8BPP:
1355 clientColorDepth = 8;
1368 !settings->ServerMode)
1374 WLog_DBG(TAG,
"Received EarlyCapabilityFlags=%s",
1375 rdp_early_client_caps_string(settings->EarlyCapabilityFlags, buffer,
sizeof(buffer)));
1377 return updateEarlyClientCaps(settings, settings->EarlyCapabilityFlags, connectionType);
1389 BOOL gcc_write_client_core_data(
wStream* s,
const rdpMcs* mcs)
1391 char buffer[2048] = { 0 };
1392 char dbuffer[2048] = { 0 };
1393 BYTE connectionType = 0;
1394 HIGH_COLOR_DEPTH highColorDepth = HIGH_COLOR_4BPP;
1396 UINT16 earlyCapabilityFlags = 0;
1397 const rdpSettings* settings = mcs_get_const_settings(mcs);
1400 WINPR_ASSERT(settings);
1402 const UINT16 SupportedColorDepths =
1406 if (!gcc_write_user_data_header(s, CS_CORE, 234))
1409 Stream_Write_UINT32(s, settings->RdpVersion);
1410 Stream_Write_UINT16(s, settings->DesktopWidth);
1411 Stream_Write_UINT16(s, settings->DesktopHeight);
1412 Stream_Write_UINT16(s,
1414 Stream_Write_UINT16(s, RNS_UD_SAS_DEL);
1415 Stream_Write_UINT32(s, settings->KeyboardLayout);
1416 Stream_Write_UINT32(s, settings->ClientBuild);
1418 if (!Stream_EnsureRemainingCapacity(s, 32 + 12 + 64 + 8))
1422 size_t clientNameLength = 0;
1423 WCHAR* clientName = ConvertUtf8ToWCharAlloc(settings->ClientHostname, &clientNameLength);
1424 if (clientNameLength >= 16)
1426 clientNameLength = 16;
1427 clientName[clientNameLength - 1] = 0;
1430 Stream_Write(s, clientName, (clientNameLength * 2));
1431 Stream_Zero(s, 32 - (clientNameLength * 2));
1433 Stream_Write_UINT32(s, settings->KeyboardType);
1434 Stream_Write_UINT32(s, settings->KeyboardSubType);
1435 Stream_Write_UINT32(s, settings->KeyboardFunctionKey);
1437 Stream_Write_UINT16(s, RNS_UD_COLOR_8BPP);
1438 Stream_Write_UINT16(s, 1);
1439 Stream_Write_UINT32(s, 0);
1440 highColorDepth = ColorDepthToHighColor(ColorDepth);
1441 earlyCapabilityFlags = earlyClientCapsFromSettings(settings);
1443 connectionType = settings->ConnectionType;
1445 if (!Stream_EnsureRemainingCapacity(s, 6))
1448 WLog_DBG(TAG,
"Sending highColorDepth=%s, supportedColorDepths=%s, earlyCapabilityFlags=%s",
1449 HighColorToString(highColorDepth),
1451 rdp_early_client_caps_string(earlyCapabilityFlags, buffer,
sizeof(buffer)));
1452 Stream_Write_UINT16(s, highColorDepth);
1453 Stream_Write_UINT16(s, SupportedColorDepths);
1454 Stream_Write_UINT16(s, earlyCapabilityFlags);
1456 if (!Stream_EnsureRemainingCapacity(s, 64 + 24))
1460 size_t clientDigProductIdLength = 0;
1461 WCHAR* clientDigProductId =
1462 ConvertUtf8ToWCharAlloc(settings->ClientProductId, &clientDigProductIdLength);
1463 if (clientDigProductIdLength >= 32)
1465 clientDigProductIdLength = 32;
1466 clientDigProductId[clientDigProductIdLength - 1] = 0;
1469 Stream_Write(s, clientDigProductId, (clientDigProductIdLength * 2));
1470 Stream_Zero(s, 64 - (clientDigProductIdLength * 2));
1471 free(clientDigProductId);
1472 Stream_Write_UINT8(s, connectionType);
1473 Stream_Write_UINT8(s, 0);
1474 Stream_Write_UINT32(s, settings->SelectedProtocol);
1475 Stream_Write_UINT32(s, settings->DesktopPhysicalWidth);
1476 Stream_Write_UINT32(s, settings->DesktopPhysicalHeight);
1477 Stream_Write_UINT16(s, settings->DesktopOrientation);
1478 Stream_Write_UINT32(s, settings->DesktopScaleFactor);
1479 Stream_Write_UINT32(s, settings->DeviceScaleFactor);
1483 BOOL gcc_read_server_core_data(
wStream* s, rdpMcs* mcs)
1485 UINT32 serverVersion = 0;
1486 rdpSettings* settings = mcs_get_settings(mcs);
1489 WINPR_ASSERT(settings);
1491 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1494 Stream_Read_UINT32(s, serverVersion);
1495 settings->RdpVersion = rdp_version_common(serverVersion, settings->RdpVersion);
1497 if (Stream_GetRemainingLength(s) >= 4)
1499 Stream_Read_UINT32(s, settings->RequestedProtocols);
1502 if (Stream_GetRemainingLength(s) >= 4)
1504 char buffer[2048] = { 0 };
1506 Stream_Read_UINT32(s, settings->EarlyCapabilityFlags);
1508 TAG,
"Received EarlyCapabilityFlags=%s",
1509 rdp_early_client_caps_string(settings->EarlyCapabilityFlags, buffer,
sizeof(buffer)));
1512 return updateEarlyServerCaps(settings, settings->EarlyCapabilityFlags,
1513 settings->ConnectionType);
1519 BOOL gcc_write_server_core_data(
wStream* s, rdpMcs* mcs)
1521 const rdpSettings* settings = mcs_get_const_settings(mcs);
1524 WINPR_ASSERT(settings);
1526 if (!gcc_write_user_data_header(s, SC_CORE, 16))
1529 const UINT32 EarlyCapabilityFlags = earlyServerCapsFromSettings(settings);
1530 Stream_Write_UINT32(s, settings->RdpVersion);
1531 Stream_Write_UINT32(s, settings->RequestedProtocols);
1532 Stream_Write_UINT32(s, EarlyCapabilityFlags);
1545 BOOL gcc_read_client_security_data(
wStream* s, rdpMcs* mcs)
1547 rdpSettings* settings = mcs_get_settings(mcs);
1550 WINPR_ASSERT(settings);
1552 const size_t blockLength = Stream_GetRemainingLength(s);
1553 if (blockLength < 8)
1556 if (settings->UseRdpSecurityLayer)
1558 Stream_Read_UINT32(s, settings->EncryptionMethods);
1560 if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE)
1561 Stream_Read_UINT32(s, settings->EncryptionMethods);
1582 BOOL gcc_write_client_security_data(
wStream* s,
const rdpMcs* mcs)
1584 const rdpSettings* settings = mcs_get_const_settings(mcs);
1587 WINPR_ASSERT(settings);
1589 if (!gcc_write_user_data_header(s, CS_SECURITY, 12))
1592 if (settings->UseRdpSecurityLayer)
1594 Stream_Write_UINT32(s, settings->EncryptionMethods);
1595 Stream_Write_UINT32(s, 0);
1600 Stream_Write_UINT32(s, 0);
1601 Stream_Write_UINT32(s, settings->EncryptionMethods);
1606 BOOL gcc_read_server_security_data(
wStream* s, rdpMcs* mcs)
1608 const BYTE* data = NULL;
1610 BOOL validCryptoConfig = FALSE;
1611 UINT32 EncryptionMethod = 0;
1612 UINT32 EncryptionLevel = 0;
1613 rdpSettings* settings = mcs_get_settings(mcs);
1616 WINPR_ASSERT(settings);
1618 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1621 Stream_Read_UINT32(s, EncryptionMethod);
1622 Stream_Read_UINT32(s, EncryptionLevel);
1625 switch (EncryptionMethod)
1627 case ENCRYPTION_METHOD_NONE:
1628 WLog_DBG(TAG,
"Server rdp encryption method: NONE");
1631 case ENCRYPTION_METHOD_40BIT:
1632 WLog_DBG(TAG,
"Server rdp encryption method: 40BIT");
1635 case ENCRYPTION_METHOD_56BIT:
1636 WLog_DBG(TAG,
"Server rdp encryption method: 56BIT");
1639 case ENCRYPTION_METHOD_128BIT:
1640 WLog_DBG(TAG,
"Server rdp encryption method: 128BIT");
1643 case ENCRYPTION_METHOD_FIPS:
1644 WLog_DBG(TAG,
"Server rdp encryption method: FIPS");
1648 WLog_ERR(TAG,
"Received unknown encryption method %08" PRIX32
"", EncryptionMethod);
1652 if (settings->UseRdpSecurityLayer && !(settings->EncryptionMethods & EncryptionMethod))
1654 WLog_WARN(TAG,
"Server uses non-advertised encryption method 0x%08" PRIX32
"",
1659 settings->EncryptionMethods = EncryptionMethod;
1660 settings->EncryptionLevel = EncryptionLevel;
1662 switch (settings->EncryptionLevel)
1664 case ENCRYPTION_LEVEL_NONE:
1665 if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE)
1667 validCryptoConfig = TRUE;
1672 case ENCRYPTION_LEVEL_FIPS:
1673 if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
1675 validCryptoConfig = TRUE;
1680 case ENCRYPTION_LEVEL_LOW:
1681 case ENCRYPTION_LEVEL_HIGH:
1682 case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE:
1683 if (settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT ||
1684 settings->EncryptionMethods == ENCRYPTION_METHOD_56BIT ||
1685 settings->EncryptionMethods == ENCRYPTION_METHOD_128BIT ||
1686 settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
1688 validCryptoConfig = TRUE;
1694 WLog_ERR(TAG,
"Received unknown encryption level 0x%08" PRIX32
"",
1695 settings->EncryptionLevel);
1698 if (!validCryptoConfig)
1701 "Received invalid cryptographic configuration (level=0x%08" PRIX32
1702 " method=0x%08" PRIX32
")",
1703 settings->EncryptionLevel, settings->EncryptionMethods);
1707 if (settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE)
1710 settings->UseRdpSecurityLayer = FALSE;
1714 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1717 Stream_Read_UINT32(s, settings->ServerRandomLength);
1718 Stream_Read_UINT32(s, settings->ServerCertificateLength);
1720 if ((settings->ServerRandomLength == 0) || (settings->ServerCertificateLength == 0))
1723 "Invalid ServerRandom (length=%" PRIu32
") or ServerCertificate (length=%" PRIu32
1725 settings->ServerRandomLength, settings->ServerCertificateLength);
1729 if (!Stream_CheckAndLogRequiredLength(TAG, s, settings->ServerRandomLength))
1734 settings->ServerRandomLength))
1737 Stream_Read(s, settings->ServerRandom, settings->ServerRandomLength);
1739 if (!Stream_CheckAndLogRequiredLength(TAG, s, settings->ServerCertificateLength))
1744 settings->ServerCertificateLength))
1747 Stream_Read(s, settings->ServerCertificate, settings->ServerCertificateLength);
1749 data = settings->ServerCertificate;
1750 length = settings->ServerCertificateLength;
1752 if (!freerdp_certificate_read_server_cert(settings->RdpServerCertificate, data, length))
1757 free(settings->ServerRandom);
1758 free(settings->ServerCertificate);
1759 settings->ServerRandom = NULL;
1760 settings->ServerCertificate = NULL;
1764 static BOOL gcc_update_server_random(rdpSettings* settings)
1766 const size_t length = 32;
1767 WINPR_ASSERT(settings);
1773 winpr_RAND(data, length);
1780 BOOL gcc_write_server_security_data(
wStream* s, rdpMcs* mcs)
1782 if (!gcc_update_server_random(mcs_get_settings(mcs)))
1785 const rdpSettings* settings = mcs_get_const_settings(mcs);
1788 WINPR_ASSERT(settings);
1790 const size_t posHeader = Stream_GetPosition(s);
1791 if (!gcc_write_user_data_header(s, SC_SECURITY, 12))
1794 Stream_Write_UINT32(s, settings->EncryptionMethods);
1795 Stream_Write_UINT32(s, settings->EncryptionLevel);
1797 if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE)
1800 if (!Stream_EnsureRemainingCapacity(s,
sizeof(UINT32) + settings->ServerRandomLength))
1802 Stream_Write_UINT32(s, settings->ServerRandomLength);
1803 const size_t posCertLen = Stream_GetPosition(s);
1804 Stream_Seek_UINT32(s);
1805 Stream_Write(s, settings->ServerRandom, settings->ServerRandomLength);
1807 const SSIZE_T len = freerdp_certificate_write_server_cert(
1808 settings->RdpServerCertificate, CERT_TEMPORARILY_ISSUED | CERT_CHAIN_VERSION_1, s);
1811 const size_t end = Stream_GetPosition(s);
1812 Stream_SetPosition(s, posHeader);
1813 if (!gcc_write_user_data_header(s, SC_SECURITY, end - posHeader))
1815 Stream_SetPosition(s, posCertLen);
1816 WINPR_ASSERT(len <= UINT32_MAX);
1817 Stream_Write_UINT32(s, (UINT32)len);
1818 Stream_SetPosition(s, end);
1832 BOOL gcc_read_client_network_data(
wStream* s, rdpMcs* mcs)
1837 const size_t blockLength = Stream_GetRemainingLength(s);
1838 if (blockLength < 4)
1841 Stream_Read_UINT32(s, mcs->channelCount);
1843 if (blockLength < 4 + mcs->channelCount * 12)
1846 if (mcs->channelCount > CHANNEL_MAX_COUNT)
1850 for (UINT32 i = 0; i < mcs->channelCount; i++)
1858 rdpMcsChannel* channel = &mcs->channels[i];
1859 Stream_Read(s, channel->Name, CHANNEL_NAME_LEN + 1);
1861 if (!memchr(channel->Name, 0, CHANNEL_NAME_LEN + 1))
1865 "protocol violation: received a static channel name with missing null-termination");
1869 Stream_Read_UINT32(s, channel->options);
1870 channel->ChannelId = mcs->baseChannelId++;
1885 BOOL gcc_write_client_network_data(
wStream* s,
const rdpMcs* mcs)
1890 if (mcs->channelCount > 0)
1892 length = mcs->channelCount * 12 + 8;
1893 if (!gcc_write_user_data_header(s, CS_NET, length))
1895 Stream_Write_UINT32(s, mcs->channelCount);
1898 for (UINT32 i = 0; i < mcs->channelCount; i++)
1901 rdpMcsChannel* channel = &mcs->channels[i];
1902 Stream_Write(s, channel->Name, CHANNEL_NAME_LEN + 1);
1903 Stream_Write_UINT32(s, channel->options);
1909 BOOL gcc_read_server_network_data(
wStream* s, rdpMcs* mcs)
1911 UINT16 channelId = 0;
1912 UINT16 MCSChannelId = 0;
1913 UINT16 channelCount = 0;
1914 UINT32 parsedChannelCount = 0;
1917 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1920 Stream_Read_UINT16(s, MCSChannelId);
1921 Stream_Read_UINT16(s, channelCount);
1922 parsedChannelCount = channelCount;
1924 if (channelCount != mcs->channelCount)
1926 WLog_ERR(TAG,
"requested %" PRIu32
" channels, got %" PRIu16
" instead", mcs->channelCount,
1931 mcs->channelCount = channelCount;
1934 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, channelCount, 2ull))
1937 if (mcs->channelMaxCount < parsedChannelCount)
1939 WLog_ERR(TAG,
"requested %" PRIu32
" channels > channelMaxCount %" PRIu16,
1940 mcs->channelCount, mcs->channelMaxCount);
1944 for (UINT32 i = 0; i < parsedChannelCount; i++)
1946 rdpMcsChannel* channel = &mcs->channels[i];
1947 Stream_Read_UINT16(s, channelId);
1948 channel->ChannelId = channelId;
1951 if (channelCount % 2 == 1)
1952 return Stream_SafeSeek(s, 2);
1957 BOOL gcc_write_server_network_data(
wStream* s,
const rdpMcs* mcs)
1961 const size_t payloadLen = 8 + mcs->channelCount * 2 + (mcs->channelCount % 2 == 1 ? 2 : 0);
1963 if (!gcc_write_user_data_header(s, SC_NET, payloadLen))
1966 Stream_Write_UINT16(s, MCS_GLOBAL_CHANNEL_ID);
1967 Stream_Write_UINT16(s, mcs->channelCount);
1969 for (UINT32 i = 0; i < mcs->channelCount; i++)
1971 const rdpMcsChannel* channel = &mcs->channels[i];
1972 Stream_Write_UINT16(s, channel->ChannelId);
1975 if (mcs->channelCount % 2 == 1)
1976 Stream_Write_UINT16(s, 0);
1990 BOOL gcc_read_client_cluster_data(
wStream* s, rdpMcs* mcs)
1992 char buffer[128] = { 0 };
1993 UINT32 redirectedSessionId = 0;
1994 rdpSettings* settings = mcs_get_settings(mcs);
1997 WINPR_ASSERT(settings);
1999 const size_t blockLength = Stream_GetRemainingLength(s);
2000 if (blockLength < 8)
2003 Stream_Read_UINT32(s, settings->ClusterInfoFlags);
2004 Stream_Read_UINT32(s, redirectedSessionId);
2006 WLog_VRB(TAG,
"read ClusterInfoFlags=%s, RedirectedSessionId=0x%08" PRIx32,
2007 rdp_cluster_info_flags_to_string(settings->ClusterInfoFlags, buffer,
sizeof(buffer)),
2008 redirectedSessionId);
2009 if (settings->ClusterInfoFlags & REDIRECTED_SESSIONID_FIELD_VALID)
2010 settings->RedirectedSessionId = redirectedSessionId;
2012 settings->ConsoleSession =
2013 (settings->ClusterInfoFlags & REDIRECTED_SESSIONID_FIELD_VALID) ? TRUE : FALSE;
2014 settings->RedirectSmartCards =
2015 (settings->ClusterInfoFlags & REDIRECTED_SMARTCARD) ? TRUE : FALSE;
2017 if (blockLength > 8ULL)
2019 if (Stream_GetRemainingLength(s) >= (blockLength - 8ULL))
2022 Stream_Seek(s, (blockLength - 8));
2038 BOOL gcc_write_client_cluster_data(
wStream* s,
const rdpMcs* mcs)
2040 char buffer[128] = { 0 };
2042 const rdpSettings* settings = mcs_get_const_settings(mcs);
2045 WINPR_ASSERT(settings);
2047 if (!gcc_write_user_data_header(s, CS_CLUSTER, 12))
2049 flags = settings->ClusterInfoFlags;
2051 if (settings->ConsoleSession || settings->RedirectedSessionId)
2052 flags |= REDIRECTED_SESSIONID_FIELD_VALID;
2054 if (settings->RedirectSmartCards && settings->SmartcardLogon)
2055 flags |= REDIRECTED_SMARTCARD;
2057 if (flags & REDIRECTION_SUPPORTED)
2062 flags |= (REDIRECTION_VERSION6 << 2);
2064 flags |= (REDIRECTION_VERSION5 << 2);
2067 WLog_VRB(TAG,
"write ClusterInfoFlags=%s, RedirectedSessionId=0x%08" PRIx32,
2068 rdp_cluster_info_flags_to_string(flags, buffer,
sizeof(buffer)),
2069 settings->RedirectedSessionId);
2070 Stream_Write_UINT32(s, flags);
2071 Stream_Write_UINT32(s, settings->RedirectedSessionId);
2084 BOOL gcc_read_client_monitor_data(
wStream* s, rdpMcs* mcs)
2086 UINT32 monitorCount = 0;
2087 rdpSettings* settings = mcs_get_settings(mcs);
2090 WINPR_ASSERT(settings);
2092 const size_t blockLength = Stream_GetRemainingLength(s);
2093 if (blockLength < 8)
2096 Stream_Read_UINT32(s, settings->MonitorFlags);
2097 Stream_Read_UINT32(s, monitorCount);
2103 if (monitorCount > 16)
2105 WLog_ERR(TAG,
"announced monitors(%" PRIu32
") exceed the 16 limit", monitorCount);
2109 if (monitorCount > settings->MonitorDefArraySize)
2111 WLog_ERR(TAG,
"too many announced monitors(%" PRIu32
"), clamping to %" PRIu32
"",
2112 monitorCount, settings->MonitorDefArraySize);
2113 monitorCount = settings->MonitorDefArraySize;
2116 if ((UINT32)((blockLength - 8) / 20) < monitorCount)
2119 settings->MonitorCount = monitorCount;
2121 for (UINT32 index = 0; index < monitorCount; index++)
2128 rdpMonitor* current = &settings->MonitorDefArray[index];
2130 Stream_Read_INT32(s, left);
2131 Stream_Read_INT32(s, top);
2132 Stream_Read_INT32(s, right);
2133 Stream_Read_INT32(s, bottom);
2134 Stream_Read_INT32(s, flags);
2137 current->width = right - left + 1;
2138 current->height = bottom - top + 1;
2139 current->is_primary = (flags & MONITOR_PRIMARY) ? TRUE : FALSE;
2154 BOOL gcc_write_client_monitor_data(
wStream* s,
const rdpMcs* mcs)
2159 const rdpSettings* settings = mcs_get_const_settings(mcs);
2162 WINPR_ASSERT(settings);
2164 WLog_DBG(TAG,
"MonitorCount=%" PRIu32, settings->MonitorCount);
2165 if (settings->MonitorCount > 1)
2167 length = (20 * settings->MonitorCount) + 12;
2168 if (!gcc_write_user_data_header(s, CS_MONITOR, length))
2170 Stream_Write_UINT32(s, settings->MonitorFlags);
2171 Stream_Write_UINT32(s, settings->MonitorCount);
2175 for (UINT32 i = 0; i < settings->MonitorCount; i++)
2177 const rdpMonitor* current = &settings->MonitorDefArray[i];
2178 if (current->is_primary)
2186 for (UINT32 i = 0; i < settings->MonitorCount; i++)
2188 const rdpMonitor* current = &settings->MonitorDefArray[i];
2189 const UINT32 left = current->x - baseX;
2190 const UINT32 top = current->y - baseY;
2191 const UINT32 right = left + current->width - 1;
2192 const UINT32 bottom = top + current->height - 1;
2193 const UINT32 flags = current->is_primary ? MONITOR_PRIMARY : 0;
2195 "Monitor[%" PRIu32
"]: top=%" PRIu32
", left=%" PRIu32
", bottom=%" PRIu32
2196 ", right=%" PRIu32
", flags=%" PRIu32,
2197 i, top, left, bottom, right, flags);
2198 Stream_Write_UINT32(s, left);
2199 Stream_Write_UINT32(s, top);
2200 Stream_Write_UINT32(s, right);
2201 Stream_Write_UINT32(s, bottom);
2202 Stream_Write_UINT32(s, flags);
2205 WLog_DBG(TAG,
"FINISHED");
2209 BOOL gcc_read_client_monitor_extended_data(
wStream* s, rdpMcs* mcs)
2211 UINT32 monitorCount = 0;
2212 UINT32 monitorAttributeSize = 0;
2213 rdpSettings* settings = mcs_get_settings(mcs);
2216 WINPR_ASSERT(settings);
2218 const size_t blockLength = Stream_GetRemainingLength(s);
2219 if (blockLength < 12)
2222 Stream_Read_UINT32(s, settings->MonitorAttributeFlags);
2223 Stream_Read_UINT32(s, monitorAttributeSize);
2224 Stream_Read_UINT32(s, monitorCount);
2226 if (monitorAttributeSize != 20)
2229 if ((blockLength - 12) / monitorAttributeSize < monitorCount)
2232 if (settings->MonitorCount != monitorCount)
2235 settings->HasMonitorAttributes = TRUE;
2237 for (UINT32 index = 0; index < monitorCount; index++)
2239 rdpMonitor* current = &settings->MonitorDefArray[index];
2240 Stream_Read_UINT32(s, current->attributes.physicalWidth);
2241 Stream_Read_UINT32(s, current->attributes.physicalHeight);
2242 Stream_Read_UINT32(s, current->attributes.orientation);
2243 Stream_Read_UINT32(s, current->attributes.desktopScaleFactor);
2244 Stream_Read_UINT32(s, current->attributes.deviceScaleFactor);
2250 BOOL gcc_write_client_monitor_extended_data(
wStream* s,
const rdpMcs* mcs)
2253 const rdpSettings* settings = mcs_get_const_settings(mcs);
2256 WINPR_ASSERT(settings);
2258 if (settings->HasMonitorAttributes)
2260 length = (20 * settings->MonitorCount) + 16;
2261 if (!gcc_write_user_data_header(s, CS_MONITOR_EX, length))
2263 Stream_Write_UINT32(s, settings->MonitorAttributeFlags);
2264 Stream_Write_UINT32(s, 20);
2265 Stream_Write_UINT32(s, settings->MonitorCount);
2267 for (UINT32 i = 0; i < settings->MonitorCount; i++)
2269 const rdpMonitor* current = &settings->MonitorDefArray[i];
2270 Stream_Write_UINT32(s, current->attributes.physicalWidth);
2271 Stream_Write_UINT32(s, current->attributes.physicalHeight);
2272 Stream_Write_UINT32(s, current->attributes.orientation);
2273 Stream_Write_UINT32(s, current->attributes.desktopScaleFactor);
2274 Stream_Write_UINT32(s, current->attributes.deviceScaleFactor);
2289 BOOL gcc_read_client_message_channel_data(
wStream* s, rdpMcs* mcs)
2294 const size_t blockLength = Stream_GetRemainingLength(s);
2295 if (blockLength < 4)
2298 Stream_Read_UINT32(s, mcs->flags);
2299 mcs->messageChannelId = mcs->baseChannelId++;
2312 BOOL gcc_write_client_message_channel_data(
wStream* s,
const rdpMcs* mcs)
2314 const rdpSettings* settings = mcs_get_const_settings(mcs);
2318 WINPR_ASSERT(settings);
2320 settings->SupportHeartbeatPdu || settings->SupportMultitransport)
2322 if (!gcc_write_user_data_header(s, CS_MCS_MSGCHANNEL, 8))
2324 Stream_Write_UINT32(s, mcs->flags);
2329 BOOL gcc_read_server_message_channel_data(
wStream* s, rdpMcs* mcs)
2331 UINT16 MCSChannelId = 0;
2334 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
2337 Stream_Read_UINT16(s, MCSChannelId);
2339 mcs->messageChannelId = MCSChannelId;
2343 BOOL gcc_write_server_message_channel_data(
wStream* s,
const rdpMcs* mcs)
2347 if (mcs->messageChannelId == 0)
2350 if (!gcc_write_user_data_header(s, SC_MCS_MSGCHANNEL, 6))
2353 Stream_Write_UINT16(s, mcs->messageChannelId);
2366 BOOL gcc_read_client_multitransport_channel_data(
wStream* s, rdpMcs* mcs)
2368 rdpSettings* settings = mcs_get_settings(mcs);
2371 WINPR_ASSERT(settings);
2373 const size_t blockLength = Stream_GetRemainingLength(s);
2374 if (blockLength < 4)
2377 UINT32 remoteFlags = 0;
2378 Stream_Read_UINT32(s, remoteFlags);
2379 settings->MultitransportFlags &= remoteFlags;
2393 BOOL gcc_write_client_multitransport_channel_data(
wStream* s,
const rdpMcs* mcs)
2395 const rdpSettings* settings = mcs_get_const_settings(mcs);
2398 WINPR_ASSERT(settings);
2399 if (!gcc_write_user_data_header(s, CS_MULTITRANSPORT, 8))
2401 Stream_Write_UINT32(s, settings->MultitransportFlags);
2405 BOOL gcc_read_server_multitransport_channel_data(
wStream* s, rdpMcs* mcs)
2407 rdpSettings* settings = mcs_get_settings(mcs);
2408 UINT32 remoteFlags = 0;
2411 WINPR_ASSERT(settings);
2412 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2415 Stream_Read_UINT32(s, remoteFlags);
2416 settings->MultitransportFlags &= remoteFlags;
2420 BOOL gcc_write_server_multitransport_channel_data(
wStream* s,
const rdpMcs* mcs)
2422 const rdpSettings* settings = mcs_get_const_settings(mcs);
2425 WINPR_ASSERT(settings);
2427 if (!gcc_write_user_data_header(s, SC_MULTITRANSPORT, 8))
2430 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.