FreeRDP
pf_channel_rdpdr.c
1 
21 #include <freerdp/config.h>
22 
23 #include <winpr/assert.h>
24 #include <winpr/cast.h>
25 #include <winpr/string.h>
26 #include <winpr/print.h>
27 
28 #include "pf_channel_rdpdr.h"
29 #include "pf_channel_smartcard.h"
30 
31 #include <freerdp/server/proxy/proxy_log.h>
32 #include <freerdp/channels/rdpdr.h>
33 #include <freerdp/channels/channels.h>
34 #include <freerdp/utils/rdpdr_utils.h>
35 
36 #define RTAG PROXY_TAG("channel.rdpdr")
37 
38 #define SCARD_DEVICE_ID UINT32_MAX
39 
40 typedef struct
41 {
43  wStream* s;
44  wStream* buffer;
45  UINT16 versionMajor;
46  UINT16 versionMinor;
47  UINT32 clientID;
48  UINT32 computerNameLen;
49  BOOL computerNameUnicode;
50  union
51  {
52  WCHAR* wc;
53  char* c;
54  void* v;
55  } computerName;
56  UINT32 SpecialDeviceCount;
57  UINT32 capabilityVersions[6];
58 } pf_channel_common_context;
59 
60 typedef enum
61 {
62  STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST = 0x01,
63  STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST = 0x02,
64  STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM = 0x04,
65  STATE_CLIENT_CHANNEL_RUNNING = 0x10
66 } pf_channel_client_state;
67 
68 typedef struct
69 {
70  pf_channel_common_context common;
71  pf_channel_client_state state;
72  UINT32 flags;
73  UINT16 maxMajorVersion;
74  UINT16 maxMinorVersion;
75  wQueue* queue;
76  wLog* log;
77 } pf_channel_client_context;
78 
79 typedef enum
80 {
81  STATE_SERVER_INITIAL,
82  STATE_SERVER_EXPECT_CLIENT_ANNOUNCE_REPLY,
83  STATE_SERVER_EXPECT_CLIENT_NAME_REQUEST,
84  STATE_SERVER_EXPECT_EXPECT_CLIENT_CAPABILITY_RESPONE,
85  STATE_SERVER_CHANNEL_RUNNING
86 } pf_channel_server_state;
87 
88 typedef struct
89 {
90  pf_channel_common_context common;
91  pf_channel_server_state state;
92  DWORD SessionId;
93  HANDLE handle;
94  wArrayList* blockedDevices;
95  wLog* log;
96 } pf_channel_server_context;
97 
98 #define proxy_client "[proxy<-->client]"
99 #define proxy_server "[proxy<-->server]"
100 
101 #define proxy_client_rx proxy_client " receive"
102 #define proxy_client_tx proxy_client " send"
103 #define proxy_server_rx proxy_server " receive"
104 #define proxy_server_tx proxy_server " send"
105 
106 #define SERVER_RX_LOG(log, lvl, fmt, ...) WLog_Print(log, lvl, proxy_client_rx fmt, ##__VA_ARGS__)
107 #define CLIENT_RX_LOG(log, lvl, fmt, ...) WLog_Print(log, lvl, proxy_server_rx fmt, ##__VA_ARGS__)
108 #define SERVER_TX_LOG(log, lvl, fmt, ...) WLog_Print(log, lvl, proxy_client_tx fmt, ##__VA_ARGS__)
109 #define CLIENT_TX_LOG(log, lvl, fmt, ...) WLog_Print(log, lvl, proxy_server_tx fmt, ##__VA_ARGS__)
110 #define RX_LOG(srv, lvl, fmt, ...) \
111  do \
112  { \
113  if (srv) \
114  { \
115  SERVER_RX_LOG(lvl, fmt, ##__VA_ARGS__); \
116  } \
117  else \
118  { \
119  CLIENT_RX_LOG(lvl, fmt, ##__VA_ARGS__); \
120  } \
121  } while (0)
122 
123 #define SERVER_RXTX_LOG(send, log, lvl, fmt, ...) \
124  do \
125  { \
126  if (send) \
127  { \
128  SERVER_TX_LOG(log, lvl, fmt, ##__VA_ARGS__); \
129  } \
130  else \
131  { \
132  SERVER_RX_LOG(log, lvl, fmt, ##__VA_ARGS__); \
133  } \
134  } while (0)
135 
136 #define Stream_CheckAndLogRequiredLengthSrv(log, s, len) \
137  Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, len, 1, \
138  proxy_client_rx " %s(%s:%" PRIuz ")", __func__, \
139  __FILE__, (size_t)__LINE__)
140 #define Stream_CheckAndLogRequiredLengthClient(log, s, len) \
141  Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, len, 1, \
142  proxy_server_rx " %s(%s:%" PRIuz ")", __func__, \
143  __FILE__, (size_t)__LINE__)
144 #define Stream_CheckAndLogRequiredLengthRx(srv, log, s, len) \
145  Stream_CheckAndLogRequiredLengthRx_(srv, log, s, len, 1, __func__, __FILE__, __LINE__)
146 static BOOL Stream_CheckAndLogRequiredLengthRx_(BOOL srv, wLog* log, wStream* s, size_t nmemb,
147  size_t size, const char* fkt, const char* file,
148  size_t line)
149 {
150  const char* fmt =
151  srv ? proxy_server_rx " %s(%s:%" PRIuz ")" : proxy_client_rx " %s(%s:%" PRIuz ")";
152 
153  return Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, nmemb, size, fmt, fkt, file,
154  line);
155 }
156 
157 static const char* rdpdr_server_state_to_string(pf_channel_server_state state)
158 {
159  switch (state)
160  {
161  case STATE_SERVER_INITIAL:
162  return "STATE_SERVER_INITIAL";
163  case STATE_SERVER_EXPECT_CLIENT_ANNOUNCE_REPLY:
164  return "STATE_SERVER_EXPECT_CLIENT_ANNOUNCE_REPLY";
165  case STATE_SERVER_EXPECT_CLIENT_NAME_REQUEST:
166  return "STATE_SERVER_EXPECT_CLIENT_NAME_REQUEST";
167  case STATE_SERVER_EXPECT_EXPECT_CLIENT_CAPABILITY_RESPONE:
168  return "STATE_SERVER_EXPECT_EXPECT_CLIENT_CAPABILITY_RESPONE";
169  case STATE_SERVER_CHANNEL_RUNNING:
170  return "STATE_SERVER_CHANNEL_RUNNING";
171  default:
172  return "STATE_SERVER_UNKNOWN";
173  }
174 }
175 
176 static const char* rdpdr_client_state_to_string(pf_channel_client_state state)
177 {
178  switch (state)
179  {
180  case STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST:
181  return "STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST";
182  case STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST:
183  return "STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST";
184  case STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM:
185  return "STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM";
186  case STATE_CLIENT_CHANNEL_RUNNING:
187  return "STATE_CLIENT_CHANNEL_RUNNING";
188  default:
189  return "STATE_CLIENT_UNKNOWN";
190  }
191 }
192 
193 static wStream* rdpdr_get_send_buffer(pf_channel_common_context* rdpdr, UINT16 component,
194  UINT16 PacketID, size_t capacity)
195 {
196  WINPR_ASSERT(rdpdr);
197  WINPR_ASSERT(rdpdr->s);
198  if (!Stream_SetPosition(rdpdr->s, 0))
199  return NULL;
200  if (!Stream_EnsureCapacity(rdpdr->s, capacity + 4))
201  return NULL;
202  Stream_Write_UINT16(rdpdr->s, component);
203  Stream_Write_UINT16(rdpdr->s, PacketID);
204  return rdpdr->s;
205 }
206 
207 static wStream* rdpdr_client_get_send_buffer(pf_channel_client_context* rdpdr, UINT16 component,
208  UINT16 PacketID, size_t capacity)
209 {
210  WINPR_ASSERT(rdpdr);
211  return rdpdr_get_send_buffer(&rdpdr->common, component, PacketID, capacity);
212 }
213 
214 static wStream* rdpdr_server_get_send_buffer(pf_channel_server_context* rdpdr, UINT16 component,
215  UINT16 PacketID, size_t capacity)
216 {
217  WINPR_ASSERT(rdpdr);
218  return rdpdr_get_send_buffer(&rdpdr->common, component, PacketID, capacity);
219 }
220 
221 static UINT rdpdr_client_send(wLog* log, pClientContext* pc, wStream* s)
222 {
223  UINT16 channelId = 0;
224 
225  WINPR_ASSERT(log);
226  WINPR_ASSERT(pc);
227  WINPR_ASSERT(s);
228  WINPR_ASSERT(pc->context.instance);
229 
230  if (!pc->connected)
231  {
232  CLIENT_TX_LOG(log, WLOG_WARN, "Ignoring channel %s message, not connected!",
233  RDPDR_SVC_CHANNEL_NAME);
234  return CHANNEL_RC_OK;
235  }
236 
237  channelId = freerdp_channels_get_id_by_name(pc->context.instance, RDPDR_SVC_CHANNEL_NAME);
238  /* Ignore unmappable channels. Might happen when the channel was already down and
239  * some delayed message is tried to be sent. */
240  if ((channelId == 0) || (channelId == UINT16_MAX))
241  return ERROR_INTERNAL_ERROR;
242 
243  Stream_SealLength(s);
244  rdpdr_dump_send_packet(log, WLOG_TRACE, s, proxy_server_tx);
245  WINPR_ASSERT(pc->context.instance->SendChannelData);
246  if (!pc->context.instance->SendChannelData(pc->context.instance, channelId, Stream_Buffer(s),
247  Stream_Length(s)))
248  return ERROR_EVT_CHANNEL_NOT_FOUND;
249  return CHANNEL_RC_OK;
250 }
251 
252 static UINT rdpdr_seal_send_free_request(pf_channel_server_context* context, wStream* s)
253 {
254  BOOL status = 0;
255  size_t len = 0;
256 
257  WINPR_ASSERT(context);
258  WINPR_ASSERT(context->handle);
259  WINPR_ASSERT(s);
260 
261  Stream_SealLength(s);
262  len = Stream_Length(s);
263  WINPR_ASSERT(len <= UINT32_MAX);
264 
265  rdpdr_dump_send_packet(context->log, WLOG_TRACE, s, proxy_client_tx);
266  status = WTSVirtualChannelWrite(context->handle, Stream_BufferAs(s, char), (ULONG)len, NULL);
267  return (status) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
268 }
269 
270 static BOOL rdpdr_process_server_header(BOOL server, wLog* log, wStream* s, UINT16 component,
271  UINT16 PacketId, size_t expect)
272 {
273  UINT16 rpacketid = 0;
274  UINT16 rcomponent = 0;
275 
276  WINPR_ASSERT(s);
277  if (!Stream_CheckAndLogRequiredLengthRx(server, log, s, 4))
278  {
279  RX_LOG(server, log, WLOG_WARN, "RDPDR_HEADER[%s | %s]: expected length 4, got %" PRIuz,
280  rdpdr_component_string(component), rdpdr_packetid_string(PacketId),
281  Stream_GetRemainingLength(s));
282  return FALSE;
283  }
284 
285  Stream_Read_UINT16(s, rcomponent);
286  Stream_Read_UINT16(s, rpacketid);
287 
288  if (rcomponent != component)
289  {
290  RX_LOG(server, log, WLOG_WARN, "RDPDR_HEADER[%s | %s]: got component %s",
291  rdpdr_component_string(component), rdpdr_packetid_string(PacketId),
292  rdpdr_component_string(rcomponent));
293  return FALSE;
294  }
295 
296  if (rpacketid != PacketId)
297  {
298  RX_LOG(server, log, WLOG_WARN, "RDPDR_HEADER[%s | %s]: got PacketID %s",
299  rdpdr_component_string(component), rdpdr_packetid_string(PacketId),
300  rdpdr_packetid_string(rpacketid));
301  return FALSE;
302  }
303 
304  if (!Stream_CheckAndLogRequiredLengthRx(server, log, s, expect))
305  {
306  RX_LOG(server, log, WLOG_WARN,
307  "RDPDR_HEADER[%s | %s] not enough data, expected %" PRIuz ", "
308  "got %" PRIuz,
309  rdpdr_component_string(component), rdpdr_packetid_string(PacketId), expect,
310  Stream_GetRemainingLength(s));
311  return ERROR_INVALID_DATA;
312  }
313 
314  return TRUE;
315 }
316 
317 static BOOL rdpdr_check_version(BOOL server, wLog* log, UINT16 versionMajor, UINT16 versionMinor,
318  UINT16 component, UINT16 PacketId)
319 {
320  if (versionMajor != RDPDR_VERSION_MAJOR)
321  {
322  RX_LOG(server, log, WLOG_WARN, "[%s | %s] expected MajorVersion %" PRIu16 ", got %" PRIu16,
323  rdpdr_component_string(component), rdpdr_packetid_string(PacketId),
324  RDPDR_VERSION_MAJOR, versionMajor);
325  return FALSE;
326  }
327  switch (versionMinor)
328  {
329  case RDPDR_VERSION_MINOR_RDP50:
330  case RDPDR_VERSION_MINOR_RDP51:
331  case RDPDR_VERSION_MINOR_RDP52:
332  case RDPDR_VERSION_MINOR_RDP6X:
333  case RDPDR_VERSION_MINOR_RDP10X:
334  break;
335  default:
336  {
337  RX_LOG(server, log, WLOG_WARN, "[%s | %s] unsupported MinorVersion %" PRIu16,
338  rdpdr_component_string(component), rdpdr_packetid_string(PacketId),
339  versionMinor);
340  return FALSE;
341  }
342  }
343  return TRUE;
344 }
345 
346 static UINT rdpdr_process_server_announce_request(pf_channel_client_context* rdpdr, wStream* s)
347 {
348  const UINT16 component = RDPDR_CTYP_CORE;
349  const UINT16 packetid = PAKID_CORE_SERVER_ANNOUNCE;
350  WINPR_ASSERT(rdpdr);
351  WINPR_ASSERT(s);
352 
353  if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, component, packetid, 8))
354  return ERROR_INVALID_DATA;
355 
356  Stream_Read_UINT16(s, rdpdr->common.versionMajor);
357  Stream_Read_UINT16(s, rdpdr->common.versionMinor);
358 
359  if (!rdpdr_check_version(FALSE, rdpdr->log, rdpdr->common.versionMajor,
360  rdpdr->common.versionMinor, component, packetid))
361  return ERROR_INVALID_DATA;
362 
363  /* Limit maximum channel protocol version to the one set by proxy server */
364  if (rdpdr->common.versionMajor > rdpdr->maxMajorVersion)
365  {
366  rdpdr->common.versionMajor = rdpdr->maxMajorVersion;
367  rdpdr->common.versionMinor = rdpdr->maxMinorVersion;
368  }
369  else if (rdpdr->common.versionMinor > rdpdr->maxMinorVersion)
370  rdpdr->common.versionMinor = rdpdr->maxMinorVersion;
371 
372  Stream_Read_UINT32(s, rdpdr->common.clientID);
373  return CHANNEL_RC_OK;
374 }
375 
376 static UINT rdpdr_server_send_announce_request(pf_channel_server_context* context)
377 {
378  wStream* s =
379  rdpdr_server_get_send_buffer(context, RDPDR_CTYP_CORE, PAKID_CORE_SERVER_ANNOUNCE, 8);
380  if (!s)
381  return CHANNEL_RC_NO_MEMORY;
382 
383  Stream_Write_UINT16(s, context->common.versionMajor); /* VersionMajor (2 bytes) */
384  Stream_Write_UINT16(s, context->common.versionMinor); /* VersionMinor (2 bytes) */
385  Stream_Write_UINT32(s, context->common.clientID); /* ClientId (4 bytes) */
386  return rdpdr_seal_send_free_request(context, s);
387 }
388 
389 static UINT rdpdr_process_client_announce_reply(pf_channel_server_context* rdpdr, wStream* s)
390 {
391  const UINT16 component = RDPDR_CTYP_CORE;
392  const UINT16 packetid = PAKID_CORE_CLIENTID_CONFIRM;
393  UINT16 versionMajor = 0;
394  UINT16 versionMinor = 0;
395  UINT32 clientID = 0;
396 
397  WINPR_ASSERT(rdpdr);
398  WINPR_ASSERT(s);
399 
400  if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 8))
401  return ERROR_INVALID_DATA;
402 
403  Stream_Read_UINT16(s, versionMajor);
404  Stream_Read_UINT16(s, versionMinor);
405 
406  if (!rdpdr_check_version(TRUE, rdpdr->log, versionMajor, versionMinor, component, packetid))
407  return ERROR_INVALID_DATA;
408 
409  if ((rdpdr->common.versionMajor != versionMajor) ||
410  (rdpdr->common.versionMinor != versionMinor))
411  {
412  SERVER_RX_LOG(
413  rdpdr->log, WLOG_WARN,
414  "[%s | %s] downgrading version from %" PRIu16 ".%" PRIu16 " to %" PRIu16 ".%" PRIu16,
415  rdpdr_component_string(component), rdpdr_packetid_string(packetid),
416  rdpdr->common.versionMajor, rdpdr->common.versionMinor, versionMajor, versionMinor);
417  rdpdr->common.versionMajor = versionMajor;
418  rdpdr->common.versionMinor = versionMinor;
419  }
420  Stream_Read_UINT32(s, clientID);
421  if (rdpdr->common.clientID != clientID)
422  {
423  SERVER_RX_LOG(rdpdr->log, WLOG_WARN,
424  "[%s | %s] changing clientID 0x%08" PRIu32 " to 0x%08" PRIu32,
425  rdpdr_component_string(component), rdpdr_packetid_string(packetid),
426  rdpdr->common.clientID, clientID);
427  rdpdr->common.clientID = clientID;
428  }
429 
430  return CHANNEL_RC_OK;
431 }
432 
433 static UINT rdpdr_send_client_announce_reply(pClientContext* pc, pf_channel_client_context* rdpdr)
434 {
435  wStream* s =
436  rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENTID_CONFIRM, 8);
437  if (!s)
438  return CHANNEL_RC_NO_MEMORY;
439 
440  Stream_Write_UINT16(s, rdpdr->common.versionMajor);
441  Stream_Write_UINT16(s, rdpdr->common.versionMinor);
442  Stream_Write_UINT32(s, rdpdr->common.clientID);
443  return rdpdr_client_send(rdpdr->log, pc, s);
444 }
445 
446 static UINT rdpdr_process_client_name_request(pf_channel_server_context* rdpdr, wStream* s,
447  pClientContext* pc)
448 {
449  UINT32 unicodeFlag = 0;
450  UINT32 codePage = 0;
451 
452  WINPR_ASSERT(rdpdr);
453  WINPR_ASSERT(s);
454  WINPR_ASSERT(pc);
455 
456  if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_NAME,
457  12))
458  return ERROR_INVALID_DATA;
459 
460  Stream_Read_UINT32(s, unicodeFlag);
461  rdpdr->common.computerNameUnicode = ((unicodeFlag & 1) != 0) ? TRUE : FALSE;
462 
463  Stream_Read_UINT32(s, codePage);
464  WINPR_UNUSED(codePage); /* Field is ignored */
465  Stream_Read_UINT32(s, rdpdr->common.computerNameLen);
466  if (!Stream_CheckAndLogRequiredLengthSrv(rdpdr->log, s, rdpdr->common.computerNameLen))
467  {
468  SERVER_RX_LOG(
469  rdpdr->log, WLOG_WARN, "[%s | %s]: missing data, got %" PRIu32 ", expected %" PRIu32,
470  rdpdr_component_string(RDPDR_CTYP_CORE), rdpdr_packetid_string(PAKID_CORE_CLIENT_NAME),
471  Stream_GetRemainingLength(s), rdpdr->common.computerNameLen);
472  return ERROR_INVALID_DATA;
473  }
474  void* tmp = realloc(rdpdr->common.computerName.v, rdpdr->common.computerNameLen);
475  if (!tmp)
476  return CHANNEL_RC_NO_MEMORY;
477  rdpdr->common.computerName.v = tmp;
478 
479  Stream_Read(s, rdpdr->common.computerName.v, rdpdr->common.computerNameLen);
480 
481  pc->computerNameLen = rdpdr->common.computerNameLen;
482  pc->computerNameUnicode = rdpdr->common.computerNameUnicode;
483  tmp = realloc(pc->computerName.v, pc->computerNameLen);
484  if (!tmp)
485  return CHANNEL_RC_NO_MEMORY;
486  pc->computerName.v = tmp;
487  memcpy(pc->computerName.v, rdpdr->common.computerName.v, pc->computerNameLen);
488 
489  return CHANNEL_RC_OK;
490 }
491 
492 static UINT rdpdr_send_client_name_request(pClientContext* pc, pf_channel_client_context* rdpdr)
493 {
494  wStream* s = NULL;
495 
496  WINPR_ASSERT(rdpdr);
497  WINPR_ASSERT(pc);
498 
499  {
500  void* tmp = realloc(rdpdr->common.computerName.v, pc->computerNameLen);
501  if (!tmp)
502  return CHANNEL_RC_NO_MEMORY;
503  rdpdr->common.computerName.v = tmp;
504  rdpdr->common.computerNameLen = pc->computerNameLen;
505  rdpdr->common.computerNameUnicode = pc->computerNameUnicode;
506  memcpy(rdpdr->common.computerName.v, pc->computerName.v, pc->computerNameLen);
507  }
508  s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_NAME,
509  12U + rdpdr->common.computerNameLen);
510  if (!s)
511  return CHANNEL_RC_NO_MEMORY;
512 
513  Stream_Write_UINT32(s, rdpdr->common.computerNameUnicode
514  ? 1
515  : 0); /* unicodeFlag, 0 for ASCII and 1 for Unicode */
516  Stream_Write_UINT32(s, 0); /* codePage, must be set to zero */
517  Stream_Write_UINT32(s, rdpdr->common.computerNameLen);
518  Stream_Write(s, rdpdr->common.computerName.v, rdpdr->common.computerNameLen);
519  return rdpdr_client_send(rdpdr->log, pc, s);
520 }
521 
522 #define rdpdr_ignore_capset(srv, log, s, header) \
523  rdpdr_ignore_capset_((srv), (log), (s), header, __func__)
524 static UINT rdpdr_ignore_capset_(BOOL srv, wLog* log, wStream* s,
525  const RDPDR_CAPABILITY_HEADER* header, const char* fkt)
526 {
527  WINPR_ASSERT(s);
528  WINPR_ASSERT(header);
529 
530  Stream_Seek(s, header->CapabilityLength);
531  return CHANNEL_RC_OK;
532 }
533 
534 static UINT rdpdr_client_process_general_capset(pf_channel_client_context* rdpdr, wStream* s,
535  const RDPDR_CAPABILITY_HEADER* header)
536 {
537  WINPR_UNUSED(rdpdr);
538  return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
539 }
540 
541 static UINT rdpdr_process_printer_capset(pf_channel_client_context* rdpdr, wStream* s,
542  const RDPDR_CAPABILITY_HEADER* header)
543 {
544  WINPR_UNUSED(rdpdr);
545  return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
546 }
547 
548 static UINT rdpdr_process_port_capset(pf_channel_client_context* rdpdr, wStream* s,
549  const RDPDR_CAPABILITY_HEADER* header)
550 {
551  WINPR_UNUSED(rdpdr);
552  return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
553 }
554 
555 static UINT rdpdr_process_drive_capset(pf_channel_client_context* rdpdr, wStream* s,
556  const RDPDR_CAPABILITY_HEADER* header)
557 {
558  WINPR_UNUSED(rdpdr);
559  return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
560 }
561 
562 static UINT rdpdr_process_smartcard_capset(pf_channel_client_context* rdpdr, wStream* s,
563  const RDPDR_CAPABILITY_HEADER* header)
564 {
565  WINPR_UNUSED(rdpdr);
566  return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
567 }
568 
569 static UINT rdpdr_process_server_core_capability_request(pf_channel_client_context* rdpdr,
570  wStream* s)
571 {
572  UINT status = CHANNEL_RC_OK;
573  UINT16 numCapabilities = 0;
574 
575  WINPR_ASSERT(rdpdr);
576 
577  if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE,
578  PAKID_CORE_SERVER_CAPABILITY, 4))
579  return ERROR_INVALID_DATA;
580 
581  Stream_Read_UINT16(s, numCapabilities);
582  Stream_Seek(s, 2); /* pad (2 bytes) */
583 
584  for (UINT16 i = 0; i < numCapabilities; i++)
585  {
586  RDPDR_CAPABILITY_HEADER header = { 0 };
587  UINT error = rdpdr_read_capset_header(rdpdr->log, s, &header);
588  if (error != CHANNEL_RC_OK)
589  return error;
590 
591  if (header.CapabilityType < ARRAYSIZE(rdpdr->common.capabilityVersions))
592  {
593  if (rdpdr->common.capabilityVersions[header.CapabilityType] > header.Version)
594  rdpdr->common.capabilityVersions[header.CapabilityType] = header.Version;
595 
596  WLog_Print(rdpdr->log, WLOG_TRACE,
597  "capability %s got version %" PRIu32 ", will use version %" PRIu32,
598  rdpdr_cap_type_string(header.CapabilityType), header.Version,
599  rdpdr->common.capabilityVersions[header.CapabilityType]);
600  }
601 
602  switch (header.CapabilityType)
603  {
604  case CAP_GENERAL_TYPE:
605  status = rdpdr_client_process_general_capset(rdpdr, s, &header);
606  break;
607 
608  case CAP_PRINTER_TYPE:
609  status = rdpdr_process_printer_capset(rdpdr, s, &header);
610  break;
611 
612  case CAP_PORT_TYPE:
613  status = rdpdr_process_port_capset(rdpdr, s, &header);
614  break;
615 
616  case CAP_DRIVE_TYPE:
617  status = rdpdr_process_drive_capset(rdpdr, s, &header);
618  break;
619 
620  case CAP_SMARTCARD_TYPE:
621  status = rdpdr_process_smartcard_capset(rdpdr, s, &header);
622  break;
623 
624  default:
625  WLog_Print(rdpdr->log, WLOG_WARN,
626  "unknown capability 0x%04" PRIx16 ", length %" PRIu16
627  ", version %" PRIu32,
628  header.CapabilityType, header.CapabilityLength, header.Version);
629  Stream_Seek(s, header.CapabilityLength);
630  break;
631  }
632 
633  if (status != CHANNEL_RC_OK)
634  return status;
635  }
636 
637  return CHANNEL_RC_OK;
638 }
639 
640 static BOOL rdpdr_write_general_capset(wLog* log, pf_channel_common_context* rdpdr, wStream* s)
641 {
642  WINPR_ASSERT(rdpdr);
643  WINPR_ASSERT(s);
644 
645  const RDPDR_CAPABILITY_HEADER header = { CAP_GENERAL_TYPE, 44,
646  rdpdr->capabilityVersions[CAP_GENERAL_TYPE] };
647  if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
648  return FALSE;
649  Stream_Write_UINT32(s, 0); /* osType, ignored on receipt */
650  Stream_Write_UINT32(s, 0); /* osVersion, should be ignored */
651  Stream_Write_UINT16(s, rdpdr->versionMajor); /* protocolMajorVersion, must be set to 1 */
652  Stream_Write_UINT16(s, rdpdr->versionMinor); /* protocolMinorVersion */
653  Stream_Write_UINT32(s, 0x0000FFFF); /* ioCode1 */
654  Stream_Write_UINT32(s, 0); /* ioCode2, must be set to zero, reserved for future use */
655  Stream_Write_UINT32(s, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU |
656  RDPDR_USER_LOGGEDON_PDU); /* extendedPDU */
657  Stream_Write_UINT32(s, ENABLE_ASYNCIO); /* extraFlags1 */
658  Stream_Write_UINT32(s, 0); /* extraFlags2, must be set to zero, reserved for future use */
659  Stream_Write_UINT32(s, rdpdr->SpecialDeviceCount); /* SpecialTypeDeviceCap, number of special
660  devices to be redirected before logon */
661  return TRUE;
662 }
663 
664 static BOOL rdpdr_write_printer_capset(wLog* log, pf_channel_common_context* rdpdr, wStream* s)
665 {
666  WINPR_ASSERT(rdpdr);
667  WINPR_ASSERT(s);
668 
669  const RDPDR_CAPABILITY_HEADER header = { CAP_PRINTER_TYPE, 8,
670  rdpdr->capabilityVersions[CAP_PRINTER_TYPE] };
671  if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
672  return FALSE;
673  return TRUE;
674 }
675 
676 static BOOL rdpdr_write_port_capset(wLog* log, pf_channel_common_context* rdpdr, wStream* s)
677 {
678  WINPR_ASSERT(rdpdr);
679  WINPR_ASSERT(s);
680 
681  const RDPDR_CAPABILITY_HEADER header = { CAP_PORT_TYPE, 8,
682  rdpdr->capabilityVersions[CAP_PORT_TYPE] };
683  if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
684  return FALSE;
685  return TRUE;
686 }
687 
688 static BOOL rdpdr_write_drive_capset(wLog* log, pf_channel_common_context* rdpdr, wStream* s)
689 {
690  WINPR_ASSERT(rdpdr);
691  WINPR_ASSERT(s);
692 
693  const RDPDR_CAPABILITY_HEADER header = { CAP_DRIVE_TYPE, 8,
694  rdpdr->capabilityVersions[CAP_DRIVE_TYPE] };
695  if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
696  return FALSE;
697  return TRUE;
698 }
699 
700 static BOOL rdpdr_write_smartcard_capset(wLog* log, pf_channel_common_context* rdpdr, wStream* s)
701 {
702  WINPR_ASSERT(rdpdr);
703  WINPR_ASSERT(s);
704 
705  const RDPDR_CAPABILITY_HEADER header = { CAP_SMARTCARD_TYPE, 8,
706  rdpdr->capabilityVersions[CAP_SMARTCARD_TYPE] };
707  if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
708  return FALSE;
709  return TRUE;
710 }
711 
712 static UINT rdpdr_send_server_capability_request(pf_channel_server_context* rdpdr)
713 {
714  wStream* s =
715  rdpdr_server_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_SERVER_CAPABILITY, 8);
716  if (!s)
717  return CHANNEL_RC_NO_MEMORY;
718  Stream_Write_UINT16(s, 5); /* numCapabilities */
719  Stream_Write_UINT16(s, 0); /* pad */
720  if (!rdpdr_write_general_capset(rdpdr->log, &rdpdr->common, s))
721  return CHANNEL_RC_NO_MEMORY;
722  if (!rdpdr_write_printer_capset(rdpdr->log, &rdpdr->common, s))
723  return CHANNEL_RC_NO_MEMORY;
724  if (!rdpdr_write_port_capset(rdpdr->log, &rdpdr->common, s))
725  return CHANNEL_RC_NO_MEMORY;
726  if (!rdpdr_write_drive_capset(rdpdr->log, &rdpdr->common, s))
727  return CHANNEL_RC_NO_MEMORY;
728  if (!rdpdr_write_smartcard_capset(rdpdr->log, &rdpdr->common, s))
729  return CHANNEL_RC_NO_MEMORY;
730  return rdpdr_seal_send_free_request(rdpdr, s);
731 }
732 
733 static UINT rdpdr_process_client_capability_response(pf_channel_server_context* rdpdr, wStream* s)
734 {
735  const UINT16 component = RDPDR_CTYP_CORE;
736  const UINT16 packetid = PAKID_CORE_CLIENT_CAPABILITY;
737  UINT status = CHANNEL_RC_OK;
738  UINT16 numCapabilities = 0;
739  WINPR_ASSERT(rdpdr);
740 
741  if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 4))
742  return ERROR_INVALID_DATA;
743 
744  Stream_Read_UINT16(s, numCapabilities);
745  Stream_Seek_UINT16(s); /* padding */
746 
747  for (UINT16 x = 0; x < numCapabilities; x++)
748  {
749  RDPDR_CAPABILITY_HEADER header = { 0 };
750  UINT error = rdpdr_read_capset_header(rdpdr->log, s, &header);
751  if (error != CHANNEL_RC_OK)
752  return error;
753  if (header.CapabilityType < ARRAYSIZE(rdpdr->common.capabilityVersions))
754  {
755  if (rdpdr->common.capabilityVersions[header.CapabilityType] > header.Version)
756  rdpdr->common.capabilityVersions[header.CapabilityType] = header.Version;
757 
758  WLog_Print(rdpdr->log, WLOG_TRACE,
759  "capability %s got version %" PRIu32 ", will use version %" PRIu32,
760  rdpdr_cap_type_string(header.CapabilityType), header.Version,
761  rdpdr->common.capabilityVersions[header.CapabilityType]);
762  }
763 
764  switch (header.CapabilityType)
765  {
766  case CAP_GENERAL_TYPE:
767  status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
768  break;
769 
770  case CAP_PRINTER_TYPE:
771  status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
772  break;
773 
774  case CAP_PORT_TYPE:
775  status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
776  break;
777 
778  case CAP_DRIVE_TYPE:
779  status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
780  break;
781 
782  case CAP_SMARTCARD_TYPE:
783  status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
784  break;
785 
786  default:
787  SERVER_RX_LOG(rdpdr->log, WLOG_WARN,
788  "[%s | %s] invalid capability type 0x%04" PRIx16,
789  rdpdr_component_string(component), rdpdr_packetid_string(packetid),
790  header.CapabilityType);
791  status = ERROR_INVALID_DATA;
792  break;
793  }
794 
795  if (status != CHANNEL_RC_OK)
796  break;
797  }
798 
799  return status;
800 }
801 
802 static UINT rdpdr_send_client_capability_response(pClientContext* pc,
803  pf_channel_client_context* rdpdr)
804 {
805  wStream* s = NULL;
806 
807  WINPR_ASSERT(rdpdr);
808  s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_CAPABILITY, 4);
809  if (!s)
810  return CHANNEL_RC_NO_MEMORY;
811 
812  Stream_Write_UINT16(s, 5); /* numCapabilities */
813  Stream_Write_UINT16(s, 0); /* pad */
814  if (!rdpdr_write_general_capset(rdpdr->log, &rdpdr->common, s))
815  return CHANNEL_RC_NO_MEMORY;
816  if (!rdpdr_write_printer_capset(rdpdr->log, &rdpdr->common, s))
817  return CHANNEL_RC_NO_MEMORY;
818  if (!rdpdr_write_port_capset(rdpdr->log, &rdpdr->common, s))
819  return CHANNEL_RC_NO_MEMORY;
820  if (!rdpdr_write_drive_capset(rdpdr->log, &rdpdr->common, s))
821  return CHANNEL_RC_NO_MEMORY;
822  if (!rdpdr_write_smartcard_capset(rdpdr->log, &rdpdr->common, s))
823  return CHANNEL_RC_NO_MEMORY;
824  return rdpdr_client_send(rdpdr->log, pc, s);
825 }
826 
827 static UINT rdpdr_send_server_clientid_confirm(pf_channel_server_context* rdpdr)
828 {
829  wStream* s = NULL;
830 
831  s = rdpdr_server_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENTID_CONFIRM, 8);
832  if (!s)
833  return CHANNEL_RC_NO_MEMORY;
834  Stream_Write_UINT16(s, rdpdr->common.versionMajor);
835  Stream_Write_UINT16(s, rdpdr->common.versionMinor);
836  Stream_Write_UINT32(s, rdpdr->common.clientID);
837  return rdpdr_seal_send_free_request(rdpdr, s);
838 }
839 
840 static UINT rdpdr_process_server_clientid_confirm(pf_channel_client_context* rdpdr, wStream* s)
841 {
842  UINT16 versionMajor = 0;
843  UINT16 versionMinor = 0;
844  UINT32 clientID = 0;
845 
846  WINPR_ASSERT(rdpdr);
847  WINPR_ASSERT(s);
848 
849  if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE,
850  PAKID_CORE_CLIENTID_CONFIRM, 8))
851  return ERROR_INVALID_DATA;
852 
853  Stream_Read_UINT16(s, versionMajor);
854  Stream_Read_UINT16(s, versionMinor);
855  if (!rdpdr_check_version(FALSE, rdpdr->log, versionMajor, versionMinor, RDPDR_CTYP_CORE,
856  PAKID_CORE_CLIENTID_CONFIRM))
857  return ERROR_INVALID_DATA;
858 
859  Stream_Read_UINT32(s, clientID);
860 
861  if ((versionMajor != rdpdr->common.versionMajor) ||
862  (versionMinor != rdpdr->common.versionMinor))
863  {
864  CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
865  "[%s | %s] Version mismatch, sent %" PRIu16 ".%" PRIu16
866  ", downgraded to %" PRIu16 ".%" PRIu16,
867  rdpdr_component_string(RDPDR_CTYP_CORE),
868  rdpdr_packetid_string(PAKID_CORE_CLIENTID_CONFIRM),
869  rdpdr->common.versionMajor, rdpdr->common.versionMinor, versionMajor,
870  versionMinor);
871  rdpdr->common.versionMajor = versionMajor;
872  rdpdr->common.versionMinor = versionMinor;
873  }
874 
875  if (clientID != rdpdr->common.clientID)
876  {
877  CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
878  "[%s | %s] clientID mismatch, sent 0x%08" PRIx32 ", changed to 0x%08" PRIx32,
879  rdpdr_component_string(RDPDR_CTYP_CORE),
880  rdpdr_packetid_string(PAKID_CORE_CLIENTID_CONFIRM), rdpdr->common.clientID,
881  clientID);
882  rdpdr->common.clientID = clientID;
883  }
884 
885  return CHANNEL_RC_OK;
886 }
887 
888 static BOOL
889 rdpdr_process_server_capability_request_or_clientid_confirm(pf_channel_client_context* rdpdr,
890  wStream* s)
891 {
892  const UINT32 mask = STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM |
893  STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST;
894  const UINT16 rcomponent = RDPDR_CTYP_CORE;
895  UINT16 component = 0;
896  UINT16 packetid = 0;
897 
898  WINPR_ASSERT(rdpdr);
899  WINPR_ASSERT(s);
900 
901  if ((rdpdr->flags & mask) == mask)
902  {
903  CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, "already past this state, abort!");
904  return FALSE;
905  }
906 
907  if (!Stream_CheckAndLogRequiredLengthClient(rdpdr->log, s, 4))
908  return FALSE;
909 
910  Stream_Read_UINT16(s, component);
911  if (rcomponent != component)
912  {
913  CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, "got component %s, expected %s",
914  rdpdr_component_string(component), rdpdr_component_string(rcomponent));
915  return FALSE;
916  }
917  Stream_Read_UINT16(s, packetid);
918  Stream_Rewind(s, 4);
919 
920  switch (packetid)
921  {
922  case PAKID_CORE_SERVER_CAPABILITY:
923  if (rdpdr->flags & STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST)
924  {
925  CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, "got duplicate packetid %s",
926  rdpdr_packetid_string(packetid));
927  return FALSE;
928  }
929  rdpdr->flags |= STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST;
930  return rdpdr_process_server_core_capability_request(rdpdr, s) == CHANNEL_RC_OK;
931  case PAKID_CORE_CLIENTID_CONFIRM:
932  default:
933  if (rdpdr->flags & STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM)
934  {
935  CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, "got duplicate packetid %s",
936  rdpdr_packetid_string(packetid));
937  return FALSE;
938  }
939  rdpdr->flags |= STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM;
940  return rdpdr_process_server_clientid_confirm(rdpdr, s) == CHANNEL_RC_OK;
941  }
942 }
943 
944 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
945 static UINT rdpdr_send_emulated_scard_device_list_announce_request(pClientContext* pc,
946  pf_channel_client_context* rdpdr)
947 {
948  wStream* s = NULL;
949 
950  s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_DEVICELIST_ANNOUNCE, 24);
951  if (!s)
952  return CHANNEL_RC_NO_MEMORY;
953 
954  Stream_Write_UINT32(s, 1); /* deviceCount -> our emulated smartcard only */
955  Stream_Write_UINT32(s, RDPDR_DTYP_SMARTCARD); /* deviceType */
956  Stream_Write_UINT32(
957  s, SCARD_DEVICE_ID); /* deviceID -> reserve highest value for the emulated smartcard */
958  Stream_Write(s, "SCARD\0\0\0", 8);
959  Stream_Write_UINT32(s, 6);
960  Stream_Write(s, "SCARD\0", 6);
961 
962  return rdpdr_client_send(rdpdr->log, pc, s);
963 }
964 
965 static UINT rdpdr_send_emulated_scard_device_remove(pClientContext* pc,
966  pf_channel_client_context* rdpdr)
967 {
968  wStream* s = NULL;
969 
970  s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_DEVICELIST_REMOVE, 24);
971  if (!s)
972  return CHANNEL_RC_NO_MEMORY;
973 
974  Stream_Write_UINT32(s, 1); /* deviceCount -> our emulated smartcard only */
975  Stream_Write_UINT32(
976  s, SCARD_DEVICE_ID); /* deviceID -> reserve highest value for the emulated smartcard */
977 
978  return rdpdr_client_send(rdpdr->log, pc, s);
979 }
980 
981 static UINT rdpdr_process_server_device_announce_response(pf_channel_client_context* rdpdr,
982  wStream* s)
983 {
984  const UINT16 component = RDPDR_CTYP_CORE;
985  const UINT16 packetid = PAKID_CORE_DEVICE_REPLY;
986  UINT32 deviceID = 0;
987  UINT32 resultCode = 0;
988 
989  WINPR_ASSERT(rdpdr);
990  WINPR_ASSERT(s);
991 
992  if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 8))
993  return ERROR_INVALID_DATA;
994 
995  Stream_Read_UINT32(s, deviceID);
996  Stream_Read_UINT32(s, resultCode);
997 
998  if (deviceID != SCARD_DEVICE_ID)
999  {
1000  CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
1001  "[%s | %s] deviceID mismatch, sent 0x%08" PRIx32 ", changed to 0x%08" PRIx32,
1002  rdpdr_component_string(component), rdpdr_packetid_string(packetid),
1003  SCARD_DEVICE_ID, deviceID);
1004  }
1005  else if (resultCode != 0)
1006  {
1007  CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
1008  "[%s | %s] deviceID 0x%08" PRIx32 " resultCode=0x%08" PRIx32,
1009  rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID,
1010  resultCode);
1011  }
1012  else
1013  CLIENT_RX_LOG(rdpdr->log, WLOG_DEBUG,
1014  "[%s | %s] deviceID 0x%08" PRIx32 " resultCode=0x%08" PRIx32
1015  " -> emulated smartcard redirected!",
1016  rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID,
1017  resultCode);
1018 
1019  return CHANNEL_RC_OK;
1020 }
1021 #endif
1022 
1023 static BOOL pf_channel_rdpdr_rewrite_device_list_to(wStream* s, UINT32 fromVersion,
1024  UINT32 toVersion)
1025 {
1026  BOOL rc = FALSE;
1027  if (fromVersion == toVersion)
1028  return TRUE;
1029 
1030  const size_t cap = Stream_GetRemainingLength(s);
1031  wStream* clone = Stream_New(NULL, cap);
1032  if (!clone)
1033  goto fail;
1034  const size_t pos = Stream_GetPosition(s);
1035  Stream_Copy(s, clone, cap);
1036  Stream_SealLength(clone);
1037 
1038  Stream_SetPosition(clone, 0);
1039  Stream_SetPosition(s, pos);
1040 
1041  /* Skip device count */
1042  if (!Stream_SafeSeek(s, 4))
1043  goto fail;
1044 
1045  UINT32 count = 0;
1046  if (Stream_GetRemainingLength(clone) < 4)
1047  goto fail;
1048  Stream_Read_UINT32(clone, count);
1049 
1050  for (UINT32 x = 0; x < count; x++)
1051  {
1052  RdpdrDevice device = { 0 };
1053  const size_t charCount = ARRAYSIZE(device.PreferredDosName);
1054  if (Stream_GetRemainingLength(clone) < 20)
1055  goto fail;
1056 
1057  Stream_Read_UINT32(clone, device.DeviceType); /* DeviceType (4 bytes) */
1058  Stream_Read_UINT32(clone, device.DeviceId); /* DeviceId (4 bytes) */
1059  Stream_Read(clone, device.PreferredDosName, charCount); /* PreferredDosName (8 bytes) */
1060  Stream_Read_UINT32(clone, device.DeviceDataLength); /* DeviceDataLength (4 bytes) */
1061  device.DeviceData = Stream_Pointer(clone);
1062  if (!Stream_SafeSeek(clone, device.DeviceDataLength))
1063  goto fail;
1064 
1065  if (!Stream_EnsureRemainingCapacity(s, 20))
1066  goto fail;
1067  Stream_Write_UINT32(s, device.DeviceType);
1068  Stream_Write_UINT32(s, device.DeviceId);
1069  Stream_Write(s, device.PreferredDosName, charCount);
1070 
1071  if (device.DeviceType == RDPDR_DTYP_FILESYSTEM)
1072  {
1073  if (toVersion == DRIVE_CAPABILITY_VERSION_01)
1074  Stream_Write_UINT32(s, 0); /* No unicode name */
1075  else
1076  {
1077  const size_t datalen = charCount * sizeof(WCHAR);
1078  if (!Stream_EnsureRemainingCapacity(s, datalen + sizeof(UINT32)))
1079  goto fail;
1080  Stream_Write_UINT32(s, datalen);
1081 
1082  const SSIZE_T rcw = Stream_Write_UTF16_String_From_UTF8(
1083  s, charCount, device.PreferredDosName, charCount - 1, TRUE);
1084  if (rcw < 0)
1085  goto fail;
1086  }
1087  }
1088  else
1089  {
1090  Stream_Write_UINT32(s, device.DeviceDataLength);
1091  if (!Stream_EnsureRemainingCapacity(s, device.DeviceDataLength))
1092  goto fail;
1093  Stream_Write(s, device.DeviceData, device.DeviceDataLength);
1094  }
1095  }
1096 
1097  Stream_SealLength(s);
1098  rc = TRUE;
1099 
1100 fail:
1101  Stream_Free(clone, TRUE);
1102  return rc;
1103 }
1104 
1105 static BOOL pf_channel_rdpdr_rewrite_device_list(pf_channel_client_context* rdpdr,
1106  pServerContext* ps, wStream* s, BOOL toServer)
1107 {
1108  WINPR_ASSERT(rdpdr);
1109  WINPR_ASSERT(ps);
1110 
1111  const size_t pos = Stream_GetPosition(s);
1112  UINT16 component = 0;
1113  UINT16 packetid = 0;
1114  Stream_SetPosition(s, 0);
1115 
1116  if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))
1117  return FALSE;
1118 
1119  Stream_Read_UINT16(s, component);
1120  Stream_Read_UINT16(s, packetid);
1121  if ((component != RDPDR_CTYP_CORE) || (packetid != PAKID_CORE_DEVICELIST_ANNOUNCE))
1122  {
1123  Stream_SetPosition(s, pos);
1124  return TRUE;
1125  }
1126 
1127  const pf_channel_server_context* srv =
1128  HashTable_GetItemValue(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1129  if (!srv)
1130  {
1131  WLog_Print(rdpdr->log, WLOG_ERROR, "No channel %s in intercep map", RDPDR_SVC_CHANNEL_NAME);
1132  return FALSE;
1133  }
1134 
1135  UINT32 from = srv->common.capabilityVersions[CAP_DRIVE_TYPE];
1136  UINT32 to = rdpdr->common.capabilityVersions[CAP_DRIVE_TYPE];
1137  if (toServer)
1138  {
1139  from = rdpdr->common.capabilityVersions[CAP_DRIVE_TYPE];
1140  to = srv->common.capabilityVersions[CAP_DRIVE_TYPE];
1141  }
1142  if (!pf_channel_rdpdr_rewrite_device_list_to(s, from, to))
1143  return FALSE;
1144 
1145  Stream_SetPosition(s, pos);
1146  return TRUE;
1147 }
1148 
1149 static BOOL pf_channel_rdpdr_client_send_to_server(pf_channel_client_context* rdpdr,
1150  pServerContext* ps, wStream* s)
1151 {
1152  WINPR_ASSERT(rdpdr);
1153  if (ps)
1154  {
1155  UINT16 server_channel_id = WTSChannelGetId(ps->context.peer, RDPDR_SVC_CHANNEL_NAME);
1156 
1157  /* Ignore messages for channels that can not be mapped.
1158  * The client might not have enabled support for this specific channel,
1159  * so just drop the message. */
1160  if (server_channel_id == 0)
1161  return TRUE;
1162 
1163  if (!pf_channel_rdpdr_rewrite_device_list(rdpdr, ps, s, TRUE))
1164  return FALSE;
1165  size_t len = Stream_Length(s);
1166  Stream_SetPosition(s, len);
1167  rdpdr_dump_send_packet(rdpdr->log, WLOG_TRACE, s, proxy_client_tx);
1168  WINPR_ASSERT(ps->context.peer);
1169  WINPR_ASSERT(ps->context.peer->SendChannelData);
1170  return ps->context.peer->SendChannelData(ps->context.peer, server_channel_id,
1171  Stream_Buffer(s), len);
1172  }
1173  return TRUE;
1174 }
1175 
1176 static BOOL pf_channel_send_client_queue(pClientContext* pc, pf_channel_client_context* rdpdr);
1177 
1178 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1179 static BOOL rdpdr_process_server_loggedon_request(pServerContext* ps, pClientContext* pc,
1180  pf_channel_client_context* rdpdr, wStream* s,
1181  UINT16 component, UINT16 packetid)
1182 {
1183  WINPR_ASSERT(rdpdr);
1184  WLog_Print(rdpdr->log, WLOG_DEBUG, "[%s | %s]", rdpdr_component_string(component),
1185  rdpdr_packetid_string(packetid));
1186  if (rdpdr_send_emulated_scard_device_remove(pc, rdpdr) != CHANNEL_RC_OK)
1187  return FALSE;
1188  if (rdpdr_send_emulated_scard_device_list_announce_request(pc, rdpdr) != CHANNEL_RC_OK)
1189  return FALSE;
1190  return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s);
1191 }
1192 
1193 static BOOL filter_smartcard_io_requests(pf_channel_client_context* rdpdr, wStream* s,
1194  UINT16* pPacketid)
1195 {
1196  BOOL rc = FALSE;
1197  UINT16 component = 0;
1198  UINT16 packetid = 0;
1199  UINT32 deviceID = 0;
1200  size_t pos = 0;
1201 
1202  WINPR_ASSERT(rdpdr);
1203  WINPR_ASSERT(pPacketid);
1204 
1205  if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))
1206  return FALSE;
1207 
1208  pos = Stream_GetPosition(s);
1209  Stream_Read_UINT16(s, component);
1210  Stream_Read_UINT16(s, packetid);
1211 
1212  if (Stream_GetRemainingLength(s) >= 4)
1213  Stream_Read_UINT32(s, deviceID);
1214 
1215  WLog_Print(rdpdr->log, WLOG_DEBUG, "got: [%s | %s]: [0x%08" PRIx32 "]",
1216  rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID);
1217 
1218  if (component != RDPDR_CTYP_CORE)
1219  goto fail;
1220 
1221  switch (packetid)
1222  {
1223  case PAKID_CORE_SERVER_ANNOUNCE:
1224  case PAKID_CORE_CLIENTID_CONFIRM:
1225  case PAKID_CORE_CLIENT_NAME:
1226  case PAKID_CORE_DEVICELIST_ANNOUNCE:
1227  case PAKID_CORE_DEVICELIST_REMOVE:
1228  case PAKID_CORE_SERVER_CAPABILITY:
1229  case PAKID_CORE_CLIENT_CAPABILITY:
1230  WLog_Print(rdpdr->log, WLOG_WARN, "Filtering client -> server message [%s | %s]",
1231  rdpdr_component_string(component), rdpdr_packetid_string(packetid));
1232  *pPacketid = packetid;
1233  break;
1234  case PAKID_CORE_USER_LOGGEDON:
1235  *pPacketid = packetid;
1236  break;
1237  case PAKID_CORE_DEVICE_REPLY:
1238  case PAKID_CORE_DEVICE_IOREQUEST:
1239  if (deviceID != SCARD_DEVICE_ID)
1240  goto fail;
1241  *pPacketid = packetid;
1242  break;
1243  default:
1244  if (deviceID != SCARD_DEVICE_ID)
1245  goto fail;
1246  WLog_Print(rdpdr->log, WLOG_WARN,
1247  "Got [%s | %s] for deviceID 0x%08" PRIx32 ", TODO: Not handled!",
1248  rdpdr_component_string(component), rdpdr_packetid_string(packetid),
1249  deviceID);
1250  goto fail;
1251  }
1252 
1253  rc = TRUE;
1254 
1255 fail:
1256  Stream_SetPosition(s, pos);
1257  return rc;
1258 }
1259 #endif
1260 
1261 BOOL pf_channel_send_client_queue(pClientContext* pc, pf_channel_client_context* rdpdr)
1262 {
1263  UINT16 channelId = 0;
1264 
1265  WINPR_ASSERT(pc);
1266  WINPR_ASSERT(rdpdr);
1267 
1268  if (rdpdr->state != STATE_CLIENT_CHANNEL_RUNNING)
1269  return FALSE;
1270  channelId = freerdp_channels_get_id_by_name(pc->context.instance, RDPDR_SVC_CHANNEL_NAME);
1271  if ((channelId == 0) || (channelId == UINT16_MAX))
1272  return TRUE;
1273 
1274  Queue_Lock(rdpdr->queue);
1275  while (Queue_Count(rdpdr->queue) > 0)
1276  {
1277  wStream* s = Queue_Dequeue(rdpdr->queue);
1278  if (!s)
1279  continue;
1280 
1281  size_t len = Stream_Length(s);
1282  Stream_SetPosition(s, len);
1283 
1284  rdpdr_dump_send_packet(rdpdr->log, WLOG_TRACE, s, proxy_server_tx " (queue) ");
1285  WINPR_ASSERT(pc->context.instance->SendChannelData);
1286  if (!pc->context.instance->SendChannelData(pc->context.instance, channelId,
1287  Stream_Buffer(s), len))
1288  {
1289  CLIENT_TX_LOG(rdpdr->log, WLOG_ERROR, "xxxxxx TODO: Failed to send data!");
1290  }
1291  Stream_Free(s, TRUE);
1292  }
1293  Queue_Unlock(rdpdr->queue);
1294  return TRUE;
1295 }
1296 
1297 static BOOL rdpdr_handle_server_announce_request(pClientContext* pc,
1298  pf_channel_client_context* rdpdr, wStream* s)
1299 {
1300  WINPR_ASSERT(pc);
1301  WINPR_ASSERT(rdpdr);
1302  WINPR_ASSERT(s);
1303 
1304  if (rdpdr_process_server_announce_request(rdpdr, s) != CHANNEL_RC_OK)
1305  return FALSE;
1306  if (rdpdr_send_client_announce_reply(pc, rdpdr) != CHANNEL_RC_OK)
1307  return FALSE;
1308  if (rdpdr_send_client_name_request(pc, rdpdr) != CHANNEL_RC_OK)
1309  return FALSE;
1310  rdpdr->state = STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST;
1311  return TRUE;
1312 }
1313 
1314 BOOL pf_channel_rdpdr_client_handle(pClientContext* pc, UINT16 channelId, const char* channel_name,
1315  const BYTE* xdata, size_t xsize, UINT32 flags, size_t totalSize)
1316 {
1317  pf_channel_client_context* rdpdr = NULL;
1318  pServerContext* ps = NULL;
1319  wStream* s = NULL;
1320 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1321  UINT16 packetid = 0;
1322 #endif
1323 
1324  WINPR_ASSERT(pc);
1325  WINPR_ASSERT(pc->pdata);
1326  WINPR_ASSERT(pc->interceptContextMap);
1327  WINPR_ASSERT(channel_name);
1328  WINPR_ASSERT(xdata);
1329 
1330  ps = pc->pdata->ps;
1331 
1332  rdpdr = HashTable_GetItemValue(pc->interceptContextMap, channel_name);
1333  if (!rdpdr)
1334  {
1335  CLIENT_RX_LOG(WLog_Get(RTAG), WLOG_ERROR,
1336  "Channel %s [0x%04" PRIx16 "] missing context in interceptContextMap",
1337  channel_name, channelId);
1338  return FALSE;
1339  }
1340  s = rdpdr->common.buffer;
1341  if (flags & CHANNEL_FLAG_FIRST)
1342  Stream_SetPosition(s, 0);
1343  if (!Stream_EnsureRemainingCapacity(s, xsize))
1344  {
1345  CLIENT_RX_LOG(rdpdr->log, WLOG_ERROR,
1346  "Channel %s [0x%04" PRIx16 "] not enough memory [need %" PRIuz "]",
1347  channel_name, channelId, xsize);
1348  return FALSE;
1349  }
1350  Stream_Write(s, xdata, xsize);
1351  if ((flags & CHANNEL_FLAG_LAST) == 0)
1352  return TRUE;
1353 
1354  Stream_SealLength(s);
1355  Stream_SetPosition(s, 0);
1356  if (Stream_Length(s) != totalSize)
1357  {
1358  CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
1359  "Received invalid %s channel data (server -> proxy), expected %" PRIuz
1360  "bytes, got %" PRIuz,
1361  channel_name, totalSize, Stream_Length(s));
1362  return FALSE;
1363  }
1364 
1365  rdpdr_dump_received_packet(rdpdr->log, WLOG_TRACE, s, proxy_server_rx);
1366  switch (rdpdr->state)
1367  {
1368  case STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST:
1369  if (!rdpdr_handle_server_announce_request(pc, rdpdr, s))
1370  return FALSE;
1371  break;
1372  case STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST:
1373  if (!rdpdr_process_server_capability_request_or_clientid_confirm(rdpdr, s))
1374  return FALSE;
1375  rdpdr->state = STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM;
1376  break;
1377  case STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM:
1378  if (!rdpdr_process_server_capability_request_or_clientid_confirm(rdpdr, s))
1379  return FALSE;
1380  if (rdpdr_send_client_capability_response(pc, rdpdr) != CHANNEL_RC_OK)
1381  return FALSE;
1382 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1383  if (pf_channel_smartcard_client_emulate(pc))
1384  {
1385  if (rdpdr_send_emulated_scard_device_list_announce_request(pc, rdpdr) !=
1386  CHANNEL_RC_OK)
1387  return FALSE;
1388  rdpdr->state = STATE_CLIENT_CHANNEL_RUNNING;
1389  }
1390  else
1391 #endif
1392  {
1393  rdpdr->state = STATE_CLIENT_CHANNEL_RUNNING;
1394  pf_channel_send_client_queue(pc, rdpdr);
1395  }
1396 
1397  break;
1398  case STATE_CLIENT_CHANNEL_RUNNING:
1399 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1400  if (!pf_channel_smartcard_client_emulate(pc) ||
1401  !filter_smartcard_io_requests(rdpdr, s, &packetid))
1402  return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s);
1403  else
1404  {
1405  switch (packetid)
1406  {
1407  case PAKID_CORE_USER_LOGGEDON:
1408  return rdpdr_process_server_loggedon_request(ps, pc, rdpdr, s,
1409  RDPDR_CTYP_CORE, packetid);
1410  case PAKID_CORE_DEVICE_IOREQUEST:
1411  {
1412  wStream* out = rdpdr_client_get_send_buffer(
1413  rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_DEVICE_IOCOMPLETION, 0);
1414  WINPR_ASSERT(out);
1415 
1416  if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE,
1417  PAKID_CORE_DEVICE_IOREQUEST, 20))
1418  return FALSE;
1419 
1420  if (!pf_channel_smartcard_client_handle(rdpdr->log, pc, s, out,
1421  rdpdr_client_send))
1422  return FALSE;
1423  }
1424  break;
1425  case PAKID_CORE_SERVER_ANNOUNCE:
1426  pf_channel_rdpdr_client_reset(pc);
1427  if (!rdpdr_handle_server_announce_request(pc, rdpdr, s))
1428  return FALSE;
1429  break;
1430  case PAKID_CORE_SERVER_CAPABILITY:
1431  rdpdr->state = STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST;
1432  rdpdr->flags = 0;
1433  return pf_channel_rdpdr_client_handle(pc, channelId, channel_name, xdata,
1434  xsize, flags, totalSize);
1435  case PAKID_CORE_DEVICE_REPLY:
1436  break;
1437  default:
1438  CLIENT_RX_LOG(
1439  rdpdr->log, WLOG_ERROR,
1440  "Channel %s [0x%04" PRIx16
1441  "] we´ve reached an impossible state %s! [%s] aliens invaded!",
1442  channel_name, channelId, rdpdr_client_state_to_string(rdpdr->state),
1443  rdpdr_packetid_string(packetid));
1444  return FALSE;
1445  }
1446  }
1447  break;
1448 #else
1449  return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s);
1450 #endif
1451  default:
1452  CLIENT_RX_LOG(rdpdr->log, WLOG_ERROR,
1453  "Channel %s [0x%04" PRIx16
1454  "] we´ve reached an impossible state %s! aliens invaded!",
1455  channel_name, channelId, rdpdr_client_state_to_string(rdpdr->state));
1456  return FALSE;
1457  }
1458 
1459  return TRUE;
1460 }
1461 
1462 static void pf_channel_rdpdr_common_context_free(pf_channel_common_context* common)
1463 {
1464  if (!common)
1465  return;
1466  free(common->computerName.v);
1467  Stream_Free(common->s, TRUE);
1468  Stream_Free(common->buffer, TRUE);
1469 }
1470 
1471 static void pf_channel_rdpdr_client_context_free(InterceptContextMapEntry* base)
1472 {
1473  pf_channel_client_context* entry = (pf_channel_client_context*)base;
1474  if (!entry)
1475  return;
1476 
1477  pf_channel_rdpdr_common_context_free(&entry->common);
1478  Queue_Free(entry->queue);
1479  free(entry);
1480 }
1481 
1482 static BOOL pf_channel_rdpdr_common_context_new(pf_channel_common_context* common,
1483  void (*fkt)(InterceptContextMapEntry*))
1484 {
1485  if (!common)
1486  return FALSE;
1487  common->base.free = fkt;
1488  common->s = Stream_New(NULL, 1024);
1489  if (!common->s)
1490  return FALSE;
1491  common->buffer = Stream_New(NULL, 1024);
1492  if (!common->buffer)
1493  return FALSE;
1494  common->computerNameUnicode = 1;
1495  common->computerName.v = NULL;
1496  common->versionMajor = RDPDR_VERSION_MAJOR;
1497  common->versionMinor = RDPDR_VERSION_MINOR_RDP10X;
1498  common->clientID = SCARD_DEVICE_ID;
1499 
1500  const UINT32 versions[] = { 0,
1501  GENERAL_CAPABILITY_VERSION_02,
1502  PRINT_CAPABILITY_VERSION_01,
1503  PORT_CAPABILITY_VERSION_01,
1504  DRIVE_CAPABILITY_VERSION_02,
1505  SMARTCARD_CAPABILITY_VERSION_01 };
1506 
1507  memcpy(common->capabilityVersions, versions, sizeof(common->capabilityVersions));
1508  return TRUE;
1509 }
1510 
1511 static BOOL pf_channel_rdpdr_client_pass_message(pServerContext* ps, pClientContext* pc,
1512  UINT16 channelId, const char* channel_name,
1513  wStream* s)
1514 {
1515  pf_channel_client_context* rdpdr = NULL;
1516 
1517  WINPR_ASSERT(ps);
1518  WINPR_ASSERT(pc);
1519 
1520  rdpdr = HashTable_GetItemValue(pc->interceptContextMap, channel_name);
1521  if (!rdpdr)
1522  return TRUE; /* Ignore data for channels not available on proxy -> server connection */
1523  WINPR_ASSERT(rdpdr->queue);
1524 
1525  if (!pf_channel_rdpdr_rewrite_device_list(rdpdr, ps, s, FALSE))
1526  return FALSE;
1527  if (!Queue_Enqueue(rdpdr->queue, s))
1528  return FALSE;
1529  pf_channel_send_client_queue(pc, rdpdr);
1530  return TRUE;
1531 }
1532 
1533 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1534 static BOOL filter_smartcard_device_list_remove(pf_channel_server_context* rdpdr, wStream* s)
1535 {
1536  size_t pos = 0;
1537  UINT32 count = 0;
1538 
1539  WINPR_ASSERT(rdpdr);
1540  if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, sizeof(UINT32)))
1541  return TRUE;
1542  pos = Stream_GetPosition(s);
1543  Stream_Read_UINT32(s, count);
1544 
1545  if (count == 0)
1546  return TRUE;
1547 
1548  if (!Stream_CheckAndLogRequiredLengthOfSizeWLog(rdpdr->log, s, count, sizeof(UINT32)))
1549  return TRUE;
1550 
1551  for (UINT32 x = 0; x < count; x++)
1552  {
1553  UINT32 deviceID = 0;
1554  BYTE* dst = Stream_Pointer(s);
1555  Stream_Read_UINT32(s, deviceID);
1556  if (deviceID == SCARD_DEVICE_ID)
1557  {
1558  ArrayList_Remove(rdpdr->blockedDevices, (void*)(size_t)deviceID);
1559 
1560  /* This is the only device, filter it! */
1561  if (count == 1)
1562  return TRUE;
1563 
1564  /* Remove this device from the list */
1565  memmove(dst, Stream_ConstPointer(s), (count - x - 1) * sizeof(UINT32));
1566 
1567  count--;
1568  Stream_SetPosition(s, pos);
1569  Stream_Write_UINT32(s, count);
1570  return FALSE;
1571  }
1572  }
1573 
1574  return FALSE;
1575 }
1576 
1577 static BOOL filter_smartcard_device_io_request(pf_channel_server_context* rdpdr, wStream* s)
1578 {
1579  UINT32 DeviceID = 0;
1580  WINPR_ASSERT(rdpdr);
1581  WINPR_ASSERT(s);
1582  Stream_Read_UINT32(s, DeviceID);
1583  return ArrayList_Contains(rdpdr->blockedDevices, (void*)(size_t)DeviceID);
1584 }
1585 
1586 static BOOL filter_smartcard_device_list_announce(pf_channel_server_context* rdpdr, wStream* s)
1587 {
1588  UINT32 count = 0;
1589 
1590  WINPR_ASSERT(rdpdr);
1591  if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, sizeof(UINT32)))
1592  return TRUE;
1593  const size_t pos = Stream_GetPosition(s);
1594  Stream_Read_UINT32(s, count);
1595 
1596  if (count == 0)
1597  return TRUE;
1598 
1599  for (UINT32 x = 0; x < count; x++)
1600  {
1601  UINT32 DeviceType = 0;
1602  UINT32 DeviceId = 0;
1603  char PreferredDosName[8];
1604  UINT32 DeviceDataLength = 0;
1605  BYTE* dst = Stream_Pointer(s);
1606  if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 20))
1607  return TRUE;
1608  Stream_Read_UINT32(s, DeviceType);
1609  Stream_Read_UINT32(s, DeviceId);
1610  Stream_Read(s, PreferredDosName, ARRAYSIZE(PreferredDosName));
1611  Stream_Read_UINT32(s, DeviceDataLength);
1612  if (!Stream_SafeSeek(s, DeviceDataLength))
1613  return TRUE;
1614  if (DeviceType == RDPDR_DTYP_SMARTCARD)
1615  {
1616  ArrayList_Append(rdpdr->blockedDevices, (void*)(size_t)DeviceId);
1617  if (count == 1)
1618  return TRUE;
1619 
1620  WLog_Print(rdpdr->log, WLOG_INFO, "Filtering smartcard device 0x%08" PRIx32 "",
1621  DeviceId);
1622 
1623  memmove(dst, Stream_ConstPointer(s), Stream_GetRemainingLength(s));
1624  Stream_SetPosition(s, pos);
1625  Stream_Write_UINT32(s, count - 1);
1626  return FALSE;
1627  }
1628  }
1629 
1630  return FALSE;
1631 }
1632 
1633 static BOOL filter_smartcard_device_list_announce_request(pf_channel_server_context* rdpdr,
1634  wStream* s)
1635 {
1636  BOOL rc = TRUE;
1637  size_t pos = 0;
1638  UINT16 component = 0;
1639  UINT16 packetid = 0;
1640 
1641  WINPR_ASSERT(rdpdr);
1642  if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 8))
1643  return FALSE;
1644 
1645  pos = Stream_GetPosition(s);
1646 
1647  Stream_Read_UINT16(s, component);
1648  Stream_Read_UINT16(s, packetid);
1649 
1650  if (component != RDPDR_CTYP_CORE)
1651  goto fail;
1652 
1653  switch (packetid)
1654  {
1655  case PAKID_CORE_DEVICELIST_ANNOUNCE:
1656  if (filter_smartcard_device_list_announce(rdpdr, s))
1657  goto fail;
1658  break;
1659  case PAKID_CORE_DEVICELIST_REMOVE:
1660  if (filter_smartcard_device_list_remove(rdpdr, s))
1661  goto fail;
1662  break;
1663  case PAKID_CORE_DEVICE_IOREQUEST:
1664  if (filter_smartcard_device_io_request(rdpdr, s))
1665  goto fail;
1666  break;
1667 
1668  case PAKID_CORE_SERVER_ANNOUNCE:
1669  case PAKID_CORE_CLIENTID_CONFIRM:
1670  case PAKID_CORE_CLIENT_NAME:
1671  case PAKID_CORE_DEVICE_REPLY:
1672  case PAKID_CORE_SERVER_CAPABILITY:
1673  case PAKID_CORE_CLIENT_CAPABILITY:
1674  case PAKID_CORE_USER_LOGGEDON:
1675  WLog_Print(rdpdr->log, WLOG_WARN, "Filtering client -> server message [%s | %s]",
1676  rdpdr_component_string(component), rdpdr_packetid_string(packetid));
1677  goto fail;
1678  default:
1679  break;
1680  }
1681 
1682  rc = FALSE;
1683 fail:
1684  Stream_SetPosition(s, pos);
1685  return rc;
1686 }
1687 #endif
1688 
1689 static void* stream_copy(const void* obj)
1690 {
1691  const wStream* src = obj;
1692  wStream* dst = Stream_New(NULL, Stream_Capacity(src));
1693  if (!dst)
1694  return NULL;
1695  memcpy(Stream_Buffer(dst), Stream_ConstBuffer(src), Stream_Capacity(dst));
1696  Stream_SetLength(dst, Stream_Length(src));
1697  Stream_SetPosition(dst, Stream_GetPosition(src));
1698  return dst;
1699 }
1700 
1701 static void stream_free(void* obj)
1702 {
1703  wStream* s = obj;
1704  Stream_Free(s, TRUE);
1705 }
1706 
1707 static const char* pf_channel_rdpdr_client_context(void* arg)
1708 {
1709  pClientContext* pc = arg;
1710  if (!pc)
1711  return "pc=null";
1712  if (!pc->pdata)
1713  return "pc->pdata=null";
1714  return pc->pdata->session_id;
1715 }
1716 
1717 BOOL pf_channel_rdpdr_client_new(pClientContext* pc)
1718 {
1719  wObject* obj = NULL;
1720  pf_channel_client_context* rdpdr = NULL;
1721 
1722  WINPR_ASSERT(pc);
1723  WINPR_ASSERT(pc->interceptContextMap);
1724 
1725  rdpdr = calloc(1, sizeof(pf_channel_client_context));
1726  if (!rdpdr)
1727  return FALSE;
1728  rdpdr->log = WLog_Get(RTAG);
1729  WINPR_ASSERT(rdpdr->log);
1730 
1731  WLog_SetContext(rdpdr->log, pf_channel_rdpdr_client_context, pc);
1732  if (!pf_channel_rdpdr_common_context_new(&rdpdr->common, pf_channel_rdpdr_client_context_free))
1733  goto fail;
1734 
1735  rdpdr->maxMajorVersion = RDPDR_VERSION_MAJOR;
1736  rdpdr->maxMinorVersion = RDPDR_VERSION_MINOR_RDP10X;
1737  rdpdr->state = STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST;
1738 
1739  rdpdr->queue = Queue_New(TRUE, 0, 0);
1740  if (!rdpdr->queue)
1741  goto fail;
1742  obj = Queue_Object(rdpdr->queue);
1743  WINPR_ASSERT(obj);
1744  obj->fnObjectNew = stream_copy;
1745  obj->fnObjectFree = stream_free;
1746  if (!HashTable_Insert(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME, rdpdr))
1747  goto fail;
1748  // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert takes ownership of rdpdr
1749  return TRUE;
1750 fail:
1751  pf_channel_rdpdr_client_context_free(&rdpdr->common.base);
1752  return FALSE;
1753 }
1754 
1755 void pf_channel_rdpdr_client_free(pClientContext* pc)
1756 {
1757  WINPR_ASSERT(pc);
1758  WINPR_ASSERT(pc->interceptContextMap);
1759  HashTable_Remove(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1760 }
1761 
1762 static void pf_channel_rdpdr_server_context_free(InterceptContextMapEntry* base)
1763 {
1764  pf_channel_server_context* entry = (pf_channel_server_context*)base;
1765  if (!entry)
1766  return;
1767 
1768  (void)WTSVirtualChannelClose(entry->handle);
1769  pf_channel_rdpdr_common_context_free(&entry->common);
1770  ArrayList_Free(entry->blockedDevices);
1771  free(entry);
1772 }
1773 
1774 static const char* pf_channel_rdpdr_server_context(void* arg)
1775 {
1776  pServerContext* ps = arg;
1777  if (!ps)
1778  return "ps=null";
1779  if (!ps->pdata)
1780  return "ps->pdata=null";
1781  return ps->pdata->session_id;
1782 }
1783 
1784 BOOL pf_channel_rdpdr_server_new(pServerContext* ps)
1785 {
1786  pf_channel_server_context* rdpdr = NULL;
1787  PULONG pSessionId = NULL;
1788  DWORD BytesReturned = 0;
1789 
1790  WINPR_ASSERT(ps);
1791  WINPR_ASSERT(ps->interceptContextMap);
1792 
1793  rdpdr = calloc(1, sizeof(pf_channel_server_context));
1794  if (!rdpdr)
1795  return FALSE;
1796  rdpdr->log = WLog_Get(RTAG);
1797  WINPR_ASSERT(rdpdr->log);
1798  WLog_SetContext(rdpdr->log, pf_channel_rdpdr_server_context, ps);
1799 
1800  if (!pf_channel_rdpdr_common_context_new(&rdpdr->common, pf_channel_rdpdr_server_context_free))
1801  goto fail;
1802  rdpdr->state = STATE_SERVER_INITIAL;
1803 
1804  rdpdr->blockedDevices = ArrayList_New(FALSE);
1805  if (!rdpdr->blockedDevices)
1806  goto fail;
1807 
1808  rdpdr->SessionId = WTS_CURRENT_SESSION;
1809  if (WTSQuerySessionInformationA(ps->vcm, WTS_CURRENT_SESSION, WTSSessionId, (LPSTR*)&pSessionId,
1810  &BytesReturned))
1811  {
1812  rdpdr->SessionId = (DWORD)*pSessionId;
1813  WTSFreeMemory(pSessionId);
1814  }
1815 
1816  rdpdr->handle = WTSVirtualChannelOpenEx(rdpdr->SessionId, RDPDR_SVC_CHANNEL_NAME, 0);
1817  if (rdpdr->handle == 0)
1818  goto fail;
1819  if (!HashTable_Insert(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME, rdpdr))
1820  goto fail;
1821 
1822  // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert takes ownership of rdpdr
1823  return TRUE;
1824 fail:
1825  pf_channel_rdpdr_server_context_free(&rdpdr->common.base);
1826  return FALSE;
1827 }
1828 
1829 void pf_channel_rdpdr_server_free(pServerContext* ps)
1830 {
1831  WINPR_ASSERT(ps);
1832  WINPR_ASSERT(ps->interceptContextMap);
1833  HashTable_Remove(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1834 }
1835 
1836 static pf_channel_server_context* get_channel(pServerContext* ps, BOOL send)
1837 {
1838  pf_channel_server_context* rdpdr = NULL;
1839  WINPR_ASSERT(ps);
1840  WINPR_ASSERT(ps->interceptContextMap);
1841 
1842  rdpdr = HashTable_GetItemValue(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1843  if (!rdpdr)
1844  {
1845  SERVER_RXTX_LOG(send, WLog_Get(RTAG), WLOG_ERROR,
1846  "Channel %s missing context in interceptContextMap",
1847  RDPDR_SVC_CHANNEL_NAME);
1848  return NULL;
1849  }
1850 
1851  return rdpdr;
1852 }
1853 
1854 BOOL pf_channel_rdpdr_server_handle(pServerContext* ps, UINT16 channelId, const char* channel_name,
1855  const BYTE* xdata, size_t xsize, UINT32 flags, size_t totalSize)
1856 {
1857  wStream* s = NULL;
1858  pClientContext* pc = NULL;
1859  pf_channel_server_context* rdpdr = get_channel(ps, FALSE);
1860  if (!rdpdr)
1861  return FALSE;
1862 
1863  WINPR_ASSERT(ps->pdata);
1864  pc = ps->pdata->pc;
1865 
1866  s = rdpdr->common.buffer;
1867 
1868  if (flags & CHANNEL_FLAG_FIRST)
1869  Stream_SetPosition(s, 0);
1870 
1871  if (!Stream_EnsureRemainingCapacity(s, xsize))
1872  return FALSE;
1873  Stream_Write(s, xdata, xsize);
1874 
1875  if ((flags & CHANNEL_FLAG_LAST) == 0)
1876  return TRUE;
1877 
1878  Stream_SealLength(s);
1879  Stream_SetPosition(s, 0);
1880 
1881  if (Stream_Length(s) != totalSize)
1882  {
1883  SERVER_RX_LOG(rdpdr->log, WLOG_WARN,
1884  "Received invalid %s channel data (client -> proxy), expected %" PRIuz
1885  "bytes, got %" PRIuz,
1886  channel_name, totalSize, Stream_Length(s));
1887  return FALSE;
1888  }
1889 
1890  rdpdr_dump_received_packet(rdpdr->log, WLOG_TRACE, s, proxy_client_rx);
1891  switch (rdpdr->state)
1892  {
1893  case STATE_SERVER_EXPECT_CLIENT_ANNOUNCE_REPLY:
1894  if (rdpdr_process_client_announce_reply(rdpdr, s) != CHANNEL_RC_OK)
1895  return FALSE;
1896  rdpdr->state = STATE_SERVER_EXPECT_CLIENT_NAME_REQUEST;
1897  break;
1898  case STATE_SERVER_EXPECT_CLIENT_NAME_REQUEST:
1899  if (rdpdr_process_client_name_request(rdpdr, s, pc) != CHANNEL_RC_OK)
1900  return FALSE;
1901  if (rdpdr_send_server_capability_request(rdpdr) != CHANNEL_RC_OK)
1902  return FALSE;
1903  if (rdpdr_send_server_clientid_confirm(rdpdr) != CHANNEL_RC_OK)
1904  return FALSE;
1905  rdpdr->state = STATE_SERVER_EXPECT_EXPECT_CLIENT_CAPABILITY_RESPONE;
1906  break;
1907  case STATE_SERVER_EXPECT_EXPECT_CLIENT_CAPABILITY_RESPONE:
1908  if (rdpdr_process_client_capability_response(rdpdr, s) != CHANNEL_RC_OK)
1909  return FALSE;
1910  rdpdr->state = STATE_SERVER_CHANNEL_RUNNING;
1911  break;
1912  case STATE_SERVER_CHANNEL_RUNNING:
1913 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1914  if (!pf_channel_smartcard_client_emulate(pc) ||
1915  !filter_smartcard_device_list_announce_request(rdpdr, s))
1916  {
1917  if (!pf_channel_rdpdr_client_pass_message(ps, pc, channelId, channel_name, s))
1918  return FALSE;
1919  }
1920  else
1921  return pf_channel_smartcard_server_handle(ps, s);
1922 #else
1923  if (!pf_channel_rdpdr_client_pass_message(ps, pc, channelId, channel_name, s))
1924  return FALSE;
1925 #endif
1926  break;
1927  default:
1928  case STATE_SERVER_INITIAL:
1929  SERVER_RX_LOG(rdpdr->log, WLOG_WARN, "Invalid state %s",
1930  rdpdr_server_state_to_string(rdpdr->state));
1931  return FALSE;
1932  }
1933 
1934  return TRUE;
1935 }
1936 
1937 BOOL pf_channel_rdpdr_server_announce(pServerContext* ps)
1938 {
1939  pf_channel_server_context* rdpdr = get_channel(ps, TRUE);
1940  if (!rdpdr)
1941  return FALSE;
1942 
1943  WINPR_ASSERT(rdpdr->state == STATE_SERVER_INITIAL);
1944  if (rdpdr_server_send_announce_request(rdpdr) != CHANNEL_RC_OK)
1945  return FALSE;
1946  rdpdr->state = STATE_SERVER_EXPECT_CLIENT_ANNOUNCE_REPLY;
1947  return TRUE;
1948 }
1949 
1950 BOOL pf_channel_rdpdr_client_reset(pClientContext* pc)
1951 {
1952  pf_channel_client_context* rdpdr = NULL;
1953 
1954  WINPR_ASSERT(pc);
1955  WINPR_ASSERT(pc->pdata);
1956  WINPR_ASSERT(pc->interceptContextMap);
1957 
1958  rdpdr = HashTable_GetItemValue(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1959  if (!rdpdr)
1960  return TRUE;
1961 
1962  Queue_Clear(rdpdr->queue);
1963  rdpdr->flags = 0;
1964  rdpdr->state = STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST;
1965 
1966  return TRUE;
1967 }
1968 
1969 static PfChannelResult pf_rdpdr_back_data(proxyData* pdata,
1970  const pServerStaticChannelContext* channel,
1971  const BYTE* xdata, size_t xsize, UINT32 flags,
1972  size_t totalSize)
1973 {
1974  WINPR_ASSERT(pdata);
1975  WINPR_ASSERT(channel);
1976 
1977  if (!pf_channel_rdpdr_client_handle(pdata->pc,
1978  WINPR_ASSERTING_INT_CAST(UINT16, channel->back_channel_id),
1979  channel->channel_name, xdata, xsize, flags, totalSize))
1980  return PF_CHANNEL_RESULT_ERROR;
1981 
1982 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1983  if (pf_channel_smartcard_client_emulate(pdata->pc))
1984  return PF_CHANNEL_RESULT_DROP;
1985 #endif
1986  return PF_CHANNEL_RESULT_DROP;
1987 }
1988 
1989 static PfChannelResult pf_rdpdr_front_data(proxyData* pdata,
1990  const pServerStaticChannelContext* channel,
1991  const BYTE* xdata, size_t xsize, UINT32 flags,
1992  size_t totalSize)
1993 {
1994  WINPR_ASSERT(pdata);
1995  WINPR_ASSERT(channel);
1996 
1997  if (!pf_channel_rdpdr_server_handle(pdata->ps,
1998  WINPR_ASSERTING_INT_CAST(UINT16, channel->front_channel_id),
1999  channel->channel_name, xdata, xsize, flags, totalSize))
2000  return PF_CHANNEL_RESULT_ERROR;
2001 
2002 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
2003  if (pf_channel_smartcard_client_emulate(pdata->pc))
2004  return PF_CHANNEL_RESULT_DROP;
2005 #endif
2006  return PF_CHANNEL_RESULT_DROP;
2007 }
2008 
2009 BOOL pf_channel_setup_rdpdr(pServerContext* ps, pServerStaticChannelContext* channel)
2010 {
2011  channel->onBackData = pf_rdpdr_back_data;
2012  channel->onFrontData = pf_rdpdr_front_data;
2013 
2014  if (!pf_channel_rdpdr_server_new(ps))
2015  return FALSE;
2016  if (!pf_channel_rdpdr_server_announce(ps))
2017  return FALSE;
2018 
2019  return TRUE;
2020 }
This struct contains function pointer to initialize/free objects.
Definition: collections.h:57