23#include <freerdp/config.h>
26#include <winpr/assert.h>
27#include <winpr/stream.h>
29#include <freerdp/log.h>
38#define NEGO_TAG FREERDP_TAG("core.nego")
47 DWORD RoutingTokenLength;
48 BOOL SendPreconnectionPdu;
49 UINT32 PreconnectionId;
50 const char* PreconnectionBlob;
54 BOOL SecurityConnected;
55 UINT32 CookieMaxLength;
58 UINT32 SelectedProtocol;
59 UINT32 RequestedProtocols;
61 BOOL NegotiateSecurityLayer;
62 BOOL EnabledProtocols[32];
63 BOOL RestrictedAdminModeRequired;
64 BOOL RestrictedAdminModeSupported;
65 BOOL RemoteCredsGuardRequired;
66 BOOL RemoteCredsGuardActive;
67 BOOL RemoteCredsGuardSupported;
69 BOOL GatewayBypassLocal;
70 BOOL ConnectChildSession;
72 rdpTransport* transport;
77static const char* nego_state_string(NEGO_STATE state)
79 static const char*
const NEGO_STATE_STRINGS[] = {
"NEGO_STATE_INITIAL",
"NEGO_STATE_RDSTLS",
80 "NEGO_STATE_AAD",
"NEGO_STATE_EXT",
81 "NEGO_STATE_NLA",
"NEGO_STATE_TLS",
82 "NEGO_STATE_RDP",
"NEGO_STATE_FAIL",
83 "NEGO_STATE_FINAL",
"NEGO_STATE_INVALID" };
84 if (state >= ARRAYSIZE(NEGO_STATE_STRINGS))
85 return NEGO_STATE_STRINGS[ARRAYSIZE(NEGO_STATE_STRINGS) - 1];
86 return NEGO_STATE_STRINGS[state];
90static BOOL nego_tcp_connect(rdpNego* nego);
93static BOOL nego_transport_connect(rdpNego* nego);
95static BOOL nego_transport_disconnect(rdpNego* nego);
98static BOOL nego_security_connect(rdpNego* nego);
101static BOOL nego_send_preconnection_pdu(rdpNego* nego);
104static BOOL nego_recv_response(rdpNego* nego);
106static void nego_send(rdpNego* nego);
109static BOOL nego_process_negotiation_request(rdpNego* nego,
wStream* s);
112static BOOL nego_process_negotiation_response(rdpNego* nego,
wStream* s);
115static BOOL nego_process_negotiation_failure(rdpNego* nego,
wStream* s);
118static const char* nego_rdp_neg_fail_str(uint32_t what);
126static UINT32 nego_failure_to_error(uint32_t failureCode)
130 case SSL_CERT_NOT_ON_SERVER:
132 return FREERDP_ERROR_TLS_CONNECT_FAILED;
134 case HYBRID_REQUIRED_BY_SERVER:
137 return FREERDP_ERROR_CONNECT_HYBRID_REQUIRED_BY_SERVER;
141 return FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED;
145BOOL nego_update_settings_from_state(rdpNego* nego, rdpSettings* settings)
151 nego->RequestedProtocols) &&
153 nego->SelectedProtocol) &&
165BOOL nego_connect(rdpNego* nego)
167 rdpContext* context =
nullptr;
168 rdpSettings* settings =
nullptr;
170 context = transport_get_context(nego->transport);
171 WINPR_ASSERT(context);
172 settings = context->settings;
173 WINPR_ASSERT(settings);
175 if (nego_get_state(nego) == NEGO_STATE_INITIAL)
177 if (nego->EnabledProtocols[PROTOCOL_RDSAAD])
179 nego_set_state(nego, NEGO_STATE_AAD);
181 else if (nego->EnabledProtocols[PROTOCOL_RDSTLS])
183 nego_set_state(nego, NEGO_STATE_RDSTLS);
185 else if (nego->EnabledProtocols[PROTOCOL_HYBRID_EX])
187 nego_set_state(nego, NEGO_STATE_EXT);
189 else if (nego->EnabledProtocols[PROTOCOL_HYBRID])
191 nego_set_state(nego, NEGO_STATE_NLA);
193 else if (nego->EnabledProtocols[PROTOCOL_SSL])
195 nego_set_state(nego, NEGO_STATE_TLS);
197 else if (nego->EnabledProtocols[PROTOCOL_RDP])
199 nego_set_state(nego, NEGO_STATE_RDP);
203 WLog_Print(nego->log, WLOG_ERROR,
"No security protocol is enabled");
204 nego_set_state(nego, NEGO_STATE_FAIL);
208 if (!nego->NegotiateSecurityLayer)
210 WLog_Print(nego->log, WLOG_DEBUG,
"Security Layer Negotiation is disabled");
212 nego->EnabledProtocols[PROTOCOL_RDSAAD] = FALSE;
213 nego->EnabledProtocols[PROTOCOL_HYBRID] = FALSE;
214 nego->EnabledProtocols[PROTOCOL_SSL] = FALSE;
215 nego->EnabledProtocols[PROTOCOL_RDP] = FALSE;
216 nego->EnabledProtocols[PROTOCOL_HYBRID_EX] = FALSE;
217 nego->EnabledProtocols[PROTOCOL_RDSTLS] = FALSE;
219 UINT32 SelectedProtocol = 0;
220 switch (nego_get_state(nego))
223 nego->EnabledProtocols[PROTOCOL_RDSAAD] = TRUE;
224 SelectedProtocol = PROTOCOL_RDSAAD;
226 case NEGO_STATE_RDSTLS:
227 nego->EnabledProtocols[PROTOCOL_RDSTLS] = TRUE;
228 SelectedProtocol = PROTOCOL_RDSTLS;
231 nego->EnabledProtocols[PROTOCOL_HYBRID_EX] = TRUE;
232 nego->EnabledProtocols[PROTOCOL_HYBRID] = TRUE;
233 SelectedProtocol = PROTOCOL_HYBRID_EX;
236 nego->EnabledProtocols[PROTOCOL_HYBRID] = TRUE;
237 SelectedProtocol = PROTOCOL_HYBRID;
240 nego->EnabledProtocols[PROTOCOL_SSL] = TRUE;
241 SelectedProtocol = PROTOCOL_SSL;
244 nego->EnabledProtocols[PROTOCOL_RDP] = TRUE;
245 SelectedProtocol = PROTOCOL_RDP;
248 WLog_Print(nego->log, WLOG_ERROR,
"Invalid NEGO state 0x%08" PRIx32,
249 nego_get_state(nego));
252 if (!nego_set_selected_protocol(nego, SelectedProtocol))
256 if (!nego_tcp_connect(nego))
258 WLog_Print(nego->log, WLOG_ERROR,
"Failed to connect");
262 if (nego->SendPreconnectionPdu)
264 if (!nego_send_preconnection_pdu(nego))
266 WLog_Print(nego->log, WLOG_ERROR,
"Failed to send preconnection pdu");
267 nego_set_state(nego, NEGO_STATE_FINAL);
273 if (!nego->NegotiateSecurityLayer)
275 nego_set_state(nego, NEGO_STATE_FINAL);
281 WLog_Print(nego->log, WLOG_DEBUG,
"state: %s", nego_state_string(nego_get_state(nego)));
284 if (nego_get_state(nego) == NEGO_STATE_FAIL)
286 if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
288 if (nego->failureCode != 0)
289 WLog_Print(nego->log, WLOG_ERROR,
290 "Protocol Security Negotiation Failure: %s [0x%08" PRIx32
"]",
291 nego_rdp_neg_fail_str(nego->failureCode), nego->failureCode);
293 WLog_Print(nego->log, WLOG_ERROR,
"Protocol Security Negotiation Failure");
296 if (nego->failureCode != 0)
297 freerdp_set_last_error_if_not(context,
298 nego_failure_to_error(nego->failureCode));
300 nego_set_state(nego, NEGO_STATE_FINAL);
303 }
while (nego_get_state(nego) != NEGO_STATE_FINAL);
307 char buffer[64] = WINPR_C_ARRAY_INIT;
308 WLog_Print(nego->log, WLOG_DEBUG,
"Negotiated %s security",
309 nego_protocol_to_str(nego->SelectedProtocol, buffer,
sizeof(buffer)));
313 if (!nego_update_settings_from_state(nego, settings))
316 if (nego->SelectedProtocol == PROTOCOL_RDP)
328 ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT |
329 ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS))
335 if (!nego_security_connect(nego))
337 char buffer[64] = WINPR_C_ARRAY_INIT;
338 WLog_Print(nego->log, WLOG_DEBUG,
"Failed to connect with %s security",
339 nego_protocol_to_str(nego->SelectedProtocol, buffer,
sizeof(buffer)));
346BOOL nego_disconnect(rdpNego* nego)
349 nego_set_state(nego, NEGO_STATE_INITIAL);
350 return nego_transport_disconnect(nego);
354static BOOL nego_try_connect(rdpNego* nego)
358 switch (nego->SelectedProtocol)
360 case PROTOCOL_RDSAAD:
361 WLog_Print(nego->log, WLOG_DEBUG,
"nego_security_connect with PROTOCOL_RDSAAD");
362 nego->SecurityConnected = transport_connect_aad(nego->transport);
364 case PROTOCOL_RDSTLS:
365 WLog_Print(nego->log, WLOG_DEBUG,
"nego_security_connect with PROTOCOL_RDSTLS");
366 nego->SecurityConnected = transport_connect_rdstls(nego->transport);
368 case PROTOCOL_HYBRID:
369 WLog_Print(nego->log, WLOG_DEBUG,
"nego_security_connect with PROTOCOL_HYBRID");
370 nego->SecurityConnected = transport_connect_nla(nego->transport, FALSE);
372 case PROTOCOL_HYBRID_EX:
373 WLog_Print(nego->log, WLOG_DEBUG,
"nego_security_connect with PROTOCOL_HYBRID_EX");
374 nego->SecurityConnected = transport_connect_nla(nego->transport, TRUE);
377 WLog_Print(nego->log, WLOG_DEBUG,
"nego_security_connect with PROTOCOL_SSL");
378 nego->SecurityConnected = transport_connect_tls(nego->transport);
381 WLog_Print(nego->log, WLOG_DEBUG,
"nego_security_connect with PROTOCOL_RDP");
382 nego->SecurityConnected = transport_connect_rdp(nego->transport);
385 WLog_Print(nego->log, WLOG_ERROR,
386 "cannot connect security layer because no protocol has been selected yet.");
389 return nego->SecurityConnected;
393BOOL nego_security_connect(rdpNego* nego)
396 if (!nego->TcpConnected)
398 nego->SecurityConnected = FALSE;
400 else if (!nego->SecurityConnected)
402 if (!nego_try_connect(nego))
406 return nego->SecurityConnected;
410static BOOL nego_tcp_connect(rdpNego* nego)
412 rdpContext* context =
nullptr;
414 if (!nego->TcpConnected)
416 UINT32 TcpConnectTimeout = 0;
418 context = transport_get_context(nego->transport);
419 WINPR_ASSERT(context);
424 if (nego->GatewayEnabled)
426 if (nego->GatewayBypassLocal)
430 nego->log, WLOG_INFO,
431 "Detecting if host can be reached locally. - This might take some time.");
432 WLog_Print(nego->log, WLOG_INFO,
433 "To disable auto detection use /gateway-usage-method:direct");
434 transport_set_gateway_enabled(nego->transport, FALSE);
435 nego->TcpConnected = transport_connect(nego->transport, nego->hostname, nego->port,
439 if (!nego->TcpConnected)
441 transport_set_gateway_enabled(nego->transport, TRUE);
442 nego->TcpConnected = transport_connect(nego->transport, nego->hostname, nego->port,
446 else if (nego->ConnectChildSession)
448 nego->TcpConnected = transport_connect_childsession(nego->transport);
453 transport_connect(nego->transport, nego->hostname, nego->port, TcpConnectTimeout);
457 return nego->TcpConnected;
468BOOL nego_transport_connect(rdpNego* nego)
471 if (!nego_tcp_connect(nego))
474 if (nego->TcpConnected && !nego->NegotiateSecurityLayer)
475 return nego_security_connect(nego);
477 return nego->TcpConnected;
488BOOL nego_transport_disconnect(rdpNego* nego)
491 if (nego->TcpConnected)
492 transport_disconnect(nego->transport);
494 nego->TcpConnected = FALSE;
495 nego->SecurityConnected = FALSE;
507BOOL nego_send_preconnection_pdu(rdpNego* nego)
512 WCHAR* wszPCB =
nullptr;
516 WLog_Print(nego->log, WLOG_DEBUG,
"Sending preconnection PDU");
518 if (!nego_tcp_connect(nego))
522 cbSize = PRECONNECTION_PDU_V2_MIN_SIZE;
524 if (nego->PreconnectionBlob)
527 wszPCB = ConvertUtf8ToWCharAlloc(nego->PreconnectionBlob, &len);
528 if (len > UINT16_MAX - 1)
533 cchPCB = (UINT16)len;
535 cbSize += cchPCB *
sizeof(WCHAR);
538 s = Stream_New(
nullptr, cbSize);
543 WLog_Print(nego->log, WLOG_ERROR,
"Stream_New failed!");
547 Stream_Write_UINT32(s, cbSize);
548 Stream_Write_UINT32(s, 0);
549 Stream_Write_UINT32(s, PRECONNECTION_PDU_V2);
550 Stream_Write_UINT32(s, nego->PreconnectionId);
551 Stream_Write_UINT16(s, cchPCB);
555 Stream_Write(s, wszPCB, cchPCB *
sizeof(WCHAR));
559 Stream_SealLength(s);
561 if (transport_write(nego->transport, s) < 0)
563 Stream_Free(s, TRUE);
567 Stream_Free(s, TRUE);
571static void nego_attempt_rdstls(rdpNego* nego)
574 nego->RequestedProtocols = PROTOCOL_RDSTLS | PROTOCOL_SSL;
575 WLog_Print(nego->log, WLOG_DEBUG,
"Attempting RDSTLS security");
577 if (!nego_transport_connect(nego))
579 nego_set_state(nego, NEGO_STATE_FAIL);
583 if (!nego_send_negotiation_request(nego))
585 nego_set_state(nego, NEGO_STATE_FAIL);
589 if (!nego_recv_response(nego))
591 nego_set_state(nego, NEGO_STATE_FAIL);
595 WLog_Print(nego->log, WLOG_DEBUG,
"state: %s", nego_state_string(nego_get_state(nego)));
597 if (nego_get_state(nego) != NEGO_STATE_FINAL)
599 nego_transport_disconnect(nego);
601 if (nego->EnabledProtocols[PROTOCOL_HYBRID_EX])
602 nego_set_state(nego, NEGO_STATE_EXT);
603 else if (nego->EnabledProtocols[PROTOCOL_HYBRID])
604 nego_set_state(nego, NEGO_STATE_NLA);
605 else if (nego->EnabledProtocols[PROTOCOL_SSL])
606 nego_set_state(nego, NEGO_STATE_TLS);
607 else if (nego->EnabledProtocols[PROTOCOL_RDP])
608 nego_set_state(nego, NEGO_STATE_RDP);
610 nego_set_state(nego, NEGO_STATE_FAIL);
614static void nego_attempt_rdsaad(rdpNego* nego)
617 nego->RequestedProtocols = PROTOCOL_RDSAAD;
618 WLog_Print(nego->log, WLOG_DEBUG,
"Attempting RDS AAD Auth security");
620 if (!nego_transport_connect(nego))
622 nego_set_state(nego, NEGO_STATE_FAIL);
626 if (!nego_send_negotiation_request(nego))
628 nego_set_state(nego, NEGO_STATE_FAIL);
632 if (!nego_recv_response(nego))
634 nego_set_state(nego, NEGO_STATE_FAIL);
638 WLog_Print(nego->log, WLOG_DEBUG,
"state: %s", nego_state_string(nego_get_state(nego)));
640 if (nego_get_state(nego) != NEGO_STATE_FINAL)
642 nego_transport_disconnect(nego);
644 if (nego->EnabledProtocols[PROTOCOL_HYBRID_EX])
645 nego_set_state(nego, NEGO_STATE_EXT);
646 else if (nego->EnabledProtocols[PROTOCOL_HYBRID])
647 nego_set_state(nego, NEGO_STATE_NLA);
648 else if (nego->EnabledProtocols[PROTOCOL_SSL])
649 nego_set_state(nego, NEGO_STATE_TLS);
650 else if (nego->EnabledProtocols[PROTOCOL_RDP])
651 nego_set_state(nego, NEGO_STATE_RDP);
653 nego_set_state(nego, NEGO_STATE_FAIL);
657static void nego_attempt_ext(rdpNego* nego)
660 nego->RequestedProtocols = PROTOCOL_HYBRID | PROTOCOL_SSL | PROTOCOL_HYBRID_EX;
661 WLog_Print(nego->log, WLOG_DEBUG,
"Attempting NLA extended security");
663 if (!nego_transport_connect(nego))
665 nego_set_state(nego, NEGO_STATE_FAIL);
669 if (!nego_send_negotiation_request(nego))
671 nego_set_state(nego, NEGO_STATE_FAIL);
675 if (!nego_recv_response(nego))
677 nego_set_state(nego, NEGO_STATE_FAIL);
681 WLog_Print(nego->log, WLOG_DEBUG,
"state: %s", nego_state_string(nego_get_state(nego)));
683 if (nego_get_state(nego) != NEGO_STATE_FINAL)
685 nego_transport_disconnect(nego);
687 if (nego->EnabledProtocols[PROTOCOL_HYBRID])
688 nego_set_state(nego, NEGO_STATE_NLA);
689 else if (nego->EnabledProtocols[PROTOCOL_SSL])
690 nego_set_state(nego, NEGO_STATE_TLS);
691 else if (nego->EnabledProtocols[PROTOCOL_RDP])
692 nego_set_state(nego, NEGO_STATE_RDP);
694 nego_set_state(nego, NEGO_STATE_FAIL);
698static void nego_attempt_nla(rdpNego* nego)
701 nego->RequestedProtocols = PROTOCOL_HYBRID | PROTOCOL_SSL;
702 WLog_Print(nego->log, WLOG_DEBUG,
"Attempting NLA security");
704 if (!nego_transport_connect(nego))
706 nego_set_state(nego, NEGO_STATE_FAIL);
710 if (!nego_send_negotiation_request(nego))
712 nego_set_state(nego, NEGO_STATE_FAIL);
716 if (!nego_recv_response(nego))
718 nego_set_state(nego, NEGO_STATE_FAIL);
722 WLog_Print(nego->log, WLOG_DEBUG,
"state: %s", nego_state_string(nego_get_state(nego)));
724 if (nego_get_state(nego) != NEGO_STATE_FINAL)
726 nego_transport_disconnect(nego);
728 if (nego->EnabledProtocols[PROTOCOL_SSL])
729 nego_set_state(nego, NEGO_STATE_TLS);
730 else if (nego->EnabledProtocols[PROTOCOL_RDP])
731 nego_set_state(nego, NEGO_STATE_RDP);
733 nego_set_state(nego, NEGO_STATE_FAIL);
737static void nego_attempt_tls(rdpNego* nego)
740 nego->RequestedProtocols = PROTOCOL_SSL;
741 WLog_Print(nego->log, WLOG_DEBUG,
"Attempting TLS security");
743 if (!nego_transport_connect(nego))
745 nego_set_state(nego, NEGO_STATE_FAIL);
749 if (!nego_send_negotiation_request(nego))
751 nego_set_state(nego, NEGO_STATE_FAIL);
755 if (!nego_recv_response(nego))
757 nego_set_state(nego, NEGO_STATE_FAIL);
761 if (nego_get_state(nego) != NEGO_STATE_FINAL)
763 nego_transport_disconnect(nego);
765 if (nego->EnabledProtocols[PROTOCOL_RDP])
766 nego_set_state(nego, NEGO_STATE_RDP);
768 nego_set_state(nego, NEGO_STATE_FAIL);
772static void nego_attempt_rdp(rdpNego* nego)
775 nego->RequestedProtocols = PROTOCOL_RDP;
776 WLog_Print(nego->log, WLOG_DEBUG,
"Attempting RDP security");
778 if (!nego_transport_connect(nego))
780 nego_set_state(nego, NEGO_STATE_FAIL);
784 if (!nego_send_negotiation_request(nego))
786 nego_set_state(nego, NEGO_STATE_FAIL);
790 if (!nego_recv_response(nego))
792 nego_set_state(nego, NEGO_STATE_FAIL);
805BOOL nego_recv_response(rdpNego* nego)
811 s = Stream_New(
nullptr, 1024);
815 WLog_Print(nego->log, WLOG_ERROR,
"Stream_New failed!");
819 status = transport_read_pdu(nego->transport, s);
823 Stream_Free(s, TRUE);
827 status = nego_recv(nego->transport, s, nego);
828 Stream_Free(s, TRUE);
830 return (status >= 0);
844int nego_recv(WINPR_ATTR_UNUSED rdpTransport* transport,
wStream* s,
void* extra)
849 rdpNego* nego = (rdpNego*)extra;
852 if (!tpkt_read_header(s, &length))
855 if (!tpdu_read_connection_confirm(s, &li, length))
861 Stream_Read_UINT8(s, type);
865 case TYPE_RDP_NEG_RSP:
866 if (!nego_process_negotiation_response(nego, s))
869 char buffer[64] = WINPR_C_ARRAY_INIT;
871 nego->log, WLOG_DEBUG,
"selected_protocol: %s",
872 nego_protocol_to_str(nego->SelectedProtocol, buffer,
sizeof(buffer)));
877 if (nego->SelectedProtocol)
879 const UINT32 flags[] = { PROTOCOL_RDP, PROTOCOL_SSL, PROTOCOL_HYBRID,
880 PROTOCOL_RDSTLS, PROTOCOL_HYBRID_EX, PROTOCOL_RDSAAD };
882 BOOL enabled = FALSE;
883 for (
size_t x = 0; x < ARRAYSIZE(flags); x++)
885 const UINT32 flag = flags[x];
886 if ((nego->SelectedProtocol == flag) && (nego->EnabledProtocols[flag]))
890 nego_set_state(nego, NEGO_STATE_FAIL);
892 else if (!nego->EnabledProtocols[PROTOCOL_RDP])
894 nego_set_state(nego, NEGO_STATE_FAIL);
899 case TYPE_RDP_NEG_FAILURE:
900 if (!nego_process_negotiation_failure(nego, s))
909 WLog_Print(nego->log, WLOG_DEBUG,
"no rdpNegData");
911 if (!nego->EnabledProtocols[PROTOCOL_RDP])
912 nego_set_state(nego, NEGO_STATE_FAIL);
914 nego_set_state(nego, NEGO_STATE_FINAL);
918 WLog_Print(nego->log, WLOG_ERROR,
"invalid negotiation response");
919 nego_set_state(nego, NEGO_STATE_FAIL);
922 if (!tpkt_ensure_stream_consumed(nego->log, s, length))
932static BOOL nego_read_request_token_or_cookie(rdpNego* nego,
wStream* s)
948 BOOL isToken = FALSE;
949 size_t remain = Stream_GetRemainingLength(s);
953 const char* str = Stream_ConstPointer(s);
954 const size_t pos = Stream_GetPosition(s);
960 if ((remain < 17) || (memcmp(Stream_ConstPointer(s),
"Cookie: mstshash=", 17) != 0))
962 if (memcmp(Stream_ConstPointer(s),
"Cookie: msts=", 13) != 0)
964 if (memcmp(Stream_ConstPointer(s),
"tsv:", 4) != 0)
966 if (memcmp(Stream_ConstPointer(s),
"mth://", 6) != 0)
984 while (Stream_GetRemainingLength(s) >= 2)
986 Stream_Read_UINT16(s, crlf);
997 const size_t len = Stream_GetPosition(s) - pos;
998 Stream_Write_UINT16(s, 0);
1000 if (len > UINT32_MAX)
1003 if (strnlen(str, len) == len)
1006 result = nego_set_routing_token(nego, str, (UINT32)len);
1008 result = nego_set_cookie(nego, str);
1014 if (!Stream_SetPosition(s, pos))
1016 WLog_Print(nego->log, WLOG_ERROR,
"invalid %s received",
1017 isToken ?
"routing token" :
"cookie");
1021 WLog_Print(nego->log, WLOG_DEBUG,
"received %s [%s]", isToken ?
"routing token" :
"cookie",
1037BOOL nego_read_request(rdpNego* nego,
wStream* s)
1046 if (!tpkt_read_header(s, &length))
1049 if (!tpdu_read_connection_request(s, &li, length))
1052 if (li != Stream_GetRemainingLength(s) + 6)
1054 WLog_Print(nego->log, WLOG_ERROR,
"Incorrect TPDU length indicator.");
1058 if (!nego_read_request_token_or_cookie(nego, s))
1060 WLog_Print(nego->log, WLOG_ERROR,
"Failed to parse routing token or cookie.");
1064 if (Stream_GetRemainingLength(s) >= 8)
1067 Stream_Read_UINT8(s, type);
1069 if (type != TYPE_RDP_NEG_REQ)
1071 WLog_Print(nego->log, WLOG_ERROR,
"Incorrect negotiation request type %" PRIu8
"",
1076 if (!nego_process_negotiation_request(nego, s))
1080 return tpkt_ensure_stream_consumed(nego->log, s, length);
1089void nego_send(rdpNego* nego)
1093 switch (nego_get_state(nego))
1095 case NEGO_STATE_AAD:
1096 nego_attempt_rdsaad(nego);
1098 case NEGO_STATE_RDSTLS:
1099 nego_attempt_rdstls(nego);
1101 case NEGO_STATE_EXT:
1102 nego_attempt_ext(nego);
1104 case NEGO_STATE_NLA:
1105 nego_attempt_nla(nego);
1107 case NEGO_STATE_TLS:
1108 nego_attempt_tls(nego);
1110 case NEGO_STATE_RDP:
1111 nego_attempt_rdp(nego);
1114 WLog_Print(nego->log, WLOG_ERROR,
"invalid negotiation state for sending");
1129BOOL nego_send_negotiation_request(rdpNego* nego)
1132 wStream* s = Stream_New(
nullptr, 512);
1137 WLog_Print(nego->log, WLOG_ERROR,
"Stream_New failed!");
1141 const size_t bm = Stream_GetPosition(s);
1142 if (!Stream_SafeZero(s, TPDU_CONNECTION_REQUEST_LENGTH))
1145 if (nego->RoutingToken)
1147 if (!Stream_EnsureRemainingCapacity(s, nego->RoutingTokenLength))
1149 Stream_Write(s, nego->RoutingToken, nego->RoutingTokenLength);
1153 if ((nego->RoutingTokenLength > 2) &&
1154 (nego->RoutingToken[nego->RoutingTokenLength - 2] == 0x0D) &&
1155 (nego->RoutingToken[nego->RoutingTokenLength - 1] == 0x0A))
1157 WLog_Print(nego->log, WLOG_DEBUG,
1158 "Routing token looks correctly terminated - use verbatim");
1162 WLog_Print(nego->log, WLOG_DEBUG,
"Adding terminating CRLF to routing token");
1163 if (!Stream_EnsureRemainingCapacity(s, 2))
1165 Stream_Write_UINT8(s, 0x0D);
1166 Stream_Write_UINT8(s, 0x0A);
1169 else if (nego->cookie)
1171 size_t cookie_length = strlen(nego->cookie);
1173 if (cookie_length > nego->CookieMaxLength)
1174 cookie_length = nego->CookieMaxLength;
1176 if (!Stream_EnsureRemainingCapacity(s, 17))
1178 Stream_Write(s,
"Cookie: mstshash=", 17);
1179 if (!Stream_EnsureRemainingCapacity(s, cookie_length))
1181 Stream_Write(s, (BYTE*)nego->cookie, cookie_length);
1182 if (!Stream_EnsureRemainingCapacity(s, 2))
1184 Stream_Write_UINT8(s, 0x0D);
1185 Stream_Write_UINT8(s, 0x0A);
1189 char buffer[64] = WINPR_C_ARRAY_INIT;
1190 WLog_Print(nego->log, WLOG_DEBUG,
"RequestedProtocols: %s",
1191 nego_protocol_to_str(nego->RequestedProtocols, buffer,
sizeof(buffer)));
1194 if ((nego->RequestedProtocols > PROTOCOL_RDP) || (nego->sendNegoData))
1199 if (nego->RestrictedAdminModeRequired)
1200 flags |= RESTRICTED_ADMIN_MODE_REQUIRED;
1202 if (nego->RemoteCredsGuardRequired)
1203 flags |= REDIRECTED_AUTHENTICATION_MODE_REQUIRED;
1205 if (!Stream_EnsureRemainingCapacity(s, 8))
1208 Stream_Write_UINT8(s, TYPE_RDP_NEG_REQ);
1209 Stream_Write_UINT8(s, flags);
1210 Stream_Write_UINT16(s, 8);
1211 Stream_Write_UINT32(s, nego->RequestedProtocols);
1214 const size_t em = Stream_GetPosition(s);
1215 if ((em < 5) || (em > UINT16_MAX))
1217 if (!Stream_SetPosition(s, bm))
1219 if (!tpkt_write_header(s, (UINT16)em))
1221 if (!tpdu_write_connection_request(s, (UINT16)em - 5))
1223 if (!Stream_SetPosition(s, em))
1225 Stream_SealLength(s);
1226 rc = (transport_write(nego->transport, s) >= 0);
1228 Stream_Free(s, TRUE);
1233static BOOL nego_process_correlation_info(WINPR_ATTR_UNUSED rdpNego* nego,
wStream* s)
1238 BYTE correlationId[16] = WINPR_C_ARRAY_INIT;
1240 if (!Stream_CheckAndLogRequiredLengthWLog(nego->log, s, 36))
1242 WLog_Print(nego->log, WLOG_ERROR,
1243 "RDP_NEG_REQ::flags CORRELATION_INFO_PRESENT but data is missing");
1247 Stream_Read_UINT8(s, type);
1248 if (type != TYPE_RDP_CORRELATION_INFO)
1250 WLog_Print(nego->log, WLOG_ERROR,
1251 "(RDP_NEG_CORRELATION_INFO::type != TYPE_RDP_CORRELATION_INFO");
1254 Stream_Read_UINT8(s, flags);
1257 WLog_Print(nego->log, WLOG_ERROR,
"(RDP_NEG_CORRELATION_INFO::flags != 0");
1260 Stream_Read_UINT16(s, length);
1263 WLog_Print(nego->log, WLOG_ERROR,
"(RDP_NEG_CORRELATION_INFO::length != 36");
1267 Stream_Read(s, correlationId,
sizeof(correlationId));
1268 if ((correlationId[0] == 0x00) || (correlationId[0] == 0xF4))
1270 WLog_Print(nego->log, WLOG_ERROR,
1271 "(RDP_NEG_CORRELATION_INFO::correlationId[0] has invalid value 0x%02" PRIx8,
1275 for (
size_t x = 0; x < ARRAYSIZE(correlationId); x++)
1277 if (correlationId[x] == 0x0D)
1279 WLog_Print(nego->log, WLOG_ERROR,
1280 "(RDP_NEG_CORRELATION_INFO::correlationId[%" PRIuz
1281 "] has invalid value 0x%02" PRIx8,
1282 x, correlationId[x]);
1288 WLog_Print(nego->log, WLOG_INFO,
1289 "RDP_NEG_CORRELATION_INFO::correlationId = { %02" PRIx8
", %02" PRIx8
", %02" PRIx8
1290 ", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
1291 ", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
1293 correlationId[0], correlationId[1], correlationId[2], correlationId[3],
1294 correlationId[4], correlationId[5], correlationId[6], correlationId[7],
1295 correlationId[8], correlationId[9], correlationId[10], correlationId[11],
1296 correlationId[12], correlationId[13], correlationId[14], correlationId[15]);
1300BOOL nego_process_negotiation_request(rdpNego* nego,
wStream* s)
1308 if (!Stream_CheckAndLogRequiredLengthWLog(nego->log, s, 7))
1310 Stream_Read_UINT8(s, flags);
1311 if ((flags & ~(RESTRICTED_ADMIN_MODE_REQUIRED | REDIRECTED_AUTHENTICATION_MODE_REQUIRED |
1312 CORRELATION_INFO_PRESENT)) != 0)
1314 WLog_Print(nego->log, WLOG_ERROR,
"RDP_NEG_REQ::flags invalid value 0x%02" PRIx8, flags);
1317 if (flags & RESTRICTED_ADMIN_MODE_REQUIRED)
1319 if (nego->RestrictedAdminModeSupported)
1321 WLog_Print(nego->log, WLOG_INFO,
"RDP_NEG_REQ::flags RESTRICTED_ADMIN_MODE_REQUIRED");
1325 WLog_Print(nego->log, WLOG_ERROR,
1326 "RDP_NEG_REQ::flags RESTRICTED_ADMIN_MODE_REQUIRED but disabled");
1331 if (flags & REDIRECTED_AUTHENTICATION_MODE_REQUIRED)
1333 if (nego->RemoteCredsGuardSupported)
1335 WLog_Print(nego->log, WLOG_INFO,
1336 "RDP_NEG_REQ::flags REDIRECTED_AUTHENTICATION_MODE_REQUIRED");
1337 nego->RemoteCredsGuardActive = TRUE;
1344 if (flags & RESTRICTED_ADMIN_MODE_REQUIRED)
1346 WLog_Print(nego->log, WLOG_INFO,
1347 "RDP_NEG_REQ::flags REDIRECTED_AUTHENTICATION_MODE_REQUIRED ignored.");
1352 nego->log, WLOG_ERROR,
1353 "RDP_NEG_REQ::flags REDIRECTED_AUTHENTICATION_MODE_REQUIRED but disabled");
1359 Stream_Read_UINT16(s, length);
1362 WLog_Print(nego->log, WLOG_ERROR,
"RDP_NEG_REQ::length != 8");
1365 Stream_Read_UINT32(s, nego->RequestedProtocols);
1367 if (flags & CORRELATION_INFO_PRESENT)
1369 if (!nego_process_correlation_info(nego, s))
1374 char buffer[64] = WINPR_C_ARRAY_INIT;
1375 WLog_Print(nego->log, WLOG_DEBUG,
"RDP_NEG_REQ: RequestedProtocol: %s",
1376 nego_protocol_to_str(nego->RequestedProtocols, buffer,
sizeof(buffer)));
1378 nego_set_state(nego, NEGO_STATE_FINAL);
1383static const char* nego_rdp_neg_rsp_flags_str(UINT32 flags)
1385 const uint32_t mask =
1386 (EXTENDED_CLIENT_DATA_SUPPORTED | DYNVC_GFX_PROTOCOL_SUPPORTED | RDP_NEGRSP_RESERVED |
1387 RESTRICTED_ADMIN_MODE_SUPPORTED | REDIRECTED_AUTHENTICATION_MODE_SUPPORTED);
1388 static char buffer[1024] = WINPR_C_ARRAY_INIT;
1390 (void)_snprintf(buffer, ARRAYSIZE(buffer),
"[0x%02" PRIx32
"] ", flags);
1391 if (flags & EXTENDED_CLIENT_DATA_SUPPORTED)
1392 winpr_str_append(
"EXTENDED_CLIENT_DATA_SUPPORTED", buffer,
sizeof(buffer),
"|");
1393 if (flags & DYNVC_GFX_PROTOCOL_SUPPORTED)
1394 winpr_str_append(
"DYNVC_GFX_PROTOCOL_SUPPORTED", buffer,
sizeof(buffer),
"|");
1395 if (flags & RDP_NEGRSP_RESERVED)
1396 winpr_str_append(
"RDP_NEGRSP_RESERVED", buffer,
sizeof(buffer),
"|");
1397 if (flags & RESTRICTED_ADMIN_MODE_SUPPORTED)
1398 winpr_str_append(
"RESTRICTED_ADMIN_MODE_SUPPORTED", buffer,
sizeof(buffer),
"|");
1399 if (flags & REDIRECTED_AUTHENTICATION_MODE_SUPPORTED)
1400 winpr_str_append(
"REDIRECTED_AUTHENTICATION_MODE_SUPPORTED", buffer,
sizeof(buffer),
"|");
1403 char buffer2[32] = WINPR_C_ARRAY_INIT;
1404 (void)_snprintf(buffer2,
sizeof(buffer2),
"UNKNOWN[0x%04" PRIx32
"]", flags & ~mask);
1405 winpr_str_append(buffer2, buffer,
sizeof(buffer),
"|");
1411BOOL nego_process_negotiation_response(rdpNego* nego,
wStream* s)
1418 if (!Stream_CheckAndLogRequiredLengthWLog(nego->log, s, 7))
1420 nego_set_state(nego, NEGO_STATE_FAIL);
1424 Stream_Read_UINT8(s, nego->flags);
1425 WLog_Print(nego->log, WLOG_DEBUG,
"RDP_NEG_RSP::flags = { %s }",
1426 nego_rdp_neg_rsp_flags_str(nego->flags));
1428 if ((nego->flags & RESTRICTED_ADMIN_MODE_SUPPORTED) == 0)
1430 if (nego->RestrictedAdminModeRequired)
1432 WLog_Print(nego->log, WLOG_ERROR,
1433 "restricted-admin mode requested but not supported, terminating");
1438 if ((nego->flags & REDIRECTED_AUTHENTICATION_MODE_SUPPORTED) == 0)
1440 if (nego->RemoteCredsGuardRequired)
1442 WLog_Print(nego->log, WLOG_ERROR,
1443 "remote credential guard requested but not supported, terminating");
1448 Stream_Read_UINT16(s, length);
1451 WLog_Print(nego->log, WLOG_ERROR,
"RDP_NEG_RSP::length != 8");
1452 nego_set_state(nego, NEGO_STATE_FAIL);
1455 UINT32 SelectedProtocol = 0;
1456 Stream_Read_UINT32(s, SelectedProtocol);
1458 if (!nego_set_selected_protocol(nego, SelectedProtocol))
1460 return nego_set_state(nego, NEGO_STATE_FINAL);
1464static const char* nego_rdp_neg_fail_str(uint32_t what)
1468 case SSL_REQUIRED_BY_SERVER:
1469 return "SSL_REQUIRED_BY_SERVER";
1470 case SSL_NOT_ALLOWED_BY_SERVER:
1471 return "SSL_NOT_ALLOWED_BY_SERVER";
1472 case SSL_CERT_NOT_ON_SERVER:
1473 return "SSL_CERT_NOT_ON_SERVER";
1474 case INCONSISTENT_FLAGS:
1475 return "INCONSISTENT_FLAGS";
1476 case HYBRID_REQUIRED_BY_SERVER:
1477 return "HYBRID_REQUIRED_BY_SERVER";
1478 case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
1479 return "SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER";
1485static void nego_disable_all_except(rdpNego* nego, uint32_t what)
1489 char buffer[32] = WINPR_C_ARRAY_INIT;
1490 WLog_Print(nego->log, WLOG_DEBUG,
"Disabling all modes except %s",
1491 nego_protocol_to_str(what, buffer,
sizeof(buffer)));
1493 for (
size_t x = 0; x < ARRAYSIZE(nego->EnabledProtocols); x++)
1497 nego->EnabledProtocols[x] = FALSE;
1509BOOL nego_process_negotiation_failure(rdpNego* nego,
wStream* s)
1517 WLog_Print(nego->log, WLOG_DEBUG,
"RDP_NEG_FAILURE");
1518 if (!Stream_CheckAndLogRequiredLengthWLog(nego->log, s, 7))
1521 Stream_Read_UINT8(s, flags);
1524 WLog_Print(nego->log, WLOG_ERROR,
"RDP_NEG_FAILURE::flags = 0x%02" PRIx8, flags);
1527 Stream_Read_UINT16(s, length);
1530 WLog_Print(nego->log, WLOG_ERROR,
"RDP_NEG_FAILURE::length != 8");
1533 const uint32_t failureCode = Stream_Get_UINT32(s);
1534 const char* failureStr = nego_rdp_neg_fail_str(failureCode);
1535 DWORD level = WLOG_WARN;
1539 nego->failureCode = failureCode;
1541 switch (failureCode)
1543 case SSL_REQUIRED_BY_SERVER:
1544 nego_disable_all_except(nego, PROTOCOL_SSL);
1547 case SSL_NOT_ALLOWED_BY_SERVER:
1548 nego_disable_all_except(nego, PROTOCOL_RDP);
1549 nego->sendNegoData = TRUE;
1552 case SSL_CERT_NOT_ON_SERVER:
1554 nego->sendNegoData = TRUE;
1557 case INCONSISTENT_FLAGS:
1561 case HYBRID_REQUIRED_BY_SERVER:
1562 nego_disable_all_except(nego, PROTOCOL_HYBRID);
1570 WLog_Print(nego->log, level,
"Error: %s [0x%08" PRIx32
"]", failureStr, failureCode);
1571 nego_set_state(nego, NEGO_STATE_FAIL);
1580BOOL nego_send_negotiation_response(rdpNego* nego)
1582 BOOL status = FALSE;
1584 rdpContext* context =
nullptr;
1585 rdpSettings* settings =
nullptr;
1588 context = transport_get_context(nego->transport);
1589 WINPR_ASSERT(context);
1591 settings = context->settings;
1592 WINPR_ASSERT(settings);
1594 wStream* s = Stream_New(
nullptr, 512);
1598 WLog_Print(nego->log, WLOG_ERROR,
"Stream_New failed!");
1602 UINT16 length = TPDU_CONNECTION_CONFIRM_LENGTH;
1603 const size_t bm = Stream_GetPosition(s);
1604 if (!Stream_SafeZero(s, length))
1607 if (nego->SelectedProtocol & PROTOCOL_FAILED_NEGO)
1609 UINT32 errorCode = (nego->SelectedProtocol & ~PROTOCOL_FAILED_NEGO);
1611 Stream_Write_UINT8(s, TYPE_RDP_NEG_FAILURE);
1612 Stream_Write_UINT8(s, flags);
1613 Stream_Write_UINT16(s, 8);
1614 Stream_Write_UINT32(s, errorCode);
1619 flags = EXTENDED_CLIENT_DATA_SUPPORTED;
1622 flags |= DYNVC_GFX_PROTOCOL_SUPPORTED;
1624 if (nego->RestrictedAdminModeSupported)
1625 flags |= RESTRICTED_ADMIN_MODE_SUPPORTED;
1627 if (nego->RemoteCredsGuardSupported)
1628 flags |= REDIRECTED_AUTHENTICATION_MODE_SUPPORTED;
1631 Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP);
1632 Stream_Write_UINT8(s, flags);
1633 Stream_Write_UINT16(s, 8);
1634 Stream_Write_UINT32(s, nego->SelectedProtocol);
1638 const size_t em = Stream_GetPosition(s);
1639 if (!Stream_SetPosition(s, bm))
1641 if (!tpkt_write_header(s, length))
1644 if (!tpdu_write_connection_confirm(s, length - 5))
1647 if (!Stream_SetPosition(s, em))
1649 Stream_SealLength(s);
1651 status = (transport_write(nego->transport, s) >= 0);
1654 Stream_Free(s, TRUE);
1660 nego->RequestedProtocols))
1663 nego->SelectedProtocol))
1666 switch (nego->SelectedProtocol)
1681 ENCRYPTION_LEVEL_NONE)
1688 ENCRYPTION_LEVEL_CLIENT_COMPATIBLE))
1700 WLog_Print(nego->log, WLOG_INFO,
1701 "Turning off encryption for local peer with standard rdp security");
1705 ENCRYPTION_LEVEL_NONE))
1710 WLog_Print(nego->log, WLOG_ERROR,
"Missing server certificate");
1729 ENCRYPTION_LEVEL_NONE))
1732 case PROTOCOL_HYBRID:
1747 ENCRYPTION_LEVEL_NONE))
1750 case PROTOCOL_RDSTLS:
1765 ENCRYPTION_LEVEL_NONE))
1781void nego_init(rdpNego* nego)
1784 nego_set_state(nego, NEGO_STATE_INITIAL);
1785 nego->RequestedProtocols = PROTOCOL_RDP;
1786 nego->CookieMaxLength = DEFAULT_COOKIE_MAX_LENGTH;
1787 nego->sendNegoData = FALSE;
1789 nego->failureCode = 0;
1800rdpNego* nego_new(rdpTransport* transport)
1802 rdpNego* nego = (rdpNego*)calloc(1,
sizeof(rdpNego));
1807 nego->log = WLog_Get(NEGO_TAG);
1808 WINPR_ASSERT(nego->log);
1809 nego->transport = transport;
1819void nego_free(rdpNego* nego)
1823 free(nego->RoutingToken);
1838BOOL nego_set_target(rdpNego* nego,
const char* hostname, UINT16 port)
1841 WINPR_ASSERT(hostname);
1843 nego->hostname = hostname;
1855void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer)
1857 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling security layer negotiation: %s",
1858 NegotiateSecurityLayer ?
"TRUE" :
"FALSE");
1859 nego->NegotiateSecurityLayer = NegotiateSecurityLayer;
1869void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdminModeRequired)
1871 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling restricted admin mode: %s",
1872 RestrictedAdminModeRequired ?
"TRUE" :
"FALSE");
1873 nego->RestrictedAdminModeRequired = RestrictedAdminModeRequired;
1876void nego_set_restricted_admin_mode_supported(rdpNego* nego, BOOL enabled)
1880 nego->RestrictedAdminModeSupported = enabled;
1883void nego_set_RCG_required(rdpNego* nego, BOOL enabled)
1887 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling remoteCredentialGuards: %s",
1888 enabled ?
"TRUE" :
"FALSE");
1889 nego->RemoteCredsGuardRequired = enabled;
1892void nego_set_RCG_supported(rdpNego* nego, BOOL enabled)
1896 nego->RemoteCredsGuardSupported = enabled;
1899BOOL nego_get_remoteCredentialGuard(
const rdpNego* nego)
1903 return nego->RemoteCredsGuardActive;
1906void nego_set_childsession_enabled(rdpNego* nego, BOOL ChildSessionEnabled)
1909 nego->ConnectChildSession = ChildSessionEnabled;
1912void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled)
1914 nego->GatewayEnabled = GatewayEnabled;
1917void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal)
1919 nego->GatewayBypassLocal = GatewayBypassLocal;
1928void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp)
1930 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling RDP security: %s", enable_rdp ?
"TRUE" :
"FALSE");
1931 nego->EnabledProtocols[PROTOCOL_RDP] = enable_rdp;
1940void nego_enable_tls(rdpNego* nego, BOOL enable_tls)
1942 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling TLS security: %s", enable_tls ?
"TRUE" :
"FALSE");
1943 nego->EnabledProtocols[PROTOCOL_SSL] = enable_tls;
1953void nego_enable_nla(rdpNego* nego, BOOL enable_nla)
1955 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling NLA security: %s", enable_nla ?
"TRUE" :
"FALSE");
1956 nego->EnabledProtocols[PROTOCOL_HYBRID] = enable_nla;
1966void nego_enable_rdstls(rdpNego* nego, BOOL enable_rdstls)
1968 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling RDSTLS security: %s",
1969 enable_rdstls ?
"TRUE" :
"FALSE");
1970 nego->EnabledProtocols[PROTOCOL_RDSTLS] = enable_rdstls;
1980void nego_enable_ext(rdpNego* nego, BOOL enable_ext)
1982 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling NLA extended security: %s",
1983 enable_ext ?
"TRUE" :
"FALSE");
1984 nego->EnabledProtocols[PROTOCOL_HYBRID_EX] = enable_ext;
1994void nego_enable_aad(rdpNego* nego, BOOL enable_aad)
1997 if (aad_is_supported())
1999 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling RDS AAD security: %s",
2000 enable_aad ?
"TRUE" :
"FALSE");
2001 nego->EnabledProtocols[PROTOCOL_RDSAAD] = enable_aad;
2005 WLog_Print(nego->log, WLOG_WARN,
"This build does not support AAD security, disabling.");
2018BOOL nego_set_routing_token(rdpNego* nego,
const void* RoutingToken, DWORD RoutingTokenLength)
2020 if (RoutingTokenLength == 0)
2023 free(nego->RoutingToken);
2024 nego->RoutingTokenLength = RoutingTokenLength;
2025 nego->RoutingToken = (BYTE*)malloc(nego->RoutingTokenLength);
2027 if (!nego->RoutingToken)
2030 CopyMemory(nego->RoutingToken, RoutingToken, nego->RoutingTokenLength);
2042BOOL nego_set_cookie(rdpNego* nego,
const char* cookie)
2047 nego->cookie =
nullptr;
2053 nego->cookie = _strdup(cookie);
2055 return (nego->cookie !=
nullptr);
2064void nego_set_cookie_max_length(rdpNego* nego, UINT32 CookieMaxLength)
2066 nego->CookieMaxLength = CookieMaxLength;
2075void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL SendPreconnectionPdu)
2077 nego->SendPreconnectionPdu = SendPreconnectionPdu;
2086void nego_set_preconnection_id(rdpNego* nego, UINT32 PreconnectionId)
2088 nego->PreconnectionId = PreconnectionId;
2097void nego_set_preconnection_blob(rdpNego* nego,
const char* PreconnectionBlob)
2099 nego->PreconnectionBlob = PreconnectionBlob;
2102UINT32 nego_get_selected_protocol(
const rdpNego* nego)
2107 return nego->SelectedProtocol;
2110BOOL nego_set_selected_protocol(rdpNego* nego, UINT32 SelectedProtocol)
2113 nego->SelectedProtocol = SelectedProtocol;
2117UINT32 nego_get_requested_protocols(
const rdpNego* nego)
2122 return nego->RequestedProtocols;
2125BOOL nego_set_requested_protocols(rdpNego* nego, UINT32 RequestedProtocols)
2130 nego->RequestedProtocols = RequestedProtocols;
2134NEGO_STATE nego_get_state(
const rdpNego* nego)
2137 return NEGO_STATE_FAIL;
2142BOOL nego_set_state(rdpNego* nego, NEGO_STATE state)
2145 nego->state = state;
2149SEC_WINNT_AUTH_IDENTITY* nego_get_identity(rdpNego* nego)
2151 rdpNla* nla =
nullptr;
2155 nla = transport_get_nla(nego->transport);
2156 return nla_get_identity(nla);
2159void nego_free_nla(rdpNego* nego)
2161 if (!nego || !nego->transport)
2164 transport_set_nla(nego->transport,
nullptr);
2167const BYTE* nego_get_routing_token(
const rdpNego* nego, DWORD* RoutingTokenLength)
2171 if (RoutingTokenLength)
2172 *RoutingTokenLength = nego->RoutingTokenLength;
2173 return nego->RoutingToken;
2176const char* nego_protocol_to_str(UINT32 protocol,
char* buffer,
size_t size)
2178 const UINT32 mask = ~(PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_RDSTLS | PROTOCOL_HYBRID_EX |
2179 PROTOCOL_RDSAAD | PROTOCOL_FAILED_NEGO);
2180 char str[48] = WINPR_C_ARRAY_INIT;
2182 if (protocol & PROTOCOL_SSL)
2183 (void)winpr_str_append(
"SSL", str,
sizeof(str),
"|");
2184 if (protocol & PROTOCOL_HYBRID)
2185 (void)winpr_str_append(
"HYBRID", str,
sizeof(str),
"|");
2186 if (protocol & PROTOCOL_RDSTLS)
2187 (void)winpr_str_append(
"RDSTLS", str,
sizeof(str),
"|");
2188 if (protocol & PROTOCOL_HYBRID_EX)
2189 (void)winpr_str_append(
"HYBRID_EX", str,
sizeof(str),
"|");
2190 if (protocol & PROTOCOL_RDSAAD)
2191 (void)winpr_str_append(
"RDSAAD", str,
sizeof(str),
"|");
2192 if (protocol & PROTOCOL_FAILED_NEGO)
2193 (void)winpr_str_append(
"NEGO FAILED", str,
sizeof(str),
"|");
2195 if (protocol == PROTOCOL_RDP)
2196 (void)winpr_str_append(
"RDP", str,
sizeof(str),
"");
2197 else if ((protocol & mask) != 0)
2198 (
void)winpr_str_append(
"UNKNOWN", str,
sizeof(str),
"|");
2200 (void)_snprintf(buffer, size,
"[%s][0x%08" PRIx32
"]", str, protocol);
WINPR_ATTR_NODISCARD FREERDP_API const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.