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