21 #include <freerdp/config.h>
23 #include <winpr/assert.h>
24 #include <winpr/cast.h>
25 #include <winpr/string.h>
26 #include <winpr/print.h>
28 #include "pf_channel_rdpdr.h"
29 #include "pf_channel_smartcard.h"
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>
36 #define RTAG PROXY_TAG("channel.rdpdr")
38 #define SCARD_DEVICE_ID UINT32_MAX
48 UINT32 computerNameLen;
49 BOOL computerNameUnicode;
56 UINT32 SpecialDeviceCount;
57 UINT32 capabilityVersions[6];
58 } pf_channel_common_context;
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;
70 pf_channel_common_context common;
71 pf_channel_client_state state;
73 UINT16 maxMajorVersion;
74 UINT16 maxMinorVersion;
77 } pf_channel_client_context;
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;
90 pf_channel_common_context common;
91 pf_channel_server_state state;
94 wArrayList* blockedDevices;
96 } pf_channel_server_context;
98 #define proxy_client "[proxy<-->client]"
99 #define proxy_server "[proxy<-->server]"
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"
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, ...) \
115 SERVER_RX_LOG(lvl, fmt, ##__VA_ARGS__); \
119 CLIENT_RX_LOG(lvl, fmt, ##__VA_ARGS__); \
123 #define SERVER_RXTX_LOG(send, log, lvl, fmt, ...) \
128 SERVER_TX_LOG(log, lvl, fmt, ##__VA_ARGS__); \
132 SERVER_RX_LOG(log, lvl, fmt, ##__VA_ARGS__); \
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,
151 srv ? proxy_server_rx
" %s(%s:%" PRIuz
")" : proxy_client_rx
" %s(%s:%" PRIuz
")";
153 return Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, nmemb, size, fmt, fkt, file,
157 static const char* rdpdr_server_state_to_string(pf_channel_server_state state)
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";
172 return "STATE_SERVER_UNKNOWN";
176 static const char* rdpdr_client_state_to_string(pf_channel_client_state state)
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";
189 return "STATE_CLIENT_UNKNOWN";
193 static wStream* rdpdr_get_send_buffer(pf_channel_common_context* rdpdr, UINT16 component,
194 UINT16 PacketID,
size_t capacity)
197 WINPR_ASSERT(rdpdr->s);
198 if (!Stream_SetPosition(rdpdr->s, 0))
200 if (!Stream_EnsureCapacity(rdpdr->s, capacity + 4))
202 Stream_Write_UINT16(rdpdr->s, component);
203 Stream_Write_UINT16(rdpdr->s, PacketID);
207 static wStream* rdpdr_client_get_send_buffer(pf_channel_client_context* rdpdr, UINT16 component,
208 UINT16 PacketID,
size_t capacity)
211 return rdpdr_get_send_buffer(&rdpdr->common, component, PacketID, capacity);
214 static wStream* rdpdr_server_get_send_buffer(pf_channel_server_context* rdpdr, UINT16 component,
215 UINT16 PacketID,
size_t capacity)
218 return rdpdr_get_send_buffer(&rdpdr->common, component, PacketID, capacity);
221 static UINT rdpdr_client_send(wLog* log, pClientContext* pc,
wStream* s)
223 UINT16 channelId = 0;
228 WINPR_ASSERT(pc->context.instance);
232 CLIENT_TX_LOG(log, WLOG_WARN,
"Ignoring channel %s message, not connected!",
233 RDPDR_SVC_CHANNEL_NAME);
234 return CHANNEL_RC_OK;
237 channelId = freerdp_channels_get_id_by_name(pc->context.instance, RDPDR_SVC_CHANNEL_NAME);
240 if ((channelId == 0) || (channelId == UINT16_MAX))
241 return ERROR_INTERNAL_ERROR;
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),
248 return ERROR_EVT_CHANNEL_NOT_FOUND;
249 return CHANNEL_RC_OK;
252 static UINT rdpdr_seal_send_free_request(pf_channel_server_context* context,
wStream* s)
257 WINPR_ASSERT(context);
258 WINPR_ASSERT(context->handle);
261 Stream_SealLength(s);
262 len = Stream_Length(s);
263 WINPR_ASSERT(len <= UINT32_MAX);
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;
270 static BOOL rdpdr_process_server_header(BOOL server, wLog* log,
wStream* s, UINT16 component,
271 UINT16 PacketId,
size_t expect)
273 UINT16 rpacketid = 0;
274 UINT16 rcomponent = 0;
277 if (!Stream_CheckAndLogRequiredLengthRx(server, log, s, 4))
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));
285 Stream_Read_UINT16(s, rcomponent);
286 Stream_Read_UINT16(s, rpacketid);
288 if (rcomponent != component)
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));
296 if (rpacketid != PacketId)
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));
304 if (!Stream_CheckAndLogRequiredLengthRx(server, log, s, expect))
306 RX_LOG(server, log, WLOG_WARN,
307 "RDPDR_HEADER[%s | %s] not enough data, expected %" PRIuz
", "
309 rdpdr_component_string(component), rdpdr_packetid_string(PacketId), expect,
310 Stream_GetRemainingLength(s));
311 return ERROR_INVALID_DATA;
317 static BOOL rdpdr_check_version(BOOL server, wLog* log, UINT16 versionMajor, UINT16 versionMinor,
318 UINT16 component, UINT16 PacketId)
320 if (versionMajor != RDPDR_VERSION_MAJOR)
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);
327 switch (versionMinor)
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:
337 RX_LOG(server, log, WLOG_WARN,
"[%s | %s] unsupported MinorVersion %" PRIu16,
338 rdpdr_component_string(component), rdpdr_packetid_string(PacketId),
346 static UINT rdpdr_process_server_announce_request(pf_channel_client_context* rdpdr,
wStream* s)
348 const UINT16 component = RDPDR_CTYP_CORE;
349 const UINT16 packetid = PAKID_CORE_SERVER_ANNOUNCE;
353 if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, component, packetid, 8))
354 return ERROR_INVALID_DATA;
356 Stream_Read_UINT16(s, rdpdr->common.versionMajor);
357 Stream_Read_UINT16(s, rdpdr->common.versionMinor);
359 if (!rdpdr_check_version(FALSE, rdpdr->log, rdpdr->common.versionMajor,
360 rdpdr->common.versionMinor, component, packetid))
361 return ERROR_INVALID_DATA;
364 if (rdpdr->common.versionMajor > rdpdr->maxMajorVersion)
366 rdpdr->common.versionMajor = rdpdr->maxMajorVersion;
367 rdpdr->common.versionMinor = rdpdr->maxMinorVersion;
369 else if (rdpdr->common.versionMinor > rdpdr->maxMinorVersion)
370 rdpdr->common.versionMinor = rdpdr->maxMinorVersion;
372 Stream_Read_UINT32(s, rdpdr->common.clientID);
373 return CHANNEL_RC_OK;
376 static UINT rdpdr_server_send_announce_request(pf_channel_server_context* context)
379 rdpdr_server_get_send_buffer(context, RDPDR_CTYP_CORE, PAKID_CORE_SERVER_ANNOUNCE, 8);
381 return CHANNEL_RC_NO_MEMORY;
383 Stream_Write_UINT16(s, context->common.versionMajor);
384 Stream_Write_UINT16(s, context->common.versionMinor);
385 Stream_Write_UINT32(s, context->common.clientID);
386 return rdpdr_seal_send_free_request(context, s);
389 static UINT rdpdr_process_client_announce_reply(pf_channel_server_context* rdpdr,
wStream* s)
391 const UINT16 component = RDPDR_CTYP_CORE;
392 const UINT16 packetid = PAKID_CORE_CLIENTID_CONFIRM;
393 UINT16 versionMajor = 0;
394 UINT16 versionMinor = 0;
400 if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 8))
401 return ERROR_INVALID_DATA;
403 Stream_Read_UINT16(s, versionMajor);
404 Stream_Read_UINT16(s, versionMinor);
406 if (!rdpdr_check_version(TRUE, rdpdr->log, versionMajor, versionMinor, component, packetid))
407 return ERROR_INVALID_DATA;
409 if ((rdpdr->common.versionMajor != versionMajor) ||
410 (rdpdr->common.versionMinor != versionMinor))
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;
420 Stream_Read_UINT32(s, clientID);
421 if (rdpdr->common.clientID != clientID)
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;
430 return CHANNEL_RC_OK;
433 static UINT rdpdr_send_client_announce_reply(pClientContext* pc, pf_channel_client_context* rdpdr)
436 rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENTID_CONFIRM, 8);
438 return CHANNEL_RC_NO_MEMORY;
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);
446 static UINT rdpdr_process_client_name_request(pf_channel_server_context* rdpdr,
wStream* s,
449 UINT32 unicodeFlag = 0;
456 if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_NAME,
458 return ERROR_INVALID_DATA;
460 Stream_Read_UINT32(s, unicodeFlag);
461 rdpdr->common.computerNameUnicode = ((unicodeFlag & 1) != 0) ? TRUE : FALSE;
463 Stream_Read_UINT32(s, codePage);
464 WINPR_UNUSED(codePage);
465 Stream_Read_UINT32(s, rdpdr->common.computerNameLen);
466 if (!Stream_CheckAndLogRequiredLengthSrv(rdpdr->log, s, rdpdr->common.computerNameLen))
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;
474 void* tmp = realloc(rdpdr->common.computerName.v, rdpdr->common.computerNameLen);
476 return CHANNEL_RC_NO_MEMORY;
477 rdpdr->common.computerName.v = tmp;
479 Stream_Read(s, rdpdr->common.computerName.v, rdpdr->common.computerNameLen);
481 pc->computerNameLen = rdpdr->common.computerNameLen;
482 pc->computerNameUnicode = rdpdr->common.computerNameUnicode;
483 tmp = realloc(pc->computerName.v, pc->computerNameLen);
485 return CHANNEL_RC_NO_MEMORY;
486 pc->computerName.v = tmp;
487 memcpy(pc->computerName.v, rdpdr->common.computerName.v, pc->computerNameLen);
489 return CHANNEL_RC_OK;
492 static UINT rdpdr_send_client_name_request(pClientContext* pc, pf_channel_client_context* rdpdr)
500 void* tmp = realloc(rdpdr->common.computerName.v, pc->computerNameLen);
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);
508 s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_NAME,
509 12U + rdpdr->common.computerNameLen);
511 return CHANNEL_RC_NO_MEMORY;
513 Stream_Write_UINT32(s, rdpdr->common.computerNameUnicode
516 Stream_Write_UINT32(s, 0);
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);
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,
528 WINPR_ASSERT(header);
530 Stream_Seek(s, header->CapabilityLength);
531 return CHANNEL_RC_OK;
534 static UINT rdpdr_client_process_general_capset(pf_channel_client_context* rdpdr,
wStream* s,
538 return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
541 static UINT rdpdr_process_printer_capset(pf_channel_client_context* rdpdr,
wStream* s,
545 return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
548 static UINT rdpdr_process_port_capset(pf_channel_client_context* rdpdr,
wStream* s,
552 return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
555 static UINT rdpdr_process_drive_capset(pf_channel_client_context* rdpdr,
wStream* s,
559 return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
562 static UINT rdpdr_process_smartcard_capset(pf_channel_client_context* rdpdr,
wStream* s,
566 return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
569 static UINT rdpdr_process_server_core_capability_request(pf_channel_client_context* rdpdr,
572 UINT status = CHANNEL_RC_OK;
573 UINT16 numCapabilities = 0;
577 if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE,
578 PAKID_CORE_SERVER_CAPABILITY, 4))
579 return ERROR_INVALID_DATA;
581 Stream_Read_UINT16(s, numCapabilities);
584 for (UINT16 i = 0; i < numCapabilities; i++)
587 UINT error = rdpdr_read_capset_header(rdpdr->log, s, &header);
588 if (error != CHANNEL_RC_OK)
591 if (header.CapabilityType < ARRAYSIZE(rdpdr->common.capabilityVersions))
593 if (rdpdr->common.capabilityVersions[header.CapabilityType] > header.Version)
594 rdpdr->common.capabilityVersions[header.CapabilityType] = header.Version;
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]);
602 switch (header.CapabilityType)
604 case CAP_GENERAL_TYPE:
605 status = rdpdr_client_process_general_capset(rdpdr, s, &header);
608 case CAP_PRINTER_TYPE:
609 status = rdpdr_process_printer_capset(rdpdr, s, &header);
613 status = rdpdr_process_port_capset(rdpdr, s, &header);
617 status = rdpdr_process_drive_capset(rdpdr, s, &header);
620 case CAP_SMARTCARD_TYPE:
621 status = rdpdr_process_smartcard_capset(rdpdr, s, &header);
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);
633 if (status != CHANNEL_RC_OK)
637 return CHANNEL_RC_OK;
640 static BOOL rdpdr_write_general_capset(wLog* log, pf_channel_common_context* rdpdr,
wStream* s)
646 rdpdr->capabilityVersions[CAP_GENERAL_TYPE] };
647 if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
649 Stream_Write_UINT32(s, 0);
650 Stream_Write_UINT32(s, 0);
651 Stream_Write_UINT16(s, rdpdr->versionMajor);
652 Stream_Write_UINT16(s, rdpdr->versionMinor);
653 Stream_Write_UINT32(s, 0x0000FFFF);
654 Stream_Write_UINT32(s, 0);
655 Stream_Write_UINT32(s, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU |
656 RDPDR_USER_LOGGEDON_PDU);
657 Stream_Write_UINT32(s, ENABLE_ASYNCIO);
658 Stream_Write_UINT32(s, 0);
659 Stream_Write_UINT32(s, rdpdr->SpecialDeviceCount);
664 static BOOL rdpdr_write_printer_capset(wLog* log, pf_channel_common_context* rdpdr,
wStream* s)
670 rdpdr->capabilityVersions[CAP_PRINTER_TYPE] };
671 if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
676 static BOOL rdpdr_write_port_capset(wLog* log, pf_channel_common_context* rdpdr,
wStream* s)
682 rdpdr->capabilityVersions[CAP_PORT_TYPE] };
683 if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
688 static BOOL rdpdr_write_drive_capset(wLog* log, pf_channel_common_context* rdpdr,
wStream* s)
694 rdpdr->capabilityVersions[CAP_DRIVE_TYPE] };
695 if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
700 static BOOL rdpdr_write_smartcard_capset(wLog* log, pf_channel_common_context* rdpdr,
wStream* s)
706 rdpdr->capabilityVersions[CAP_SMARTCARD_TYPE] };
707 if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
712 static UINT rdpdr_send_server_capability_request(pf_channel_server_context* rdpdr)
715 rdpdr_server_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_SERVER_CAPABILITY, 8);
717 return CHANNEL_RC_NO_MEMORY;
718 Stream_Write_UINT16(s, 5);
719 Stream_Write_UINT16(s, 0);
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);
733 static UINT rdpdr_process_client_capability_response(pf_channel_server_context* rdpdr,
wStream* s)
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;
741 if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 4))
742 return ERROR_INVALID_DATA;
744 Stream_Read_UINT16(s, numCapabilities);
745 Stream_Seek_UINT16(s);
747 for (UINT16 x = 0; x < numCapabilities; x++)
750 UINT error = rdpdr_read_capset_header(rdpdr->log, s, &header);
751 if (error != CHANNEL_RC_OK)
753 if (header.CapabilityType < ARRAYSIZE(rdpdr->common.capabilityVersions))
755 if (rdpdr->common.capabilityVersions[header.CapabilityType] > header.Version)
756 rdpdr->common.capabilityVersions[header.CapabilityType] = header.Version;
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]);
764 switch (header.CapabilityType)
766 case CAP_GENERAL_TYPE:
767 status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
770 case CAP_PRINTER_TYPE:
771 status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
775 status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
779 status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
782 case CAP_SMARTCARD_TYPE:
783 status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
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;
795 if (status != CHANNEL_RC_OK)
802 static UINT rdpdr_send_client_capability_response(pClientContext* pc,
803 pf_channel_client_context* rdpdr)
808 s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_CAPABILITY, 4);
810 return CHANNEL_RC_NO_MEMORY;
812 Stream_Write_UINT16(s, 5);
813 Stream_Write_UINT16(s, 0);
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);
827 static UINT rdpdr_send_server_clientid_confirm(pf_channel_server_context* rdpdr)
831 s = rdpdr_server_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENTID_CONFIRM, 8);
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);
840 static UINT rdpdr_process_server_clientid_confirm(pf_channel_client_context* rdpdr,
wStream* s)
842 UINT16 versionMajor = 0;
843 UINT16 versionMinor = 0;
849 if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE,
850 PAKID_CORE_CLIENTID_CONFIRM, 8))
851 return ERROR_INVALID_DATA;
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;
859 Stream_Read_UINT32(s, clientID);
861 if ((versionMajor != rdpdr->common.versionMajor) ||
862 (versionMinor != rdpdr->common.versionMinor))
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,
871 rdpdr->common.versionMajor = versionMajor;
872 rdpdr->common.versionMinor = versionMinor;
875 if (clientID != rdpdr->common.clientID)
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,
882 rdpdr->common.clientID = clientID;
885 return CHANNEL_RC_OK;
889 rdpdr_process_server_capability_request_or_clientid_confirm(pf_channel_client_context* rdpdr,
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;
901 if ((rdpdr->flags & mask) == mask)
903 CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
"already past this state, abort!");
907 if (!Stream_CheckAndLogRequiredLengthClient(rdpdr->log, s, 4))
910 Stream_Read_UINT16(s, component);
911 if (rcomponent != component)
913 CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
"got component %s, expected %s",
914 rdpdr_component_string(component), rdpdr_component_string(rcomponent));
917 Stream_Read_UINT16(s, packetid);
922 case PAKID_CORE_SERVER_CAPABILITY:
923 if (rdpdr->flags & STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST)
925 CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
"got duplicate packetid %s",
926 rdpdr_packetid_string(packetid));
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:
933 if (rdpdr->flags & STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM)
935 CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
"got duplicate packetid %s",
936 rdpdr_packetid_string(packetid));
939 rdpdr->flags |= STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM;
940 return rdpdr_process_server_clientid_confirm(rdpdr, s) == CHANNEL_RC_OK;
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)
950 s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_DEVICELIST_ANNOUNCE, 24);
952 return CHANNEL_RC_NO_MEMORY;
954 Stream_Write_UINT32(s, 1);
955 Stream_Write_UINT32(s, RDPDR_DTYP_SMARTCARD);
958 Stream_Write(s,
"SCARD\0\0\0", 8);
959 Stream_Write_UINT32(s, 6);
960 Stream_Write(s,
"SCARD\0", 6);
962 return rdpdr_client_send(rdpdr->log, pc, s);
965 static UINT rdpdr_send_emulated_scard_device_remove(pClientContext* pc,
966 pf_channel_client_context* rdpdr)
970 s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_DEVICELIST_REMOVE, 24);
972 return CHANNEL_RC_NO_MEMORY;
974 Stream_Write_UINT32(s, 1);
978 return rdpdr_client_send(rdpdr->log, pc, s);
981 static UINT rdpdr_process_server_device_announce_response(pf_channel_client_context* rdpdr,
984 const UINT16 component = RDPDR_CTYP_CORE;
985 const UINT16 packetid = PAKID_CORE_DEVICE_REPLY;
987 UINT32 resultCode = 0;
992 if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 8))
993 return ERROR_INVALID_DATA;
995 Stream_Read_UINT32(s, deviceID);
996 Stream_Read_UINT32(s, resultCode);
998 if (deviceID != SCARD_DEVICE_ID)
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);
1005 else if (resultCode != 0)
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,
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,
1019 return CHANNEL_RC_OK;
1023 static BOOL pf_channel_rdpdr_rewrite_device_list_to(
wStream* s, UINT32 fromVersion,
1027 if (fromVersion == toVersion)
1030 const size_t cap = Stream_GetRemainingLength(s);
1031 wStream* clone = Stream_New(NULL, cap);
1034 const size_t pos = Stream_GetPosition(s);
1035 Stream_Copy(s, clone, cap);
1036 Stream_SealLength(clone);
1038 Stream_SetPosition(clone, 0);
1039 Stream_SetPosition(s, pos);
1042 if (!Stream_SafeSeek(s, 4))
1046 if (Stream_GetRemainingLength(clone) < 4)
1048 Stream_Read_UINT32(clone, count);
1050 for (UINT32 x = 0; x < count; x++)
1053 const size_t charCount = ARRAYSIZE(device.PreferredDosName);
1054 if (Stream_GetRemainingLength(clone) < 20)
1057 Stream_Read_UINT32(clone, device.DeviceType);
1058 Stream_Read_UINT32(clone, device.DeviceId);
1059 Stream_Read(clone, device.PreferredDosName, charCount);
1060 Stream_Read_UINT32(clone, device.DeviceDataLength);
1061 device.DeviceData = Stream_Pointer(clone);
1062 if (!Stream_SafeSeek(clone, device.DeviceDataLength))
1065 if (!Stream_EnsureRemainingCapacity(s, 20))
1067 Stream_Write_UINT32(s, device.DeviceType);
1068 Stream_Write_UINT32(s, device.DeviceId);
1069 Stream_Write(s, device.PreferredDosName, charCount);
1071 if (device.DeviceType == RDPDR_DTYP_FILESYSTEM)
1073 if (toVersion == DRIVE_CAPABILITY_VERSION_01)
1074 Stream_Write_UINT32(s, 0);
1077 const size_t datalen = charCount *
sizeof(WCHAR);
1078 if (!Stream_EnsureRemainingCapacity(s, datalen +
sizeof(UINT32)))
1080 Stream_Write_UINT32(s, datalen);
1082 const SSIZE_T rcw = Stream_Write_UTF16_String_From_UTF8(
1083 s, charCount, device.PreferredDosName, charCount - 1, TRUE);
1090 Stream_Write_UINT32(s, device.DeviceDataLength);
1091 if (!Stream_EnsureRemainingCapacity(s, device.DeviceDataLength))
1093 Stream_Write(s, device.DeviceData, device.DeviceDataLength);
1097 Stream_SealLength(s);
1101 Stream_Free(clone, TRUE);
1105 static BOOL pf_channel_rdpdr_rewrite_device_list(pf_channel_client_context* rdpdr,
1106 pServerContext* ps,
wStream* s, BOOL toServer)
1108 WINPR_ASSERT(rdpdr);
1111 const size_t pos = Stream_GetPosition(s);
1112 UINT16 component = 0;
1113 UINT16 packetid = 0;
1114 Stream_SetPosition(s, 0);
1116 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))
1119 Stream_Read_UINT16(s, component);
1120 Stream_Read_UINT16(s, packetid);
1121 if ((component != RDPDR_CTYP_CORE) || (packetid != PAKID_CORE_DEVICELIST_ANNOUNCE))
1123 Stream_SetPosition(s, pos);
1127 const pf_channel_server_context* srv =
1128 HashTable_GetItemValue(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1131 WLog_Print(rdpdr->log, WLOG_ERROR,
"No channel %s in intercep map", RDPDR_SVC_CHANNEL_NAME);
1135 UINT32 from = srv->common.capabilityVersions[CAP_DRIVE_TYPE];
1136 UINT32 to = rdpdr->common.capabilityVersions[CAP_DRIVE_TYPE];
1139 from = rdpdr->common.capabilityVersions[CAP_DRIVE_TYPE];
1140 to = srv->common.capabilityVersions[CAP_DRIVE_TYPE];
1142 if (!pf_channel_rdpdr_rewrite_device_list_to(s, from, to))
1145 Stream_SetPosition(s, pos);
1149 static BOOL pf_channel_rdpdr_client_send_to_server(pf_channel_client_context* rdpdr,
1150 pServerContext* ps,
wStream* s)
1152 WINPR_ASSERT(rdpdr);
1155 UINT16 server_channel_id = WTSChannelGetId(ps->context.peer, RDPDR_SVC_CHANNEL_NAME);
1160 if (server_channel_id == 0)
1163 if (!pf_channel_rdpdr_rewrite_device_list(rdpdr, ps, s, TRUE))
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);
1176 static BOOL pf_channel_send_client_queue(pClientContext* pc, pf_channel_client_context* rdpdr);
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)
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)
1188 if (rdpdr_send_emulated_scard_device_list_announce_request(pc, rdpdr) != CHANNEL_RC_OK)
1190 return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s);
1193 static BOOL filter_smartcard_io_requests(pf_channel_client_context* rdpdr,
wStream* s,
1197 UINT16 component = 0;
1198 UINT16 packetid = 0;
1199 UINT32 deviceID = 0;
1202 WINPR_ASSERT(rdpdr);
1203 WINPR_ASSERT(pPacketid);
1205 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))
1208 pos = Stream_GetPosition(s);
1209 Stream_Read_UINT16(s, component);
1210 Stream_Read_UINT16(s, packetid);
1212 if (Stream_GetRemainingLength(s) >= 4)
1213 Stream_Read_UINT32(s, deviceID);
1215 WLog_Print(rdpdr->log, WLOG_DEBUG,
"got: [%s | %s]: [0x%08" PRIx32
"]",
1216 rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID);
1218 if (component != RDPDR_CTYP_CORE)
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;
1234 case PAKID_CORE_USER_LOGGEDON:
1235 *pPacketid = packetid;
1237 case PAKID_CORE_DEVICE_REPLY:
1238 case PAKID_CORE_DEVICE_IOREQUEST:
1239 if (deviceID != SCARD_DEVICE_ID)
1241 *pPacketid = packetid;
1244 if (deviceID != SCARD_DEVICE_ID)
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),
1256 Stream_SetPosition(s, pos);
1261 BOOL pf_channel_send_client_queue(pClientContext* pc, pf_channel_client_context* rdpdr)
1263 UINT16 channelId = 0;
1266 WINPR_ASSERT(rdpdr);
1268 if (rdpdr->state != STATE_CLIENT_CHANNEL_RUNNING)
1270 channelId = freerdp_channels_get_id_by_name(pc->context.instance, RDPDR_SVC_CHANNEL_NAME);
1271 if ((channelId == 0) || (channelId == UINT16_MAX))
1274 Queue_Lock(rdpdr->queue);
1275 while (Queue_Count(rdpdr->queue) > 0)
1277 wStream* s = Queue_Dequeue(rdpdr->queue);
1281 size_t len = Stream_Length(s);
1282 Stream_SetPosition(s, len);
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))
1289 CLIENT_TX_LOG(rdpdr->log, WLOG_ERROR,
"xxxxxx TODO: Failed to send data!");
1291 Stream_Free(s, TRUE);
1293 Queue_Unlock(rdpdr->queue);
1297 static BOOL rdpdr_handle_server_announce_request(pClientContext* pc,
1298 pf_channel_client_context* rdpdr,
wStream* s)
1301 WINPR_ASSERT(rdpdr);
1304 if (rdpdr_process_server_announce_request(rdpdr, s) != CHANNEL_RC_OK)
1306 if (rdpdr_send_client_announce_reply(pc, rdpdr) != CHANNEL_RC_OK)
1308 if (rdpdr_send_client_name_request(pc, rdpdr) != CHANNEL_RC_OK)
1310 rdpdr->state = STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST;
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)
1317 pf_channel_client_context* rdpdr = NULL;
1318 pServerContext* ps = NULL;
1320 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1321 UINT16 packetid = 0;
1325 WINPR_ASSERT(pc->pdata);
1326 WINPR_ASSERT(pc->interceptContextMap);
1327 WINPR_ASSERT(channel_name);
1328 WINPR_ASSERT(xdata);
1332 rdpdr = HashTable_GetItemValue(pc->interceptContextMap, channel_name);
1335 CLIENT_RX_LOG(WLog_Get(RTAG), WLOG_ERROR,
1336 "Channel %s [0x%04" PRIx16
"] missing context in interceptContextMap",
1337 channel_name, channelId);
1340 s = rdpdr->common.buffer;
1341 if (flags & CHANNEL_FLAG_FIRST)
1342 Stream_SetPosition(s, 0);
1343 if (!Stream_EnsureRemainingCapacity(s, xsize))
1345 CLIENT_RX_LOG(rdpdr->log, WLOG_ERROR,
1346 "Channel %s [0x%04" PRIx16
"] not enough memory [need %" PRIuz
"]",
1347 channel_name, channelId, xsize);
1350 Stream_Write(s, xdata, xsize);
1351 if ((flags & CHANNEL_FLAG_LAST) == 0)
1354 Stream_SealLength(s);
1355 Stream_SetPosition(s, 0);
1356 if (Stream_Length(s) != totalSize)
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));
1365 rdpdr_dump_received_packet(rdpdr->log, WLOG_TRACE, s, proxy_server_rx);
1366 switch (rdpdr->state)
1368 case STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST:
1369 if (!rdpdr_handle_server_announce_request(pc, rdpdr, s))
1372 case STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST:
1373 if (!rdpdr_process_server_capability_request_or_clientid_confirm(rdpdr, s))
1375 rdpdr->state = STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM;
1377 case STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM:
1378 if (!rdpdr_process_server_capability_request_or_clientid_confirm(rdpdr, s))
1380 if (rdpdr_send_client_capability_response(pc, rdpdr) != CHANNEL_RC_OK)
1382 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1383 if (pf_channel_smartcard_client_emulate(pc))
1385 if (rdpdr_send_emulated_scard_device_list_announce_request(pc, rdpdr) !=
1388 rdpdr->state = STATE_CLIENT_CHANNEL_RUNNING;
1393 rdpdr->state = STATE_CLIENT_CHANNEL_RUNNING;
1394 pf_channel_send_client_queue(pc, rdpdr);
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);
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:
1412 wStream* out = rdpdr_client_get_send_buffer(
1413 rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_DEVICE_IOCOMPLETION, 0);
1416 if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE,
1417 PAKID_CORE_DEVICE_IOREQUEST, 20))
1420 if (!pf_channel_smartcard_client_handle(rdpdr->log, pc, s, out,
1425 case PAKID_CORE_SERVER_ANNOUNCE:
1426 pf_channel_rdpdr_client_reset(pc);
1427 if (!rdpdr_handle_server_announce_request(pc, rdpdr, s))
1430 case PAKID_CORE_SERVER_CAPABILITY:
1431 rdpdr->state = STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST;
1433 return pf_channel_rdpdr_client_handle(pc, channelId, channel_name, xdata,
1434 xsize, flags, totalSize);
1435 case PAKID_CORE_DEVICE_REPLY:
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));
1449 return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s);
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));
1462 static void pf_channel_rdpdr_common_context_free(pf_channel_common_context* common)
1466 free(common->computerName.v);
1467 Stream_Free(common->s, TRUE);
1468 Stream_Free(common->buffer, TRUE);
1473 pf_channel_client_context* entry = (pf_channel_client_context*)base;
1477 pf_channel_rdpdr_common_context_free(&entry->common);
1478 Queue_Free(entry->queue);
1482 static BOOL pf_channel_rdpdr_common_context_new(pf_channel_common_context* common,
1487 common->base.free = fkt;
1488 common->s = Stream_New(NULL, 1024);
1491 common->buffer = Stream_New(NULL, 1024);
1492 if (!common->buffer)
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;
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 };
1507 memcpy(common->capabilityVersions, versions,
sizeof(common->capabilityVersions));
1511 static BOOL pf_channel_rdpdr_client_pass_message(pServerContext* ps, pClientContext* pc,
1512 UINT16 channelId,
const char* channel_name,
1515 pf_channel_client_context* rdpdr = NULL;
1520 rdpdr = HashTable_GetItemValue(pc->interceptContextMap, channel_name);
1523 WINPR_ASSERT(rdpdr->queue);
1525 if (!pf_channel_rdpdr_rewrite_device_list(rdpdr, ps, s, FALSE))
1527 if (!Queue_Enqueue(rdpdr->queue, s))
1529 pf_channel_send_client_queue(pc, rdpdr);
1533 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1534 static BOOL filter_smartcard_device_list_remove(pf_channel_server_context* rdpdr,
wStream* s)
1539 WINPR_ASSERT(rdpdr);
1540 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s,
sizeof(UINT32)))
1542 pos = Stream_GetPosition(s);
1543 Stream_Read_UINT32(s, count);
1548 if (!Stream_CheckAndLogRequiredLengthOfSizeWLog(rdpdr->log, s, count,
sizeof(UINT32)))
1551 for (UINT32 x = 0; x < count; x++)
1553 UINT32 deviceID = 0;
1554 BYTE* dst = Stream_Pointer(s);
1555 Stream_Read_UINT32(s, deviceID);
1556 if (deviceID == SCARD_DEVICE_ID)
1558 ArrayList_Remove(rdpdr->blockedDevices, (
void*)(
size_t)deviceID);
1565 memmove(dst, Stream_ConstPointer(s), (count - x - 1) *
sizeof(UINT32));
1568 Stream_SetPosition(s, pos);
1569 Stream_Write_UINT32(s, count);
1577 static BOOL filter_smartcard_device_io_request(pf_channel_server_context* rdpdr,
wStream* s)
1579 UINT32 DeviceID = 0;
1580 WINPR_ASSERT(rdpdr);
1582 Stream_Read_UINT32(s, DeviceID);
1583 return ArrayList_Contains(rdpdr->blockedDevices, (
void*)(
size_t)DeviceID);
1586 static BOOL filter_smartcard_device_list_announce(pf_channel_server_context* rdpdr,
wStream* s)
1590 WINPR_ASSERT(rdpdr);
1591 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s,
sizeof(UINT32)))
1593 const size_t pos = Stream_GetPosition(s);
1594 Stream_Read_UINT32(s, count);
1599 for (UINT32 x = 0; x < count; x++)
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))
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))
1614 if (DeviceType == RDPDR_DTYP_SMARTCARD)
1616 ArrayList_Append(rdpdr->blockedDevices, (
void*)(
size_t)DeviceId);
1620 WLog_Print(rdpdr->log, WLOG_INFO,
"Filtering smartcard device 0x%08" PRIx32
"",
1623 memmove(dst, Stream_ConstPointer(s), Stream_GetRemainingLength(s));
1624 Stream_SetPosition(s, pos);
1625 Stream_Write_UINT32(s, count - 1);
1633 static BOOL filter_smartcard_device_list_announce_request(pf_channel_server_context* rdpdr,
1638 UINT16 component = 0;
1639 UINT16 packetid = 0;
1641 WINPR_ASSERT(rdpdr);
1642 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 8))
1645 pos = Stream_GetPosition(s);
1647 Stream_Read_UINT16(s, component);
1648 Stream_Read_UINT16(s, packetid);
1650 if (component != RDPDR_CTYP_CORE)
1655 case PAKID_CORE_DEVICELIST_ANNOUNCE:
1656 if (filter_smartcard_device_list_announce(rdpdr, s))
1659 case PAKID_CORE_DEVICELIST_REMOVE:
1660 if (filter_smartcard_device_list_remove(rdpdr, s))
1663 case PAKID_CORE_DEVICE_IOREQUEST:
1664 if (filter_smartcard_device_io_request(rdpdr, s))
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));
1684 Stream_SetPosition(s, pos);
1689 static void* stream_copy(
const void* obj)
1692 wStream* dst = Stream_New(NULL, Stream_Capacity(src));
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));
1701 static void stream_free(
void* obj)
1704 Stream_Free(s, TRUE);
1707 static const char* pf_channel_rdpdr_client_context(
void* arg)
1709 pClientContext* pc = arg;
1713 return "pc->pdata=null";
1714 return pc->pdata->session_id;
1717 BOOL pf_channel_rdpdr_client_new(pClientContext* pc)
1720 pf_channel_client_context* rdpdr = NULL;
1723 WINPR_ASSERT(pc->interceptContextMap);
1725 rdpdr = calloc(1,
sizeof(pf_channel_client_context));
1728 rdpdr->log = WLog_Get(RTAG);
1729 WINPR_ASSERT(rdpdr->log);
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))
1735 rdpdr->maxMajorVersion = RDPDR_VERSION_MAJOR;
1736 rdpdr->maxMinorVersion = RDPDR_VERSION_MINOR_RDP10X;
1737 rdpdr->state = STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST;
1739 rdpdr->queue = Queue_New(TRUE, 0, 0);
1742 obj = Queue_Object(rdpdr->queue);
1744 obj->fnObjectNew = stream_copy;
1745 obj->fnObjectFree = stream_free;
1746 if (!HashTable_Insert(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME, rdpdr))
1751 pf_channel_rdpdr_client_context_free(&rdpdr->common.base);
1755 void pf_channel_rdpdr_client_free(pClientContext* pc)
1758 WINPR_ASSERT(pc->interceptContextMap);
1759 HashTable_Remove(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1764 pf_channel_server_context* entry = (pf_channel_server_context*)base;
1768 (void)WTSVirtualChannelClose(entry->handle);
1769 pf_channel_rdpdr_common_context_free(&entry->common);
1770 ArrayList_Free(entry->blockedDevices);
1774 static const char* pf_channel_rdpdr_server_context(
void* arg)
1776 pServerContext* ps = arg;
1780 return "ps->pdata=null";
1781 return ps->pdata->session_id;
1784 BOOL pf_channel_rdpdr_server_new(pServerContext* ps)
1786 pf_channel_server_context* rdpdr = NULL;
1787 PULONG pSessionId = NULL;
1788 DWORD BytesReturned = 0;
1791 WINPR_ASSERT(ps->interceptContextMap);
1793 rdpdr = calloc(1,
sizeof(pf_channel_server_context));
1796 rdpdr->log = WLog_Get(RTAG);
1797 WINPR_ASSERT(rdpdr->log);
1798 WLog_SetContext(rdpdr->log, pf_channel_rdpdr_server_context, ps);
1800 if (!pf_channel_rdpdr_common_context_new(&rdpdr->common, pf_channel_rdpdr_server_context_free))
1802 rdpdr->state = STATE_SERVER_INITIAL;
1804 rdpdr->blockedDevices = ArrayList_New(FALSE);
1805 if (!rdpdr->blockedDevices)
1808 rdpdr->SessionId = WTS_CURRENT_SESSION;
1809 if (WTSQuerySessionInformationA(ps->vcm, WTS_CURRENT_SESSION, WTSSessionId, (LPSTR*)&pSessionId,
1812 rdpdr->SessionId = (DWORD)*pSessionId;
1813 WTSFreeMemory(pSessionId);
1816 rdpdr->handle = WTSVirtualChannelOpenEx(rdpdr->SessionId, RDPDR_SVC_CHANNEL_NAME, 0);
1817 if (rdpdr->handle == 0)
1819 if (!HashTable_Insert(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME, rdpdr))
1825 pf_channel_rdpdr_server_context_free(&rdpdr->common.base);
1829 void pf_channel_rdpdr_server_free(pServerContext* ps)
1832 WINPR_ASSERT(ps->interceptContextMap);
1833 HashTable_Remove(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1836 static pf_channel_server_context* get_channel(pServerContext* ps, BOOL send)
1838 pf_channel_server_context* rdpdr = NULL;
1840 WINPR_ASSERT(ps->interceptContextMap);
1842 rdpdr = HashTable_GetItemValue(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1845 SERVER_RXTX_LOG(send, WLog_Get(RTAG), WLOG_ERROR,
1846 "Channel %s missing context in interceptContextMap",
1847 RDPDR_SVC_CHANNEL_NAME);
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)
1858 pClientContext* pc = NULL;
1859 pf_channel_server_context* rdpdr = get_channel(ps, FALSE);
1863 WINPR_ASSERT(ps->pdata);
1866 s = rdpdr->common.buffer;
1868 if (flags & CHANNEL_FLAG_FIRST)
1869 Stream_SetPosition(s, 0);
1871 if (!Stream_EnsureRemainingCapacity(s, xsize))
1873 Stream_Write(s, xdata, xsize);
1875 if ((flags & CHANNEL_FLAG_LAST) == 0)
1878 Stream_SealLength(s);
1879 Stream_SetPosition(s, 0);
1881 if (Stream_Length(s) != totalSize)
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));
1890 rdpdr_dump_received_packet(rdpdr->log, WLOG_TRACE, s, proxy_client_rx);
1891 switch (rdpdr->state)
1893 case STATE_SERVER_EXPECT_CLIENT_ANNOUNCE_REPLY:
1894 if (rdpdr_process_client_announce_reply(rdpdr, s) != CHANNEL_RC_OK)
1896 rdpdr->state = STATE_SERVER_EXPECT_CLIENT_NAME_REQUEST;
1898 case STATE_SERVER_EXPECT_CLIENT_NAME_REQUEST:
1899 if (rdpdr_process_client_name_request(rdpdr, s, pc) != CHANNEL_RC_OK)
1901 if (rdpdr_send_server_capability_request(rdpdr) != CHANNEL_RC_OK)
1903 if (rdpdr_send_server_clientid_confirm(rdpdr) != CHANNEL_RC_OK)
1905 rdpdr->state = STATE_SERVER_EXPECT_EXPECT_CLIENT_CAPABILITY_RESPONE;
1907 case STATE_SERVER_EXPECT_EXPECT_CLIENT_CAPABILITY_RESPONE:
1908 if (rdpdr_process_client_capability_response(rdpdr, s) != CHANNEL_RC_OK)
1910 rdpdr->state = STATE_SERVER_CHANNEL_RUNNING;
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))
1917 if (!pf_channel_rdpdr_client_pass_message(ps, pc, channelId, channel_name, s))
1921 return pf_channel_smartcard_server_handle(ps, s);
1923 if (!pf_channel_rdpdr_client_pass_message(ps, pc, channelId, channel_name, s))
1928 case STATE_SERVER_INITIAL:
1929 SERVER_RX_LOG(rdpdr->log, WLOG_WARN,
"Invalid state %s",
1930 rdpdr_server_state_to_string(rdpdr->state));
1937 BOOL pf_channel_rdpdr_server_announce(pServerContext* ps)
1939 pf_channel_server_context* rdpdr = get_channel(ps, TRUE);
1943 WINPR_ASSERT(rdpdr->state == STATE_SERVER_INITIAL);
1944 if (rdpdr_server_send_announce_request(rdpdr) != CHANNEL_RC_OK)
1946 rdpdr->state = STATE_SERVER_EXPECT_CLIENT_ANNOUNCE_REPLY;
1950 BOOL pf_channel_rdpdr_client_reset(pClientContext* pc)
1952 pf_channel_client_context* rdpdr = NULL;
1955 WINPR_ASSERT(pc->pdata);
1956 WINPR_ASSERT(pc->interceptContextMap);
1958 rdpdr = HashTable_GetItemValue(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1962 Queue_Clear(rdpdr->queue);
1964 rdpdr->state = STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST;
1969 static PfChannelResult pf_rdpdr_back_data(proxyData* pdata,
1970 const pServerStaticChannelContext* channel,
1971 const BYTE* xdata,
size_t xsize, UINT32 flags,
1974 WINPR_ASSERT(pdata);
1975 WINPR_ASSERT(channel);
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;
1982 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1983 if (pf_channel_smartcard_client_emulate(pdata->pc))
1984 return PF_CHANNEL_RESULT_DROP;
1986 return PF_CHANNEL_RESULT_DROP;
1989 static PfChannelResult pf_rdpdr_front_data(proxyData* pdata,
1990 const pServerStaticChannelContext* channel,
1991 const BYTE* xdata,
size_t xsize, UINT32 flags,
1994 WINPR_ASSERT(pdata);
1995 WINPR_ASSERT(channel);
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;
2002 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
2003 if (pf_channel_smartcard_client_emulate(pdata->pc))
2004 return PF_CHANNEL_RESULT_DROP;
2006 return PF_CHANNEL_RESULT_DROP;
2009 BOOL pf_channel_setup_rdpdr(pServerContext* ps, pServerStaticChannelContext* channel)
2011 channel->onBackData = pf_rdpdr_back_data;
2012 channel->onFrontData = pf_rdpdr_front_data;
2014 if (!pf_channel_rdpdr_server_new(ps))
2016 if (!pf_channel_rdpdr_server_announce(ps))
This struct contains function pointer to initialize/free objects.