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 if (winpr_strnstr(str,
"\n", len) || winpr_strnstr(str,
"\r", len))
1010 result = nego_set_routing_token(nego, str, (UINT32)len);
1012 result = nego_set_cookie(nego, str);
1018 if (!Stream_SetPosition(s, pos))
1020 WLog_Print(nego->log, WLOG_ERROR,
"invalid %s received",
1021 isToken ?
"routing token" :
"cookie");
1025 WLog_Print(nego->log, WLOG_DEBUG,
"received %s [%s]", isToken ?
"routing token" :
"cookie",
1041BOOL nego_read_request(rdpNego* nego,
wStream* s)
1050 if (!tpkt_read_header(s, &length))
1053 if (!tpdu_read_connection_request(s, &li, length))
1056 if (li != Stream_GetRemainingLength(s) + 6)
1058 WLog_Print(nego->log, WLOG_ERROR,
"Incorrect TPDU length indicator.");
1062 if (!nego_read_request_token_or_cookie(nego, s))
1064 WLog_Print(nego->log, WLOG_ERROR,
"Failed to parse routing token or cookie.");
1068 if (Stream_GetRemainingLength(s) >= 8)
1071 Stream_Read_UINT8(s, type);
1073 if (type != TYPE_RDP_NEG_REQ)
1075 WLog_Print(nego->log, WLOG_ERROR,
"Incorrect negotiation request type %" PRIu8
"",
1080 if (!nego_process_negotiation_request(nego, s))
1084 return tpkt_ensure_stream_consumed(nego->log, s, length);
1093void nego_send(rdpNego* nego)
1097 switch (nego_get_state(nego))
1099 case NEGO_STATE_AAD:
1100 nego_attempt_rdsaad(nego);
1102 case NEGO_STATE_RDSTLS:
1103 nego_attempt_rdstls(nego);
1105 case NEGO_STATE_EXT:
1106 nego_attempt_ext(nego);
1108 case NEGO_STATE_NLA:
1109 nego_attempt_nla(nego);
1111 case NEGO_STATE_TLS:
1112 nego_attempt_tls(nego);
1114 case NEGO_STATE_RDP:
1115 nego_attempt_rdp(nego);
1118 WLog_Print(nego->log, WLOG_ERROR,
"invalid negotiation state for sending");
1133BOOL nego_send_negotiation_request(rdpNego* nego)
1136 wStream* s = Stream_New(
nullptr, 512);
1141 WLog_Print(nego->log, WLOG_ERROR,
"Stream_New failed!");
1145 const size_t bm = Stream_GetPosition(s);
1146 if (!Stream_SafeZero(s, TPDU_CONNECTION_REQUEST_LENGTH))
1149 if (nego->RoutingToken)
1151 if (!Stream_EnsureRemainingCapacity(s, nego->RoutingTokenLength))
1153 Stream_Write(s, nego->RoutingToken, nego->RoutingTokenLength);
1157 if ((nego->RoutingTokenLength > 2) &&
1158 (nego->RoutingToken[nego->RoutingTokenLength - 2] == 0x0D) &&
1159 (nego->RoutingToken[nego->RoutingTokenLength - 1] == 0x0A))
1161 WLog_Print(nego->log, WLOG_DEBUG,
1162 "Routing token looks correctly terminated - use verbatim");
1166 WLog_Print(nego->log, WLOG_DEBUG,
"Adding terminating CRLF to routing token");
1167 if (!Stream_EnsureRemainingCapacity(s, 2))
1169 Stream_Write_UINT8(s, 0x0D);
1170 Stream_Write_UINT8(s, 0x0A);
1173 else if (nego->cookie)
1175 size_t cookie_length = strlen(nego->cookie);
1177 if (cookie_length > nego->CookieMaxLength)
1178 cookie_length = nego->CookieMaxLength;
1180 if (!Stream_EnsureRemainingCapacity(s, 17))
1182 Stream_Write(s,
"Cookie: mstshash=", 17);
1183 if (!Stream_EnsureRemainingCapacity(s, cookie_length))
1185 Stream_Write(s, (BYTE*)nego->cookie, cookie_length);
1186 if (!Stream_EnsureRemainingCapacity(s, 2))
1188 Stream_Write_UINT8(s, 0x0D);
1189 Stream_Write_UINT8(s, 0x0A);
1193 char buffer[64] = WINPR_C_ARRAY_INIT;
1194 WLog_Print(nego->log, WLOG_DEBUG,
"RequestedProtocols: %s",
1195 nego_protocol_to_str(nego->RequestedProtocols, buffer,
sizeof(buffer)));
1198 if ((nego->RequestedProtocols > PROTOCOL_RDP) || (nego->sendNegoData))
1203 if (nego->RestrictedAdminModeRequired)
1204 flags |= RESTRICTED_ADMIN_MODE_REQUIRED;
1206 if (nego->RemoteCredsGuardRequired)
1207 flags |= REDIRECTED_AUTHENTICATION_MODE_REQUIRED;
1209 if (!Stream_EnsureRemainingCapacity(s, 8))
1212 Stream_Write_UINT8(s, TYPE_RDP_NEG_REQ);
1213 Stream_Write_UINT8(s, flags);
1214 Stream_Write_UINT16(s, 8);
1215 Stream_Write_UINT32(s, nego->RequestedProtocols);
1218 const size_t em = Stream_GetPosition(s);
1219 if ((em < 5) || (em > UINT16_MAX))
1221 if (!Stream_SetPosition(s, bm))
1223 if (!tpkt_write_header(s, (UINT16)em))
1225 if (!tpdu_write_connection_request(s, (UINT16)em - 5))
1227 if (!Stream_SetPosition(s, em))
1229 Stream_SealLength(s);
1230 rc = (transport_write(nego->transport, s) >= 0);
1232 Stream_Free(s, TRUE);
1237static BOOL nego_process_correlation_info(WINPR_ATTR_UNUSED rdpNego* nego,
wStream* s)
1242 BYTE correlationId[16] = WINPR_C_ARRAY_INIT;
1244 if (!Stream_CheckAndLogRequiredLengthWLog(nego->log, s, 36))
1246 WLog_Print(nego->log, WLOG_ERROR,
1247 "RDP_NEG_REQ::flags CORRELATION_INFO_PRESENT but data is missing");
1251 Stream_Read_UINT8(s, type);
1252 if (type != TYPE_RDP_CORRELATION_INFO)
1254 WLog_Print(nego->log, WLOG_ERROR,
1255 "(RDP_NEG_CORRELATION_INFO::type != TYPE_RDP_CORRELATION_INFO");
1258 Stream_Read_UINT8(s, flags);
1261 WLog_Print(nego->log, WLOG_ERROR,
"(RDP_NEG_CORRELATION_INFO::flags != 0");
1264 Stream_Read_UINT16(s, length);
1267 WLog_Print(nego->log, WLOG_ERROR,
"(RDP_NEG_CORRELATION_INFO::length != 36");
1271 Stream_Read(s, correlationId,
sizeof(correlationId));
1272 if ((correlationId[0] == 0x00) || (correlationId[0] == 0xF4))
1274 WLog_Print(nego->log, WLOG_ERROR,
1275 "(RDP_NEG_CORRELATION_INFO::correlationId[0] has invalid value 0x%02" PRIx8,
1279 for (
size_t x = 0; x < ARRAYSIZE(correlationId); x++)
1281 if (correlationId[x] == 0x0D)
1283 WLog_Print(nego->log, WLOG_ERROR,
1284 "(RDP_NEG_CORRELATION_INFO::correlationId[%" PRIuz
1285 "] has invalid value 0x%02" PRIx8,
1286 x, correlationId[x]);
1292 WLog_Print(nego->log, WLOG_INFO,
1293 "RDP_NEG_CORRELATION_INFO::correlationId = { %02" PRIx8
", %02" PRIx8
", %02" PRIx8
1294 ", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
1295 ", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
", %02" PRIx8
1297 correlationId[0], correlationId[1], correlationId[2], correlationId[3],
1298 correlationId[4], correlationId[5], correlationId[6], correlationId[7],
1299 correlationId[8], correlationId[9], correlationId[10], correlationId[11],
1300 correlationId[12], correlationId[13], correlationId[14], correlationId[15]);
1304BOOL nego_process_negotiation_request(rdpNego* nego,
wStream* s)
1312 if (!Stream_CheckAndLogRequiredLengthWLog(nego->log, s, 7))
1314 Stream_Read_UINT8(s, flags);
1315 if ((flags & ~(RESTRICTED_ADMIN_MODE_REQUIRED | REDIRECTED_AUTHENTICATION_MODE_REQUIRED |
1316 CORRELATION_INFO_PRESENT)) != 0)
1318 WLog_Print(nego->log, WLOG_ERROR,
"RDP_NEG_REQ::flags invalid value 0x%02" PRIx8, flags);
1321 if (flags & RESTRICTED_ADMIN_MODE_REQUIRED)
1323 if (nego->RestrictedAdminModeSupported)
1325 WLog_Print(nego->log, WLOG_INFO,
"RDP_NEG_REQ::flags RESTRICTED_ADMIN_MODE_REQUIRED");
1329 WLog_Print(nego->log, WLOG_ERROR,
1330 "RDP_NEG_REQ::flags RESTRICTED_ADMIN_MODE_REQUIRED but disabled");
1335 if (flags & REDIRECTED_AUTHENTICATION_MODE_REQUIRED)
1337 if (nego->RemoteCredsGuardSupported)
1339 WLog_Print(nego->log, WLOG_INFO,
1340 "RDP_NEG_REQ::flags REDIRECTED_AUTHENTICATION_MODE_REQUIRED");
1341 nego->RemoteCredsGuardActive = TRUE;
1348 if (flags & RESTRICTED_ADMIN_MODE_REQUIRED)
1350 WLog_Print(nego->log, WLOG_INFO,
1351 "RDP_NEG_REQ::flags REDIRECTED_AUTHENTICATION_MODE_REQUIRED ignored.");
1356 nego->log, WLOG_ERROR,
1357 "RDP_NEG_REQ::flags REDIRECTED_AUTHENTICATION_MODE_REQUIRED but disabled");
1363 Stream_Read_UINT16(s, length);
1366 WLog_Print(nego->log, WLOG_ERROR,
"RDP_NEG_REQ::length != 8");
1369 Stream_Read_UINT32(s, nego->RequestedProtocols);
1371 if (flags & CORRELATION_INFO_PRESENT)
1373 if (!nego_process_correlation_info(nego, s))
1378 char buffer[64] = WINPR_C_ARRAY_INIT;
1379 WLog_Print(nego->log, WLOG_DEBUG,
"RDP_NEG_REQ: RequestedProtocol: %s",
1380 nego_protocol_to_str(nego->RequestedProtocols, buffer,
sizeof(buffer)));
1382 nego_set_state(nego, NEGO_STATE_FINAL);
1387static const char* nego_rdp_neg_rsp_flags_str(UINT32 flags)
1389 const uint32_t mask =
1390 (EXTENDED_CLIENT_DATA_SUPPORTED | DYNVC_GFX_PROTOCOL_SUPPORTED | RDP_NEGRSP_RESERVED |
1391 RESTRICTED_ADMIN_MODE_SUPPORTED | REDIRECTED_AUTHENTICATION_MODE_SUPPORTED);
1392 static char buffer[1024] = WINPR_C_ARRAY_INIT;
1394 (void)_snprintf(buffer, ARRAYSIZE(buffer),
"[0x%02" PRIx32
"] ", flags);
1395 if (flags & EXTENDED_CLIENT_DATA_SUPPORTED)
1396 winpr_str_append(
"EXTENDED_CLIENT_DATA_SUPPORTED", buffer,
sizeof(buffer),
"|");
1397 if (flags & DYNVC_GFX_PROTOCOL_SUPPORTED)
1398 winpr_str_append(
"DYNVC_GFX_PROTOCOL_SUPPORTED", buffer,
sizeof(buffer),
"|");
1399 if (flags & RDP_NEGRSP_RESERVED)
1400 winpr_str_append(
"RDP_NEGRSP_RESERVED", buffer,
sizeof(buffer),
"|");
1401 if (flags & RESTRICTED_ADMIN_MODE_SUPPORTED)
1402 winpr_str_append(
"RESTRICTED_ADMIN_MODE_SUPPORTED", buffer,
sizeof(buffer),
"|");
1403 if (flags & REDIRECTED_AUTHENTICATION_MODE_SUPPORTED)
1404 winpr_str_append(
"REDIRECTED_AUTHENTICATION_MODE_SUPPORTED", buffer,
sizeof(buffer),
"|");
1407 char buffer2[32] = WINPR_C_ARRAY_INIT;
1408 (void)_snprintf(buffer2,
sizeof(buffer2),
"UNKNOWN[0x%04" PRIx32
"]", flags & ~mask);
1409 winpr_str_append(buffer2, buffer,
sizeof(buffer),
"|");
1415BOOL nego_process_negotiation_response(rdpNego* nego,
wStream* s)
1422 if (!Stream_CheckAndLogRequiredLengthWLog(nego->log, s, 7))
1424 nego_set_state(nego, NEGO_STATE_FAIL);
1428 Stream_Read_UINT8(s, nego->flags);
1429 WLog_Print(nego->log, WLOG_DEBUG,
"RDP_NEG_RSP::flags = { %s }",
1430 nego_rdp_neg_rsp_flags_str(nego->flags));
1432 if ((nego->flags & RESTRICTED_ADMIN_MODE_SUPPORTED) == 0)
1434 if (nego->RestrictedAdminModeRequired)
1436 WLog_Print(nego->log, WLOG_ERROR,
1437 "restricted-admin mode requested but not supported, terminating");
1442 if ((nego->flags & REDIRECTED_AUTHENTICATION_MODE_SUPPORTED) == 0)
1444 if (nego->RemoteCredsGuardRequired)
1446 WLog_Print(nego->log, WLOG_ERROR,
1447 "remote credential guard requested but not supported, terminating");
1452 Stream_Read_UINT16(s, length);
1455 WLog_Print(nego->log, WLOG_ERROR,
"RDP_NEG_RSP::length != 8");
1456 nego_set_state(nego, NEGO_STATE_FAIL);
1459 UINT32 SelectedProtocol = 0;
1460 Stream_Read_UINT32(s, SelectedProtocol);
1462 if (!nego_set_selected_protocol(nego, SelectedProtocol))
1464 return nego_set_state(nego, NEGO_STATE_FINAL);
1468static const char* nego_rdp_neg_fail_str(uint32_t what)
1472 case SSL_REQUIRED_BY_SERVER:
1473 return "SSL_REQUIRED_BY_SERVER";
1474 case SSL_NOT_ALLOWED_BY_SERVER:
1475 return "SSL_NOT_ALLOWED_BY_SERVER";
1476 case SSL_CERT_NOT_ON_SERVER:
1477 return "SSL_CERT_NOT_ON_SERVER";
1478 case INCONSISTENT_FLAGS:
1479 return "INCONSISTENT_FLAGS";
1480 case HYBRID_REQUIRED_BY_SERVER:
1481 return "HYBRID_REQUIRED_BY_SERVER";
1482 case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
1483 return "SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER";
1489static void nego_disable_all_except(rdpNego* nego, uint32_t what)
1493 char buffer[32] = WINPR_C_ARRAY_INIT;
1494 WLog_Print(nego->log, WLOG_DEBUG,
"Disabling all modes except %s",
1495 nego_protocol_to_str(what, buffer,
sizeof(buffer)));
1497 for (
size_t x = 0; x < ARRAYSIZE(nego->EnabledProtocols); x++)
1501 nego->EnabledProtocols[x] = FALSE;
1513BOOL nego_process_negotiation_failure(rdpNego* nego,
wStream* s)
1521 WLog_Print(nego->log, WLOG_DEBUG,
"RDP_NEG_FAILURE");
1522 if (!Stream_CheckAndLogRequiredLengthWLog(nego->log, s, 7))
1525 Stream_Read_UINT8(s, flags);
1528 WLog_Print(nego->log, WLOG_ERROR,
"RDP_NEG_FAILURE::flags = 0x%02" PRIx8, flags);
1531 Stream_Read_UINT16(s, length);
1534 WLog_Print(nego->log, WLOG_ERROR,
"RDP_NEG_FAILURE::length != 8");
1537 const uint32_t failureCode = Stream_Get_UINT32(s);
1538 const char* failureStr = nego_rdp_neg_fail_str(failureCode);
1539 DWORD level = WLOG_WARN;
1543 nego->failureCode = failureCode;
1545 switch (failureCode)
1547 case SSL_REQUIRED_BY_SERVER:
1548 nego_disable_all_except(nego, PROTOCOL_SSL);
1551 case SSL_NOT_ALLOWED_BY_SERVER:
1552 nego_disable_all_except(nego, PROTOCOL_RDP);
1553 nego->sendNegoData = TRUE;
1556 case SSL_CERT_NOT_ON_SERVER:
1558 nego->sendNegoData = TRUE;
1561 case INCONSISTENT_FLAGS:
1565 case HYBRID_REQUIRED_BY_SERVER:
1566 nego_disable_all_except(nego, PROTOCOL_HYBRID);
1574 WLog_Print(nego->log, level,
"Error: %s [0x%08" PRIx32
"]", failureStr, failureCode);
1575 nego_set_state(nego, NEGO_STATE_FAIL);
1584BOOL nego_send_negotiation_response(rdpNego* nego)
1586 BOOL status = FALSE;
1588 rdpContext* context =
nullptr;
1589 rdpSettings* settings =
nullptr;
1592 context = transport_get_context(nego->transport);
1593 WINPR_ASSERT(context);
1595 settings = context->settings;
1596 WINPR_ASSERT(settings);
1598 wStream* s = Stream_New(
nullptr, 512);
1602 WLog_Print(nego->log, WLOG_ERROR,
"Stream_New failed!");
1606 UINT16 length = TPDU_CONNECTION_CONFIRM_LENGTH;
1607 const size_t bm = Stream_GetPosition(s);
1608 if (!Stream_SafeZero(s, length))
1611 if (nego->SelectedProtocol & PROTOCOL_FAILED_NEGO)
1613 UINT32 errorCode = (nego->SelectedProtocol & ~PROTOCOL_FAILED_NEGO);
1615 Stream_Write_UINT8(s, TYPE_RDP_NEG_FAILURE);
1616 Stream_Write_UINT8(s, flags);
1617 Stream_Write_UINT16(s, 8);
1618 Stream_Write_UINT32(s, errorCode);
1623 flags = EXTENDED_CLIENT_DATA_SUPPORTED;
1626 flags |= DYNVC_GFX_PROTOCOL_SUPPORTED;
1628 if (nego->RestrictedAdminModeSupported)
1629 flags |= RESTRICTED_ADMIN_MODE_SUPPORTED;
1631 if (nego->RemoteCredsGuardSupported)
1632 flags |= REDIRECTED_AUTHENTICATION_MODE_SUPPORTED;
1635 Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP);
1636 Stream_Write_UINT8(s, flags);
1637 Stream_Write_UINT16(s, 8);
1638 Stream_Write_UINT32(s, nego->SelectedProtocol);
1642 const size_t em = Stream_GetPosition(s);
1643 if (!Stream_SetPosition(s, bm))
1645 if (!tpkt_write_header(s, length))
1648 if (!tpdu_write_connection_confirm(s, length - 5))
1651 if (!Stream_SetPosition(s, em))
1653 Stream_SealLength(s);
1655 status = (transport_write(nego->transport, s) >= 0);
1658 Stream_Free(s, TRUE);
1664 nego->RequestedProtocols))
1667 nego->SelectedProtocol))
1670 switch (nego->SelectedProtocol)
1685 ENCRYPTION_LEVEL_NONE)
1692 ENCRYPTION_LEVEL_CLIENT_COMPATIBLE))
1704 WLog_Print(nego->log, WLOG_INFO,
1705 "Turning off encryption for local peer with standard rdp security");
1709 ENCRYPTION_LEVEL_NONE))
1714 WLog_Print(nego->log, WLOG_ERROR,
"Missing server certificate");
1733 ENCRYPTION_LEVEL_NONE))
1736 case PROTOCOL_HYBRID:
1751 ENCRYPTION_LEVEL_NONE))
1754 case PROTOCOL_RDSTLS:
1769 ENCRYPTION_LEVEL_NONE))
1785void nego_init(rdpNego* nego)
1788 nego_set_state(nego, NEGO_STATE_INITIAL);
1789 nego->RequestedProtocols = PROTOCOL_RDP;
1790 nego->CookieMaxLength = DEFAULT_COOKIE_MAX_LENGTH;
1791 nego->sendNegoData = FALSE;
1793 nego->failureCode = 0;
1804rdpNego* nego_new(rdpTransport* transport)
1806 rdpNego* nego = (rdpNego*)calloc(1,
sizeof(rdpNego));
1811 nego->log = WLog_Get(NEGO_TAG);
1812 WINPR_ASSERT(nego->log);
1813 nego->transport = transport;
1823void nego_free(rdpNego* nego)
1827 free(nego->RoutingToken);
1842BOOL nego_set_target(rdpNego* nego,
const char* hostname, UINT16 port)
1845 WINPR_ASSERT(hostname);
1847 nego->hostname = hostname;
1859void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer)
1861 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling security layer negotiation: %s",
1862 NegotiateSecurityLayer ?
"TRUE" :
"FALSE");
1863 nego->NegotiateSecurityLayer = NegotiateSecurityLayer;
1873void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdminModeRequired)
1875 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling restricted admin mode: %s",
1876 RestrictedAdminModeRequired ?
"TRUE" :
"FALSE");
1877 nego->RestrictedAdminModeRequired = RestrictedAdminModeRequired;
1880void nego_set_restricted_admin_mode_supported(rdpNego* nego, BOOL enabled)
1884 nego->RestrictedAdminModeSupported = enabled;
1887void nego_set_RCG_required(rdpNego* nego, BOOL enabled)
1891 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling remoteCredentialGuards: %s",
1892 enabled ?
"TRUE" :
"FALSE");
1893 nego->RemoteCredsGuardRequired = enabled;
1896void nego_set_RCG_supported(rdpNego* nego, BOOL enabled)
1900 nego->RemoteCredsGuardSupported = enabled;
1903BOOL nego_get_remoteCredentialGuard(
const rdpNego* nego)
1907 return nego->RemoteCredsGuardActive;
1910void nego_set_childsession_enabled(rdpNego* nego, BOOL ChildSessionEnabled)
1913 nego->ConnectChildSession = ChildSessionEnabled;
1916void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled)
1918 nego->GatewayEnabled = GatewayEnabled;
1921void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal)
1923 nego->GatewayBypassLocal = GatewayBypassLocal;
1932void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp)
1934 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling RDP security: %s", enable_rdp ?
"TRUE" :
"FALSE");
1935 nego->EnabledProtocols[PROTOCOL_RDP] = enable_rdp;
1944void nego_enable_tls(rdpNego* nego, BOOL enable_tls)
1946 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling TLS security: %s", enable_tls ?
"TRUE" :
"FALSE");
1947 nego->EnabledProtocols[PROTOCOL_SSL] = enable_tls;
1957void nego_enable_nla(rdpNego* nego, BOOL enable_nla)
1959 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling NLA security: %s", enable_nla ?
"TRUE" :
"FALSE");
1960 nego->EnabledProtocols[PROTOCOL_HYBRID] = enable_nla;
1970void nego_enable_rdstls(rdpNego* nego, BOOL enable_rdstls)
1972 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling RDSTLS security: %s",
1973 enable_rdstls ?
"TRUE" :
"FALSE");
1974 nego->EnabledProtocols[PROTOCOL_RDSTLS] = enable_rdstls;
1984void nego_enable_ext(rdpNego* nego, BOOL enable_ext)
1986 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling NLA extended security: %s",
1987 enable_ext ?
"TRUE" :
"FALSE");
1988 nego->EnabledProtocols[PROTOCOL_HYBRID_EX] = enable_ext;
1998void nego_enable_aad(rdpNego* nego, BOOL enable_aad)
2001 if (aad_is_supported())
2003 WLog_Print(nego->log, WLOG_DEBUG,
"Enabling RDS AAD security: %s",
2004 enable_aad ?
"TRUE" :
"FALSE");
2005 nego->EnabledProtocols[PROTOCOL_RDSAAD] = enable_aad;
2009 WLog_Print(nego->log, WLOG_WARN,
"This build does not support AAD security, disabling.");
2022BOOL nego_set_routing_token(rdpNego* nego,
const void* RoutingToken, DWORD RoutingTokenLength)
2024 if (RoutingTokenLength == 0)
2027 free(nego->RoutingToken);
2028 nego->RoutingTokenLength = RoutingTokenLength;
2029 nego->RoutingToken = (BYTE*)malloc(nego->RoutingTokenLength);
2031 if (!nego->RoutingToken)
2034 CopyMemory(nego->RoutingToken, RoutingToken, nego->RoutingTokenLength);
2046BOOL nego_set_cookie(rdpNego* nego,
const char* cookie)
2051 nego->cookie =
nullptr;
2057 nego->cookie = _strdup(cookie);
2059 return (nego->cookie !=
nullptr);
2068void nego_set_cookie_max_length(rdpNego* nego, UINT32 CookieMaxLength)
2070 nego->CookieMaxLength = CookieMaxLength;
2079void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL SendPreconnectionPdu)
2081 nego->SendPreconnectionPdu = SendPreconnectionPdu;
2090void nego_set_preconnection_id(rdpNego* nego, UINT32 PreconnectionId)
2092 nego->PreconnectionId = PreconnectionId;
2101void nego_set_preconnection_blob(rdpNego* nego,
const char* PreconnectionBlob)
2103 nego->PreconnectionBlob = PreconnectionBlob;
2106UINT32 nego_get_selected_protocol(
const rdpNego* nego)
2111 return nego->SelectedProtocol;
2114BOOL nego_set_selected_protocol(rdpNego* nego, UINT32 SelectedProtocol)
2117 nego->SelectedProtocol = SelectedProtocol;
2121UINT32 nego_get_requested_protocols(
const rdpNego* nego)
2126 return nego->RequestedProtocols;
2129BOOL nego_set_requested_protocols(rdpNego* nego, UINT32 RequestedProtocols)
2134 nego->RequestedProtocols = RequestedProtocols;
2138NEGO_STATE nego_get_state(
const rdpNego* nego)
2141 return NEGO_STATE_FAIL;
2146BOOL nego_set_state(rdpNego* nego, NEGO_STATE state)
2149 nego->state = state;
2153SEC_WINNT_AUTH_IDENTITY* nego_get_identity(rdpNego* nego)
2155 rdpNla* nla =
nullptr;
2159 nla = transport_get_nla(nego->transport);
2160 return nla_get_identity(nla);
2163void nego_free_nla(rdpNego* nego)
2165 if (!nego || !nego->transport)
2168 transport_set_nla(nego->transport,
nullptr);
2171const BYTE* nego_get_routing_token(
const rdpNego* nego, DWORD* RoutingTokenLength)
2175 if (RoutingTokenLength)
2176 *RoutingTokenLength = nego->RoutingTokenLength;
2177 return nego->RoutingToken;
2180const char* nego_protocol_to_str(UINT32 protocol,
char* buffer,
size_t size)
2182 const UINT32 mask = ~(PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_RDSTLS | PROTOCOL_HYBRID_EX |
2183 PROTOCOL_RDSAAD | PROTOCOL_FAILED_NEGO);
2184 char str[48] = WINPR_C_ARRAY_INIT;
2186 if (protocol & PROTOCOL_SSL)
2187 (void)winpr_str_append(
"SSL", str,
sizeof(str),
"|");
2188 if (protocol & PROTOCOL_HYBRID)
2189 (void)winpr_str_append(
"HYBRID", str,
sizeof(str),
"|");
2190 if (protocol & PROTOCOL_RDSTLS)
2191 (void)winpr_str_append(
"RDSTLS", str,
sizeof(str),
"|");
2192 if (protocol & PROTOCOL_HYBRID_EX)
2193 (void)winpr_str_append(
"HYBRID_EX", str,
sizeof(str),
"|");
2194 if (protocol & PROTOCOL_RDSAAD)
2195 (void)winpr_str_append(
"RDSAAD", str,
sizeof(str),
"|");
2196 if (protocol & PROTOCOL_FAILED_NEGO)
2197 (void)winpr_str_append(
"NEGO FAILED", str,
sizeof(str),
"|");
2199 if (protocol == PROTOCOL_RDP)
2200 (void)winpr_str_append(
"RDP", str,
sizeof(str),
"");
2201 else if ((protocol & mask) != 0)
2202 (
void)winpr_str_append(
"UNKNOWN", str,
sizeof(str),
"|");
2204 (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.