FreeRDP
nego.c
1 
23 #include <freerdp/config.h>
24 
25 #include <winpr/crt.h>
26 #include <winpr/assert.h>
27 #include <winpr/stream.h>
28 
29 #include <freerdp/log.h>
30 
31 #include "tpkt.h"
32 
33 #include "nego.h"
34 #include "aad.h"
35 
36 #include "transport.h"
37 
38 #define TAG FREERDP_TAG("core.nego")
39 
40 struct rdp_nego
41 {
42  UINT16 port;
43  UINT32 flags;
44  const char* hostname;
45  char* cookie;
46  BYTE* RoutingToken;
47  DWORD RoutingTokenLength;
48  BOOL SendPreconnectionPdu;
49  UINT32 PreconnectionId;
50  const char* PreconnectionBlob;
51 
52  NEGO_STATE state;
53  BOOL TcpConnected;
54  BOOL SecurityConnected;
55  UINT32 CookieMaxLength;
56 
57  BOOL sendNegoData;
58  UINT32 SelectedProtocol;
59  UINT32 RequestedProtocols;
60  BOOL NegotiateSecurityLayer;
61  BOOL EnabledProtocols[32];
62  BOOL RestrictedAdminModeRequired;
63  BOOL RemoteCredsGuardRequired;
64  BOOL RemoteCredsGuardActive;
65  BOOL RemoteCredsGuardSupported;
66  BOOL GatewayEnabled;
67  BOOL GatewayBypassLocal;
68  BOOL ConnectChildSession;
69 
70  rdpTransport* transport;
71 };
72 
73 static const char* nego_state_string(NEGO_STATE state)
74 {
75  static const char* const NEGO_STATE_STRINGS[] = { "NEGO_STATE_INITIAL", "NEGO_STATE_RDSTLS",
76  "NEGO_STATE_AAD", "NEGO_STATE_EXT",
77  "NEGO_STATE_NLA", "NEGO_STATE_TLS",
78  "NEGO_STATE_RDP", "NEGO_STATE_FAIL",
79  "NEGO_STATE_FINAL", "NEGO_STATE_INVALID" };
80  if (state >= ARRAYSIZE(NEGO_STATE_STRINGS))
81  return NEGO_STATE_STRINGS[ARRAYSIZE(NEGO_STATE_STRINGS) - 1];
82  return NEGO_STATE_STRINGS[state];
83 }
84 
85 static BOOL nego_tcp_connect(rdpNego* nego);
86 static BOOL nego_transport_connect(rdpNego* nego);
87 static BOOL nego_transport_disconnect(rdpNego* nego);
88 static BOOL nego_security_connect(rdpNego* nego);
89 static BOOL nego_send_preconnection_pdu(rdpNego* nego);
90 static BOOL nego_recv_response(rdpNego* nego);
91 static void nego_send(rdpNego* nego);
92 static BOOL nego_process_negotiation_request(rdpNego* nego, wStream* s);
93 static BOOL nego_process_negotiation_response(rdpNego* nego, wStream* s);
94 static BOOL nego_process_negotiation_failure(rdpNego* nego, wStream* s);
95 
96 BOOL nego_update_settings_from_state(rdpNego* nego, rdpSettings* settings)
97 {
98  WINPR_ASSERT(nego);
99 
100  /* update settings with negotiated protocol security */
101  return freerdp_settings_set_uint32(settings, FreeRDP_RequestedProtocols,
102  nego->RequestedProtocols) &&
103  freerdp_settings_set_uint32(settings, FreeRDP_SelectedProtocol,
104  nego->SelectedProtocol) &&
105  freerdp_settings_set_uint32(settings, FreeRDP_NegotiationFlags, nego->flags);
106 }
107 
116 BOOL nego_connect(rdpNego* nego)
117 {
118  rdpContext* context = NULL;
119  rdpSettings* settings = NULL;
120  WINPR_ASSERT(nego);
121  context = transport_get_context(nego->transport);
122  WINPR_ASSERT(context);
123  settings = context->settings;
124  WINPR_ASSERT(settings);
125 
126  if (nego_get_state(nego) == NEGO_STATE_INITIAL)
127  {
128  if (nego->EnabledProtocols[PROTOCOL_RDSAAD])
129  {
130  nego_set_state(nego, NEGO_STATE_AAD);
131  }
132  else if (nego->EnabledProtocols[PROTOCOL_RDSTLS])
133  {
134  nego_set_state(nego, NEGO_STATE_RDSTLS);
135  }
136  else if (nego->EnabledProtocols[PROTOCOL_HYBRID_EX])
137  {
138  nego_set_state(nego, NEGO_STATE_EXT);
139  }
140  else if (nego->EnabledProtocols[PROTOCOL_HYBRID])
141  {
142  nego_set_state(nego, NEGO_STATE_NLA);
143  }
144  else if (nego->EnabledProtocols[PROTOCOL_SSL])
145  {
146  nego_set_state(nego, NEGO_STATE_TLS);
147  }
148  else if (nego->EnabledProtocols[PROTOCOL_RDP])
149  {
150  nego_set_state(nego, NEGO_STATE_RDP);
151  }
152  else
153  {
154  WLog_ERR(TAG, "No security protocol is enabled");
155  nego_set_state(nego, NEGO_STATE_FAIL);
156  return FALSE;
157  }
158 
159  if (!nego->NegotiateSecurityLayer)
160  {
161  WLog_DBG(TAG, "Security Layer Negotiation is disabled");
162  /* attempt only the highest enabled protocol (see nego_attempt_*) */
163  nego->EnabledProtocols[PROTOCOL_RDSAAD] = FALSE;
164  nego->EnabledProtocols[PROTOCOL_HYBRID] = FALSE;
165  nego->EnabledProtocols[PROTOCOL_SSL] = FALSE;
166  nego->EnabledProtocols[PROTOCOL_RDP] = FALSE;
167  nego->EnabledProtocols[PROTOCOL_HYBRID_EX] = FALSE;
168  nego->EnabledProtocols[PROTOCOL_RDSTLS] = FALSE;
169 
170  UINT32 SelectedProtocol = 0;
171  switch (nego_get_state(nego))
172  {
173  case NEGO_STATE_AAD:
174  nego->EnabledProtocols[PROTOCOL_RDSAAD] = TRUE;
175  SelectedProtocol = PROTOCOL_RDSAAD;
176  break;
177  case NEGO_STATE_RDSTLS:
178  nego->EnabledProtocols[PROTOCOL_RDSTLS] = TRUE;
179  SelectedProtocol = PROTOCOL_RDSTLS;
180  break;
181  case NEGO_STATE_EXT:
182  nego->EnabledProtocols[PROTOCOL_HYBRID_EX] = TRUE;
183  nego->EnabledProtocols[PROTOCOL_HYBRID] = TRUE;
184  SelectedProtocol = PROTOCOL_HYBRID_EX;
185  break;
186  case NEGO_STATE_NLA:
187  nego->EnabledProtocols[PROTOCOL_HYBRID] = TRUE;
188  SelectedProtocol = PROTOCOL_HYBRID;
189  break;
190  case NEGO_STATE_TLS:
191  nego->EnabledProtocols[PROTOCOL_SSL] = TRUE;
192  SelectedProtocol = PROTOCOL_SSL;
193  break;
194  case NEGO_STATE_RDP:
195  nego->EnabledProtocols[PROTOCOL_RDP] = TRUE;
196  SelectedProtocol = PROTOCOL_RDP;
197  break;
198  default:
199  WLog_ERR(TAG, "Invalid NEGO state 0x%08" PRIx32, nego_get_state(nego));
200  return FALSE;
201  }
202  if (!nego_set_selected_protocol(nego, SelectedProtocol))
203  return FALSE;
204  }
205 
206  if (!nego_tcp_connect(nego))
207  {
208  WLog_ERR(TAG, "Failed to connect");
209  return FALSE;
210  }
211 
212  if (nego->SendPreconnectionPdu)
213  {
214  if (!nego_send_preconnection_pdu(nego))
215  {
216  WLog_ERR(TAG, "Failed to send preconnection pdu");
217  nego_set_state(nego, NEGO_STATE_FINAL);
218  return FALSE;
219  }
220  }
221  }
222 
223  if (!nego->NegotiateSecurityLayer)
224  {
225  nego_set_state(nego, NEGO_STATE_FINAL);
226  }
227  else
228  {
229  do
230  {
231  WLog_DBG(TAG, "state: %s", nego_state_string(nego_get_state(nego)));
232  nego_send(nego);
233 
234  if (nego_get_state(nego) == NEGO_STATE_FAIL)
235  {
236  if (freerdp_get_last_error(transport_get_context(nego->transport)) ==
237  FREERDP_ERROR_SUCCESS)
238  WLog_ERR(TAG, "Protocol Security Negotiation Failure");
239 
240  nego_set_state(nego, NEGO_STATE_FINAL);
241  return FALSE;
242  }
243  } while (nego_get_state(nego) != NEGO_STATE_FINAL);
244  }
245 
246  {
247  char buffer[64] = { 0 };
248  WLog_DBG(TAG, "Negotiated %s security",
249  nego_protocol_to_str(nego->SelectedProtocol, buffer, sizeof(buffer)));
250  }
251 
252  /* update settings with negotiated protocol security */
253  if (!nego_update_settings_from_state(nego, settings))
254  return FALSE;
255 
256  if (nego->SelectedProtocol == PROTOCOL_RDP)
257  {
258  if (!freerdp_settings_set_bool(settings, FreeRDP_UseRdpSecurityLayer, TRUE))
259  return FALSE;
260 
261  if (freerdp_settings_get_uint32(settings, FreeRDP_EncryptionMethods) == 0)
262  {
267  if (!freerdp_settings_set_uint32(settings, FreeRDP_EncryptionMethods,
268  ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT |
269  ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS))
270  return FALSE;
271  }
272  }
273 
274  /* finally connect security layer (if not already done) */
275  if (!nego_security_connect(nego))
276  {
277  char buffer[64] = { 0 };
278  WLog_DBG(TAG, "Failed to connect with %s security",
279  nego_protocol_to_str(nego->SelectedProtocol, buffer, sizeof(buffer)));
280  return FALSE;
281  }
282 
283  return TRUE;
284 }
285 
286 BOOL nego_disconnect(rdpNego* nego)
287 {
288  WINPR_ASSERT(nego);
289  nego_set_state(nego, NEGO_STATE_INITIAL);
290  return nego_transport_disconnect(nego);
291 }
292 
293 static BOOL nego_try_connect(rdpNego* nego)
294 {
295  WINPR_ASSERT(nego);
296 
297  switch (nego->SelectedProtocol)
298  {
299  case PROTOCOL_RDSAAD:
300  WLog_DBG(TAG, "nego_security_connect with PROTOCOL_RDSAAD");
301  nego->SecurityConnected = transport_connect_aad(nego->transport);
302  break;
303  case PROTOCOL_RDSTLS:
304  WLog_DBG(TAG, "nego_security_connect with PROTOCOL_RDSTLS");
305  nego->SecurityConnected = transport_connect_rdstls(nego->transport);
306  break;
307  case PROTOCOL_HYBRID:
308  WLog_DBG(TAG, "nego_security_connect with PROTOCOL_HYBRID");
309  nego->SecurityConnected = transport_connect_nla(nego->transport, FALSE);
310  break;
311  case PROTOCOL_HYBRID_EX:
312  WLog_DBG(TAG, "nego_security_connect with PROTOCOL_HYBRID_EX");
313  nego->SecurityConnected = transport_connect_nla(nego->transport, TRUE);
314  break;
315  case PROTOCOL_SSL:
316  WLog_DBG(TAG, "nego_security_connect with PROTOCOL_SSL");
317  nego->SecurityConnected = transport_connect_tls(nego->transport);
318  break;
319  case PROTOCOL_RDP:
320  WLog_DBG(TAG, "nego_security_connect with PROTOCOL_RDP");
321  nego->SecurityConnected = transport_connect_rdp(nego->transport);
322  break;
323  default:
324  WLog_ERR(TAG,
325  "cannot connect security layer because no protocol has been selected yet.");
326  return FALSE;
327  }
328  return nego->SecurityConnected;
329 }
330 
331 /* connect to selected security layer */
332 BOOL nego_security_connect(rdpNego* nego)
333 {
334  WINPR_ASSERT(nego);
335  if (!nego->TcpConnected)
336  {
337  nego->SecurityConnected = FALSE;
338  }
339  else if (!nego->SecurityConnected)
340  {
341  if (!nego_try_connect(nego))
342  return FALSE;
343  }
344 
345  return nego->SecurityConnected;
346 }
347 
348 static BOOL nego_tcp_connect(rdpNego* nego)
349 {
350  rdpContext* context = NULL;
351  WINPR_ASSERT(nego);
352  if (!nego->TcpConnected)
353  {
354  UINT32 TcpConnectTimeout = 0;
355 
356  context = transport_get_context(nego->transport);
357  WINPR_ASSERT(context);
358 
359  TcpConnectTimeout =
360  freerdp_settings_get_uint32(context->settings, FreeRDP_TcpConnectTimeout);
361 
362  if (nego->GatewayEnabled)
363  {
364  if (nego->GatewayBypassLocal)
365  {
366  /* Attempt a direct connection first, and then fallback to using the gateway */
367  WLog_INFO(TAG,
368  "Detecting if host can be reached locally. - This might take some time.");
369  WLog_INFO(TAG, "To disable auto detection use /gateway-usage-method:direct");
370  transport_set_gateway_enabled(nego->transport, FALSE);
371  nego->TcpConnected = transport_connect(nego->transport, nego->hostname, nego->port,
372  TcpConnectTimeout);
373  }
374 
375  if (!nego->TcpConnected)
376  {
377  transport_set_gateway_enabled(nego->transport, TRUE);
378  nego->TcpConnected = transport_connect(nego->transport, nego->hostname, nego->port,
379  TcpConnectTimeout);
380  }
381  }
382  else if (nego->ConnectChildSession)
383  {
384  nego->TcpConnected = transport_connect_childsession(nego->transport);
385  }
386  else
387  {
388  nego->TcpConnected =
389  transport_connect(nego->transport, nego->hostname, nego->port, TcpConnectTimeout);
390  }
391  }
392 
393  return nego->TcpConnected;
394 }
395 
404 BOOL nego_transport_connect(rdpNego* nego)
405 {
406  WINPR_ASSERT(nego);
407  if (!nego_tcp_connect(nego))
408  return FALSE;
409 
410  if (nego->TcpConnected && !nego->NegotiateSecurityLayer)
411  return nego_security_connect(nego);
412 
413  return nego->TcpConnected;
414 }
415 
424 BOOL nego_transport_disconnect(rdpNego* nego)
425 {
426  WINPR_ASSERT(nego);
427  if (nego->TcpConnected)
428  transport_disconnect(nego->transport);
429 
430  nego->TcpConnected = FALSE;
431  nego->SecurityConnected = FALSE;
432  return TRUE;
433 }
434 
443 BOOL nego_send_preconnection_pdu(rdpNego* nego)
444 {
445  wStream* s = NULL;
446  UINT32 cbSize = 0;
447  UINT16 cchPCB = 0;
448  WCHAR* wszPCB = NULL;
449 
450  WINPR_ASSERT(nego);
451 
452  WLog_DBG(TAG, "Sending preconnection PDU");
453 
454  if (!nego_tcp_connect(nego))
455  return FALSE;
456 
457  /* it's easier to always send the version 2 PDU, and it's just 2 bytes overhead */
458  cbSize = PRECONNECTION_PDU_V2_MIN_SIZE;
459 
460  if (nego->PreconnectionBlob)
461  {
462  size_t len = 0;
463  wszPCB = ConvertUtf8ToWCharAlloc(nego->PreconnectionBlob, &len);
464  if (len > UINT16_MAX - 1)
465  {
466  free(wszPCB);
467  return FALSE;
468  }
469  cchPCB = (UINT16)len;
470  cchPCB += 1; /* zero-termination */
471  cbSize += cchPCB * sizeof(WCHAR);
472  }
473 
474  s = Stream_New(NULL, cbSize);
475 
476  if (!s)
477  {
478  free(wszPCB);
479  WLog_ERR(TAG, "Stream_New failed!");
480  return FALSE;
481  }
482 
483  Stream_Write_UINT32(s, cbSize); /* cbSize */
484  Stream_Write_UINT32(s, 0); /* Flags */
485  Stream_Write_UINT32(s, PRECONNECTION_PDU_V2); /* Version */
486  Stream_Write_UINT32(s, nego->PreconnectionId); /* Id */
487  Stream_Write_UINT16(s, cchPCB); /* cchPCB */
488 
489  if (wszPCB)
490  {
491  Stream_Write(s, wszPCB, cchPCB * sizeof(WCHAR)); /* wszPCB */
492  free(wszPCB);
493  }
494 
495  Stream_SealLength(s);
496 
497  if (transport_write(nego->transport, s) < 0)
498  {
499  Stream_Free(s, TRUE);
500  return FALSE;
501  }
502 
503  Stream_Free(s, TRUE);
504  return TRUE;
505 }
506 
507 static void nego_attempt_rdstls(rdpNego* nego)
508 {
509  WINPR_ASSERT(nego);
510  nego->RequestedProtocols = PROTOCOL_RDSTLS | PROTOCOL_SSL;
511  WLog_DBG(TAG, "Attempting RDSTLS security");
512 
513  if (!nego_transport_connect(nego))
514  {
515  nego_set_state(nego, NEGO_STATE_FAIL);
516  return;
517  }
518 
519  if (!nego_send_negotiation_request(nego))
520  {
521  nego_set_state(nego, NEGO_STATE_FAIL);
522  return;
523  }
524 
525  if (!nego_recv_response(nego))
526  {
527  nego_set_state(nego, NEGO_STATE_FAIL);
528  return;
529  }
530 
531  WLog_DBG(TAG, "state: %s", nego_state_string(nego_get_state(nego)));
532 
533  if (nego_get_state(nego) != NEGO_STATE_FINAL)
534  {
535  nego_transport_disconnect(nego);
536 
537  if (nego->EnabledProtocols[PROTOCOL_HYBRID_EX])
538  nego_set_state(nego, NEGO_STATE_EXT);
539  else if (nego->EnabledProtocols[PROTOCOL_HYBRID])
540  nego_set_state(nego, NEGO_STATE_NLA);
541  else if (nego->EnabledProtocols[PROTOCOL_SSL])
542  nego_set_state(nego, NEGO_STATE_TLS);
543  else if (nego->EnabledProtocols[PROTOCOL_RDP])
544  nego_set_state(nego, NEGO_STATE_RDP);
545  else
546  nego_set_state(nego, NEGO_STATE_FAIL);
547  }
548 }
549 
550 static void nego_attempt_rdsaad(rdpNego* nego)
551 {
552  WINPR_ASSERT(nego);
553  nego->RequestedProtocols = PROTOCOL_RDSAAD;
554  WLog_DBG(TAG, "Attempting RDS AAD Auth security");
555 
556  if (!nego_transport_connect(nego))
557  {
558  nego_set_state(nego, NEGO_STATE_FAIL);
559  return;
560  }
561 
562  if (!nego_send_negotiation_request(nego))
563  {
564  nego_set_state(nego, NEGO_STATE_FAIL);
565  return;
566  }
567 
568  if (!nego_recv_response(nego))
569  {
570  nego_set_state(nego, NEGO_STATE_FAIL);
571  return;
572  }
573 
574  WLog_DBG(TAG, "state: %s", nego_state_string(nego_get_state(nego)));
575 
576  if (nego_get_state(nego) != NEGO_STATE_FINAL)
577  {
578  nego_transport_disconnect(nego);
579 
580  if (nego->EnabledProtocols[PROTOCOL_HYBRID_EX])
581  nego_set_state(nego, NEGO_STATE_EXT);
582  else if (nego->EnabledProtocols[PROTOCOL_HYBRID])
583  nego_set_state(nego, NEGO_STATE_NLA);
584  else if (nego->EnabledProtocols[PROTOCOL_SSL])
585  nego_set_state(nego, NEGO_STATE_TLS);
586  else if (nego->EnabledProtocols[PROTOCOL_RDP])
587  nego_set_state(nego, NEGO_STATE_RDP);
588  else
589  nego_set_state(nego, NEGO_STATE_FAIL);
590  }
591 }
592 
593 static void nego_attempt_ext(rdpNego* nego)
594 {
595  WINPR_ASSERT(nego);
596  nego->RequestedProtocols = PROTOCOL_HYBRID | PROTOCOL_SSL | PROTOCOL_HYBRID_EX;
597  WLog_DBG(TAG, "Attempting NLA extended security");
598 
599  if (!nego_transport_connect(nego))
600  {
601  nego_set_state(nego, NEGO_STATE_FAIL);
602  return;
603  }
604 
605  if (!nego_send_negotiation_request(nego))
606  {
607  nego_set_state(nego, NEGO_STATE_FAIL);
608  return;
609  }
610 
611  if (!nego_recv_response(nego))
612  {
613  nego_set_state(nego, NEGO_STATE_FAIL);
614  return;
615  }
616 
617  WLog_DBG(TAG, "state: %s", nego_state_string(nego_get_state(nego)));
618 
619  if (nego_get_state(nego) != NEGO_STATE_FINAL)
620  {
621  nego_transport_disconnect(nego);
622 
623  if (nego->EnabledProtocols[PROTOCOL_HYBRID])
624  nego_set_state(nego, NEGO_STATE_NLA);
625  else if (nego->EnabledProtocols[PROTOCOL_SSL])
626  nego_set_state(nego, NEGO_STATE_TLS);
627  else if (nego->EnabledProtocols[PROTOCOL_RDP])
628  nego_set_state(nego, NEGO_STATE_RDP);
629  else
630  nego_set_state(nego, NEGO_STATE_FAIL);
631  }
632 }
633 
634 static void nego_attempt_nla(rdpNego* nego)
635 {
636  WINPR_ASSERT(nego);
637  nego->RequestedProtocols = PROTOCOL_HYBRID | PROTOCOL_SSL;
638  WLog_DBG(TAG, "Attempting NLA security");
639 
640  if (!nego_transport_connect(nego))
641  {
642  nego_set_state(nego, NEGO_STATE_FAIL);
643  return;
644  }
645 
646  if (!nego_send_negotiation_request(nego))
647  {
648  nego_set_state(nego, NEGO_STATE_FAIL);
649  return;
650  }
651 
652  if (!nego_recv_response(nego))
653  {
654  nego_set_state(nego, NEGO_STATE_FAIL);
655  return;
656  }
657 
658  WLog_DBG(TAG, "state: %s", nego_state_string(nego_get_state(nego)));
659 
660  if (nego_get_state(nego) != NEGO_STATE_FINAL)
661  {
662  nego_transport_disconnect(nego);
663 
664  if (nego->EnabledProtocols[PROTOCOL_SSL])
665  nego_set_state(nego, NEGO_STATE_TLS);
666  else if (nego->EnabledProtocols[PROTOCOL_RDP])
667  nego_set_state(nego, NEGO_STATE_RDP);
668  else
669  nego_set_state(nego, NEGO_STATE_FAIL);
670  }
671 }
672 
673 static void nego_attempt_tls(rdpNego* nego)
674 {
675  WINPR_ASSERT(nego);
676  nego->RequestedProtocols = PROTOCOL_SSL;
677  WLog_DBG(TAG, "Attempting TLS security");
678 
679  if (!nego_transport_connect(nego))
680  {
681  nego_set_state(nego, NEGO_STATE_FAIL);
682  return;
683  }
684 
685  if (!nego_send_negotiation_request(nego))
686  {
687  nego_set_state(nego, NEGO_STATE_FAIL);
688  return;
689  }
690 
691  if (!nego_recv_response(nego))
692  {
693  nego_set_state(nego, NEGO_STATE_FAIL);
694  return;
695  }
696 
697  if (nego_get_state(nego) != NEGO_STATE_FINAL)
698  {
699  nego_transport_disconnect(nego);
700 
701  if (nego->EnabledProtocols[PROTOCOL_RDP])
702  nego_set_state(nego, NEGO_STATE_RDP);
703  else
704  nego_set_state(nego, NEGO_STATE_FAIL);
705  }
706 }
707 
708 static void nego_attempt_rdp(rdpNego* nego)
709 {
710  WINPR_ASSERT(nego);
711  nego->RequestedProtocols = PROTOCOL_RDP;
712  WLog_DBG(TAG, "Attempting RDP security");
713 
714  if (!nego_transport_connect(nego))
715  {
716  nego_set_state(nego, NEGO_STATE_FAIL);
717  return;
718  }
719 
720  if (!nego_send_negotiation_request(nego))
721  {
722  nego_set_state(nego, NEGO_STATE_FAIL);
723  return;
724  }
725 
726  if (!nego_recv_response(nego))
727  {
728  nego_set_state(nego, NEGO_STATE_FAIL);
729  return;
730  }
731 }
732 
741 BOOL nego_recv_response(rdpNego* nego)
742 {
743  int status = 0;
744  wStream* s = NULL;
745 
746  WINPR_ASSERT(nego);
747  s = Stream_New(NULL, 1024);
748 
749  if (!s)
750  {
751  WLog_ERR(TAG, "Stream_New failed!");
752  return FALSE;
753  }
754 
755  status = transport_read_pdu(nego->transport, s);
756 
757  if (status < 0)
758  {
759  Stream_Free(s, TRUE);
760  return FALSE;
761  }
762 
763  status = nego_recv(nego->transport, s, nego);
764  Stream_Free(s, TRUE);
765 
766  if (status < 0)
767  return FALSE;
768 
769  return TRUE;
770 }
771 
783 int nego_recv(rdpTransport* transport, wStream* s, void* extra)
784 {
785  BYTE li = 0;
786  BYTE type = 0;
787  UINT16 length = 0;
788  rdpNego* nego = (rdpNego*)extra;
789 
790  WINPR_ASSERT(nego);
791  if (!tpkt_read_header(s, &length))
792  return -1;
793 
794  if (!tpdu_read_connection_confirm(s, &li, length))
795  return -1;
796 
797  if (li > 6)
798  {
799  /* rdpNegData (optional) */
800  Stream_Read_UINT8(s, type); /* Type */
801 
802  switch (type)
803  {
804  case TYPE_RDP_NEG_RSP:
805  if (!nego_process_negotiation_response(nego, s))
806  return -1;
807  {
808  char buffer[64] = { 0 };
809  WLog_DBG(TAG, "selected_protocol: %s",
810  nego_protocol_to_str(nego->SelectedProtocol, buffer, sizeof(buffer)));
811  }
812 
813  /* enhanced security selected ? */
814 
815  if (nego->SelectedProtocol)
816  {
817  if ((nego->SelectedProtocol == PROTOCOL_RDSAAD) &&
818  (!nego->EnabledProtocols[PROTOCOL_RDSAAD]))
819  {
820  nego_set_state(nego, NEGO_STATE_FAIL);
821  }
822  if ((nego->SelectedProtocol == PROTOCOL_HYBRID) &&
823  (!nego->EnabledProtocols[PROTOCOL_HYBRID]))
824  {
825  nego_set_state(nego, NEGO_STATE_FAIL);
826  }
827 
828  if ((nego->SelectedProtocol == PROTOCOL_SSL) &&
829  (!nego->EnabledProtocols[PROTOCOL_SSL]))
830  {
831  nego_set_state(nego, NEGO_STATE_FAIL);
832  }
833  }
834  else if (!nego->EnabledProtocols[PROTOCOL_RDP])
835  {
836  nego_set_state(nego, NEGO_STATE_FAIL);
837  }
838 
839  break;
840 
841  case TYPE_RDP_NEG_FAILURE:
842  if (!nego_process_negotiation_failure(nego, s))
843  return -1;
844  break;
845  default:
846  return -1;
847  }
848  }
849  else if (li == 6)
850  {
851  WLog_DBG(TAG, "no rdpNegData");
852 
853  if (!nego->EnabledProtocols[PROTOCOL_RDP])
854  nego_set_state(nego, NEGO_STATE_FAIL);
855  else
856  nego_set_state(nego, NEGO_STATE_FINAL);
857  }
858  else
859  {
860  WLog_ERR(TAG, "invalid negotiation response");
861  nego_set_state(nego, NEGO_STATE_FAIL);
862  }
863 
864  if (!tpkt_ensure_stream_consumed(s, length))
865  return -1;
866  return 0;
867 }
868 
874 static BOOL nego_read_request_token_or_cookie(rdpNego* nego, wStream* s)
875 {
876  /* routingToken and cookie are optional and mutually exclusive!
877  *
878  * routingToken (variable): An optional and variable-length routing
879  * token (used for load balancing) terminated by a 0x0D0A two-byte
880  * sequence: (check [MSFT-SDLBTS] for details!)
881  * Cookie:[space]msts=[ip address].[port].[reserved][\x0D\x0A]
882  * tsv://MS Terminal Services Plugin.1.[\x0D\x0A]
883  *
884  * cookie (variable): An optional and variable-length ANSI character
885  * string terminated by a 0x0D0A two-byte sequence:
886  * Cookie:[space]mstshash=[ANSISTRING][\x0D\x0A]
887  */
888  UINT16 crlf = 0;
889  BOOL result = FALSE;
890  BOOL isToken = FALSE;
891  size_t remain = Stream_GetRemainingLength(s);
892 
893  WINPR_ASSERT(nego);
894 
895  const char* str = Stream_ConstPointer(s);
896  const size_t pos = Stream_GetPosition(s);
897 
898  /* minimum length for token is 15 */
899  if (remain < 15)
900  return TRUE;
901 
902  if (memcmp(Stream_ConstPointer(s), "Cookie: mstshash=", 17) != 0)
903  {
904  if (memcmp(Stream_ConstPointer(s), "Cookie: msts=", 13) != 0)
905  {
906  if (memcmp(Stream_ConstPointer(s), "tsv:", 4) != 0)
907  {
908  if (memcmp(Stream_ConstPointer(s), "mth://", 6) != 0)
909  {
910  /* remaining bytes are neither a token nor a cookie */
911  return TRUE;
912  }
913  }
914  }
915  isToken = TRUE;
916  }
917  else
918  {
919  /* not a token, minimum length for cookie is 19 */
920  if (remain < 19)
921  return TRUE;
922 
923  Stream_Seek(s, 17);
924  }
925 
926  while (Stream_GetRemainingLength(s) >= 2)
927  {
928  Stream_Read_UINT16(s, crlf);
929 
930  if (crlf == 0x0A0D)
931  break;
932 
933  Stream_Rewind(s, 1);
934  }
935 
936  if (crlf == 0x0A0D)
937  {
938  Stream_Rewind(s, 2);
939  const size_t len = Stream_GetPosition(s) - pos;
940  Stream_Write_UINT16(s, 0);
941 
942  if (len > UINT32_MAX)
943  return FALSE;
944 
945  if (strnlen(str, len) == len)
946  {
947  if (isToken)
948  result = nego_set_routing_token(nego, str, (UINT32)len);
949  else
950  result = nego_set_cookie(nego, str);
951  }
952  }
953 
954  if (!result)
955  {
956  Stream_SetPosition(s, pos);
957  WLog_ERR(TAG, "invalid %s received", isToken ? "routing token" : "cookie");
958  }
959  else
960  {
961  WLog_DBG(TAG, "received %s [%s]", isToken ? "routing token" : "cookie", str);
962  }
963 
964  return result;
965 }
966 
976 BOOL nego_read_request(rdpNego* nego, wStream* s)
977 {
978  BYTE li = 0;
979  BYTE type = 0;
980  UINT16 length = 0;
981 
982  WINPR_ASSERT(nego);
983  WINPR_ASSERT(s);
984 
985  if (!tpkt_read_header(s, &length))
986  return FALSE;
987 
988  if (!tpdu_read_connection_request(s, &li, length))
989  return FALSE;
990 
991  if (li != Stream_GetRemainingLength(s) + 6)
992  {
993  WLog_ERR(TAG, "Incorrect TPDU length indicator.");
994  return FALSE;
995  }
996 
997  if (!nego_read_request_token_or_cookie(nego, s))
998  {
999  WLog_ERR(TAG, "Failed to parse routing token or cookie.");
1000  return FALSE;
1001  }
1002 
1003  if (Stream_GetRemainingLength(s) >= 8)
1004  {
1005  /* rdpNegData (optional) */
1006  Stream_Read_UINT8(s, type); /* Type */
1007 
1008  if (type != TYPE_RDP_NEG_REQ)
1009  {
1010  WLog_ERR(TAG, "Incorrect negotiation request type %" PRIu8 "", type);
1011  return FALSE;
1012  }
1013 
1014  if (!nego_process_negotiation_request(nego, s))
1015  return FALSE;
1016  }
1017 
1018  return tpkt_ensure_stream_consumed(s, length);
1019 }
1020 
1027 void nego_send(rdpNego* nego)
1028 {
1029  WINPR_ASSERT(nego);
1030 
1031  switch (nego_get_state(nego))
1032  {
1033  case NEGO_STATE_AAD:
1034  nego_attempt_rdsaad(nego);
1035  break;
1036  case NEGO_STATE_RDSTLS:
1037  nego_attempt_rdstls(nego);
1038  break;
1039  case NEGO_STATE_EXT:
1040  nego_attempt_ext(nego);
1041  break;
1042  case NEGO_STATE_NLA:
1043  nego_attempt_nla(nego);
1044  break;
1045  case NEGO_STATE_TLS:
1046  nego_attempt_tls(nego);
1047  break;
1048  case NEGO_STATE_RDP:
1049  nego_attempt_rdp(nego);
1050  break;
1051  default:
1052  WLog_ERR(TAG, "invalid negotiation state for sending");
1053  break;
1054  }
1055 }
1056 
1067 BOOL nego_send_negotiation_request(rdpNego* nego)
1068 {
1069  BOOL rc = FALSE;
1070  wStream* s = NULL;
1071  size_t length = 0;
1072  size_t bm = 0;
1073  size_t em = 0;
1074  BYTE flags = 0;
1075  size_t cookie_length = 0;
1076  s = Stream_New(NULL, 512);
1077 
1078  WINPR_ASSERT(nego);
1079  if (!s)
1080  {
1081  WLog_ERR(TAG, "Stream_New failed!");
1082  return FALSE;
1083  }
1084 
1085  length = TPDU_CONNECTION_REQUEST_LENGTH;
1086  bm = Stream_GetPosition(s);
1087  Stream_Seek(s, length);
1088 
1089  if (nego->RoutingToken)
1090  {
1091  Stream_Write(s, nego->RoutingToken, nego->RoutingTokenLength);
1092 
1093  /* Ensure Routing Token is correctly terminated - may already be present in string */
1094 
1095  if ((nego->RoutingTokenLength > 2) &&
1096  (nego->RoutingToken[nego->RoutingTokenLength - 2] == 0x0D) &&
1097  (nego->RoutingToken[nego->RoutingTokenLength - 1] == 0x0A))
1098  {
1099  WLog_DBG(TAG, "Routing token looks correctly terminated - use verbatim");
1100  length += nego->RoutingTokenLength;
1101  }
1102  else
1103  {
1104  WLog_DBG(TAG, "Adding terminating CRLF to routing token");
1105  Stream_Write_UINT8(s, 0x0D); /* CR */
1106  Stream_Write_UINT8(s, 0x0A); /* LF */
1107  length += nego->RoutingTokenLength + 2;
1108  }
1109  }
1110  else if (nego->cookie)
1111  {
1112  cookie_length = strlen(nego->cookie);
1113 
1114  if (cookie_length > nego->CookieMaxLength)
1115  cookie_length = nego->CookieMaxLength;
1116 
1117  Stream_Write(s, "Cookie: mstshash=", 17);
1118  Stream_Write(s, (BYTE*)nego->cookie, cookie_length);
1119  Stream_Write_UINT8(s, 0x0D); /* CR */
1120  Stream_Write_UINT8(s, 0x0A); /* LF */
1121  length += cookie_length + 19;
1122  }
1123 
1124  {
1125  char buffer[64] = { 0 };
1126  WLog_DBG(TAG, "RequestedProtocols: %s",
1127  nego_protocol_to_str(nego->RequestedProtocols, buffer, sizeof(buffer)));
1128  }
1129 
1130  if ((nego->RequestedProtocols > PROTOCOL_RDP) || (nego->sendNegoData))
1131  {
1132  /* RDP_NEG_DATA must be present for TLS and NLA */
1133  if (nego->RestrictedAdminModeRequired)
1134  flags |= RESTRICTED_ADMIN_MODE_REQUIRED;
1135 
1136  if (nego->RemoteCredsGuardRequired)
1137  flags |= REDIRECTED_AUTHENTICATION_MODE_REQUIRED;
1138 
1139  Stream_Write_UINT8(s, TYPE_RDP_NEG_REQ);
1140  Stream_Write_UINT8(s, flags);
1141  Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
1142  Stream_Write_UINT32(s, nego->RequestedProtocols); /* requestedProtocols */
1143  length += 8;
1144  }
1145 
1146  if (length > UINT16_MAX)
1147  goto fail;
1148 
1149  em = Stream_GetPosition(s);
1150  Stream_SetPosition(s, bm);
1151  if (!tpkt_write_header(s, (UINT16)length))
1152  goto fail;
1153  if (!tpdu_write_connection_request(s, (UINT16)length - 5))
1154  goto fail;
1155  Stream_SetPosition(s, em);
1156  Stream_SealLength(s);
1157  rc = (transport_write(nego->transport, s) >= 0);
1158 fail:
1159  Stream_Free(s, TRUE);
1160  return rc;
1161 }
1162 
1163 static BOOL nego_process_correlation_info(rdpNego* nego, wStream* s)
1164 {
1165  UINT8 type = 0;
1166  UINT8 flags = 0;
1167  UINT16 length = 0;
1168  BYTE correlationId[16] = { 0 };
1169 
1170  if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
1171  {
1172  WLog_ERR(TAG, "RDP_NEG_REQ::flags CORRELATION_INFO_PRESENT but data is missing");
1173  return FALSE;
1174  }
1175 
1176  Stream_Read_UINT8(s, type);
1177  if (type != TYPE_RDP_CORRELATION_INFO)
1178  {
1179  WLog_ERR(TAG, "(RDP_NEG_CORRELATION_INFO::type != TYPE_RDP_CORRELATION_INFO");
1180  return FALSE;
1181  }
1182  Stream_Read_UINT8(s, flags);
1183  if (flags != 0)
1184  {
1185  WLog_ERR(TAG, "(RDP_NEG_CORRELATION_INFO::flags != 0");
1186  return FALSE;
1187  }
1188  Stream_Read_UINT16(s, length);
1189  if (length != 36)
1190  {
1191  WLog_ERR(TAG, "(RDP_NEG_CORRELATION_INFO::length != 36");
1192  return FALSE;
1193  }
1194 
1195  Stream_Read(s, correlationId, sizeof(correlationId));
1196  if ((correlationId[0] == 0x00) || (correlationId[0] == 0xF4))
1197  {
1198  WLog_ERR(TAG, "(RDP_NEG_CORRELATION_INFO::correlationId[0] has invalid value 0x%02" PRIx8,
1199  correlationId[0]);
1200  return FALSE;
1201  }
1202  for (size_t x = 0; x < ARRAYSIZE(correlationId); x++)
1203  {
1204  if (correlationId[x] == 0x0D)
1205  {
1206  WLog_ERR(TAG,
1207  "(RDP_NEG_CORRELATION_INFO::correlationId[%" PRIuz
1208  "] has invalid value 0x%02" PRIx8,
1209  x, correlationId[x]);
1210  return FALSE;
1211  }
1212  }
1213  Stream_Seek(s, 16); /* skip reserved bytes */
1214 
1215  WLog_INFO(TAG,
1216  "RDP_NEG_CORRELATION_INFO::correlationId = { %02" PRIx8 ", %02" PRIx8 ", %02" PRIx8
1217  ", %02" PRIx8 ", %02" PRIx8 ", %02" PRIx8 ", %02" PRIx8 ", %02" PRIx8 ", %02" PRIx8
1218  ", %02" PRIx8 ", %02" PRIx8 ", %02" PRIx8 ", %02" PRIx8 ", %02" PRIx8 ", %02" PRIx8
1219  ", %02" PRIx8 " }",
1220  correlationId[0], correlationId[1], correlationId[2], correlationId[3],
1221  correlationId[4], correlationId[5], correlationId[6], correlationId[7],
1222  correlationId[8], correlationId[9], correlationId[10], correlationId[11],
1223  correlationId[12], correlationId[13], correlationId[14], correlationId[15]);
1224  return TRUE;
1225 }
1226 
1227 BOOL nego_process_negotiation_request(rdpNego* nego, wStream* s)
1228 {
1229  BYTE flags = 0;
1230  UINT16 length = 0;
1231 
1232  WINPR_ASSERT(nego);
1233  WINPR_ASSERT(s);
1234 
1235  if (!Stream_CheckAndLogRequiredLength(TAG, s, 7))
1236  return FALSE;
1237  Stream_Read_UINT8(s, flags);
1238  if ((flags & ~(RESTRICTED_ADMIN_MODE_REQUIRED | REDIRECTED_AUTHENTICATION_MODE_REQUIRED |
1239  CORRELATION_INFO_PRESENT)) != 0)
1240  {
1241  WLog_ERR(TAG, "RDP_NEG_REQ::flags invalid value 0x%02" PRIx8, flags);
1242  return FALSE;
1243  }
1244  if (flags & RESTRICTED_ADMIN_MODE_REQUIRED)
1245  WLog_INFO(TAG, "RDP_NEG_REQ::flags RESTRICTED_ADMIN_MODE_REQUIRED");
1246 
1247  if (flags & REDIRECTED_AUTHENTICATION_MODE_REQUIRED)
1248  {
1249  if (!nego->RemoteCredsGuardSupported)
1250  {
1251  WLog_ERR(TAG,
1252  "RDP_NEG_REQ::flags REDIRECTED_AUTHENTICATION_MODE_REQUIRED but disabled");
1253  return FALSE;
1254  }
1255  else
1256  {
1257  WLog_INFO(TAG, "RDP_NEG_REQ::flags REDIRECTED_AUTHENTICATION_MODE_REQUIRED");
1258  }
1259  nego->RemoteCredsGuardActive = TRUE;
1260  }
1261 
1262  Stream_Read_UINT16(s, length);
1263  if (length != 8)
1264  {
1265  WLog_ERR(TAG, "RDP_NEG_REQ::length != 8");
1266  return FALSE;
1267  }
1268  Stream_Read_UINT32(s, nego->RequestedProtocols);
1269 
1270  if (flags & CORRELATION_INFO_PRESENT)
1271  {
1272  if (!nego_process_correlation_info(nego, s))
1273  return FALSE;
1274  }
1275 
1276  {
1277  char buffer[64] = { 0 };
1278  WLog_DBG(TAG, "RDP_NEG_REQ: RequestedProtocol: %s",
1279  nego_protocol_to_str(nego->RequestedProtocols, buffer, sizeof(buffer)));
1280  }
1281  nego_set_state(nego, NEGO_STATE_FINAL);
1282  return TRUE;
1283 }
1284 
1285 static const char* nego_rdp_neg_rsp_flags_str(UINT32 flags)
1286 {
1287  static char buffer[1024] = { 0 };
1288 
1289  (void)_snprintf(buffer, ARRAYSIZE(buffer), "[0x%02" PRIx32 "] ", flags);
1290  if (flags & EXTENDED_CLIENT_DATA_SUPPORTED)
1291  winpr_str_append("EXTENDED_CLIENT_DATA_SUPPORTED", buffer, sizeof(buffer), "|");
1292  if (flags & DYNVC_GFX_PROTOCOL_SUPPORTED)
1293  winpr_str_append("DYNVC_GFX_PROTOCOL_SUPPORTED", buffer, sizeof(buffer), "|");
1294  if (flags & RDP_NEGRSP_RESERVED)
1295  winpr_str_append("RDP_NEGRSP_RESERVED", buffer, sizeof(buffer), "|");
1296  if (flags & RESTRICTED_ADMIN_MODE_SUPPORTED)
1297  winpr_str_append("RESTRICTED_ADMIN_MODE_SUPPORTED", buffer, sizeof(buffer), "|");
1298  if (flags & REDIRECTED_AUTHENTICATION_MODE_SUPPORTED)
1299  winpr_str_append("REDIRECTED_AUTHENTICATION_MODE_SUPPORTED", buffer, sizeof(buffer), "|");
1300  if ((flags &
1301  ~(EXTENDED_CLIENT_DATA_SUPPORTED | DYNVC_GFX_PROTOCOL_SUPPORTED | RDP_NEGRSP_RESERVED |
1302  RESTRICTED_ADMIN_MODE_SUPPORTED | REDIRECTED_AUTHENTICATION_MODE_SUPPORTED)))
1303  winpr_str_append("UNKNOWN", buffer, sizeof(buffer), "|");
1304 
1305  return buffer;
1306 }
1307 
1308 BOOL nego_process_negotiation_response(rdpNego* nego, wStream* s)
1309 {
1310  UINT16 length = 0;
1311 
1312  WINPR_ASSERT(nego);
1313  WINPR_ASSERT(s);
1314 
1315  if (!Stream_CheckAndLogRequiredLength(TAG, s, 7))
1316  {
1317  nego_set_state(nego, NEGO_STATE_FAIL);
1318  return FALSE;
1319  }
1320 
1321  Stream_Read_UINT8(s, nego->flags);
1322  WLog_DBG(TAG, "RDP_NEG_RSP::flags = { %s }", nego_rdp_neg_rsp_flags_str(nego->flags));
1323 
1324  Stream_Read_UINT16(s, length);
1325  if (length != 8)
1326  {
1327  WLog_ERR(TAG, "RDP_NEG_RSP::length != 8");
1328  nego_set_state(nego, NEGO_STATE_FAIL);
1329  return FALSE;
1330  }
1331  UINT32 SelectedProtocol = 0;
1332  Stream_Read_UINT32(s, SelectedProtocol);
1333 
1334  if (!nego_set_selected_protocol(nego, SelectedProtocol))
1335  return FALSE;
1336  return nego_set_state(nego, NEGO_STATE_FINAL);
1337 }
1338 
1347 BOOL nego_process_negotiation_failure(rdpNego* nego, wStream* s)
1348 {
1349  BYTE flags = 0;
1350  UINT16 length = 0;
1351  UINT32 failureCode = 0;
1352 
1353  WINPR_ASSERT(nego);
1354  WINPR_ASSERT(s);
1355 
1356  WLog_DBG(TAG, "RDP_NEG_FAILURE");
1357  if (!Stream_CheckAndLogRequiredLength(TAG, s, 7))
1358  return FALSE;
1359 
1360  Stream_Read_UINT8(s, flags);
1361  if (flags != 0)
1362  {
1363  WLog_WARN(TAG, "RDP_NEG_FAILURE::flags = 0x%02" PRIx8, flags);
1364  return FALSE;
1365  }
1366  Stream_Read_UINT16(s, length);
1367  if (length != 8)
1368  {
1369  WLog_ERR(TAG, "RDP_NEG_FAILURE::length != 8");
1370  return FALSE;
1371  }
1372  Stream_Read_UINT32(s, failureCode);
1373 
1374  switch (failureCode)
1375  {
1376  case SSL_REQUIRED_BY_SERVER:
1377  WLog_WARN(TAG, "Error: SSL_REQUIRED_BY_SERVER");
1378  break;
1379 
1380  case SSL_NOT_ALLOWED_BY_SERVER:
1381  WLog_WARN(TAG, "Error: SSL_NOT_ALLOWED_BY_SERVER");
1382  nego->sendNegoData = TRUE;
1383  break;
1384 
1385  case SSL_CERT_NOT_ON_SERVER:
1386  WLog_ERR(TAG, "Error: SSL_CERT_NOT_ON_SERVER");
1387  nego->sendNegoData = TRUE;
1388  break;
1389 
1390  case INCONSISTENT_FLAGS:
1391  WLog_ERR(TAG, "Error: INCONSISTENT_FLAGS");
1392  break;
1393 
1394  case HYBRID_REQUIRED_BY_SERVER:
1395  WLog_WARN(TAG, "Error: HYBRID_REQUIRED_BY_SERVER");
1396  break;
1397 
1398  default:
1399  WLog_ERR(TAG, "Error: Unknown protocol security error %" PRIu32 "", failureCode);
1400  break;
1401  }
1402 
1403  nego_set_state(nego, NEGO_STATE_FAIL);
1404  return TRUE;
1405 }
1406 
1412 BOOL nego_send_negotiation_response(rdpNego* nego)
1413 {
1414  UINT16 length = 0;
1415  size_t bm = 0;
1416  size_t em = 0;
1417  BOOL status = 0;
1418  wStream* s = NULL;
1419  BYTE flags = 0;
1420  rdpContext* context = NULL;
1421  rdpSettings* settings = NULL;
1422 
1423  WINPR_ASSERT(nego);
1424  context = transport_get_context(nego->transport);
1425  WINPR_ASSERT(context);
1426 
1427  settings = context->settings;
1428  WINPR_ASSERT(settings);
1429 
1430  s = Stream_New(NULL, 512);
1431 
1432  if (!s)
1433  {
1434  WLog_ERR(TAG, "Stream_New failed!");
1435  return FALSE;
1436  }
1437 
1438  length = TPDU_CONNECTION_CONFIRM_LENGTH;
1439  bm = Stream_GetPosition(s);
1440  Stream_Seek(s, length);
1441 
1442  if (nego->SelectedProtocol & PROTOCOL_FAILED_NEGO)
1443  {
1444  UINT32 errorCode = (nego->SelectedProtocol & ~PROTOCOL_FAILED_NEGO);
1445  flags = 0;
1446  Stream_Write_UINT8(s, TYPE_RDP_NEG_FAILURE);
1447  Stream_Write_UINT8(s, flags); /* flags */
1448  Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
1449  Stream_Write_UINT32(s, errorCode);
1450  length += 8;
1451  }
1452  else
1453  {
1454  flags = EXTENDED_CLIENT_DATA_SUPPORTED;
1455 
1456  if (freerdp_settings_get_bool(settings, FreeRDP_SupportGraphicsPipeline))
1457  flags |= DYNVC_GFX_PROTOCOL_SUPPORTED;
1458 
1459  if (freerdp_settings_get_bool(settings, FreeRDP_RestrictedAdminModeRequired))
1460  flags |= RESTRICTED_ADMIN_MODE_SUPPORTED;
1461 
1462  if (nego->RemoteCredsGuardSupported)
1463  flags |= REDIRECTED_AUTHENTICATION_MODE_SUPPORTED;
1464 
1465  /* RDP_NEG_DATA must be present for TLS, NLA, RDP and RDSTLS */
1466  Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP);
1467  Stream_Write_UINT8(s, flags); /* flags */
1468  Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
1469  Stream_Write_UINT32(s, nego->SelectedProtocol); /* selectedProtocol */
1470  length += 8;
1471  }
1472 
1473  em = Stream_GetPosition(s);
1474  Stream_SetPosition(s, bm);
1475  status = tpkt_write_header(s, length);
1476  if (status)
1477  {
1478  tpdu_write_connection_confirm(s, length - 5);
1479  Stream_SetPosition(s, em);
1480  Stream_SealLength(s);
1481 
1482  status = (transport_write(nego->transport, s) >= 0);
1483  }
1484  Stream_Free(s, TRUE);
1485 
1486  if (status)
1487  {
1488  /* update settings with negotiated protocol security */
1489  if (!freerdp_settings_set_uint32(settings, FreeRDP_RequestedProtocols,
1490  nego->RequestedProtocols))
1491  return FALSE;
1492  if (!freerdp_settings_set_uint32(settings, FreeRDP_SelectedProtocol,
1493  nego->SelectedProtocol))
1494  return FALSE;
1495 
1496  switch (nego->SelectedProtocol)
1497  {
1498  case PROTOCOL_RDP:
1499  if (!freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, FALSE))
1500  return FALSE;
1501  if (!freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, FALSE))
1502  return FALSE;
1503  if (!freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, TRUE))
1504  return FALSE;
1505  if (!freerdp_settings_set_bool(settings, FreeRDP_UseRdpSecurityLayer, TRUE))
1506  return FALSE;
1507 
1508  if (freerdp_settings_get_uint32(settings, FreeRDP_EncryptionLevel) ==
1509  ENCRYPTION_LEVEL_NONE)
1510  {
1515  if (!freerdp_settings_set_uint32(settings, FreeRDP_EncryptionLevel,
1516  ENCRYPTION_LEVEL_CLIENT_COMPATIBLE))
1517  return FALSE;
1518  }
1519 
1520  if (freerdp_settings_get_bool(settings, FreeRDP_LocalConnection))
1521  {
1528  WLog_INFO(TAG,
1529  "Turning off encryption for local peer with standard rdp security");
1530  if (!freerdp_settings_set_bool(settings, FreeRDP_UseRdpSecurityLayer, FALSE))
1531  return FALSE;
1532  if (!freerdp_settings_set_uint32(settings, FreeRDP_EncryptionLevel,
1533  ENCRYPTION_LEVEL_NONE))
1534  return FALSE;
1535  }
1536  else if (!freerdp_settings_get_pointer(settings, FreeRDP_RdpServerRsaKey))
1537  {
1538  WLog_ERR(TAG, "Missing server certificate");
1539  return FALSE;
1540  }
1541  break;
1542  case PROTOCOL_SSL:
1543  if (!freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, TRUE))
1544  return FALSE;
1545  if (!freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, FALSE))
1546  return FALSE;
1547  if (!freerdp_settings_set_bool(settings, FreeRDP_RdstlsSecurity, FALSE))
1548  return FALSE;
1549  if (!freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, FALSE))
1550  return FALSE;
1551  if (!freerdp_settings_set_bool(settings, FreeRDP_UseRdpSecurityLayer, FALSE))
1552  return FALSE;
1553 
1554  if (!freerdp_settings_set_uint32(settings, FreeRDP_EncryptionLevel,
1555  ENCRYPTION_LEVEL_NONE))
1556  return FALSE;
1557  break;
1558  case PROTOCOL_HYBRID:
1559  if (!freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, TRUE))
1560  return FALSE;
1561  if (!freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, TRUE))
1562  return FALSE;
1563  if (!freerdp_settings_set_bool(settings, FreeRDP_RdstlsSecurity, FALSE))
1564  return FALSE;
1565  if (!freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, FALSE))
1566  return FALSE;
1567  if (!freerdp_settings_set_bool(settings, FreeRDP_UseRdpSecurityLayer, FALSE))
1568  return FALSE;
1569 
1570  if (!freerdp_settings_set_uint32(settings, FreeRDP_EncryptionLevel,
1571  ENCRYPTION_LEVEL_NONE))
1572  return FALSE;
1573  break;
1574  case PROTOCOL_RDSTLS:
1575  if (!freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, TRUE))
1576  return FALSE;
1577  if (!freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, FALSE))
1578  return FALSE;
1579  if (!freerdp_settings_set_bool(settings, FreeRDP_RdstlsSecurity, TRUE))
1580  return FALSE;
1581  if (!freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, FALSE))
1582  return FALSE;
1583  if (!freerdp_settings_set_bool(settings, FreeRDP_UseRdpSecurityLayer, FALSE))
1584  return FALSE;
1585 
1586  if (!freerdp_settings_set_uint32(settings, FreeRDP_EncryptionLevel,
1587  ENCRYPTION_LEVEL_NONE))
1588  return FALSE;
1589  break;
1590  default:
1591  break;
1592  }
1593  }
1594 
1595  return status;
1596 }
1597 
1603 void nego_init(rdpNego* nego)
1604 {
1605  WINPR_ASSERT(nego);
1606  nego_set_state(nego, NEGO_STATE_INITIAL);
1607  nego->RequestedProtocols = PROTOCOL_RDP;
1608  nego->CookieMaxLength = DEFAULT_COOKIE_MAX_LENGTH;
1609  nego->sendNegoData = FALSE;
1610  nego->flags = 0;
1611 }
1612 
1621 rdpNego* nego_new(rdpTransport* transport)
1622 {
1623  rdpNego* nego = (rdpNego*)calloc(1, sizeof(rdpNego));
1624 
1625  if (!nego)
1626  return NULL;
1627 
1628  nego->transport = transport;
1629  nego_init(nego);
1630  return nego;
1631 }
1632 
1638 void nego_free(rdpNego* nego)
1639 {
1640  if (nego)
1641  {
1642  free(nego->RoutingToken);
1643  free(nego->cookie);
1644  free(nego);
1645  }
1646 }
1647 
1657 BOOL nego_set_target(rdpNego* nego, const char* hostname, UINT16 port)
1658 {
1659  if (!nego || !hostname)
1660  return FALSE;
1661 
1662  nego->hostname = hostname;
1663  nego->port = port;
1664  return TRUE;
1665 }
1666 
1674 void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer)
1675 {
1676  WLog_DBG(TAG, "Enabling security layer negotiation: %s",
1677  NegotiateSecurityLayer ? "TRUE" : "FALSE");
1678  nego->NegotiateSecurityLayer = NegotiateSecurityLayer;
1679 }
1680 
1688 void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdminModeRequired)
1689 {
1690  WLog_DBG(TAG, "Enabling restricted admin mode: %s",
1691  RestrictedAdminModeRequired ? "TRUE" : "FALSE");
1692  nego->RestrictedAdminModeRequired = RestrictedAdminModeRequired;
1693 }
1694 
1695 void nego_set_RCG_required(rdpNego* nego, BOOL enabled)
1696 {
1697  WINPR_ASSERT(nego);
1698 
1699  WLog_DBG(TAG, "Enabling remoteCredentialGuards: %s", enabled ? "TRUE" : "FALSE");
1700  nego->RemoteCredsGuardRequired = enabled;
1701 }
1702 
1703 void nego_set_RCG_supported(rdpNego* nego, BOOL enabled)
1704 {
1705  WINPR_ASSERT(nego);
1706 
1707  nego->RemoteCredsGuardSupported = enabled;
1708 }
1709 
1710 BOOL nego_get_remoteCredentialGuard(rdpNego* nego)
1711 {
1712  WINPR_ASSERT(nego);
1713 
1714  return nego->RemoteCredsGuardActive;
1715 }
1716 
1717 void nego_set_childsession_enabled(rdpNego* nego, BOOL ChildSessionEnabled)
1718 {
1719  WINPR_ASSERT(nego);
1720  nego->ConnectChildSession = ChildSessionEnabled;
1721 }
1722 
1723 void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled)
1724 {
1725  nego->GatewayEnabled = GatewayEnabled;
1726 }
1727 
1728 void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal)
1729 {
1730  nego->GatewayBypassLocal = GatewayBypassLocal;
1731 }
1732 
1739 void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp)
1740 {
1741  WLog_DBG(TAG, "Enabling RDP security: %s", enable_rdp ? "TRUE" : "FALSE");
1742  nego->EnabledProtocols[PROTOCOL_RDP] = enable_rdp;
1743 }
1744 
1751 void nego_enable_tls(rdpNego* nego, BOOL enable_tls)
1752 {
1753  WLog_DBG(TAG, "Enabling TLS security: %s", enable_tls ? "TRUE" : "FALSE");
1754  nego->EnabledProtocols[PROTOCOL_SSL] = enable_tls;
1755 }
1756 
1764 void nego_enable_nla(rdpNego* nego, BOOL enable_nla)
1765 {
1766  WLog_DBG(TAG, "Enabling NLA security: %s", enable_nla ? "TRUE" : "FALSE");
1767  nego->EnabledProtocols[PROTOCOL_HYBRID] = enable_nla;
1768 }
1769 
1777 void nego_enable_rdstls(rdpNego* nego, BOOL enable_rdstls)
1778 {
1779  WLog_DBG(TAG, "Enabling RDSTLS security: %s", enable_rdstls ? "TRUE" : "FALSE");
1780  nego->EnabledProtocols[PROTOCOL_RDSTLS] = enable_rdstls;
1781 }
1782 
1790 void nego_enable_ext(rdpNego* nego, BOOL enable_ext)
1791 {
1792  WLog_DBG(TAG, "Enabling NLA extended security: %s", enable_ext ? "TRUE" : "FALSE");
1793  nego->EnabledProtocols[PROTOCOL_HYBRID_EX] = enable_ext;
1794 }
1795 
1803 void nego_enable_aad(rdpNego* nego, BOOL enable_aad)
1804 {
1805  if (aad_is_supported())
1806  {
1807  WLog_DBG(TAG, "Enabling RDS AAD security: %s", enable_aad ? "TRUE" : "FALSE");
1808  nego->EnabledProtocols[PROTOCOL_RDSAAD] = enable_aad;
1809  }
1810  else
1811  {
1812  WLog_WARN(TAG, "This build does not support AAD security, disabling.");
1813  }
1814 }
1815 
1825 BOOL nego_set_routing_token(rdpNego* nego, const void* RoutingToken, DWORD RoutingTokenLength)
1826 {
1827  if (RoutingTokenLength == 0)
1828  return FALSE;
1829 
1830  free(nego->RoutingToken);
1831  nego->RoutingTokenLength = RoutingTokenLength;
1832  nego->RoutingToken = (BYTE*)malloc(nego->RoutingTokenLength);
1833 
1834  if (!nego->RoutingToken)
1835  return FALSE;
1836 
1837  CopyMemory(nego->RoutingToken, RoutingToken, nego->RoutingTokenLength);
1838  return TRUE;
1839 }
1840 
1849 BOOL nego_set_cookie(rdpNego* nego, const char* cookie)
1850 {
1851  if (nego->cookie)
1852  {
1853  free(nego->cookie);
1854  nego->cookie = NULL;
1855  }
1856 
1857  if (!cookie)
1858  return TRUE;
1859 
1860  nego->cookie = _strdup(cookie);
1861 
1862  if (!nego->cookie)
1863  return FALSE;
1864 
1865  return TRUE;
1866 }
1867 
1874 void nego_set_cookie_max_length(rdpNego* nego, UINT32 CookieMaxLength)
1875 {
1876  nego->CookieMaxLength = CookieMaxLength;
1877 }
1878 
1885 void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL SendPreconnectionPdu)
1886 {
1887  nego->SendPreconnectionPdu = SendPreconnectionPdu;
1888 }
1889 
1896 void nego_set_preconnection_id(rdpNego* nego, UINT32 PreconnectionId)
1897 {
1898  nego->PreconnectionId = PreconnectionId;
1899 }
1900 
1907 void nego_set_preconnection_blob(rdpNego* nego, const char* PreconnectionBlob)
1908 {
1909  nego->PreconnectionBlob = PreconnectionBlob;
1910 }
1911 
1912 UINT32 nego_get_selected_protocol(rdpNego* nego)
1913 {
1914  if (!nego)
1915  return 0;
1916 
1917  return nego->SelectedProtocol;
1918 }
1919 
1920 BOOL nego_set_selected_protocol(rdpNego* nego, UINT32 SelectedProtocol)
1921 {
1922  WINPR_ASSERT(nego);
1923  nego->SelectedProtocol = SelectedProtocol;
1924  return TRUE;
1925 }
1926 
1927 UINT32 nego_get_requested_protocols(rdpNego* nego)
1928 {
1929  if (!nego)
1930  return 0;
1931 
1932  return nego->RequestedProtocols;
1933 }
1934 
1935 BOOL nego_set_requested_protocols(rdpNego* nego, UINT32 RequestedProtocols)
1936 {
1937  if (!nego)
1938  return FALSE;
1939 
1940  nego->RequestedProtocols = RequestedProtocols;
1941  return TRUE;
1942 }
1943 
1944 NEGO_STATE nego_get_state(rdpNego* nego)
1945 {
1946  if (!nego)
1947  return NEGO_STATE_FAIL;
1948 
1949  return nego->state;
1950 }
1951 
1952 BOOL nego_set_state(rdpNego* nego, NEGO_STATE state)
1953 {
1954  if (!nego)
1955  return FALSE;
1956 
1957  nego->state = state;
1958  return TRUE;
1959 }
1960 
1961 SEC_WINNT_AUTH_IDENTITY* nego_get_identity(rdpNego* nego)
1962 {
1963  rdpNla* nla = NULL;
1964  if (!nego)
1965  return NULL;
1966 
1967  nla = transport_get_nla(nego->transport);
1968  return nla_get_identity(nla);
1969 }
1970 
1971 void nego_free_nla(rdpNego* nego)
1972 {
1973  if (!nego || !nego->transport)
1974  return;
1975 
1976  transport_set_nla(nego->transport, NULL);
1977 }
1978 
1979 const BYTE* nego_get_routing_token(rdpNego* nego, DWORD* RoutingTokenLength)
1980 {
1981  if (!nego)
1982  return NULL;
1983  if (RoutingTokenLength)
1984  *RoutingTokenLength = nego->RoutingTokenLength;
1985  return nego->RoutingToken;
1986 }
1987 
1988 const char* nego_protocol_to_str(UINT32 protocol, char* buffer, size_t size)
1989 {
1990  const UINT32 mask = ~(PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_RDSTLS | PROTOCOL_HYBRID_EX |
1991  PROTOCOL_RDSAAD | PROTOCOL_FAILED_NEGO);
1992  char str[48] = { 0 };
1993 
1994  if (protocol & PROTOCOL_SSL)
1995  (void)winpr_str_append("SSL", str, sizeof(str), "|");
1996  if (protocol & PROTOCOL_HYBRID)
1997  (void)winpr_str_append("HYBRID", str, sizeof(str), "|");
1998  if (protocol & PROTOCOL_RDSTLS)
1999  (void)winpr_str_append("RDSTLS", str, sizeof(str), "|");
2000  if (protocol & PROTOCOL_HYBRID_EX)
2001  (void)winpr_str_append("HYBRID_EX", str, sizeof(str), "|");
2002  if (protocol & PROTOCOL_RDSAAD)
2003  (void)winpr_str_append("RDSAAD", str, sizeof(str), "|");
2004  if (protocol & PROTOCOL_FAILED_NEGO)
2005  (void)winpr_str_append("NEGO FAILED", str, sizeof(str), "|");
2006 
2007  if (protocol == PROTOCOL_RDP)
2008  (void)winpr_str_append("RDP", str, sizeof(str), "");
2009  else if ((protocol & mask) != 0)
2010  (void)winpr_str_append("UNKNOWN", str, sizeof(str), "|");
2011 
2012  (void)_snprintf(buffer, size, "[%s][0x%08" PRIx32 "]", str, protocol);
2013  return buffer;
2014 }
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_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer 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.