FreeRDP
rdp.c
1 
21 #include <freerdp/config.h>
22 
23 #include "settings.h"
24 
25 #include <winpr/crt.h>
26 #include <winpr/string.h>
27 #include <winpr/synch.h>
28 #include <winpr/assert.h>
29 #include <winpr/cast.h>
30 #include <winpr/json.h>
31 
32 #include "rdp.h"
33 
34 #include "state.h"
35 #include "info.h"
36 #include "utils.h"
37 #include "mcs.h"
38 #include "redirection.h"
39 
40 #include <freerdp/codec/bulk.h>
41 #include <freerdp/crypto/per.h>
42 #include <freerdp/log.h>
43 #include <freerdp/buildflags.h>
44 
45 #define RDP_TAG FREERDP_TAG("core.rdp")
46 
47 typedef struct
48 {
49  const char* file;
50  const char* fkt;
51  size_t line;
52  DWORD level;
53 } log_line_t;
54 
55 static const char* DATA_PDU_TYPE_STRINGS[80] = {
56  "?",
57  "?", /* 0x00 - 0x01 */
58  "Update", /* 0x02 */
59  "?",
60  "?",
61  "?",
62  "?",
63  "?",
64  "?",
65  "?",
66  "?", /* 0x03 - 0x0A */
67  "?",
68  "?",
69  "?",
70  "?",
71  "?",
72  "?",
73  "?",
74  "?",
75  "?", /* 0x0B - 0x13 */
76  "Control", /* 0x14 */
77  "?",
78  "?",
79  "?",
80  "?",
81  "?",
82  "?", /* 0x15 - 0x1A */
83  "Pointer", /* 0x1B */
84  "Input", /* 0x1C */
85  "?",
86  "?", /* 0x1D - 0x1E */
87  "Synchronize", /* 0x1F */
88  "?", /* 0x20 */
89  "Refresh Rect", /* 0x21 */
90  "Play Sound", /* 0x22 */
91  "Suppress Output", /* 0x23 */
92  "Shutdown Request", /* 0x24 */
93  "Shutdown Denied", /* 0x25 */
94  "Save Session Info", /* 0x26 */
95  "Font List", /* 0x27 */
96  "Font Map", /* 0x28 */
97  "Set Keyboard Indicators", /* 0x29 */
98  "?", /* 0x2A */
99  "Bitmap Cache Persistent List", /* 0x2B */
100  "Bitmap Cache Error", /* 0x2C */
101  "Set Keyboard IME Status", /* 0x2D */
102  "Offscreen Cache Error", /* 0x2E */
103  "Set Error Info", /* 0x2F */
104  "Draw Nine Grid Error", /* 0x30 */
105  "Draw GDI+ Error", /* 0x31 */
106  "ARC Status", /* 0x32 */
107  "?",
108  "?",
109  "?", /* 0x33 - 0x35 */
110  "Status Info", /* 0x36 */
111  "Monitor Layout", /* 0x37 */
112  "FrameAcknowledge",
113  "?",
114  "?", /* 0x38 - 0x40 */
115  "?",
116  "?",
117  "?",
118  "?",
119  "?",
120  "?" /* 0x41 - 0x46 */
121 };
122 
123 #define rdp_check_monitor_layout_pdu_state(rdp, expected) \
124  rdp_check_monitor_layout_pdu_state_(rdp, expected, __FILE__, __func__, __LINE__)
125 
126 static BOOL rdp_check_monitor_layout_pdu_state_(const rdpRdp* rdp, BOOL expected, const char* file,
127  const char* fkt, size_t line)
128 {
129  WINPR_ASSERT(rdp);
130  if (expected != rdp->monitor_layout_pdu)
131  {
132  const DWORD log_level = WLOG_ERROR;
133  if (WLog_IsLevelActive(rdp->log, log_level))
134  {
135  WLog_PrintMessage(rdp->log, WLOG_MESSAGE_TEXT, log_level, line, file, fkt,
136  "Expected rdp->monitor_layout_pdu == %s",
137  expected ? "TRUE" : "FALSE");
138  }
139  return FALSE;
140  }
141  return TRUE;
142 }
143 
144 #define rdp_set_monitor_layout_pdu_state(rdp, expected) \
145  rdp_set_monitor_layout_pdu_state_(rdp, expected, __FILE__, __func__, __LINE__)
146 static BOOL rdp_set_monitor_layout_pdu_state_(rdpRdp* rdp, BOOL value, const char* file,
147  const char* fkt, size_t line)
148 {
149 
150  WINPR_ASSERT(rdp);
151  if (value && (value == rdp->monitor_layout_pdu))
152  {
153  const DWORD log_level = WLOG_WARN;
154  if (WLog_IsLevelActive(rdp->log, log_level))
155  {
156  WLog_PrintMessage(rdp->log, WLOG_MESSAGE_TEXT, log_level, line, file, fkt,
157  "rdp->monitor_layout_pdu == %s, expected FALSE",
158  value ? "TRUE" : "FALSE");
159  }
160  return FALSE;
161  }
162  rdp->monitor_layout_pdu = value;
163  return TRUE;
164 }
165 
166 const char* data_pdu_type_to_string(UINT8 type)
167 {
168  if (type >= ARRAYSIZE(DATA_PDU_TYPE_STRINGS))
169  return "???";
170  return DATA_PDU_TYPE_STRINGS[type];
171 }
172 
173 static BOOL rdp_read_flow_control_pdu(rdpRdp* rdp, wStream* s, UINT16* type, UINT16* channel_id);
174 static BOOL rdp_write_share_control_header(rdpRdp* rdp, wStream* s, size_t length, UINT16 type,
175  UINT16 channel_id);
176 static BOOL rdp_write_share_data_header(rdpRdp* rdp, wStream* s, size_t length, BYTE type,
177  UINT32 share_id);
178 
189 BOOL rdp_read_security_header(rdpRdp* rdp, wStream* s, UINT16* flags, UINT16* length)
190 {
191  char buffer[256] = { 0 };
192  WINPR_ASSERT(s);
193  WINPR_ASSERT(flags);
194  WINPR_ASSERT(rdp);
195 
196  /* Basic Security Header */
197  if ((length && (*length < 4)))
198  {
199  WLog_Print(rdp->log, WLOG_WARN,
200  "invalid security header length, have %" PRIu16 ", must be >= 4", *length);
201  return FALSE;
202  }
203  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
204  return FALSE;
205 
206  Stream_Read_UINT16(s, *flags); /* flags */
207  Stream_Seek(s, 2); /* flagsHi (unused) */
208  WLog_Print(rdp->log, WLOG_TRACE, "%s",
209  rdp_security_flag_string(*flags, buffer, sizeof(buffer)));
210  if (length)
211  *length -= 4;
212 
213  return TRUE;
214 }
215 
225 BOOL rdp_write_security_header(rdpRdp* rdp, wStream* s, UINT16 flags)
226 {
227  char buffer[256] = { 0 };
228  WINPR_ASSERT(s);
229  WINPR_ASSERT(rdp);
230 
231  if (!Stream_CheckAndLogRequiredCapacityWLog(rdp->log, (s), 4))
232  return FALSE;
233 
234  WLog_Print(rdp->log, WLOG_TRACE, "%s", rdp_security_flag_string(flags, buffer, sizeof(buffer)));
235  /* Basic Security Header */
236  Stream_Write_UINT16(s, flags); /* flags */
237  Stream_Write_UINT16(s, 0); /* flagsHi (unused) */
238  return TRUE;
239 }
240 
241 BOOL rdp_read_share_control_header(rdpRdp* rdp, wStream* s, UINT16* tpktLength,
242  UINT16* remainingLength, UINT16* type, UINT16* channel_id)
243 {
244  UINT16 len = 0;
245  UINT16 tmp = 0;
246 
247  WINPR_ASSERT(rdp);
248  WINPR_ASSERT(s);
249  WINPR_ASSERT(type);
250  WINPR_ASSERT(channel_id);
251 
252  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 2))
253  return FALSE;
254 
255  /* Share Control Header */
256  Stream_Read_UINT16(s, len); /* totalLength */
257 
258  /* If length is 0x8000 then we actually got a flow control PDU that we should ignore
259  http://msdn.microsoft.com/en-us/library/cc240576.aspx */
260  if (len == 0x8000)
261  {
262  if (!rdp_read_flow_control_pdu(rdp, s, type, channel_id))
263  return FALSE;
264  *channel_id = 0;
265  if (tpktLength)
266  *tpktLength = 8; /* Flow control PDU is 8 bytes */
267  if (remainingLength)
268  *remainingLength = 0;
269 
270  char buffer[128] = { 0 };
271  WLog_Print(rdp->log, WLOG_DEBUG,
272  "[Flow control PDU] type=%s, tpktLength=%" PRIuz ", remainingLength=%" PRIuz,
273  pdu_type_to_str(*type, buffer, sizeof(buffer)), tpktLength ? *tpktLength : 0,
274  remainingLength ? *remainingLength : 0);
275  return TRUE;
276  }
277 
278  if (len < 4U)
279  {
280  WLog_Print(rdp->log, WLOG_ERROR,
281  "Invalid share control header, length is %" PRIu16 ", must be >4", len);
282  return FALSE;
283  }
284 
285  if (tpktLength)
286  *tpktLength = len;
287 
288  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 2))
289  return FALSE;
290 
291  Stream_Read_UINT16(s, tmp); /* pduType */
292  *type = tmp & 0x0F; /* type is in the 4 least significant bits */
293 
294  size_t remLen = len - 4;
295  if (len > 5)
296  {
297  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 2))
298  return FALSE;
299 
300  Stream_Read_UINT16(s, *channel_id); /* pduSource */
301  remLen = len - 6;
302  }
303  else
304  *channel_id = 0; /* Windows XP can send such short DEACTIVATE_ALL PDUs. */
305 
306  char buffer[128] = { 0 };
307  WLog_Print(rdp->log, WLOG_DEBUG, "type=%s, tpktLength=%" PRIuz ", remainingLength=%" PRIuz,
308  pdu_type_to_str(*type, buffer, sizeof(buffer)), len, remLen);
309  if (remainingLength)
310  {
311  WINPR_ASSERT(remLen <= UINT16_MAX);
312  *remainingLength = (UINT16)remLen;
313  }
314  return Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, remLen);
315 }
316 
317 BOOL rdp_write_share_control_header(rdpRdp* rdp, wStream* s, size_t length, UINT16 type,
318  UINT16 channel_id)
319 {
320  WINPR_ASSERT(s);
321  WINPR_ASSERT(rdp);
322  if (length > UINT16_MAX)
323  return FALSE;
324 
325  if (length < RDP_PACKET_HEADER_MAX_LENGTH)
326  return FALSE;
327  if (!Stream_CheckAndLogRequiredCapacityWLog(rdp->log, (s), 6))
328  return FALSE;
329  length -= RDP_PACKET_HEADER_MAX_LENGTH;
330  /* Share Control Header */
331  Stream_Write_UINT16(s, WINPR_ASSERTING_INT_CAST(uint16_t, length)); /* totalLength */
332  Stream_Write_UINT16(s, WINPR_ASSERTING_INT_CAST(uint16_t, type | 0x10)); /* pduType */
333  Stream_Write_UINT16(s, WINPR_ASSERTING_INT_CAST(uint16_t, channel_id)); /* pduSource */
334  return TRUE;
335 }
336 
337 BOOL rdp_read_share_data_header(rdpRdp* rdp, wStream* s, UINT16* length, BYTE* type,
338  UINT32* shareId, BYTE* compressedType, UINT16* compressedLength)
339 {
340  WINPR_ASSERT(s);
341  WINPR_ASSERT(rdp);
342 
343  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 12))
344  return FALSE;
345 
346  /* Share Data Header */
347  Stream_Read_UINT32(s, *shareId); /* shareId (4 bytes) */
348  Stream_Seek_UINT8(s); /* pad1 (1 byte) */
349  Stream_Seek_UINT8(s); /* streamId (1 byte) */
350  Stream_Read_UINT16(s, *length); /* uncompressedLength (2 bytes) */
351  Stream_Read_UINT8(s, *type); /* pduType2, Data PDU Type (1 byte) */
352  Stream_Read_UINT8(s, *compressedType); /* compressedType (1 byte) */
353  Stream_Read_UINT16(s, *compressedLength); /* compressedLength (2 bytes) */
354  return TRUE;
355 }
356 
357 BOOL rdp_write_share_data_header(rdpRdp* rdp, wStream* s, size_t length, BYTE type, UINT32 share_id)
358 {
359  const size_t headerLen = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SHARE_CONTROL_HEADER_LENGTH +
360  RDP_SHARE_DATA_HEADER_LENGTH;
361 
362  WINPR_ASSERT(s);
363  WINPR_ASSERT(rdp);
364  if (length > UINT16_MAX)
365  return FALSE;
366 
367  if (length < headerLen)
368  return FALSE;
369  length -= headerLen;
370  if (!Stream_CheckAndLogRequiredCapacityWLog(rdp->log, (s), 12))
371  return FALSE;
372 
373  /* Share Data Header */
374  Stream_Write_UINT32(s, share_id); /* shareId (4 bytes) */
375  Stream_Write_UINT8(s, 0); /* pad1 (1 byte) */
376  Stream_Write_UINT8(s, STREAM_LOW); /* streamId (1 byte) */
377  Stream_Write_UINT16(
378  s, WINPR_ASSERTING_INT_CAST(uint16_t, length)); /* uncompressedLength (2 bytes) */
379  Stream_Write_UINT8(s, type); /* pduType2, Data PDU Type (1 byte) */
380  Stream_Write_UINT8(s, 0); /* compressedType (1 byte) */
381  Stream_Write_UINT16(s, 0); /* compressedLength (2 bytes) */
382  return TRUE;
383 }
384 
385 static BOOL rdp_security_stream_init(rdpRdp* rdp, wStream* s, BOOL sec_header)
386 {
387  WINPR_ASSERT(rdp);
388  WINPR_ASSERT(s);
389 
390  if (rdp->do_crypt)
391  {
392  if (!Stream_SafeSeek(s, 12))
393  return FALSE;
394 
395  if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
396  {
397  if (!Stream_SafeSeek(s, 4))
398  return FALSE;
399  }
400 
401  rdp->sec_flags |= SEC_ENCRYPT;
402 
403  if (rdp->do_secure_checksum)
404  rdp->sec_flags |= SEC_SECURE_CHECKSUM;
405  }
406  else if (rdp->sec_flags != 0 || sec_header)
407  {
408  if (!Stream_SafeSeek(s, 4))
409  return FALSE;
410  }
411 
412  return TRUE;
413 }
414 
415 wStream* rdp_send_stream_init(rdpRdp* rdp)
416 {
417  wStream* s = NULL;
418 
419  WINPR_ASSERT(rdp);
420  WINPR_ASSERT(rdp->transport);
421 
422  s = transport_send_stream_init(rdp->transport, 4096);
423 
424  if (!s)
425  return NULL;
426 
427  if (!Stream_SafeSeek(s, RDP_PACKET_HEADER_MAX_LENGTH))
428  goto fail;
429 
430  if (!rdp_security_stream_init(rdp, s, FALSE))
431  goto fail;
432 
433  return s;
434 fail:
435  Stream_Release(s);
436  return NULL;
437 }
438 
439 wStream* rdp_send_stream_pdu_init(rdpRdp* rdp)
440 {
441  wStream* s = rdp_send_stream_init(rdp);
442 
443  if (!s)
444  return NULL;
445 
446  if (!Stream_SafeSeek(s, RDP_SHARE_CONTROL_HEADER_LENGTH))
447  goto fail;
448 
449  return s;
450 fail:
451  Stream_Release(s);
452  return NULL;
453 }
454 
455 wStream* rdp_data_pdu_init(rdpRdp* rdp)
456 {
457  wStream* s = rdp_send_stream_pdu_init(rdp);
458 
459  if (!s)
460  return NULL;
461 
462  if (!Stream_SafeSeek(s, RDP_SHARE_DATA_HEADER_LENGTH))
463  goto fail;
464 
465  return s;
466 fail:
467  Stream_Release(s);
468  return NULL;
469 }
470 
471 BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo)
472 {
473  WINPR_ASSERT(rdp);
474 
475  rdp->errorInfo = errorInfo;
476 
477  if (rdp->errorInfo != ERRINFO_SUCCESS)
478  {
479  rdpContext* context = rdp->context;
480  WINPR_ASSERT(context);
481 
482  rdp_print_errinfo(rdp->errorInfo);
483 
484  if (context)
485  {
486  freerdp_set_last_error_log(context, MAKE_FREERDP_ERROR(ERRINFO, errorInfo));
487 
488  if (context->pubSub)
489  {
490  ErrorInfoEventArgs e = { 0 };
491  EventArgsInit(&e, "freerdp");
492  e.code = rdp->errorInfo;
493  PubSub_OnErrorInfo(context->pubSub, context, &e);
494  }
495  }
496  else
497  WLog_Print(rdp->log, WLOG_ERROR, "missing context=%p", context);
498  }
499  else
500  {
501  freerdp_set_last_error_log(rdp->context, FREERDP_ERROR_SUCCESS);
502  }
503 
504  return TRUE;
505 }
506 
507 wStream* rdp_message_channel_pdu_init(rdpRdp* rdp)
508 {
509  wStream* s = NULL;
510 
511  WINPR_ASSERT(rdp);
512 
513  s = transport_send_stream_init(rdp->transport, 4096);
514 
515  if (!s)
516  return NULL;
517 
518  if (!Stream_SafeSeek(s, RDP_PACKET_HEADER_MAX_LENGTH))
519  goto fail;
520 
521  if (!rdp_security_stream_init(rdp, s, TRUE))
522  goto fail;
523 
524  return s;
525 fail:
526  Stream_Release(s);
527  return NULL;
528 }
529 
540 BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
541 {
542  BYTE li = 0;
543  BYTE code = 0;
544  BYTE choice = 0;
545  UINT16 initiator = 0;
546 
547  WINPR_ASSERT(rdp);
548  WINPR_ASSERT(rdp->settings);
549  WINPR_ASSERT(s);
550  DomainMCSPDU MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataRequest
551  : DomainMCSPDU_SendDataIndication;
552 
553  *channelId = 0; /* Initialize in case of early abort */
554  if (!tpkt_read_header(s, length))
555  return FALSE;
556 
557  if (!tpdu_read_header(s, &code, &li, *length))
558  return FALSE;
559 
560  if (code != X224_TPDU_DATA)
561  {
562  if (code == X224_TPDU_DISCONNECT_REQUEST)
563  {
564  WLog_Print(rdp->log, WLOG_WARN, "Received X224_TPDU_DISCONNECT_REQUEST, terminating");
565  utils_abort_connect(rdp);
566  return TRUE;
567  }
568 
569  WLog_Print(rdp->log, WLOG_WARN,
570  "Unexpected X224 TPDU type %s [%08" PRIx32 "] instead of %s",
571  tpdu_type_to_string(code), code, tpdu_type_to_string(X224_TPDU_DATA));
572  return FALSE;
573  }
574 
575  if (!per_read_choice(s, &choice))
576  return FALSE;
577 
578  const DomainMCSPDU domainMCSPDU = (DomainMCSPDU)(choice >> 2);
579 
580  if (domainMCSPDU != MCSPDU)
581  {
582  if (domainMCSPDU != DomainMCSPDU_DisconnectProviderUltimatum)
583  {
584  WLog_Print(rdp->log, WLOG_WARN, "Received %s instead of %s",
585  mcs_domain_pdu_string(domainMCSPDU), mcs_domain_pdu_string(MCSPDU));
586  return FALSE;
587  }
588  }
589 
590  MCSPDU = domainMCSPDU;
591 
592  if (*length < 8U)
593  {
594  WLog_Print(rdp->log, WLOG_WARN, "TPDU invalid length, got %" PRIu16 ", expected at least 8",
595  *length);
596  return FALSE;
597  }
598 
599  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, *length - 8))
600  return FALSE;
601 
602  if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum)
603  {
604  int reason = 0;
605  TerminateEventArgs e = { 0 };
606 
607  if (!mcs_recv_disconnect_provider_ultimatum(rdp->mcs, s, &reason))
608  return FALSE;
609 
610  rdpContext* context = rdp->context;
611  WINPR_ASSERT(context);
612  context->disconnectUltimatum = reason;
613 
614  if (rdp->errorInfo == ERRINFO_SUCCESS)
615  {
621  UINT32 errorInfo = ERRINFO_RPC_INITIATED_DISCONNECT;
622  if (reason == Disconnect_Ultimatum_provider_initiated)
623  errorInfo = ERRINFO_RPC_INITIATED_DISCONNECT;
624  else if (reason == Disconnect_Ultimatum_user_requested)
625  errorInfo = ERRINFO_LOGOFF_BY_USER;
626 
627  rdp_set_error_info(rdp, errorInfo);
628  }
629 
630  WLog_Print(rdp->log, WLOG_DEBUG, "DisconnectProviderUltimatum: reason: %d", reason);
631  utils_abort_connect(rdp);
632  EventArgsInit(&e, "freerdp");
633  e.code = 0;
634  PubSub_OnTerminate(rdp->pubSub, context, &e);
635  return TRUE;
636  }
637 
638  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 5))
639  return FALSE;
640 
641  if (!per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID)) /* initiator (UserId) */
642  return FALSE;
643 
644  if (!per_read_integer16(s, channelId, 0)) /* channelId */
645  return FALSE;
646 
647  const uint8_t byte = Stream_Get_UINT8(s); /* dataPriority + Segmentation (0x70) */
648 
649  if (!per_read_length(s, length)) /* userData (OCTET_STRING) */
650  return FALSE;
651 
652  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, *length))
653  return FALSE;
654 
655  return TRUE;
656 }
657 
668 BOOL rdp_write_header(rdpRdp* rdp, wStream* s, size_t length, UINT16 channelId)
669 {
670  WINPR_ASSERT(rdp);
671  WINPR_ASSERT(rdp->settings);
672  WINPR_ASSERT(s);
673  WINPR_ASSERT(length >= RDP_PACKET_HEADER_MAX_LENGTH);
674  if (length > UINT16_MAX)
675  return FALSE;
676 
677  DomainMCSPDU MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataIndication
678  : DomainMCSPDU_SendDataRequest;
679 
680  if ((rdp->sec_flags & SEC_ENCRYPT) &&
681  (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS))
682  {
683  const UINT16 body_length = (UINT16)length - RDP_PACKET_HEADER_MAX_LENGTH;
684  const UINT16 pad = 8 - (body_length % 8);
685 
686  if (pad != 8)
687  length += pad;
688  }
689 
690  if (!mcs_write_domain_mcspdu_header(s, MCSPDU, (UINT16)length, 0))
691  return FALSE;
692  if (!per_write_integer16(s, rdp->mcs->userId, MCS_BASE_CHANNEL_ID)) /* initiator */
693  return FALSE;
694  if (!per_write_integer16(s, channelId, 0)) /* channelId */
695  return FALSE;
696  if (!Stream_EnsureRemainingCapacity(s, 3))
697  return FALSE;
698  Stream_Write_UINT8(s, 0x70); /* dataPriority + segmentation */
699  /*
700  * We always encode length in two bytes, even though we could use
701  * only one byte if length <= 0x7F. It is just easier that way,
702  * because we can leave room for fixed-length header, store all
703  * the data first and then store the header.
704  */
705  length = (length - RDP_PACKET_HEADER_MAX_LENGTH) | 0x8000;
706  Stream_Write_UINT16_BE(
707  s, WINPR_ASSERTING_INT_CAST(uint16_t, length)); /* userData (OCTET_STRING) */
708  return TRUE;
709 }
710 
711 static BOOL rdp_security_stream_out(rdpRdp* rdp, wStream* s, size_t length, UINT32 sec_flags,
712  UINT32* pad)
713 {
714  BOOL status = 0;
715  WINPR_ASSERT(rdp);
716  if (length > UINT16_MAX)
717  return FALSE;
718 
719  sec_flags |= rdp->sec_flags;
720  *pad = 0;
721 
722  if (sec_flags != 0)
723  {
724  WINPR_ASSERT(sec_flags <= UINT16_MAX);
725  if (!rdp_write_security_header(rdp, s, (UINT16)sec_flags))
726  return FALSE;
727 
728  if (sec_flags & SEC_ENCRYPT)
729  {
730  BOOL res = FALSE;
731  if (!security_lock(rdp))
732  return FALSE;
733 
734  if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
735  {
736  BYTE* data = Stream_PointerAs(s, BYTE) + 12;
737  const size_t size = WINPR_ASSERTING_INT_CAST(size_t, (data - Stream_Buffer(s)));
738  if (size > length)
739  goto unlock;
740 
741  length -= size;
742 
743  Stream_Write_UINT16(s, 0x10); /* length */
744  Stream_Write_UINT8(s, 0x1); /* TSFIPS_VERSION 1*/
745  /* handle padding */
746  *pad = 8 - (length % 8);
747 
748  if (*pad == 8)
749  *pad = 0;
750 
751  if (*pad)
752  memset(data + length, 0, *pad);
753 
754  Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, *pad));
755 
756  if (!Stream_CheckAndLogRequiredCapacityWLog(rdp->log, s, 8))
757  goto unlock;
758  if (!security_hmac_signature(data, length, Stream_Pointer(s), 8, rdp))
759  goto unlock;
760 
761  Stream_Seek(s, 8);
762  if (!security_fips_encrypt(data, length + *pad, rdp))
763  goto unlock;
764  }
765  else
766  {
767  const BYTE* data = Stream_PointerAs(s, const BYTE) + 8;
768  const size_t diff = Stream_GetPosition(s) + 8ULL;
769  if (diff > length)
770  goto unlock;
771  length -= diff;
772 
773  if (!Stream_CheckAndLogRequiredCapacityWLog(rdp->log, s, 8))
774  goto unlock;
775  if (sec_flags & SEC_SECURE_CHECKSUM)
776  status = security_salted_mac_signature(rdp, data, (UINT32)length, TRUE,
777  Stream_Pointer(s), 8);
778  else
779  status = security_mac_signature(rdp, data, (UINT32)length,
780  Stream_PointerAs(s, BYTE), 8);
781 
782  if (!status)
783  goto unlock;
784 
785  Stream_Seek(s, 8);
786 
787  if (!security_encrypt(Stream_Pointer(s), length, rdp))
788  goto unlock;
789  }
790  res = TRUE;
791 
792  unlock:
793 
794  if (!security_unlock(rdp))
795  return FALSE;
796  if (!res)
797  return FALSE;
798  }
799 
800  rdp->sec_flags = 0;
801  }
802 
803  return TRUE;
804 }
805 
806 static UINT32 rdp_get_sec_bytes(rdpRdp* rdp, UINT16 sec_flags)
807 {
808  UINT32 sec_bytes = 0;
809 
810  if (rdp->sec_flags & SEC_ENCRYPT)
811  {
812  sec_bytes = 12;
813 
814  if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
815  sec_bytes += 4;
816  }
817  else if (rdp->sec_flags != 0 || sec_flags != 0)
818  {
819  sec_bytes = 4;
820  }
821  else
822  {
823  sec_bytes = 0;
824  }
825 
826  return sec_bytes;
827 }
828 
836 BOOL rdp_send(rdpRdp* rdp, wStream* s, UINT16 channel_id)
837 {
838  BOOL rc = FALSE;
839  UINT32 pad = 0;
840 
841  if (!s)
842  return FALSE;
843 
844  if (!rdp)
845  goto fail;
846 
847  size_t length = Stream_GetPosition(s);
848  Stream_SetPosition(s, 0);
849  if (!rdp_write_header(rdp, s, length, channel_id))
850  goto fail;
851 
852  if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
853  goto fail;
854 
855  length += pad;
856  Stream_SetPosition(s, length);
857  Stream_SealLength(s);
858 
859  if (transport_write(rdp->transport, s) < 0)
860  goto fail;
861 
862  rc = TRUE;
863 fail:
864  Stream_Release(s);
865  return rc;
866 }
867 
868 BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
869 {
870  UINT32 sec_bytes = 0;
871  size_t sec_hold = 0;
872  UINT32 pad = 0;
873 
874  if (!rdp || !s)
875  return FALSE;
876 
877  size_t length = Stream_GetPosition(s);
878  Stream_SetPosition(s, 0);
879  if (!rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID))
880  return FALSE;
881  sec_bytes = rdp_get_sec_bytes(rdp, 0);
882  sec_hold = Stream_GetPosition(s);
883  Stream_Seek(s, sec_bytes);
884  if (!rdp_write_share_control_header(rdp, s, length - sec_bytes, type, channel_id))
885  return FALSE;
886  Stream_SetPosition(s, sec_hold);
887 
888  if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
889  return FALSE;
890 
891  length += pad;
892  Stream_SetPosition(s, length);
893  Stream_SealLength(s);
894 
895  if (transport_write(rdp->transport, s) < 0)
896  return FALSE;
897 
898  return TRUE;
899 }
900 
901 BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
902 {
903  BOOL rc = FALSE;
904  UINT32 sec_bytes = 0;
905  size_t sec_hold = 0;
906  UINT32 pad = 0;
907 
908  if (!s)
909  return FALSE;
910 
911  if (!rdp)
912  goto fail;
913 
914  size_t length = Stream_GetPosition(s);
915  Stream_SetPosition(s, 0);
916  if (!rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID))
917  goto fail;
918  sec_bytes = rdp_get_sec_bytes(rdp, 0);
919  sec_hold = Stream_GetPosition(s);
920  Stream_Seek(s, sec_bytes);
921  if (!rdp_write_share_control_header(rdp, s, length - sec_bytes, PDU_TYPE_DATA, channel_id))
922  goto fail;
923  if (!rdp_write_share_data_header(rdp, s, length - sec_bytes, type, rdp->settings->ShareId))
924  goto fail;
925  Stream_SetPosition(s, sec_hold);
926 
927  if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
928  goto fail;
929 
930  length += pad;
931  Stream_SetPosition(s, length);
932  Stream_SealLength(s);
933  WLog_Print(rdp->log, WLOG_DEBUG,
934  "sending data (type=0x%x size=%" PRIuz " channelId=%" PRIu16 ")", type,
935  Stream_Length(s), channel_id);
936 
937  rdp->outPackets++;
938  if (transport_write(rdp->transport, s) < 0)
939  goto fail;
940 
941  rc = TRUE;
942 fail:
943  Stream_Release(s);
944  return rc;
945 }
946 
947 BOOL rdp_send_message_channel_pdu(rdpRdp* rdp, wStream* s, UINT16 sec_flags)
948 {
949  BOOL rc = FALSE;
950  UINT32 pad = 0;
951 
952  WINPR_ASSERT(rdp);
953  WINPR_ASSERT(s);
954 
955  size_t length = Stream_GetPosition(s);
956  Stream_SetPosition(s, 0);
957  if (!rdp_write_header(rdp, s, length, rdp->mcs->messageChannelId))
958  goto fail;
959 
960  if (!rdp_security_stream_out(rdp, s, length, sec_flags, &pad))
961  goto fail;
962 
963  length += pad;
964  Stream_SetPosition(s, length);
965  Stream_SealLength(s);
966 
967  if (transport_write(rdp->transport, s) < 0)
968  goto fail;
969 
970  rc = TRUE;
971 fail:
972  Stream_Release(s);
973  return rc;
974 }
975 
976 static BOOL rdp_recv_server_shutdown_denied_pdu(rdpRdp* rdp, wStream* s)
977 {
978  return TRUE;
979 }
980 
981 static BOOL rdp_recv_server_set_keyboard_indicators_pdu(rdpRdp* rdp, wStream* s)
982 {
983  UINT16 ledFlags = 0;
984 
985  WINPR_ASSERT(rdp);
986  WINPR_ASSERT(s);
987 
988  rdpContext* context = rdp->context;
989  WINPR_ASSERT(context);
990  WINPR_ASSERT(context->update);
991 
992  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
993  return FALSE;
994 
995  const uint16_t unitId = Stream_Get_UINT16(s); /* unitId (2 bytes) */
996  Stream_Read_UINT16(s, ledFlags); /* ledFlags (2 bytes) */
997  return IFCALLRESULT(TRUE, context->update->SetKeyboardIndicators, context, ledFlags);
998 }
999 
1000 static BOOL rdp_recv_server_set_keyboard_ime_status_pdu(rdpRdp* rdp, wStream* s)
1001 {
1002  UINT16 unitId = 0;
1003  UINT32 imeState = 0;
1004  UINT32 imeConvMode = 0;
1005 
1006  if (!rdp || !rdp->input)
1007  return FALSE;
1008 
1009  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 10))
1010  return FALSE;
1011 
1012  Stream_Read_UINT16(s, unitId); /* unitId (2 bytes) */
1013  Stream_Read_UINT32(s, imeState); /* imeState (4 bytes) */
1014  Stream_Read_UINT32(s, imeConvMode); /* imeConvMode (4 bytes) */
1015  IFCALL(rdp->update->SetKeyboardImeStatus, rdp->context, unitId, imeState, imeConvMode);
1016  return TRUE;
1017 }
1018 
1019 static BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s)
1020 {
1021  UINT32 errorInfo = 0;
1022 
1023  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
1024  return FALSE;
1025 
1026  Stream_Read_UINT32(s, errorInfo); /* errorInfo (4 bytes) */
1027  return rdp_set_error_info(rdp, errorInfo);
1028 }
1029 
1030 static BOOL rdp_recv_server_auto_reconnect_status_pdu(rdpRdp* rdp, wStream* s)
1031 {
1032  UINT32 arcStatus = 0;
1033 
1034  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
1035  return FALSE;
1036 
1037  Stream_Read_UINT32(s, arcStatus); /* arcStatus (4 bytes) */
1038  WLog_Print(rdp->log, WLOG_WARN, "AutoReconnectStatus: 0x%08" PRIX32 "", arcStatus);
1039  return TRUE;
1040 }
1041 
1042 static BOOL rdp_recv_server_status_info_pdu(rdpRdp* rdp, wStream* s)
1043 {
1044  UINT32 statusCode = 0;
1045 
1046  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
1047  return FALSE;
1048 
1049  Stream_Read_UINT32(s, statusCode); /* statusCode (4 bytes) */
1050 
1051  if (rdp->update->ServerStatusInfo)
1052  return rdp->update->ServerStatusInfo(rdp->context, statusCode);
1053 
1054  return TRUE;
1055 }
1056 
1057 static BOOL rdp_recv_monitor_layout_pdu(rdpRdp* rdp, wStream* s)
1058 {
1059  UINT32 monitorCount = 0;
1060  MONITOR_DEF* monitorDefArray = NULL;
1061  BOOL ret = TRUE;
1062 
1063  WINPR_ASSERT(rdp);
1064  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
1065  return FALSE;
1066 
1067  Stream_Read_UINT32(s, monitorCount); /* monitorCount (4 bytes) */
1068 
1069  if (!Stream_CheckAndLogRequiredLengthOfSizeWLog(rdp->log, s, monitorCount, 20ull))
1070  return FALSE;
1071 
1072  monitorDefArray = (MONITOR_DEF*)calloc(monitorCount, sizeof(MONITOR_DEF));
1073 
1074  if (!monitorDefArray)
1075  return FALSE;
1076 
1077  for (UINT32 index = 0; index < monitorCount; index++)
1078  {
1079  MONITOR_DEF* monitor = &monitorDefArray[index];
1080  Stream_Read_INT32(s, monitor->left); /* left (4 bytes) */
1081  Stream_Read_INT32(s, monitor->top); /* top (4 bytes) */
1082  Stream_Read_INT32(s, monitor->right); /* right (4 bytes) */
1083  Stream_Read_INT32(s, monitor->bottom); /* bottom (4 bytes) */
1084  Stream_Read_UINT32(s, monitor->flags); /* flags (4 bytes) */
1085  }
1086 
1087  IFCALLRET(rdp->update->RemoteMonitors, ret, rdp->context, monitorCount, monitorDefArray);
1088  free(monitorDefArray);
1089  if (!ret)
1090  return FALSE;
1091  return rdp_set_monitor_layout_pdu_state(rdp, TRUE);
1092 }
1093 
1094 state_run_t rdp_recv_data_pdu(rdpRdp* rdp, wStream* s)
1095 {
1096  BYTE type = 0;
1097  wStream* cs = NULL;
1098  UINT16 length = 0;
1099  UINT32 shareId = 0;
1100  BYTE compressedType = 0;
1101  UINT16 compressedLength = 0;
1102 
1103  WINPR_ASSERT(rdp);
1104  if (!rdp_read_share_data_header(rdp, s, &length, &type, &shareId, &compressedType,
1105  &compressedLength))
1106  {
1107  WLog_Print(rdp->log, WLOG_ERROR, "rdp_read_share_data_header() failed");
1108  return STATE_RUN_FAILED;
1109  }
1110 
1111  cs = s;
1112 
1113  if (compressedType & PACKET_COMPRESSED)
1114  {
1115  if (compressedLength < 18)
1116  {
1117  WLog_Print(rdp->log, WLOG_ERROR,
1118  "bulk_decompress: not enough bytes for compressedLength %" PRIu16 "",
1119  compressedLength);
1120  return STATE_RUN_FAILED;
1121  }
1122 
1123  UINT32 DstSize = 0;
1124  const BYTE* pDstData = NULL;
1125  UINT16 SrcSize = compressedLength - 18;
1126 
1127  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, SrcSize))
1128  {
1129  WLog_Print(rdp->log, WLOG_ERROR,
1130  "bulk_decompress: not enough bytes for compressedLength %" PRIu16 "",
1131  compressedLength);
1132  return STATE_RUN_FAILED;
1133  }
1134 
1135  if (bulk_decompress(rdp->bulk, Stream_ConstPointer(s), SrcSize, &pDstData, &DstSize,
1136  compressedType))
1137  {
1138  cs = transport_take_from_pool(rdp->transport, DstSize);
1139  if (!cs)
1140  {
1141  WLog_Print(rdp->log, WLOG_ERROR, "Couldn't take stream from pool");
1142  return STATE_RUN_FAILED;
1143  }
1144 
1145  Stream_SetPosition(cs, 0);
1146  Stream_Write(cs, pDstData, DstSize);
1147  Stream_SealLength(cs);
1148  Stream_SetPosition(cs, 0);
1149  }
1150  else
1151  {
1152  WLog_Print(rdp->log, WLOG_ERROR, "bulk_decompress() failed");
1153  return STATE_RUN_FAILED;
1154  }
1155 
1156  Stream_Seek(s, SrcSize);
1157  }
1158 
1159  WLog_Print(rdp->log, WLOG_DEBUG, "recv %s Data PDU (0x%02" PRIX8 "), length: %" PRIu16 "",
1160  data_pdu_type_to_string(type), type, length);
1161 
1162  switch (type)
1163  {
1164  case DATA_PDU_TYPE_UPDATE:
1165  if (!update_recv(rdp->update, cs))
1166  {
1167  WLog_Print(rdp->log, WLOG_ERROR, "DATA_PDU_TYPE_UPDATE - update_recv() failed");
1168  goto out_fail;
1169  }
1170 
1171  break;
1172 
1173  case DATA_PDU_TYPE_CONTROL:
1174  if (!rdp_recv_server_control_pdu(rdp, cs))
1175  {
1176  WLog_Print(rdp->log, WLOG_ERROR,
1177  "DATA_PDU_TYPE_CONTROL - rdp_recv_server_control_pdu() failed");
1178  goto out_fail;
1179  }
1180 
1181  break;
1182 
1183  case DATA_PDU_TYPE_POINTER:
1184  if (!update_recv_pointer(rdp->update, cs))
1185  {
1186  WLog_Print(rdp->log, WLOG_ERROR,
1187  "DATA_PDU_TYPE_POINTER - update_recv_pointer() failed");
1188  goto out_fail;
1189  }
1190 
1191  break;
1192 
1193  case DATA_PDU_TYPE_SYNCHRONIZE:
1194  if (!rdp_recv_server_synchronize_pdu(rdp, cs))
1195  {
1196  WLog_Print(rdp->log, WLOG_ERROR,
1197  "DATA_PDU_TYPE_SYNCHRONIZE - rdp_recv_synchronize_pdu() failed");
1198  goto out_fail;
1199  }
1200 
1201  break;
1202 
1203  case DATA_PDU_TYPE_PLAY_SOUND:
1204  if (!update_recv_play_sound(rdp->update, cs))
1205  {
1206  WLog_Print(rdp->log, WLOG_ERROR,
1207  "DATA_PDU_TYPE_PLAY_SOUND - update_recv_play_sound() failed");
1208  goto out_fail;
1209  }
1210 
1211  break;
1212 
1213  case DATA_PDU_TYPE_SHUTDOWN_DENIED:
1214  if (!rdp_recv_server_shutdown_denied_pdu(rdp, cs))
1215  {
1216  WLog_Print(
1217  rdp->log, WLOG_ERROR,
1218  "DATA_PDU_TYPE_SHUTDOWN_DENIED - rdp_recv_server_shutdown_denied_pdu() failed");
1219  goto out_fail;
1220  }
1221 
1222  break;
1223 
1224  case DATA_PDU_TYPE_SAVE_SESSION_INFO:
1225  if (!rdp_recv_save_session_info(rdp, cs))
1226  {
1227  WLog_Print(rdp->log, WLOG_ERROR,
1228  "DATA_PDU_TYPE_SAVE_SESSION_INFO - rdp_recv_save_session_info() failed");
1229  goto out_fail;
1230  }
1231 
1232  break;
1233 
1234  case DATA_PDU_TYPE_FONT_MAP:
1235  if (!rdp_recv_font_map_pdu(rdp, cs))
1236  {
1237  WLog_Print(rdp->log, WLOG_ERROR,
1238  "DATA_PDU_TYPE_FONT_MAP - rdp_recv_font_map_pdu() failed");
1239  goto out_fail;
1240  }
1241 
1242  break;
1243 
1244  case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS:
1245  if (!rdp_recv_server_set_keyboard_indicators_pdu(rdp, cs))
1246  {
1247  WLog_Print(rdp->log, WLOG_ERROR,
1248  "DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS - "
1249  "rdp_recv_server_set_keyboard_indicators_pdu() failed");
1250  goto out_fail;
1251  }
1252 
1253  break;
1254 
1255  case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS:
1256  if (!rdp_recv_server_set_keyboard_ime_status_pdu(rdp, cs))
1257  {
1258  WLog_Print(rdp->log, WLOG_ERROR,
1259  "DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS - "
1260  "rdp_recv_server_set_keyboard_ime_status_pdu() failed");
1261  goto out_fail;
1262  }
1263 
1264  break;
1265 
1266  case DATA_PDU_TYPE_SET_ERROR_INFO:
1267  if (!rdp_recv_set_error_info_data_pdu(rdp, cs))
1268  {
1269  WLog_Print(
1270  rdp->log, WLOG_ERROR,
1271  "DATA_PDU_TYPE_SET_ERROR_INFO - rdp_recv_set_error_info_data_pdu() failed");
1272  goto out_fail;
1273  }
1274 
1275  break;
1276 
1277  case DATA_PDU_TYPE_ARC_STATUS:
1278  if (!rdp_recv_server_auto_reconnect_status_pdu(rdp, cs))
1279  {
1280  WLog_Print(rdp->log, WLOG_ERROR,
1281  "DATA_PDU_TYPE_ARC_STATUS - "
1282  "rdp_recv_server_auto_reconnect_status_pdu() failed");
1283  goto out_fail;
1284  }
1285 
1286  break;
1287 
1288  case DATA_PDU_TYPE_STATUS_INFO:
1289  if (!rdp_recv_server_status_info_pdu(rdp, cs))
1290  {
1291  WLog_Print(rdp->log, WLOG_ERROR,
1292  "DATA_PDU_TYPE_STATUS_INFO - rdp_recv_server_status_info_pdu() failed");
1293  goto out_fail;
1294  }
1295 
1296  break;
1297 
1298  case DATA_PDU_TYPE_MONITOR_LAYOUT:
1299  if (!rdp_recv_monitor_layout_pdu(rdp, cs))
1300  {
1301  WLog_Print(rdp->log, WLOG_ERROR,
1302  "DATA_PDU_TYPE_MONITOR_LAYOUT - rdp_recv_monitor_layout_pdu() failed");
1303  goto out_fail;
1304  }
1305 
1306  break;
1307 
1308  default:
1309  WLog_Print(rdp->log, WLOG_WARN,
1310  "[UNHANDLED] %s Data PDU (0x%02" PRIX8 "), length: %" PRIu16 "",
1311  data_pdu_type_to_string(type), type, length);
1312  break;
1313  }
1314 
1315  if (cs != s)
1316  Stream_Release(cs);
1317 
1318  return STATE_RUN_SUCCESS;
1319 out_fail:
1320 
1321  if (cs != s)
1322  Stream_Release(cs);
1323 
1324  return STATE_RUN_FAILED;
1325 }
1326 
1327 state_run_t rdp_recv_message_channel_pdu(rdpRdp* rdp, wStream* s, UINT16 securityFlags)
1328 {
1329  WINPR_ASSERT(rdp);
1330  WINPR_ASSERT(s);
1331 
1332  if (securityFlags & SEC_AUTODETECT_REQ)
1333  {
1334  /* Server Auto-Detect Request PDU */
1335  return autodetect_recv_request_packet(rdp->autodetect, RDP_TRANSPORT_TCP, s);
1336  }
1337 
1338  if (securityFlags & SEC_AUTODETECT_RSP)
1339  {
1340  /* Client Auto-Detect Response PDU */
1341  return autodetect_recv_response_packet(rdp->autodetect, RDP_TRANSPORT_TCP, s);
1342  }
1343 
1344  if (securityFlags & SEC_HEARTBEAT)
1345  {
1346  /* Heartbeat PDU */
1347  return rdp_recv_heartbeat_packet(rdp, s);
1348  }
1349 
1350  if (securityFlags & SEC_TRANSPORT_REQ)
1351  {
1352  return multitransport_recv_request(rdp->multitransport, s);
1353  }
1354 
1355  if (securityFlags & SEC_TRANSPORT_RSP)
1356  {
1357  return multitransport_recv_response(rdp->multitransport, s);
1358  }
1359 
1360  if (securityFlags & SEC_LICENSE_PKT)
1361  {
1362  return license_recv(rdp->license, s);
1363  }
1364 
1365  if (securityFlags & SEC_LICENSE_ENCRYPT_CS)
1366  {
1367  return license_recv(rdp->license, s);
1368  }
1369 
1370  if (securityFlags & SEC_LICENSE_ENCRYPT_SC)
1371  {
1372  return license_recv(rdp->license, s);
1373  }
1374 
1375  return STATE_RUN_SUCCESS;
1376 }
1377 
1378 state_run_t rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s, UINT16 pduType, UINT16 length)
1379 {
1380  state_run_t rc = STATE_RUN_FAILED;
1381  WINPR_ASSERT(rdp);
1382 
1383  switch (pduType)
1384  {
1385  case PDU_TYPE_DATA:
1386  rc = rdp_recv_data_pdu(rdp, s);
1387  break;
1388  case PDU_TYPE_SERVER_REDIRECTION:
1389  rc = rdp_recv_enhanced_security_redirection_packet(rdp, s);
1390  break;
1391  case PDU_TYPE_FLOW_RESPONSE:
1392  case PDU_TYPE_FLOW_STOP:
1393  case PDU_TYPE_FLOW_TEST:
1394  rc = STATE_RUN_SUCCESS;
1395  break;
1396  default:
1397  {
1398  char buffer1[256] = { 0 };
1399  char buffer2[256] = { 0 };
1400 
1401  WLog_Print(rdp->log, WLOG_ERROR, "expected %s, got %s",
1402  pdu_type_to_str(PDU_TYPE_DEMAND_ACTIVE, buffer1, sizeof(buffer1)),
1403  pdu_type_to_str(pduType, buffer2, sizeof(buffer2)));
1404  rc = STATE_RUN_FAILED;
1405  }
1406  break;
1407  }
1408 
1409  if (!tpkt_ensure_stream_consumed(s, length))
1410  return STATE_RUN_FAILED;
1411  return rc;
1412 }
1413 
1414 BOOL rdp_read_flow_control_pdu(rdpRdp* rdp, wStream* s, UINT16* type, UINT16* channel_id)
1415 {
1416  /*
1417  * Read flow control PDU - documented in FlowPDU section in T.128
1418  * http://www.itu.int/rec/T-REC-T.128-199802-S/en
1419  * The specification for the PDU has pad8bits listed BEFORE pduTypeFlow.
1420  * However, so far pad8bits has always been observed to arrive AFTER pduTypeFlow.
1421  * Switched the order of these two fields to match this observation.
1422  */
1423  UINT8 pduType = 0;
1424 
1425  WINPR_ASSERT(rdp);
1426  WINPR_ASSERT(s);
1427  WINPR_ASSERT(type);
1428  WINPR_ASSERT(channel_id);
1429 
1430  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 6))
1431  return FALSE;
1432  Stream_Read_UINT8(s, pduType); /* pduTypeFlow */
1433  *type = pduType;
1434  Stream_Seek_UINT8(s); /* pad8bits */
1435  Stream_Seek_UINT8(s); /* flowIdentifier */
1436  Stream_Seek_UINT8(s); /* flowNumber */
1437  Stream_Read_UINT16(s, *channel_id); /* pduSource */
1438  return TRUE;
1439 }
1440 
1452 BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, UINT16* pLength, UINT16 securityFlags)
1453 {
1454  BOOL res = FALSE;
1455  BYTE cmac[8] = { 0 };
1456  BYTE wmac[8] = { 0 };
1457  BOOL status = FALSE;
1458 
1459  WINPR_ASSERT(rdp);
1460  WINPR_ASSERT(rdp->settings);
1461  WINPR_ASSERT(s);
1462  WINPR_ASSERT(pLength);
1463 
1464  if (!security_lock(rdp))
1465  return FALSE;
1466 
1467  INT32 length = *pLength;
1468  if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_NONE)
1469  return TRUE;
1470 
1471  if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
1472  {
1473  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 12))
1474  goto unlock;
1475 
1476  UINT16 len = 0;
1477  Stream_Read_UINT16(s, len); /* 0x10 */
1478  if (len != 0x10)
1479  WLog_Print(rdp->log, WLOG_WARN, "ENCRYPTION_METHOD_FIPS length %" PRIu16 " != 0x10",
1480  len);
1481 
1482  UINT16 version = 0;
1483  Stream_Read_UINT8(s, version); /* 0x1 */
1484  if (version != 1)
1485  WLog_Print(rdp->log, WLOG_WARN, "ENCRYPTION_METHOD_FIPS version %" PRIu16 " != 1",
1486  version);
1487 
1488  BYTE pad = 0;
1489  Stream_Read_UINT8(s, pad);
1490  const BYTE* sig = Stream_ConstPointer(s);
1491  Stream_Seek(s, 8); /* signature */
1492  length -= 12;
1493  const INT32 padLength = length - pad;
1494 
1495  if ((length <= 0) || (padLength <= 0) || (padLength > UINT16_MAX))
1496  {
1497  WLog_Print(rdp->log, WLOG_ERROR, "FATAL: invalid pad length %" PRId32, padLength);
1498  goto unlock;
1499  }
1500 
1501  if (!security_fips_decrypt(Stream_Pointer(s), (size_t)length, rdp))
1502  goto unlock;
1503 
1504  if (!security_fips_check_signature(Stream_ConstPointer(s), (size_t)padLength, sig, 8, rdp))
1505  goto unlock;
1506 
1507  Stream_SetLength(s, Stream_Length(s) - pad);
1508  *pLength = (UINT16)padLength;
1509  }
1510  else
1511  {
1512  if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, sizeof(wmac)))
1513  goto unlock;
1514 
1515  Stream_Read(s, wmac, sizeof(wmac));
1516  length -= sizeof(wmac);
1517 
1518  if (length <= 0)
1519  {
1520  WLog_Print(rdp->log, WLOG_ERROR, "FATAL: invalid length field");
1521  goto unlock;
1522  }
1523 
1524  if (!security_decrypt(Stream_PointerAs(s, BYTE), (size_t)length, rdp))
1525  goto unlock;
1526 
1527  if (securityFlags & SEC_SECURE_CHECKSUM)
1528  status = security_salted_mac_signature(rdp, Stream_ConstPointer(s), (UINT32)length,
1529  FALSE, cmac, sizeof(cmac));
1530  else
1531  status = security_mac_signature(rdp, Stream_ConstPointer(s), (UINT32)length, cmac,
1532  sizeof(cmac));
1533 
1534  if (!status)
1535  goto unlock;
1536 
1537  if (memcmp(wmac, cmac, sizeof(wmac)) != 0)
1538  {
1539  WLog_Print(rdp->log, WLOG_ERROR, "WARNING: invalid packet signature");
1540  /*
1541  * Because Standard RDP Security is totally broken,
1542  * and cannot protect against MITM, don't treat signature
1543  * verification failure as critical. This at least enables
1544  * us to work with broken RDP clients and servers that
1545  * generate invalid signatures.
1546  */
1547  // return FALSE;
1548  }
1549 
1550  *pLength = (UINT16)length;
1551  }
1552  res = TRUE;
1553 unlock:
1554  if (!security_unlock(rdp))
1555  return FALSE;
1556  return res;
1557 }
1558 
1559 const char* pdu_type_to_str(UINT16 pduType, char* buffer, size_t length)
1560 {
1561  const char* str = NULL;
1562  switch (pduType)
1563  {
1564  case PDU_TYPE_DEMAND_ACTIVE:
1565  str = "PDU_TYPE_DEMAND_ACTIVE";
1566  break;
1567  case PDU_TYPE_CONFIRM_ACTIVE:
1568  str = "PDU_TYPE_CONFIRM_ACTIVE";
1569  break;
1570  case PDU_TYPE_DEACTIVATE_ALL:
1571  str = "PDU_TYPE_DEACTIVATE_ALL";
1572  break;
1573  case PDU_TYPE_DATA:
1574  str = "PDU_TYPE_DATA";
1575  break;
1576  case PDU_TYPE_SERVER_REDIRECTION:
1577  str = "PDU_TYPE_SERVER_REDIRECTION";
1578  break;
1579  case PDU_TYPE_FLOW_TEST:
1580  str = "PDU_TYPE_FLOW_TEST";
1581  break;
1582  case PDU_TYPE_FLOW_RESPONSE:
1583  str = "PDU_TYPE_FLOW_RESPONSE";
1584  break;
1585  case PDU_TYPE_FLOW_STOP:
1586  str = "PDU_TYPE_FLOW_STOP";
1587  break;
1588  default:
1589  str = "PDU_TYPE_UNKNOWN";
1590  break;
1591  }
1592 
1593  winpr_str_append(str, buffer, length, "");
1594  {
1595  char msg[32] = { 0 };
1596  (void)_snprintf(msg, sizeof(msg), "[0x%08" PRIx32 "]", pduType);
1597  winpr_str_append(msg, buffer, length, "");
1598  }
1599  return buffer;
1600 }
1601 
1608 static state_run_t rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
1609 {
1610  state_run_t rc = STATE_RUN_SUCCESS;
1611  UINT16 length = 0;
1612  UINT16 pduType = 0;
1613  UINT16 pduSource = 0;
1614  UINT16 channelId = 0;
1615  UINT16 securityFlags = 0;
1616  freerdp* instance = NULL;
1617 
1618  WINPR_ASSERT(rdp);
1619  WINPR_ASSERT(rdp->context);
1620  WINPR_ASSERT(s);
1621 
1622  instance = rdp->context->instance;
1623  WINPR_ASSERT(instance);
1624 
1625  if (!rdp_read_header(rdp, s, &length, &channelId))
1626  return STATE_RUN_FAILED;
1627 
1628  if (freerdp_shall_disconnect_context(rdp->context))
1629  return STATE_RUN_SUCCESS;
1630 
1631  if (rdp->autodetect->bandwidthMeasureStarted)
1632  {
1633  rdp->autodetect->bandwidthMeasureByteCount += length;
1634  }
1635 
1636  if (rdp->mcs->messageChannelId && (channelId == rdp->mcs->messageChannelId))
1637  {
1638  rdp->inPackets++;
1639  if (!rdp_handle_message_channel(rdp, s, channelId, length))
1640  return STATE_RUN_FAILED;
1641  return STATE_RUN_SUCCESS;
1642  }
1643 
1644  if (rdp->settings->UseRdpSecurityLayer)
1645  {
1646  if (!rdp_read_security_header(rdp, s, &securityFlags, &length))
1647  return STATE_RUN_FAILED;
1648 
1649  if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
1650  {
1651  if (!rdp_decrypt(rdp, s, &length, securityFlags))
1652  return STATE_RUN_FAILED;
1653  }
1654 
1655  if (securityFlags & SEC_REDIRECTION_PKT)
1656  {
1657  /*
1658  * [MS-RDPBCGR] 2.2.13.2.1
1659  * - no share control header, nor the 2 byte pad
1660  */
1661  Stream_Rewind(s, 2);
1662  rdp->inPackets++;
1663 
1664  rc = rdp_recv_enhanced_security_redirection_packet(rdp, s);
1665  goto out;
1666  }
1667  }
1668 
1669  if (channelId == MCS_GLOBAL_CHANNEL_ID)
1670  {
1671  while (Stream_GetRemainingLength(s) > 3)
1672  {
1673  wStream subbuffer;
1674  wStream* sub = NULL;
1675  size_t diff = 0;
1676  UINT16 remain = 0;
1677 
1678  if (!rdp_read_share_control_header(rdp, s, NULL, &remain, &pduType, &pduSource))
1679  return STATE_RUN_FAILED;
1680 
1681  sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), remain);
1682  if (!Stream_SafeSeek(s, remain))
1683  return STATE_RUN_FAILED;
1684 
1685  rdp->settings->PduSource = pduSource;
1686  rdp->inPackets++;
1687 
1688  switch (pduType)
1689  {
1690  case PDU_TYPE_DATA:
1691  rc = rdp_recv_data_pdu(rdp, sub);
1692  if (state_run_failed(rc))
1693  return rc;
1694  break;
1695 
1696  case PDU_TYPE_DEACTIVATE_ALL:
1697  if (!rdp_recv_deactivate_all(rdp, sub))
1698  {
1699  WLog_Print(rdp->log, WLOG_ERROR,
1700  "rdp_recv_tpkt_pdu: rdp_recv_deactivate_all() fail");
1701  return STATE_RUN_FAILED;
1702  }
1703 
1704  break;
1705 
1706  case PDU_TYPE_SERVER_REDIRECTION:
1707  return rdp_recv_enhanced_security_redirection_packet(rdp, sub);
1708 
1709  case PDU_TYPE_FLOW_RESPONSE:
1710  case PDU_TYPE_FLOW_STOP:
1711  case PDU_TYPE_FLOW_TEST:
1712  WLog_Print(rdp->log, WLOG_DEBUG, "flow message 0x%04" PRIX16 "", pduType);
1713  /* http://msdn.microsoft.com/en-us/library/cc240576.aspx */
1714  if (!Stream_SafeSeek(sub, remain))
1715  return STATE_RUN_FAILED;
1716  break;
1717 
1718  default:
1719  {
1720  char buffer[256] = { 0 };
1721  WLog_Print(rdp->log, WLOG_ERROR, "incorrect PDU type: %s",
1722  pdu_type_to_str(pduType, buffer, sizeof(buffer)));
1723  }
1724  break;
1725  }
1726 
1727  diff = Stream_GetRemainingLength(sub);
1728  if (diff > 0)
1729  {
1730  char buffer[256] = { 0 };
1731  WLog_Print(rdp->log, WLOG_WARN,
1732  "pduType %s not properly parsed, %" PRIdz
1733  " bytes remaining unhandled. Skipping.",
1734  pdu_type_to_str(pduType, buffer, sizeof(buffer)), diff);
1735  }
1736  }
1737  }
1738  else
1739  {
1740  rdp->inPackets++;
1741 
1742  if (!freerdp_channel_process(instance, s, channelId, length))
1743  return STATE_RUN_FAILED;
1744  }
1745 
1746 out:
1747  if (!tpkt_ensure_stream_consumed(s, length))
1748  return STATE_RUN_FAILED;
1749  return rc;
1750 }
1751 
1752 static state_run_t rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s)
1753 {
1754  UINT16 length = 0;
1755 
1756  WINPR_ASSERT(rdp);
1757  rdpFastPath* fastpath = rdp->fastpath;
1758 
1759  if (!fastpath_read_header_rdp(fastpath, s, &length))
1760  {
1761  WLog_Print(rdp->log, WLOG_ERROR, "rdp_recv_fastpath_pdu: fastpath_read_header_rdp() fail");
1762  return STATE_RUN_FAILED;
1763  }
1764 
1765  if ((length == 0) || (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, length)))
1766  {
1767  WLog_Print(rdp->log, WLOG_ERROR, "incorrect FastPath PDU header length %" PRIu16 "",
1768  length);
1769  return STATE_RUN_FAILED;
1770  }
1771 
1772  if (rdp->autodetect->bandwidthMeasureStarted)
1773  {
1774  rdp->autodetect->bandwidthMeasureByteCount += length;
1775  }
1776 
1777  if (!fastpath_decrypt(fastpath, s, &length))
1778  return STATE_RUN_FAILED;
1779 
1780  return fastpath_recv_updates(rdp->fastpath, s);
1781 }
1782 
1783 static state_run_t rdp_recv_pdu(rdpRdp* rdp, wStream* s)
1784 {
1785  const int rc = tpkt_verify_header(s);
1786  if (rc > 0)
1787  return rdp_recv_tpkt_pdu(rdp, s);
1788  else if (rc == 0)
1789  return rdp_recv_fastpath_pdu(rdp, s);
1790  else
1791  return STATE_RUN_FAILED;
1792 }
1793 
1794 static state_run_t rdp_handle_sc_flags(rdpRdp* rdp, wStream* s, UINT32 flag,
1795  CONNECTION_STATE nextState)
1796 {
1797  const UINT32 mask = FINALIZE_SC_SYNCHRONIZE_PDU | FINALIZE_SC_CONTROL_COOPERATE_PDU |
1798  FINALIZE_SC_CONTROL_GRANTED_PDU | FINALIZE_SC_FONT_MAP_PDU;
1799  WINPR_ASSERT(rdp);
1800  state_run_t status = rdp_recv_pdu(rdp, s);
1801  if (state_run_success(status))
1802  {
1803  const UINT32 flags = rdp->finalize_sc_pdus & mask;
1804  if ((flags & flag) == flag)
1805  {
1806  if (!rdp_client_transition_to_state(rdp, nextState))
1807  status = STATE_RUN_FAILED;
1808  else
1809  status = STATE_RUN_SUCCESS;
1810  }
1811  else
1812  {
1813  char flag_buffer[256] = { 0 };
1814  char mask_buffer[256] = { 0 };
1815  WLog_Print(rdp->log, WLOG_WARN,
1816  "[%s] unexpected server message, expected flag %s [have %s]",
1817  rdp_get_state_string(rdp),
1818  rdp_finalize_flags_to_str(flag, flag_buffer, sizeof(flag_buffer)),
1819  rdp_finalize_flags_to_str(flags, mask_buffer, sizeof(mask_buffer)));
1820  }
1821  }
1822  return status;
1823 }
1824 
1825 static state_run_t rdp_client_exchange_monitor_layout(rdpRdp* rdp, wStream* s)
1826 {
1827  WINPR_ASSERT(rdp);
1828 
1829  if (!rdp_check_monitor_layout_pdu_state(rdp, FALSE))
1830  return FALSE;
1831 
1832  /* We might receive unrelated messages from the server (channel traffic),
1833  * so only proceed if some flag changed
1834  */
1835  const UINT32 old = rdp->finalize_sc_pdus;
1836  state_run_t status = rdp_recv_pdu(rdp, s);
1837  const UINT32 now = rdp->finalize_sc_pdus;
1838  const BOOL changed = (old != now) || rdp->monitor_layout_pdu;
1839 
1840  /* This PDU is optional, so if we received a finalize PDU continue there */
1841  if (state_run_success(status) && changed)
1842  {
1843  if (!rdp->monitor_layout_pdu)
1844  {
1845  if (!rdp_finalize_is_flag_set(rdp, FINALIZE_SC_SYNCHRONIZE_PDU))
1846  return STATE_RUN_FAILED;
1847  }
1848 
1849  status = rdp_client_connect_finalize(rdp);
1850  if (state_run_success(status) && !rdp->monitor_layout_pdu)
1851  status = STATE_RUN_TRY_AGAIN;
1852  }
1853  return status;
1854 }
1855 
1856 static state_run_t rdp_recv_callback_int(rdpTransport* transport, wStream* s, void* extra)
1857 {
1858  state_run_t status = STATE_RUN_SUCCESS;
1859  rdpRdp* rdp = (rdpRdp*)extra;
1860 
1861  WINPR_ASSERT(transport);
1862  WINPR_ASSERT(rdp);
1863  WINPR_ASSERT(s);
1864 
1865  switch (rdp_get_state(rdp))
1866  {
1867  case CONNECTION_STATE_NEGO:
1868  if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_REQUEST))
1869  status = STATE_RUN_FAILED;
1870  else
1871  status = STATE_RUN_CONTINUE;
1872  break;
1873  case CONNECTION_STATE_NLA:
1874  if (nla_get_state(rdp->nla) < NLA_STATE_AUTH_INFO)
1875  {
1876  if (nla_recv_pdu(rdp->nla, s) < 1)
1877  {
1878  WLog_Print(rdp->log, WLOG_ERROR, "%s - nla_recv_pdu() fail",
1879  rdp_get_state_string(rdp));
1880  status = STATE_RUN_FAILED;
1881  }
1882  }
1883  else if (nla_get_state(rdp->nla) == NLA_STATE_POST_NEGO)
1884  {
1885  nego_recv(rdp->transport, s, (void*)rdp->nego);
1886 
1887  if (!nego_update_settings_from_state(rdp->nego, rdp->settings))
1888  return FALSE;
1889 
1890  if (nego_get_state(rdp->nego) != NEGO_STATE_FINAL)
1891  {
1892  WLog_Print(rdp->log, WLOG_ERROR, "%s - nego_recv() fail",
1893  rdp_get_state_string(rdp));
1894  status = STATE_RUN_FAILED;
1895  }
1896  else if (!nla_set_state(rdp->nla, NLA_STATE_FINAL))
1897  status = STATE_RUN_FAILED;
1898  }
1899 
1900  if (state_run_success(status))
1901  {
1902  if (nla_get_state(rdp->nla) == NLA_STATE_AUTH_INFO)
1903  {
1904  transport_set_nla_mode(rdp->transport, FALSE);
1905 
1906  if (rdp->settings->VmConnectMode)
1907  {
1908  if (!nego_set_state(rdp->nego, NEGO_STATE_NLA))
1909  status = STATE_RUN_FAILED;
1910  else if (!nego_set_requested_protocols(rdp->nego,
1911  PROTOCOL_HYBRID | PROTOCOL_SSL))
1912  status = STATE_RUN_FAILED;
1913  else if (!nego_send_negotiation_request(rdp->nego))
1914  status = STATE_RUN_FAILED;
1915  else if (!nla_set_state(rdp->nla, NLA_STATE_POST_NEGO))
1916  status = STATE_RUN_FAILED;
1917  }
1918  else
1919  {
1920  if (!nla_set_state(rdp->nla, NLA_STATE_FINAL))
1921  status = STATE_RUN_FAILED;
1922  }
1923  }
1924  }
1925  if (state_run_success(status))
1926  {
1927 
1928  if (nla_get_state(rdp->nla) == NLA_STATE_FINAL)
1929  {
1930  if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_REQUEST))
1931  status = STATE_RUN_FAILED;
1932  else
1933  status = STATE_RUN_CONTINUE;
1934  }
1935  }
1936  break;
1937 
1938  case CONNECTION_STATE_AAD:
1939  if (aad_recv(rdp->aad, s) < 1)
1940  {
1941  WLog_Print(rdp->log, WLOG_ERROR, "%s - aad_recv() fail", rdp_get_state_string(rdp));
1942  status = STATE_RUN_FAILED;
1943  }
1944  if (state_run_success(status))
1945  {
1946  if (aad_get_state(rdp->aad) == AAD_STATE_FINAL)
1947  {
1948  transport_set_aad_mode(rdp->transport, FALSE);
1949  if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_REQUEST))
1950  status = STATE_RUN_FAILED;
1951  else
1952  status = STATE_RUN_CONTINUE;
1953  }
1954  }
1955  break;
1956 
1957  case CONNECTION_STATE_MCS_CREATE_REQUEST:
1958  if (!mcs_client_begin(rdp->mcs))
1959  {
1960  WLog_Print(rdp->log, WLOG_ERROR, "%s - mcs_client_begin() fail",
1961  rdp_get_state_string(rdp));
1962  status = STATE_RUN_FAILED;
1963  }
1964  else if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_RESPONSE))
1965  status = STATE_RUN_FAILED;
1966  else if (Stream_GetRemainingLength(s) > 0)
1967  status = STATE_RUN_CONTINUE;
1968  break;
1969 
1970  case CONNECTION_STATE_MCS_CREATE_RESPONSE:
1971  if (!mcs_recv_connect_response(rdp->mcs, s))
1972  {
1973  WLog_Print(rdp->log, WLOG_ERROR, "mcs_recv_connect_response failure");
1974  status = STATE_RUN_FAILED;
1975  }
1976  else
1977  {
1978  if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_ERECT_DOMAIN))
1979  status = STATE_RUN_FAILED;
1980  else if (!mcs_send_erect_domain_request(rdp->mcs))
1981  {
1982  WLog_Print(rdp->log, WLOG_ERROR, "mcs_send_erect_domain_request failure");
1983  status = STATE_RUN_FAILED;
1984  }
1985  else if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_ATTACH_USER))
1986  status = STATE_RUN_FAILED;
1987  else if (!mcs_send_attach_user_request(rdp->mcs))
1988  {
1989  WLog_Print(rdp->log, WLOG_ERROR, "mcs_send_attach_user_request failure");
1990  status = STATE_RUN_FAILED;
1991  }
1992  else if (!rdp_client_transition_to_state(rdp,
1993  CONNECTION_STATE_MCS_ATTACH_USER_CONFIRM))
1994  status = STATE_RUN_FAILED;
1995  }
1996  break;
1997 
1998  case CONNECTION_STATE_MCS_ATTACH_USER_CONFIRM:
1999  if (!mcs_recv_attach_user_confirm(rdp->mcs, s))
2000  {
2001  WLog_Print(rdp->log, WLOG_ERROR, "mcs_recv_attach_user_confirm failure");
2002  status = STATE_RUN_FAILED;
2003  }
2004  else if (!freerdp_settings_get_bool(rdp->settings, FreeRDP_SupportSkipChannelJoin))
2005  {
2006  if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST))
2007  status = STATE_RUN_FAILED;
2008  else if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->userId))
2009  {
2010  WLog_Print(rdp->log, WLOG_ERROR, "mcs_send_channel_join_request failure");
2011  status = STATE_RUN_FAILED;
2012  }
2013  else if (!rdp_client_transition_to_state(
2014  rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
2015  status = STATE_RUN_FAILED;
2016  }
2017  else
2018  {
2019  /* SKIP_CHANNELJOIN is active, consider channels to be joined */
2020  if (!rdp_client_skip_mcs_channel_join(rdp))
2021  status = STATE_RUN_FAILED;
2022  }
2023  break;
2024 
2025  case CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE:
2026  if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s))
2027  {
2028  WLog_Print(rdp->log, WLOG_ERROR,
2029  "%s - "
2030  "rdp_client_connect_mcs_channel_join_confirm() fail",
2031  rdp_get_state_string(rdp));
2032  status = STATE_RUN_FAILED;
2033  }
2034 
2035  break;
2036 
2037  case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST:
2038  if (!rdp_client_connect_auto_detect(rdp, s))
2039  {
2040  if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_LICENSING))
2041  status = STATE_RUN_FAILED;
2042  else
2043  status = STATE_RUN_TRY_AGAIN;
2044  }
2045  break;
2046 
2047  case CONNECTION_STATE_LICENSING:
2048  status = rdp_client_connect_license(rdp, s);
2049 
2050  if (state_run_failed(status))
2051  {
2052  char buffer[64] = { 0 };
2053  WLog_Print(rdp->log, WLOG_DEBUG, "%s - rdp_client_connect_license() - %s",
2054  rdp_get_state_string(rdp),
2055  state_run_result_string(status, buffer, ARRAYSIZE(buffer)));
2056  }
2057 
2058  break;
2059 
2060  case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_REQUEST:
2061  if (!rdp_client_connect_auto_detect(rdp, s))
2062  {
2063  (void)rdp_client_transition_to_state(
2064  rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE);
2065  status = STATE_RUN_TRY_AGAIN;
2066  }
2067  break;
2068 
2069  case CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE:
2070  status = rdp_client_connect_demand_active(rdp, s);
2071 
2072  if (state_run_failed(status))
2073  {
2074  char buffer[64] = { 0 };
2075  WLog_Print(rdp->log, WLOG_DEBUG,
2076  "%s - "
2077  "rdp_client_connect_demand_active() - %s",
2078  rdp_get_state_string(rdp),
2079  state_run_result_string(status, buffer, ARRAYSIZE(buffer)));
2080  }
2081  else if (status == STATE_RUN_ACTIVE)
2082  {
2083  if (!rdp_client_transition_to_state(
2084  rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE))
2085  status = STATE_RUN_FAILED;
2086  else
2087  status = STATE_RUN_CONTINUE;
2088  }
2089  break;
2090 
2091  case CONNECTION_STATE_CAPABILITIES_EXCHANGE_MONITOR_LAYOUT:
2092  status = rdp_client_exchange_monitor_layout(rdp, s);
2093  break;
2094 
2095  case CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE:
2096  status = rdp_client_connect_confirm_active(rdp, s);
2097  break;
2098 
2099  case CONNECTION_STATE_FINALIZATION_CLIENT_SYNC:
2100  status = rdp_handle_sc_flags(rdp, s, FINALIZE_SC_SYNCHRONIZE_PDU,
2101  CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE);
2102  break;
2103  case CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE:
2104  status = rdp_handle_sc_flags(rdp, s, FINALIZE_SC_CONTROL_COOPERATE_PDU,
2105  CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL);
2106  break;
2107  case CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL:
2108  status = rdp_handle_sc_flags(rdp, s, FINALIZE_SC_CONTROL_GRANTED_PDU,
2109  CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP);
2110  break;
2111  case CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP:
2112  status = rdp_handle_sc_flags(rdp, s, FINALIZE_SC_FONT_MAP_PDU, CONNECTION_STATE_ACTIVE);
2113  break;
2114 
2115  case CONNECTION_STATE_ACTIVE:
2116  status = rdp_recv_pdu(rdp, s);
2117 
2118  if (state_run_failed(status))
2119  {
2120  char buffer[64] = { 0 };
2121  WLog_Print(rdp->log, WLOG_DEBUG, "%s - rdp_recv_pdu() - %s",
2122  rdp_get_state_string(rdp),
2123  state_run_result_string(status, buffer, ARRAYSIZE(buffer)));
2124  }
2125  break;
2126 
2127  default:
2128  WLog_Print(rdp->log, WLOG_ERROR, "%s state %d", rdp_get_state_string(rdp),
2129  rdp_get_state(rdp));
2130  status = STATE_RUN_FAILED;
2131  break;
2132  }
2133 
2134  if (state_run_failed(status))
2135  {
2136  char buffer[64] = { 0 };
2137  WLog_Print(rdp->log, WLOG_ERROR, "%s status %s", rdp_get_state_string(rdp),
2138  state_run_result_string(status, buffer, ARRAYSIZE(buffer)));
2139  }
2140  return status;
2141 }
2142 
2143 state_run_t rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
2144 {
2145  char buffer[64] = { 0 };
2146  state_run_t rc = STATE_RUN_FAILED;
2147  const size_t start = Stream_GetPosition(s);
2148  const rdpContext* context = transport_get_context(transport);
2149 
2150  WINPR_ASSERT(context);
2151  do
2152  {
2153  const rdpRdp* rdp = context->rdp;
2154  WINPR_ASSERT(rdp);
2155 
2156  if (rc == STATE_RUN_TRY_AGAIN)
2157  Stream_SetPosition(s, start);
2158 
2159  const char* old = rdp_get_state_string(rdp);
2160  const size_t orem = Stream_GetRemainingLength(s);
2161  rc = rdp_recv_callback_int(transport, s, extra);
2162 
2163  const char* now = rdp_get_state_string(rdp);
2164  const size_t rem = Stream_GetRemainingLength(s);
2165 
2166  WLog_Print(rdp->log, WLOG_TRACE,
2167  "(client)[%s -> %s] current return %s [feeding %" PRIuz " bytes, %" PRIuz
2168  " bytes not processed]",
2169  old, now, state_run_result_string(rc, buffer, sizeof(buffer)), orem, rem);
2170  } while ((rc == STATE_RUN_TRY_AGAIN) || (rc == STATE_RUN_CONTINUE));
2171  return rc;
2172 }
2173 
2174 BOOL rdp_send_channel_data(rdpRdp* rdp, UINT16 channelId, const BYTE* data, size_t size)
2175 {
2176  return freerdp_channel_send(rdp, channelId, data, size);
2177 }
2178 
2179 BOOL rdp_channel_send_packet(rdpRdp* rdp, UINT16 channelId, size_t totalSize, UINT32 flags,
2180  const BYTE* data, size_t chunkSize)
2181 {
2182  return freerdp_channel_send_packet(rdp, channelId, totalSize, flags, data, chunkSize);
2183 }
2184 
2185 BOOL rdp_send_error_info(rdpRdp* rdp)
2186 {
2187  wStream* s = NULL;
2188  BOOL status = 0;
2189 
2190  if (rdp->errorInfo == ERRINFO_SUCCESS)
2191  return TRUE;
2192 
2193  s = rdp_data_pdu_init(rdp);
2194 
2195  if (!s)
2196  return FALSE;
2197 
2198  Stream_Write_UINT32(s, rdp->errorInfo); /* error id (4 bytes) */
2199  status = rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SET_ERROR_INFO, 0);
2200  return status;
2201 }
2202 
2203 int rdp_check_fds(rdpRdp* rdp)
2204 {
2205  int status = 0;
2206  rdpTsg* tsg = NULL;
2207  rdpTransport* transport = NULL;
2208 
2209  WINPR_ASSERT(rdp);
2210  transport = rdp->transport;
2211 
2212  tsg = transport_get_tsg(transport);
2213  if (tsg)
2214  {
2215  if (!tsg_check_event_handles(tsg))
2216  {
2217  WLog_Print(rdp->log, WLOG_ERROR, "rdp_check_fds: tsg_check_event_handles()");
2218  return -1;
2219  }
2220 
2221  if (tsg_get_state(tsg) != TSG_STATE_PIPE_CREATED)
2222  return 1;
2223  }
2224 
2225  status = transport_check_fds(transport);
2226 
2227  if (status == 1)
2228  {
2229  if (!rdp_client_redirect(rdp)) /* session redirection */
2230  return -1;
2231  }
2232 
2233  if (status < 0)
2234  WLog_Print(rdp->log, WLOG_DEBUG, "transport_check_fds() - %i", status);
2235 
2236  return status;
2237 }
2238 
2239 BOOL freerdp_get_stats(rdpRdp* rdp, UINT64* inBytes, UINT64* outBytes, UINT64* inPackets,
2240  UINT64* outPackets)
2241 {
2242  if (!rdp)
2243  return FALSE;
2244 
2245  if (inBytes)
2246  *inBytes = rdp->inBytes;
2247  if (outBytes)
2248  *outBytes = rdp->outBytes;
2249  if (inPackets)
2250  *inPackets = rdp->inPackets;
2251  if (outPackets)
2252  *outPackets = rdp->outPackets;
2253 
2254  return TRUE;
2255 }
2256 
2262 rdpRdp* rdp_new(rdpContext* context)
2263 {
2264  rdpRdp* rdp = NULL;
2265  DWORD flags = 0;
2266  rdp = (rdpRdp*)calloc(1, sizeof(rdpRdp));
2267 
2268  if (!rdp)
2269  return NULL;
2270 
2271  rdp->log = WLog_Get(RDP_TAG);
2272  WINPR_ASSERT(rdp->log);
2273 
2274  (void)_snprintf(rdp->log_context, sizeof(rdp->log_context), "%p", (void*)context);
2275  WLog_SetContext(rdp->log, NULL, rdp->log_context);
2276 
2277  InitializeCriticalSection(&rdp->critical);
2278  rdp->context = context;
2279  WINPR_ASSERT(rdp->context);
2280 
2281  if (context->ServerMode)
2283 
2284  if (!context->settings)
2285  {
2286  context->settings = rdp->settings = freerdp_settings_new(flags);
2287 
2288  if (!rdp->settings)
2289  goto fail;
2290  }
2291  else
2292  rdp->settings = context->settings;
2293 
2294  /* Keep a backup copy of settings for later comparisons */
2295  if (!rdp_set_backup_settings(rdp))
2296  goto fail;
2297 
2298  rdp->settings->instance = context->instance;
2299 
2300  context->settings = rdp->settings;
2301  if (context->instance)
2302  context->settings->instance = context->instance;
2303  else if (context->peer)
2304  {
2305  rdp->settings->instance = context->peer;
2306 
2307 #if defined(WITH_FREERDP_DEPRECATED)
2308  context->peer->settings = rdp->settings;
2309 #endif
2310  }
2311 
2312  rdp->transport = transport_new(context);
2313 
2314  if (!rdp->transport)
2315  goto fail;
2316 
2317  {
2318  const rdpTransportIo* io = transport_get_io_callbacks(rdp->transport);
2319  if (!io)
2320  goto fail;
2321  rdp->io = calloc(1, sizeof(rdpTransportIo));
2322  if (!rdp->io)
2323  goto fail;
2324  *rdp->io = *io;
2325  }
2326 
2327  rdp->aad = aad_new(context, rdp->transport);
2328  if (!rdp->aad)
2329  goto fail;
2330 
2331  rdp->license = license_new(rdp);
2332 
2333  if (!rdp->license)
2334  goto fail;
2335 
2336  rdp->input = input_new(rdp);
2337 
2338  if (!rdp->input)
2339  goto fail;
2340 
2341  rdp->update = update_new(rdp);
2342 
2343  if (!rdp->update)
2344  goto fail;
2345 
2346  rdp->fastpath = fastpath_new(rdp);
2347 
2348  if (!rdp->fastpath)
2349  goto fail;
2350 
2351  rdp->nego = nego_new(rdp->transport);
2352 
2353  if (!rdp->nego)
2354  goto fail;
2355 
2356  rdp->mcs = mcs_new(rdp->transport);
2357 
2358  if (!rdp->mcs)
2359  goto fail;
2360 
2361  rdp->redirection = redirection_new();
2362 
2363  if (!rdp->redirection)
2364  goto fail;
2365 
2366  rdp->autodetect = autodetect_new(rdp->context);
2367 
2368  if (!rdp->autodetect)
2369  goto fail;
2370 
2371  rdp->heartbeat = heartbeat_new();
2372 
2373  if (!rdp->heartbeat)
2374  goto fail;
2375 
2376  rdp->multitransport = multitransport_new(rdp, INITIATE_REQUEST_PROTOCOL_UDPFECL |
2377  INITIATE_REQUEST_PROTOCOL_UDPFECR);
2378 
2379  if (!rdp->multitransport)
2380  goto fail;
2381 
2382  rdp->bulk = bulk_new(context);
2383 
2384  if (!rdp->bulk)
2385  goto fail;
2386 
2387  rdp->pubSub = PubSub_New(TRUE);
2388  if (!rdp->pubSub)
2389  goto fail;
2390 
2391  rdp->abortEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
2392  if (!rdp->abortEvent)
2393  goto fail;
2394  return rdp;
2395 
2396 fail:
2397  WINPR_PRAGMA_DIAG_PUSH
2398  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2399  rdp_free(rdp);
2400  WINPR_PRAGMA_DIAG_POP
2401  return NULL;
2402 }
2403 
2404 static void rdp_reset_free(rdpRdp* rdp)
2405 {
2406  WINPR_ASSERT(rdp);
2407 
2408  (void)security_lock(rdp);
2409  rdp_free_rc4_decrypt_keys(rdp);
2410  rdp_free_rc4_encrypt_keys(rdp);
2411 
2412  winpr_Cipher_Free(rdp->fips_encrypt);
2413  winpr_Cipher_Free(rdp->fips_decrypt);
2414  rdp->fips_encrypt = NULL;
2415  rdp->fips_decrypt = NULL;
2416  (void)security_unlock(rdp);
2417 
2418  mcs_free(rdp->mcs);
2419  nego_free(rdp->nego);
2420  license_free(rdp->license);
2421  transport_free(rdp->transport);
2422  fastpath_free(rdp->fastpath);
2423 
2424  rdp->mcs = NULL;
2425  rdp->nego = NULL;
2426  rdp->license = NULL;
2427  rdp->transport = NULL;
2428  rdp->fastpath = NULL;
2429 }
2430 
2431 BOOL rdp_reset(rdpRdp* rdp)
2432 {
2433  BOOL rc = TRUE;
2434  rdpContext* context = NULL;
2435  rdpSettings* settings = NULL;
2436 
2437  WINPR_ASSERT(rdp);
2438 
2439  context = rdp->context;
2440  WINPR_ASSERT(context);
2441 
2442  settings = rdp->settings;
2443  WINPR_ASSERT(settings);
2444 
2445  bulk_reset(rdp->bulk);
2446 
2447  rdp_reset_free(rdp);
2448 
2449  if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ServerRandom, NULL, 0))
2450  rc = FALSE;
2451 
2452  if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ServerCertificate, NULL, 0))
2453  rc = FALSE;
2454 
2455  if (!freerdp_settings_set_string(settings, FreeRDP_ClientAddress, NULL))
2456  rc = FALSE;
2457 
2458  if (!rc)
2459  goto fail;
2460 
2461  rc = FALSE;
2462  rdp->transport = transport_new(context);
2463  if (!rdp->transport)
2464  goto fail;
2465 
2466  if (rdp->io)
2467  {
2468  if (!transport_set_io_callbacks(rdp->transport, rdp->io))
2469  goto fail;
2470  }
2471 
2472  aad_free(rdp->aad);
2473  rdp->aad = aad_new(context, rdp->transport);
2474  if (!rdp->aad)
2475  goto fail;
2476 
2477  rdp->nego = nego_new(rdp->transport);
2478  if (!rdp->nego)
2479  goto fail;
2480 
2481  rdp->mcs = mcs_new(rdp->transport);
2482  if (!rdp->mcs)
2483  goto fail;
2484 
2485  if (!transport_set_layer(rdp->transport, TRANSPORT_LAYER_TCP))
2486  goto fail;
2487 
2488  rdp->license = license_new(rdp);
2489  if (!rdp->license)
2490  goto fail;
2491 
2492  rdp->fastpath = fastpath_new(rdp);
2493  if (!rdp->fastpath)
2494  goto fail;
2495 
2496  rdp->errorInfo = 0;
2497  rc = rdp_finalize_reset_flags(rdp, TRUE);
2498 
2499 fail:
2500  return rc;
2501 }
2502 
2508 void rdp_free(rdpRdp* rdp)
2509 {
2510  if (rdp)
2511  {
2512  rdp_reset_free(rdp);
2513 
2514  freerdp_settings_free(rdp->settings);
2515  freerdp_settings_free(rdp->originalSettings);
2516  freerdp_settings_free(rdp->remoteSettings);
2517 
2518  input_free(rdp->input);
2519  update_free(rdp->update);
2520  nla_free(rdp->nla);
2521  redirection_free(rdp->redirection);
2522  autodetect_free(rdp->autodetect);
2523  heartbeat_free(rdp->heartbeat);
2524  multitransport_free(rdp->multitransport);
2525  bulk_free(rdp->bulk);
2526  free(rdp->io);
2527  PubSub_Free(rdp->pubSub);
2528  if (rdp->abortEvent)
2529  (void)CloseHandle(rdp->abortEvent);
2530  aad_free(rdp->aad);
2531  WINPR_JSON_Delete(rdp->wellknown);
2532  DeleteCriticalSection(&rdp->critical);
2533  free(rdp);
2534  }
2535 }
2536 
2537 BOOL rdp_io_callback_set_event(rdpRdp* rdp, BOOL set)
2538 {
2539  if (!rdp)
2540  return FALSE;
2541  return transport_io_callback_set_event(rdp->transport, set);
2542 }
2543 
2544 const rdpTransportIo* rdp_get_io_callbacks(rdpRdp* rdp)
2545 {
2546  if (!rdp)
2547  return NULL;
2548  return rdp->io;
2549 }
2550 
2551 BOOL rdp_set_io_callbacks(rdpRdp* rdp, const rdpTransportIo* io_callbacks)
2552 {
2553  if (!rdp)
2554  return FALSE;
2555  free(rdp->io);
2556  rdp->io = NULL;
2557  if (io_callbacks)
2558  {
2559  rdp->io = malloc(sizeof(rdpTransportIo));
2560  if (!rdp->io)
2561  return FALSE;
2562  *rdp->io = *io_callbacks;
2563  return transport_set_io_callbacks(rdp->transport, rdp->io);
2564  }
2565  return TRUE;
2566 }
2567 
2568 BOOL rdp_set_io_callback_context(rdpRdp* rdp, void* usercontext)
2569 {
2570  WINPR_ASSERT(rdp);
2571  rdp->ioContext = usercontext;
2572  return TRUE;
2573 }
2574 
2575 void* rdp_get_io_callback_context(rdpRdp* rdp)
2576 {
2577  WINPR_ASSERT(rdp);
2578  return rdp->ioContext;
2579 }
2580 
2581 const char* rdp_finalize_flags_to_str(UINT32 flags, char* buffer, size_t size)
2582 {
2583  char number[32] = { 0 };
2584  const UINT32 mask =
2585  (uint32_t)~(FINALIZE_SC_SYNCHRONIZE_PDU | FINALIZE_SC_CONTROL_COOPERATE_PDU |
2586  FINALIZE_SC_CONTROL_GRANTED_PDU | FINALIZE_SC_FONT_MAP_PDU |
2587  FINALIZE_CS_SYNCHRONIZE_PDU | FINALIZE_CS_CONTROL_COOPERATE_PDU |
2588  FINALIZE_CS_CONTROL_REQUEST_PDU | FINALIZE_CS_PERSISTENT_KEY_LIST_PDU |
2589  FINALIZE_CS_FONT_LIST_PDU | FINALIZE_DEACTIVATE_REACTIVATE);
2590 
2591  if (flags & FINALIZE_SC_SYNCHRONIZE_PDU)
2592  winpr_str_append("FINALIZE_SC_SYNCHRONIZE_PDU", buffer, size, "|");
2593  if (flags & FINALIZE_SC_CONTROL_COOPERATE_PDU)
2594  winpr_str_append("FINALIZE_SC_CONTROL_COOPERATE_PDU", buffer, size, "|");
2595  if (flags & FINALIZE_SC_CONTROL_GRANTED_PDU)
2596  winpr_str_append("FINALIZE_SC_CONTROL_GRANTED_PDU", buffer, size, "|");
2597  if (flags & FINALIZE_SC_FONT_MAP_PDU)
2598  winpr_str_append("FINALIZE_SC_FONT_MAP_PDU", buffer, size, "|");
2599  if (flags & FINALIZE_CS_SYNCHRONIZE_PDU)
2600  winpr_str_append("FINALIZE_CS_SYNCHRONIZE_PDU", buffer, size, "|");
2601  if (flags & FINALIZE_CS_CONTROL_COOPERATE_PDU)
2602  winpr_str_append("FINALIZE_CS_CONTROL_COOPERATE_PDU", buffer, size, "|");
2603  if (flags & FINALIZE_CS_CONTROL_REQUEST_PDU)
2604  winpr_str_append("FINALIZE_CS_CONTROL_REQUEST_PDU", buffer, size, "|");
2605  if (flags & FINALIZE_CS_PERSISTENT_KEY_LIST_PDU)
2606  winpr_str_append("FINALIZE_CS_PERSISTENT_KEY_LIST_PDU", buffer, size, "|");
2607  if (flags & FINALIZE_CS_FONT_LIST_PDU)
2608  winpr_str_append("FINALIZE_CS_FONT_LIST_PDU", buffer, size, "|");
2609  if (flags & FINALIZE_DEACTIVATE_REACTIVATE)
2610  winpr_str_append("FINALIZE_DEACTIVATE_REACTIVATE", buffer, size, "|");
2611  if (flags & mask)
2612  winpr_str_append("UNKNOWN_FLAG", buffer, size, "|");
2613  if (flags == 0)
2614  winpr_str_append("NO_FLAG_SET", buffer, size, "|");
2615  (void)_snprintf(number, sizeof(number), " [0x%08" PRIx32 "]", flags);
2616  winpr_str_append(number, buffer, size, "");
2617  return buffer;
2618 }
2619 
2620 BOOL rdp_finalize_reset_flags(rdpRdp* rdp, BOOL clearAll)
2621 {
2622  WINPR_ASSERT(rdp);
2623  WLog_Print(rdp->log, WLOG_DEBUG, "[%s] reset finalize_sc_pdus", rdp_get_state_string(rdp));
2624  if (clearAll)
2625  rdp->finalize_sc_pdus = 0;
2626  else
2627  rdp->finalize_sc_pdus &= FINALIZE_DEACTIVATE_REACTIVATE;
2628 
2629  return rdp_set_monitor_layout_pdu_state(rdp, FALSE);
2630 }
2631 
2632 BOOL rdp_finalize_set_flag(rdpRdp* rdp, UINT32 flag)
2633 {
2634  char buffer[1024] = { 0 };
2635 
2636  WINPR_ASSERT(rdp);
2637 
2638  WLog_Print(rdp->log, WLOG_DEBUG, "[%s] received flag %s", rdp_get_state_string(rdp),
2639  rdp_finalize_flags_to_str(flag, buffer, sizeof(buffer)));
2640  rdp->finalize_sc_pdus |= flag;
2641  return TRUE;
2642 }
2643 
2644 BOOL rdp_finalize_is_flag_set(rdpRdp* rdp, UINT32 flag)
2645 {
2646  WINPR_ASSERT(rdp);
2647  return (rdp->finalize_sc_pdus & flag) == flag;
2648 }
2649 
2650 BOOL rdp_reset_rc4_encrypt_keys(rdpRdp* rdp)
2651 {
2652  WINPR_ASSERT(rdp);
2653  rdp_free_rc4_encrypt_keys(rdp);
2654  rdp->rc4_encrypt_key = winpr_RC4_New(rdp->encrypt_key, rdp->rc4_key_len);
2655 
2656  rdp->encrypt_use_count = 0;
2657  return rdp->rc4_encrypt_key != NULL;
2658 }
2659 
2660 void rdp_free_rc4_encrypt_keys(rdpRdp* rdp)
2661 {
2662  WINPR_ASSERT(rdp);
2663  winpr_RC4_Free(rdp->rc4_encrypt_key);
2664  rdp->rc4_encrypt_key = NULL;
2665 }
2666 
2667 void rdp_free_rc4_decrypt_keys(rdpRdp* rdp)
2668 {
2669  WINPR_ASSERT(rdp);
2670  winpr_RC4_Free(rdp->rc4_decrypt_key);
2671  rdp->rc4_decrypt_key = NULL;
2672 }
2673 
2674 BOOL rdp_reset_rc4_decrypt_keys(rdpRdp* rdp)
2675 {
2676  WINPR_ASSERT(rdp);
2677  rdp_free_rc4_decrypt_keys(rdp);
2678  rdp->rc4_decrypt_key = winpr_RC4_New(rdp->decrypt_key, rdp->rc4_key_len);
2679 
2680  rdp->decrypt_use_count = 0;
2681  return rdp->rc4_decrypt_key != NULL;
2682 }
2683 
2684 const char* rdp_security_flag_string(UINT32 securityFlags, char* buffer, size_t size)
2685 {
2686  if (securityFlags & SEC_EXCHANGE_PKT)
2687  winpr_str_append("SEC_EXCHANGE_PKT", buffer, size, "|");
2688  if (securityFlags & SEC_TRANSPORT_REQ)
2689  winpr_str_append("SEC_TRANSPORT_REQ", buffer, size, "|");
2690  if (securityFlags & SEC_TRANSPORT_RSP)
2691  winpr_str_append("SEC_TRANSPORT_RSP", buffer, size, "|");
2692  if (securityFlags & SEC_ENCRYPT)
2693  winpr_str_append("SEC_ENCRYPT", buffer, size, "|");
2694  if (securityFlags & SEC_RESET_SEQNO)
2695  winpr_str_append("SEC_RESET_SEQNO", buffer, size, "|");
2696  if (securityFlags & SEC_IGNORE_SEQNO)
2697  winpr_str_append("SEC_IGNORE_SEQNO", buffer, size, "|");
2698  if (securityFlags & SEC_INFO_PKT)
2699  winpr_str_append("SEC_INFO_PKT", buffer, size, "|");
2700  if (securityFlags & SEC_LICENSE_PKT)
2701  winpr_str_append("SEC_LICENSE_PKT", buffer, size, "|");
2702  if (securityFlags & SEC_LICENSE_ENCRYPT_CS)
2703  winpr_str_append("SEC_LICENSE_ENCRYPT_CS", buffer, size, "|");
2704  if (securityFlags & SEC_LICENSE_ENCRYPT_SC)
2705  winpr_str_append("SEC_LICENSE_ENCRYPT_SC", buffer, size, "|");
2706  if (securityFlags & SEC_REDIRECTION_PKT)
2707  winpr_str_append("SEC_REDIRECTION_PKT", buffer, size, "|");
2708  if (securityFlags & SEC_SECURE_CHECKSUM)
2709  winpr_str_append("SEC_SECURE_CHECKSUM", buffer, size, "|");
2710  if (securityFlags & SEC_AUTODETECT_REQ)
2711  winpr_str_append("SEC_AUTODETECT_REQ", buffer, size, "|");
2712  if (securityFlags & SEC_AUTODETECT_RSP)
2713  winpr_str_append("SEC_AUTODETECT_RSP", buffer, size, "|");
2714  if (securityFlags & SEC_HEARTBEAT)
2715  winpr_str_append("SEC_HEARTBEAT", buffer, size, "|");
2716  if (securityFlags & SEC_FLAGSHI_VALID)
2717  winpr_str_append("SEC_FLAGSHI_VALID", buffer, size, "|");
2718  {
2719  char msg[32] = { 0 };
2720 
2721  (void)_snprintf(msg, sizeof(msg), "[0x%08" PRIx32 "]", securityFlags);
2722  winpr_str_append(msg, buffer, size, "");
2723  }
2724  return buffer;
2725 }
2726 
2727 static BOOL rdp_reset_remote_settings(rdpRdp* rdp)
2728 {
2729  UINT32 flags = FREERDP_SETTINGS_REMOTE_MODE;
2730  WINPR_ASSERT(rdp);
2731  freerdp_settings_free(rdp->remoteSettings);
2732 
2733  if (!freerdp_settings_get_bool(rdp->settings, FreeRDP_ServerMode))
2735  rdp->remoteSettings = freerdp_settings_new(flags);
2736  return rdp->remoteSettings != NULL;
2737 }
2738 
2739 BOOL rdp_set_backup_settings(rdpRdp* rdp)
2740 {
2741  WINPR_ASSERT(rdp);
2742  freerdp_settings_free(rdp->originalSettings);
2743  rdp->originalSettings = freerdp_settings_clone(rdp->settings);
2744  if (!rdp->originalSettings)
2745  return FALSE;
2746  return rdp_reset_remote_settings(rdp);
2747 }
2748 
2749 BOOL rdp_reset_runtime_settings(rdpRdp* rdp)
2750 {
2751  WINPR_ASSERT(rdp);
2752  WINPR_ASSERT(rdp->context);
2753 
2754  freerdp_settings_free(rdp->settings);
2755  rdp->context->settings = rdp->settings = freerdp_settings_clone(rdp->originalSettings);
2756 
2757  if (!rdp->settings)
2758  return FALSE;
2759  return rdp_reset_remote_settings(rdp);
2760 }
2761 
2762 static BOOL starts_with(const char* tok, const char* val)
2763 {
2764  const size_t len = strlen(val);
2765  if (strncmp(tok, val, len) != 0)
2766  return FALSE;
2767  if (tok[len] != '=')
2768  return FALSE;
2769  return TRUE;
2770 }
2771 
2772 static BOOL option_equals(const char* what, const char* val)
2773 {
2774  return _stricmp(what, val) == 0;
2775 }
2776 
2777 static BOOL parse_on_off_option(const char* value)
2778 {
2779  WINPR_ASSERT(value);
2780  const char* sep = strchr(value, '=');
2781  if (!sep)
2782  return TRUE;
2783  if (option_equals("on", &sep[1]))
2784  return TRUE;
2785  if (option_equals("true", &sep[1]))
2786  return TRUE;
2787  if (option_equals("off", &sep[1]))
2788  return FALSE;
2789  if (option_equals("false", &sep[1]))
2790  return FALSE;
2791 
2792  errno = 0;
2793  long val = strtol(value, NULL, 0);
2794  if (errno == 0)
2795  return val == 0 ? FALSE : TRUE;
2796 
2797  return FALSE;
2798 }
2799 
2800 #define STR(x) #x
2801 
2802 static BOOL option_is_runtime_checks(wLog* log, const char* tok)
2803 {
2804  const char* experimental[] = { STR(WITH_VERBOSE_WINPR_ASSERT) };
2805  for (size_t x = 0; x < ARRAYSIZE(experimental); x++)
2806  {
2807  const char* opt = experimental[x];
2808  if (starts_with(tok, opt))
2809  {
2810  return parse_on_off_option(tok);
2811  }
2812  }
2813  return FALSE;
2814 }
2815 
2816 static BOOL option_is_experimental(wLog* log, const char* tok)
2817 {
2818  const char* experimental[] = { STR(WITH_DSP_EXPERIMENTAL), STR(WITH_VAAPI) };
2819  for (size_t x = 0; x < ARRAYSIZE(experimental); x++)
2820  {
2821  const char* opt = experimental[x];
2822  if (starts_with(tok, opt))
2823  {
2824  return parse_on_off_option(tok);
2825  }
2826  }
2827  return FALSE;
2828 }
2829 
2830 static BOOL option_is_debug(wLog* log, const char* tok)
2831 {
2832  WINPR_ASSERT(log);
2833  const char* debug[] = { STR(WITH_DEBUG_ALL),
2834  STR(WITH_DEBUG_CERTIFICATE),
2835  STR(WITH_DEBUG_CAPABILITIES),
2836  STR(WITH_DEBUG_CHANNELS),
2837  STR(WITH_DEBUG_CLIPRDR),
2838  STR(WITH_DEBUG_CODECS),
2839  STR(WITH_DEBUG_RDPGFX),
2840  STR(WITH_DEBUG_DVC),
2841  STR(WITH_DEBUG_TSMF),
2842  STR(WITH_DEBUG_KBD),
2843  STR(WITH_DEBUG_LICENSE),
2844  STR(WITH_DEBUG_NEGO),
2845  STR(WITH_DEBUG_NLA),
2846  STR(WITH_DEBUG_TSG),
2847  STR(WITH_DEBUG_RAIL),
2848  STR(WITH_DEBUG_RDP),
2849  STR(WITH_DEBUG_RDPEI),
2850  STR(WITH_DEBUG_REDIR),
2851  STR(WITH_DEBUG_RDPDR),
2852  STR(WITH_DEBUG_RFX),
2853  STR(WITH_DEBUG_SCARD),
2854  STR(WITH_DEBUG_SND),
2855  STR(WITH_DEBUG_SVC),
2856  STR(WITH_DEBUG_TRANSPORT),
2857  STR(WITH_DEBUG_TIMEZONE),
2858  STR(WITH_DEBUG_WND),
2859  STR(WITH_DEBUG_X11_CLIPRDR),
2860  STR(WITH_DEBUG_X11_LOCAL_MOVESIZE),
2861  STR(WITH_DEBUG_X11),
2862  STR(WITH_DEBUG_XV),
2863  STR(WITH_DEBUG_RINGBUFFER),
2864  STR(WITH_DEBUG_SYMBOLS),
2865  STR(WITH_DEBUG_EVENTS),
2866  STR(WITH_DEBUG_MUTEX),
2867  STR(WITH_DEBUG_NTLM),
2868  STR(WITH_DEBUG_SDL_EVENTS),
2869  STR(WITH_DEBUG_SDL_KBD_EVENTS),
2870  STR(WITH_DEBUG_THREADS),
2871  STR(WITH_DEBUG_URBDRC) };
2872 
2873  for (size_t x = 0; x < ARRAYSIZE(debug); x++)
2874  {
2875  const char* opt = debug[x];
2876  if (starts_with(tok, opt))
2877  return parse_on_off_option(tok);
2878  }
2879 
2880  if (starts_with(tok, "WITH_DEBUG"))
2881  {
2882  WLog_Print(log, WLOG_WARN, "[BUG] Unmapped Debug-Build option '%s'.", tok);
2883  return parse_on_off_option(tok);
2884  }
2885 
2886  return FALSE;
2887 }
2888 
2889 static void log_build_warn(rdpRdp* rdp, const char* what, const char* msg,
2890  BOOL (*cmp)(wLog* log, const char* tok))
2891 {
2892  WINPR_ASSERT(rdp);
2893  WINPR_PRAGMA_DIAG_PUSH
2894  WINPR_PRAGMA_DIAG_IGNORED_OVERLENGTH_STRINGS
2895 
2896  size_t len = sizeof(FREERDP_BUILD_CONFIG);
2897  char* list = calloc(len, sizeof(char));
2898  char* config = _strdup(FREERDP_BUILD_CONFIG);
2899  WINPR_PRAGMA_DIAG_POP
2900 
2901  if (config && list)
2902  {
2903  char* saveptr = NULL;
2904  char* tok = strtok_s(config, " ", &saveptr);
2905  while (tok)
2906  {
2907  if (cmp(rdp->log, tok))
2908  winpr_str_append(tok, list, len, " ");
2909 
2910  tok = strtok_s(NULL, " ", &saveptr);
2911  }
2912  }
2913  free(config);
2914 
2915  if (list)
2916  {
2917  if (strlen(list) > 0)
2918  {
2919  WLog_Print(rdp->log, WLOG_WARN, "*************************************************");
2920  WLog_Print(rdp->log, WLOG_WARN, "This build is using [%s] build options:", what);
2921 
2922  char* saveptr = NULL;
2923  char* tok = strtok_s(list, " ", &saveptr);
2924  while (tok)
2925  {
2926  WLog_Print(rdp->log, WLOG_WARN, "* '%s'", tok);
2927  tok = strtok_s(NULL, " ", &saveptr);
2928  }
2929  WLog_Print(rdp->log, WLOG_WARN, "");
2930  WLog_Print(rdp->log, WLOG_WARN, "[%s] build options %s", what, msg);
2931  WLog_Print(rdp->log, WLOG_WARN, "*************************************************");
2932  }
2933  }
2934  free(list);
2935 }
2936 
2937 #define print_first_line(log, firstLine, what) \
2938  print_first_line_int((log), (firstLine), (what), __FILE__, __func__, __LINE__)
2939 static void print_first_line_int(wLog* log, log_line_t* firstLine, const char* what,
2940  const char* file, const char* fkt, size_t line)
2941 {
2942  WINPR_ASSERT(firstLine);
2943  if (!firstLine->fkt)
2944  {
2945  const DWORD level = WLOG_WARN;
2946  if (WLog_IsLevelActive(log, level))
2947  {
2948  WLog_PrintMessage(log, WLOG_MESSAGE_TEXT, level, line, file, fkt,
2949  "*************************************************");
2950  WLog_PrintMessage(log, WLOG_MESSAGE_TEXT, level, line, file, fkt,
2951  "[SSL] {%s} build or configuration missing:", what);
2952  }
2953  firstLine->line = line;
2954  firstLine->file = file;
2955  firstLine->fkt = fkt;
2956  firstLine->level = level;
2957  }
2958 }
2959 
2960 static void print_last_line(wLog* log, const log_line_t* firstLine)
2961 {
2962  WINPR_ASSERT(firstLine);
2963  if (firstLine->fkt)
2964  {
2965  if (WLog_IsLevelActive(log, firstLine->level))
2966  WLog_PrintMessage(log, WLOG_MESSAGE_TEXT, firstLine->level, firstLine->line,
2967  firstLine->file, firstLine->fkt,
2968  "*************************************************");
2969  }
2970 }
2971 
2972 static void log_build_warn_cipher(rdpRdp* rdp, log_line_t* firstLine, WINPR_CIPHER_TYPE md,
2973  const char* what)
2974 {
2975  BOOL haveCipher = FALSE;
2976 
2977  char key[WINPR_CIPHER_MAX_KEY_LENGTH] = { 0 };
2978  char iv[WINPR_CIPHER_MAX_IV_LENGTH] = { 0 };
2979 
2980  /* RC4 only exists in the compatibility functions winpr_RC4_*
2981  * winpr_Cipher_* does not support that. */
2982  if (md == WINPR_CIPHER_ARC4_128)
2983  {
2984  WINPR_RC4_CTX* enc = winpr_RC4_New(key, sizeof(key));
2985  haveCipher = enc != NULL;
2986  winpr_RC4_Free(enc);
2987  }
2988  else
2989  {
2990  WINPR_CIPHER_CTX* enc =
2991  winpr_Cipher_NewEx(md, WINPR_ENCRYPT, key, sizeof(key), iv, sizeof(iv));
2992  WINPR_CIPHER_CTX* dec =
2993  winpr_Cipher_NewEx(md, WINPR_DECRYPT, key, sizeof(key), iv, sizeof(iv));
2994  if (enc && dec)
2995  haveCipher = TRUE;
2996 
2997  winpr_Cipher_Free(enc);
2998  winpr_Cipher_Free(dec);
2999  }
3000 
3001  if (!haveCipher)
3002  {
3003  print_first_line(rdp->log, firstLine, "Cipher");
3004  WLog_Print(rdp->log, WLOG_WARN, "* %s: %s", winpr_cipher_type_to_string(md), what);
3005  }
3006 }
3007 
3008 static void log_build_warn_hmac(rdpRdp* rdp, log_line_t* firstLine, WINPR_MD_TYPE md,
3009  const char* what)
3010 {
3011  BOOL haveHmacX = FALSE;
3012  WINPR_HMAC_CTX* hmac = winpr_HMAC_New();
3013  if (hmac)
3014  {
3015  /* We need some key length, but there is no real limit here.
3016  * just take the cipher maximum key length as we already have that available.
3017  */
3018  char key[WINPR_CIPHER_MAX_KEY_LENGTH] = { 0 };
3019  haveHmacX = winpr_HMAC_Init(hmac, md, key, sizeof(key));
3020  }
3021  winpr_HMAC_Free(hmac);
3022 
3023  if (!haveHmacX)
3024  {
3025  print_first_line(rdp->log, firstLine, "HMAC");
3026  WLog_Print(rdp->log, WLOG_WARN, " * %s: %s", winpr_md_type_to_string(md), what);
3027  }
3028 }
3029 
3030 static void log_build_warn_hash(rdpRdp* rdp, log_line_t* firstLine, WINPR_MD_TYPE md,
3031  const char* what)
3032 {
3033  BOOL haveDigestX = FALSE;
3034 
3035  WINPR_DIGEST_CTX* digest = winpr_Digest_New();
3036  if (digest)
3037  haveDigestX = winpr_Digest_Init(digest, md);
3038  winpr_Digest_Free(digest);
3039 
3040  if (!haveDigestX)
3041  {
3042  print_first_line(rdp->log, firstLine, "Digest");
3043  WLog_Print(rdp->log, WLOG_WARN, " * %s: %s", winpr_md_type_to_string(md), what);
3044  }
3045 }
3046 
3047 static void log_build_warn_ssl(rdpRdp* rdp)
3048 {
3049  WINPR_ASSERT(rdp);
3050 
3051  log_line_t firstHashLine = { 0 };
3052  log_build_warn_hash(rdp, &firstHashLine, WINPR_MD_MD4, "NTLM support not available");
3053  log_build_warn_hash(rdp, &firstHashLine, WINPR_MD_MD5,
3054  "NTLM, assistance files with encrypted passwords, autoreconnect cookies, "
3055  "licensing and RDP security will not work");
3056  log_build_warn_hash(rdp, &firstHashLine, WINPR_MD_SHA1,
3057  "assistance files with encrypted passwords, Kerberos, Smartcard Logon, RDP "
3058  "security support not available");
3059  log_build_warn_hash(
3060  rdp, &firstHashLine, WINPR_MD_SHA256,
3061  "file clipboard, AAD gateway, NLA security and certificates might not work");
3062  print_last_line(rdp->log, &firstHashLine);
3063 
3064  log_line_t firstHmacLine = { 0 };
3065  log_build_warn_hmac(rdp, &firstHmacLine, WINPR_MD_MD5, "Autoreconnect cookie not supported");
3066  log_build_warn_hmac(rdp, &firstHmacLine, WINPR_MD_SHA1, "RDP security not supported");
3067  print_last_line(rdp->log, &firstHmacLine);
3068 
3069  log_line_t firstCipherLine = { 0 };
3070  log_build_warn_cipher(rdp, &firstCipherLine, WINPR_CIPHER_ARC4_128,
3071  "assistance files with encrypted passwords, NTLM, RDP licensing and RDP "
3072  "security will not work");
3073  log_build_warn_cipher(rdp, &firstCipherLine, WINPR_CIPHER_DES_EDE3_CBC,
3074  "RDP security FIPS mode will not work");
3075  log_build_warn_cipher(
3076  rdp, &firstCipherLine, WINPR_CIPHER_AES_128_CBC,
3077  "assistance file encrypted LHTicket will not work and ARM gateway might not");
3078  log_build_warn_cipher(rdp, &firstCipherLine, WINPR_CIPHER_AES_192_CBC,
3079  "ARM gateway might not work");
3080  log_build_warn_cipher(rdp, &firstCipherLine, WINPR_CIPHER_AES_256_CBC,
3081  "ARM gateway might not work");
3082  print_last_line(rdp->log, &firstCipherLine);
3083 }
3084 
3085 void rdp_log_build_warnings(rdpRdp* rdp)
3086 {
3087  static unsigned count = 0;
3088 
3089  WINPR_ASSERT(rdp);
3090  /* Since this function is called in context creation routines stop logging
3091  * this issue repeatedly. This is required for proxy, which would otherwise
3092  * spam the log with these. */
3093  if (count > 0)
3094  return;
3095  count++;
3096  log_build_warn(rdp, "experimental", "might crash the application", option_is_experimental);
3097  log_build_warn(rdp, "debug", "might leak sensitive information (credentials, ...)",
3098  option_is_debug);
3099  log_build_warn(rdp, "runtime-check", "might slow down the application",
3100  option_is_runtime_checks);
3101  log_build_warn_ssl(rdp);
3102 }
WINPR_API void WINPR_JSON_Delete(WINPR_JSON *item)
Delete a WinPR JSON wrapper object.
Definition: json.c:144
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API rdpSettings * freerdp_settings_new(DWORD flags)
creates a new setting struct
FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
FREERDP_API void freerdp_settings_free(rdpSettings *settings)
Free a settings struct with all data in it.
#define FREERDP_SETTINGS_SERVER_MODE
FREERDP_API rdpSettings * freerdp_settings_clone(const rdpSettings *settings)
Creates a deep copy of settings.