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