21 #include <freerdp/config.h>
23 #include <winpr/assert.h>
24 #include <winpr/string.h>
25 #include <winpr/print.h>
27 #include "pf_channel_rdpdr.h"
28 #include "pf_channel_smartcard.h"
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>
35 #define RTAG PROXY_TAG("channel.rdpdr")
37 #define SCARD_DEVICE_ID UINT32_MAX
47 UINT32 computerNameLen;
48 BOOL computerNameUnicode;
55 UINT32 SpecialDeviceCount;
56 UINT32 capabilityVersions[6];
57 } pf_channel_common_context;
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;
69 pf_channel_common_context common;
70 pf_channel_client_state state;
72 UINT16 maxMajorVersion;
73 UINT16 maxMinorVersion;
76 } pf_channel_client_context;
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;
89 pf_channel_common_context common;
90 pf_channel_server_state state;
93 wArrayList* blockedDevices;
95 } pf_channel_server_context;
97 #define proxy_client "[proxy<-->client]"
98 #define proxy_server "[proxy<-->server]"
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"
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, ...) \
114 SERVER_RX_LOG(lvl, fmt, ##__VA_ARGS__); \
118 CLIENT_RX_LOG(lvl, fmt, ##__VA_ARGS__); \
122 #define SERVER_RXTX_LOG(send, log, lvl, fmt, ...) \
127 SERVER_TX_LOG(log, lvl, fmt, ##__VA_ARGS__); \
131 SERVER_RX_LOG(log, lvl, fmt, ##__VA_ARGS__); \
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,
150 srv ? proxy_server_rx
" %s(%s:%" PRIuz
")" : proxy_client_rx
" %s(%s:%" PRIuz
")";
152 return Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, nmemb, size, fmt, fkt, file,
156 static const char* rdpdr_server_state_to_string(pf_channel_server_state state)
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";
171 return "STATE_SERVER_UNKNOWN";
175 static const char* rdpdr_client_state_to_string(pf_channel_client_state state)
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";
188 return "STATE_CLIENT_UNKNOWN";
192 static wStream* rdpdr_get_send_buffer(pf_channel_common_context* rdpdr, UINT16 component,
193 UINT16 PacketID,
size_t capacity)
196 WINPR_ASSERT(rdpdr->s);
197 if (!Stream_SetPosition(rdpdr->s, 0))
199 if (!Stream_EnsureCapacity(rdpdr->s, capacity + 4))
201 Stream_Write_UINT16(rdpdr->s, component);
202 Stream_Write_UINT16(rdpdr->s, PacketID);
206 static wStream* rdpdr_client_get_send_buffer(pf_channel_client_context* rdpdr, UINT16 component,
207 UINT16 PacketID,
size_t capacity)
210 return rdpdr_get_send_buffer(&rdpdr->common, component, PacketID, capacity);
213 static wStream* rdpdr_server_get_send_buffer(pf_channel_server_context* rdpdr, UINT16 component,
214 UINT16 PacketID,
size_t capacity)
217 return rdpdr_get_send_buffer(&rdpdr->common, component, PacketID, capacity);
220 static UINT rdpdr_client_send(wLog* log, pClientContext* pc,
wStream* s)
222 UINT16 channelId = 0;
227 WINPR_ASSERT(pc->context.instance);
231 CLIENT_TX_LOG(log, WLOG_WARN,
"Ignoring channel %s message, not connected!",
232 RDPDR_SVC_CHANNEL_NAME);
233 return CHANNEL_RC_OK;
236 channelId = freerdp_channels_get_id_by_name(pc->context.instance, RDPDR_SVC_CHANNEL_NAME);
239 if ((channelId == 0) || (channelId == UINT16_MAX))
240 return ERROR_INTERNAL_ERROR;
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),
247 return ERROR_EVT_CHANNEL_NOT_FOUND;
248 return CHANNEL_RC_OK;
251 static UINT rdpdr_seal_send_free_request(pf_channel_server_context* context,
wStream* s)
256 WINPR_ASSERT(context);
257 WINPR_ASSERT(context->handle);
260 Stream_SealLength(s);
261 len = Stream_Length(s);
262 WINPR_ASSERT(len <= UINT32_MAX);
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;
269 static BOOL rdpdr_process_server_header(BOOL server, wLog* log,
wStream* s, UINT16 component,
270 UINT16 PacketId,
size_t expect)
272 UINT16 rpacketid = 0;
273 UINT16 rcomponent = 0;
276 if (!Stream_CheckAndLogRequiredLengthRx(server, log, s, 4))
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));
284 Stream_Read_UINT16(s, rcomponent);
285 Stream_Read_UINT16(s, rpacketid);
287 if (rcomponent != component)
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));
295 if (rpacketid != PacketId)
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));
303 if (!Stream_CheckAndLogRequiredLengthRx(server, log, s, expect))
305 RX_LOG(server, log, WLOG_WARN,
306 "RDPDR_HEADER[%s | %s] not enought data, expected %" PRIuz
", "
308 rdpdr_component_string(component), rdpdr_packetid_string(PacketId), expect,
309 Stream_GetRemainingLength(s));
310 return ERROR_INVALID_DATA;
316 static BOOL rdpdr_check_version(BOOL server, wLog* log, UINT16 versionMajor, UINT16 versionMinor,
317 UINT16 component, UINT16 PacketId)
319 if (versionMajor != RDPDR_VERSION_MAJOR)
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);
326 switch (versionMinor)
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:
336 RX_LOG(server, log, WLOG_WARN,
"[%s | %s] unsupported MinorVersion %" PRIu16,
337 rdpdr_component_string(component), rdpdr_packetid_string(PacketId),
345 static UINT rdpdr_process_server_announce_request(pf_channel_client_context* rdpdr,
wStream* s)
347 const UINT16 component = RDPDR_CTYP_CORE;
348 const UINT16 packetid = PAKID_CORE_SERVER_ANNOUNCE;
352 if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, component, packetid, 8))
353 return ERROR_INVALID_DATA;
355 Stream_Read_UINT16(s, rdpdr->common.versionMajor);
356 Stream_Read_UINT16(s, rdpdr->common.versionMinor);
358 if (!rdpdr_check_version(FALSE, rdpdr->log, rdpdr->common.versionMajor,
359 rdpdr->common.versionMinor, component, packetid))
360 return ERROR_INVALID_DATA;
363 if (rdpdr->common.versionMajor > rdpdr->maxMajorVersion)
365 rdpdr->common.versionMajor = rdpdr->maxMajorVersion;
366 rdpdr->common.versionMinor = rdpdr->maxMinorVersion;
368 else if (rdpdr->common.versionMinor > rdpdr->maxMinorVersion)
369 rdpdr->common.versionMinor = rdpdr->maxMinorVersion;
371 Stream_Read_UINT32(s, rdpdr->common.clientID);
372 return CHANNEL_RC_OK;
375 static UINT rdpdr_server_send_announce_request(pf_channel_server_context* context)
378 rdpdr_server_get_send_buffer(context, RDPDR_CTYP_CORE, PAKID_CORE_SERVER_ANNOUNCE, 8);
380 return CHANNEL_RC_NO_MEMORY;
382 Stream_Write_UINT16(s, context->common.versionMajor);
383 Stream_Write_UINT16(s, context->common.versionMinor);
384 Stream_Write_UINT32(s, context->common.clientID);
385 return rdpdr_seal_send_free_request(context, s);
388 static UINT rdpdr_process_client_announce_reply(pf_channel_server_context* rdpdr,
wStream* s)
390 const UINT16 component = RDPDR_CTYP_CORE;
391 const UINT16 packetid = PAKID_CORE_CLIENTID_CONFIRM;
392 UINT16 versionMajor = 0;
393 UINT16 versionMinor = 0;
399 if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 8))
400 return ERROR_INVALID_DATA;
402 Stream_Read_UINT16(s, versionMajor);
403 Stream_Read_UINT16(s, versionMinor);
405 if (!rdpdr_check_version(TRUE, rdpdr->log, versionMajor, versionMinor, component, packetid))
406 return ERROR_INVALID_DATA;
408 if ((rdpdr->common.versionMajor != versionMajor) ||
409 (rdpdr->common.versionMinor != versionMinor))
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;
419 Stream_Read_UINT32(s, clientID);
420 if (rdpdr->common.clientID != clientID)
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;
429 return CHANNEL_RC_OK;
432 static UINT rdpdr_send_client_announce_reply(pClientContext* pc, pf_channel_client_context* rdpdr)
435 rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENTID_CONFIRM, 8);
437 return CHANNEL_RC_NO_MEMORY;
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);
445 static UINT rdpdr_process_client_name_request(pf_channel_server_context* rdpdr,
wStream* s,
448 UINT32 unicodeFlag = 0;
455 if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_NAME,
457 return ERROR_INVALID_DATA;
459 Stream_Read_UINT32(s, unicodeFlag);
460 rdpdr->common.computerNameUnicode = ((unicodeFlag & 1) != 0) ? TRUE : FALSE;
462 Stream_Read_UINT32(s, codePage);
463 WINPR_UNUSED(codePage);
464 Stream_Read_UINT32(s, rdpdr->common.computerNameLen);
465 if (!Stream_CheckAndLogRequiredLengthSrv(rdpdr->log, s, rdpdr->common.computerNameLen))
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;
473 void* tmp = realloc(rdpdr->common.computerName.v, rdpdr->common.computerNameLen);
475 return CHANNEL_RC_NO_MEMORY;
476 rdpdr->common.computerName.v = tmp;
478 Stream_Read(s, rdpdr->common.computerName.v, rdpdr->common.computerNameLen);
480 pc->computerNameLen = rdpdr->common.computerNameLen;
481 pc->computerNameUnicode = rdpdr->common.computerNameUnicode;
482 tmp = realloc(pc->computerName.v, pc->computerNameLen);
484 return CHANNEL_RC_NO_MEMORY;
485 pc->computerName.v = tmp;
486 memcpy(pc->computerName.v, rdpdr->common.computerName.v, pc->computerNameLen);
488 return CHANNEL_RC_OK;
491 static UINT rdpdr_send_client_name_request(pClientContext* pc, pf_channel_client_context* rdpdr)
499 void* tmp = realloc(rdpdr->common.computerName.v, pc->computerNameLen);
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);
507 s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_NAME,
508 12U + rdpdr->common.computerNameLen);
510 return CHANNEL_RC_NO_MEMORY;
512 Stream_Write_UINT32(s, rdpdr->common.computerNameUnicode
515 Stream_Write_UINT32(s, 0);
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);
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,
527 WINPR_ASSERT(header);
529 Stream_Seek(s, header->CapabilityLength);
530 return CHANNEL_RC_OK;
533 static UINT rdpdr_client_process_general_capset(pf_channel_client_context* rdpdr,
wStream* s,
537 return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
540 static UINT rdpdr_process_printer_capset(pf_channel_client_context* rdpdr,
wStream* s,
544 return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
547 static UINT rdpdr_process_port_capset(pf_channel_client_context* rdpdr,
wStream* s,
551 return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
554 static UINT rdpdr_process_drive_capset(pf_channel_client_context* rdpdr,
wStream* s,
558 return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
561 static UINT rdpdr_process_smartcard_capset(pf_channel_client_context* rdpdr,
wStream* s,
565 return rdpdr_ignore_capset(FALSE, rdpdr->log, s, header);
568 static UINT rdpdr_process_server_core_capability_request(pf_channel_client_context* rdpdr,
571 UINT status = CHANNEL_RC_OK;
572 UINT16 numCapabilities = 0;
576 if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE,
577 PAKID_CORE_SERVER_CAPABILITY, 4))
578 return ERROR_INVALID_DATA;
580 Stream_Read_UINT16(s, numCapabilities);
583 for (UINT16 i = 0; i < numCapabilities; i++)
586 UINT error = rdpdr_read_capset_header(rdpdr->log, s, &header);
587 if (error != CHANNEL_RC_OK)
590 if (header.CapabilityType < ARRAYSIZE(rdpdr->common.capabilityVersions))
592 if (rdpdr->common.capabilityVersions[header.CapabilityType] > header.Version)
593 rdpdr->common.capabilityVersions[header.CapabilityType] = header.Version;
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]);
601 switch (header.CapabilityType)
603 case CAP_GENERAL_TYPE:
604 status = rdpdr_client_process_general_capset(rdpdr, s, &header);
607 case CAP_PRINTER_TYPE:
608 status = rdpdr_process_printer_capset(rdpdr, s, &header);
612 status = rdpdr_process_port_capset(rdpdr, s, &header);
616 status = rdpdr_process_drive_capset(rdpdr, s, &header);
619 case CAP_SMARTCARD_TYPE:
620 status = rdpdr_process_smartcard_capset(rdpdr, s, &header);
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);
632 if (status != CHANNEL_RC_OK)
636 return CHANNEL_RC_OK;
639 static BOOL rdpdr_write_general_capset(wLog* log, pf_channel_common_context* rdpdr,
wStream* s)
645 rdpdr->capabilityVersions[CAP_GENERAL_TYPE] };
646 if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
648 Stream_Write_UINT32(s, 0);
649 Stream_Write_UINT32(s, 0);
650 Stream_Write_UINT16(s, rdpdr->versionMajor);
651 Stream_Write_UINT16(s, rdpdr->versionMinor);
652 Stream_Write_UINT32(s, 0x0000FFFF);
653 Stream_Write_UINT32(s, 0);
654 Stream_Write_UINT32(s, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU |
655 RDPDR_USER_LOGGEDON_PDU);
656 Stream_Write_UINT32(s, ENABLE_ASYNCIO);
657 Stream_Write_UINT32(s, 0);
658 Stream_Write_UINT32(s, rdpdr->SpecialDeviceCount);
663 static BOOL rdpdr_write_printer_capset(wLog* log, pf_channel_common_context* rdpdr,
wStream* s)
669 rdpdr->capabilityVersions[CAP_PRINTER_TYPE] };
670 if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
675 static BOOL rdpdr_write_port_capset(wLog* log, pf_channel_common_context* rdpdr,
wStream* s)
681 rdpdr->capabilityVersions[CAP_PORT_TYPE] };
682 if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
687 static BOOL rdpdr_write_drive_capset(wLog* log, pf_channel_common_context* rdpdr,
wStream* s)
693 rdpdr->capabilityVersions[CAP_DRIVE_TYPE] };
694 if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
699 static BOOL rdpdr_write_smartcard_capset(wLog* log, pf_channel_common_context* rdpdr,
wStream* s)
705 rdpdr->capabilityVersions[CAP_SMARTCARD_TYPE] };
706 if (rdpdr_write_capset_header(log, s, &header) != CHANNEL_RC_OK)
711 static UINT rdpdr_send_server_capability_request(pf_channel_server_context* rdpdr)
714 rdpdr_server_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_SERVER_CAPABILITY, 8);
716 return CHANNEL_RC_NO_MEMORY;
717 Stream_Write_UINT16(s, 5);
718 Stream_Write_UINT16(s, 0);
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);
732 static UINT rdpdr_process_client_capability_response(pf_channel_server_context* rdpdr,
wStream* s)
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;
740 if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 4))
741 return ERROR_INVALID_DATA;
743 Stream_Read_UINT16(s, numCapabilities);
744 Stream_Seek_UINT16(s);
746 for (UINT16 x = 0; x < numCapabilities; x++)
749 UINT error = rdpdr_read_capset_header(rdpdr->log, s, &header);
750 if (error != CHANNEL_RC_OK)
752 if (header.CapabilityType < ARRAYSIZE(rdpdr->common.capabilityVersions))
754 if (rdpdr->common.capabilityVersions[header.CapabilityType] > header.Version)
755 rdpdr->common.capabilityVersions[header.CapabilityType] = header.Version;
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]);
763 switch (header.CapabilityType)
765 case CAP_GENERAL_TYPE:
766 status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
769 case CAP_PRINTER_TYPE:
770 status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
774 status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
778 status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
781 case CAP_SMARTCARD_TYPE:
782 status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, &header);
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;
794 if (status != CHANNEL_RC_OK)
801 static UINT rdpdr_send_client_capability_response(pClientContext* pc,
802 pf_channel_client_context* rdpdr)
807 s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_CAPABILITY, 4);
809 return CHANNEL_RC_NO_MEMORY;
811 Stream_Write_UINT16(s, 5);
812 Stream_Write_UINT16(s, 0);
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);
826 static UINT rdpdr_send_server_clientid_confirm(pf_channel_server_context* rdpdr)
830 s = rdpdr_server_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_CLIENTID_CONFIRM, 8);
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);
839 static UINT rdpdr_process_server_clientid_confirm(pf_channel_client_context* rdpdr,
wStream* s)
841 UINT16 versionMajor = 0;
842 UINT16 versionMinor = 0;
848 if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE,
849 PAKID_CORE_CLIENTID_CONFIRM, 8))
850 return ERROR_INVALID_DATA;
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;
858 Stream_Read_UINT32(s, clientID);
860 if ((versionMajor != rdpdr->common.versionMajor) ||
861 (versionMinor != rdpdr->common.versionMinor))
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,
870 rdpdr->common.versionMajor = versionMajor;
871 rdpdr->common.versionMinor = versionMinor;
874 if (clientID != rdpdr->common.clientID)
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,
881 rdpdr->common.clientID = clientID;
884 return CHANNEL_RC_OK;
888 rdpdr_process_server_capability_request_or_clientid_confirm(pf_channel_client_context* rdpdr,
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;
900 if ((rdpdr->flags & mask) == mask)
902 CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
"already past this state, abort!");
906 if (!Stream_CheckAndLogRequiredLengthClient(rdpdr->log, s, 4))
909 Stream_Read_UINT16(s, component);
910 if (rcomponent != component)
912 CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
"got component %s, expected %s",
913 rdpdr_component_string(component), rdpdr_component_string(rcomponent));
916 Stream_Read_UINT16(s, packetid);
921 case PAKID_CORE_SERVER_CAPABILITY:
922 if (rdpdr->flags & STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST)
924 CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
"got duplicate packetid %s",
925 rdpdr_packetid_string(packetid));
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:
932 if (rdpdr->flags & STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM)
934 CLIENT_RX_LOG(rdpdr->log, WLOG_WARN,
"got duplicate packetid %s",
935 rdpdr_packetid_string(packetid));
938 rdpdr->flags |= STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM;
939 return rdpdr_process_server_clientid_confirm(rdpdr, s) == CHANNEL_RC_OK;
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)
949 s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_DEVICELIST_ANNOUNCE, 24);
951 return CHANNEL_RC_NO_MEMORY;
953 Stream_Write_UINT32(s, 1);
954 Stream_Write_UINT32(s, RDPDR_DTYP_SMARTCARD);
957 Stream_Write(s,
"SCARD\0\0\0", 8);
958 Stream_Write_UINT32(s, 6);
959 Stream_Write(s,
"SCARD\0", 6);
961 return rdpdr_client_send(rdpdr->log, pc, s);
964 static UINT rdpdr_send_emulated_scard_device_remove(pClientContext* pc,
965 pf_channel_client_context* rdpdr)
969 s = rdpdr_client_get_send_buffer(rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_DEVICELIST_REMOVE, 24);
971 return CHANNEL_RC_NO_MEMORY;
973 Stream_Write_UINT32(s, 1);
977 return rdpdr_client_send(rdpdr->log, pc, s);
980 static UINT rdpdr_process_server_device_announce_response(pf_channel_client_context* rdpdr,
983 const UINT16 component = RDPDR_CTYP_CORE;
984 const UINT16 packetid = PAKID_CORE_DEVICE_REPLY;
986 UINT32 resultCode = 0;
991 if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 8))
992 return ERROR_INVALID_DATA;
994 Stream_Read_UINT32(s, deviceID);
995 Stream_Read_UINT32(s, resultCode);
997 if (deviceID != SCARD_DEVICE_ID)
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);
1004 else if (resultCode != 0)
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,
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,
1018 return CHANNEL_RC_OK;
1022 static BOOL pf_channel_rdpdr_rewrite_device_list_to(
wStream* s, UINT32 fromVersion,
1026 if (fromVersion == toVersion)
1029 const size_t cap = Stream_GetRemainingLength(s);
1030 wStream* clone = Stream_New(NULL, cap);
1033 const size_t pos = Stream_GetPosition(s);
1034 Stream_Copy(s, clone, cap);
1035 Stream_SealLength(clone);
1037 Stream_SetPosition(clone, 0);
1038 Stream_SetPosition(s, pos);
1041 if (!Stream_SafeSeek(s, 4))
1045 if (Stream_GetRemainingLength(clone) < 4)
1047 Stream_Read_UINT32(clone, count);
1049 for (UINT32 x = 0; x < count; x++)
1052 const size_t charCount = ARRAYSIZE(device.PreferredDosName);
1053 if (Stream_GetRemainingLength(clone) < 20)
1056 Stream_Read_UINT32(clone, device.DeviceType);
1057 Stream_Read_UINT32(clone, device.DeviceId);
1058 Stream_Read(clone, device.PreferredDosName, charCount);
1059 Stream_Read_UINT32(clone, device.DeviceDataLength);
1060 device.DeviceData = Stream_Pointer(clone);
1061 if (!Stream_SafeSeek(clone, device.DeviceDataLength))
1064 if (!Stream_EnsureRemainingCapacity(s, 20))
1066 Stream_Write_UINT32(s, device.DeviceType);
1067 Stream_Write_UINT32(s, device.DeviceId);
1068 Stream_Write(s, device.PreferredDosName, charCount);
1070 if (device.DeviceType == RDPDR_DTYP_FILESYSTEM)
1072 if (toVersion == DRIVE_CAPABILITY_VERSION_01)
1073 Stream_Write_UINT32(s, 0);
1076 const size_t datalen = charCount *
sizeof(WCHAR);
1077 if (!Stream_EnsureRemainingCapacity(s, datalen +
sizeof(UINT32)))
1079 Stream_Write_UINT32(s, datalen);
1081 const SSIZE_T rcw = Stream_Write_UTF16_String_From_UTF8(
1082 s, charCount, device.PreferredDosName, charCount - 1, TRUE);
1089 Stream_Write_UINT32(s, device.DeviceDataLength);
1090 if (!Stream_EnsureRemainingCapacity(s, device.DeviceDataLength))
1092 Stream_Write(s, device.DeviceData, device.DeviceDataLength);
1096 Stream_SealLength(s);
1100 Stream_Free(clone, TRUE);
1104 static BOOL pf_channel_rdpdr_rewrite_device_list(pf_channel_client_context* rdpdr,
1105 pServerContext* ps,
wStream* s, BOOL toServer)
1107 WINPR_ASSERT(rdpdr);
1110 const size_t pos = Stream_GetPosition(s);
1111 UINT16 component = 0;
1112 UINT16 packetid = 0;
1113 Stream_SetPosition(s, 0);
1115 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))
1118 Stream_Read_UINT16(s, component);
1119 Stream_Read_UINT16(s, packetid);
1120 if ((component != RDPDR_CTYP_CORE) || (packetid != PAKID_CORE_DEVICELIST_ANNOUNCE))
1122 Stream_SetPosition(s, pos);
1126 const pf_channel_server_context* srv =
1127 HashTable_GetItemValue(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1130 WLog_Print(rdpdr->log, WLOG_ERROR,
"No channel %s in intercep map", RDPDR_SVC_CHANNEL_NAME);
1134 UINT32 from = srv->common.capabilityVersions[CAP_DRIVE_TYPE];
1135 UINT32 to = rdpdr->common.capabilityVersions[CAP_DRIVE_TYPE];
1138 from = rdpdr->common.capabilityVersions[CAP_DRIVE_TYPE];
1139 to = srv->common.capabilityVersions[CAP_DRIVE_TYPE];
1141 if (!pf_channel_rdpdr_rewrite_device_list_to(s, from, to))
1144 Stream_SetPosition(s, pos);
1148 static BOOL pf_channel_rdpdr_client_send_to_server(pf_channel_client_context* rdpdr,
1149 pServerContext* ps,
wStream* s)
1151 WINPR_ASSERT(rdpdr);
1154 UINT16 server_channel_id = WTSChannelGetId(ps->context.peer, RDPDR_SVC_CHANNEL_NAME);
1159 if (server_channel_id == 0)
1162 if (!pf_channel_rdpdr_rewrite_device_list(rdpdr, ps, s, TRUE))
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);
1175 static BOOL pf_channel_send_client_queue(pClientContext* pc, pf_channel_client_context* rdpdr);
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)
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)
1187 if (rdpdr_send_emulated_scard_device_list_announce_request(pc, rdpdr) != CHANNEL_RC_OK)
1189 return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s);
1192 static BOOL filter_smartcard_io_requests(pf_channel_client_context* rdpdr,
wStream* s,
1196 UINT16 component = 0;
1197 UINT16 packetid = 0;
1198 UINT32 deviceID = 0;
1201 WINPR_ASSERT(rdpdr);
1202 WINPR_ASSERT(pPacketid);
1204 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))
1207 pos = Stream_GetPosition(s);
1208 Stream_Read_UINT16(s, component);
1209 Stream_Read_UINT16(s, packetid);
1211 if (Stream_GetRemainingLength(s) >= 4)
1212 Stream_Read_UINT32(s, deviceID);
1214 WLog_Print(rdpdr->log, WLOG_DEBUG,
"got: [%s | %s]: [0x%08" PRIx32
"]",
1215 rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID);
1217 if (component != RDPDR_CTYP_CORE)
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;
1233 case PAKID_CORE_USER_LOGGEDON:
1234 *pPacketid = packetid;
1236 case PAKID_CORE_DEVICE_REPLY:
1237 case PAKID_CORE_DEVICE_IOREQUEST:
1238 if (deviceID != SCARD_DEVICE_ID)
1240 *pPacketid = packetid;
1243 if (deviceID != SCARD_DEVICE_ID)
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),
1255 Stream_SetPosition(s, pos);
1260 BOOL pf_channel_send_client_queue(pClientContext* pc, pf_channel_client_context* rdpdr)
1262 UINT16 channelId = 0;
1265 WINPR_ASSERT(rdpdr);
1267 if (rdpdr->state != STATE_CLIENT_CHANNEL_RUNNING)
1269 channelId = freerdp_channels_get_id_by_name(pc->context.instance, RDPDR_SVC_CHANNEL_NAME);
1270 if ((channelId == 0) || (channelId == UINT16_MAX))
1273 Queue_Lock(rdpdr->queue);
1274 while (Queue_Count(rdpdr->queue) > 0)
1276 wStream* s = Queue_Dequeue(rdpdr->queue);
1280 size_t len = Stream_Length(s);
1281 Stream_SetPosition(s, len);
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))
1288 CLIENT_TX_LOG(rdpdr->log, WLOG_ERROR,
"xxxxxx TODO: Failed to send data!");
1290 Stream_Free(s, TRUE);
1292 Queue_Unlock(rdpdr->queue);
1296 static BOOL rdpdr_handle_server_announce_request(pClientContext* pc,
1297 pf_channel_client_context* rdpdr,
wStream* s)
1300 WINPR_ASSERT(rdpdr);
1303 if (rdpdr_process_server_announce_request(rdpdr, s) != CHANNEL_RC_OK)
1305 if (rdpdr_send_client_announce_reply(pc, rdpdr) != CHANNEL_RC_OK)
1307 if (rdpdr_send_client_name_request(pc, rdpdr) != CHANNEL_RC_OK)
1309 rdpdr->state = STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST;
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)
1316 pf_channel_client_context* rdpdr = NULL;
1317 pServerContext* ps = NULL;
1319 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1320 UINT16 packetid = 0;
1324 WINPR_ASSERT(pc->pdata);
1325 WINPR_ASSERT(pc->interceptContextMap);
1326 WINPR_ASSERT(channel_name);
1327 WINPR_ASSERT(xdata);
1331 rdpdr = HashTable_GetItemValue(pc->interceptContextMap, channel_name);
1334 CLIENT_RX_LOG(WLog_Get(RTAG), WLOG_ERROR,
1335 "Channel %s [0x%04" PRIx16
"] missing context in interceptContextMap",
1336 channel_name, channelId);
1339 s = rdpdr->common.buffer;
1340 if (flags & CHANNEL_FLAG_FIRST)
1341 Stream_SetPosition(s, 0);
1342 if (!Stream_EnsureRemainingCapacity(s, xsize))
1344 CLIENT_RX_LOG(rdpdr->log, WLOG_ERROR,
1345 "Channel %s [0x%04" PRIx16
"] not enough memory [need %" PRIuz
"]",
1346 channel_name, channelId, xsize);
1349 Stream_Write(s, xdata, xsize);
1350 if ((flags & CHANNEL_FLAG_LAST) == 0)
1353 Stream_SealLength(s);
1354 Stream_SetPosition(s, 0);
1355 if (Stream_Length(s) != totalSize)
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));
1364 rdpdr_dump_received_packet(rdpdr->log, WLOG_TRACE, s, proxy_server_rx);
1365 switch (rdpdr->state)
1367 case STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST:
1368 if (!rdpdr_handle_server_announce_request(pc, rdpdr, s))
1371 case STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST:
1372 if (!rdpdr_process_server_capability_request_or_clientid_confirm(rdpdr, s))
1374 rdpdr->state = STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM;
1376 case STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM:
1377 if (!rdpdr_process_server_capability_request_or_clientid_confirm(rdpdr, s))
1379 if (rdpdr_send_client_capability_response(pc, rdpdr) != CHANNEL_RC_OK)
1381 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1382 if (pf_channel_smartcard_client_emulate(pc))
1384 if (rdpdr_send_emulated_scard_device_list_announce_request(pc, rdpdr) !=
1387 rdpdr->state = STATE_CLIENT_CHANNEL_RUNNING;
1392 rdpdr->state = STATE_CLIENT_CHANNEL_RUNNING;
1393 pf_channel_send_client_queue(pc, rdpdr);
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);
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:
1411 wStream* out = rdpdr_client_get_send_buffer(
1412 rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_DEVICE_IOCOMPLETION, 0);
1415 if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE,
1416 PAKID_CORE_DEVICE_IOREQUEST, 20))
1419 if (!pf_channel_smartcard_client_handle(rdpdr->log, pc, s, out,
1424 case PAKID_CORE_SERVER_ANNOUNCE:
1425 pf_channel_rdpdr_client_reset(pc);
1426 if (!rdpdr_handle_server_announce_request(pc, rdpdr, s))
1429 case PAKID_CORE_SERVER_CAPABILITY:
1430 rdpdr->state = STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST;
1432 return pf_channel_rdpdr_client_handle(pc, channelId, channel_name, xdata,
1433 xsize, flags, totalSize);
1434 case PAKID_CORE_DEVICE_REPLY:
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));
1448 return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s);
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));
1461 static void pf_channel_rdpdr_common_context_free(pf_channel_common_context* common)
1465 free(common->computerName.v);
1466 Stream_Free(common->s, TRUE);
1467 Stream_Free(common->buffer, TRUE);
1472 pf_channel_client_context* entry = (pf_channel_client_context*)base;
1476 pf_channel_rdpdr_common_context_free(&entry->common);
1477 Queue_Free(entry->queue);
1481 static BOOL pf_channel_rdpdr_common_context_new(pf_channel_common_context* common,
1486 common->base.free = fkt;
1487 common->s = Stream_New(NULL, 1024);
1490 common->buffer = Stream_New(NULL, 1024);
1491 if (!common->buffer)
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;
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 };
1506 memcpy(common->capabilityVersions, versions,
sizeof(common->capabilityVersions));
1510 static BOOL pf_channel_rdpdr_client_pass_message(pServerContext* ps, pClientContext* pc,
1511 UINT16 channelId,
const char* channel_name,
1514 pf_channel_client_context* rdpdr = NULL;
1519 rdpdr = HashTable_GetItemValue(pc->interceptContextMap, channel_name);
1522 WINPR_ASSERT(rdpdr->queue);
1524 if (!pf_channel_rdpdr_rewrite_device_list(rdpdr, ps, s, FALSE))
1526 if (!Queue_Enqueue(rdpdr->queue, s))
1528 pf_channel_send_client_queue(pc, rdpdr);
1532 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1533 static BOOL filter_smartcard_device_list_remove(pf_channel_server_context* rdpdr,
wStream* s)
1538 WINPR_ASSERT(rdpdr);
1539 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s,
sizeof(UINT32)))
1541 pos = Stream_GetPosition(s);
1542 Stream_Read_UINT32(s, count);
1547 if (!Stream_CheckAndLogRequiredLengthOfSizeWLog(rdpdr->log, s, count,
sizeof(UINT32)))
1550 for (UINT32 x = 0; x < count; x++)
1552 UINT32 deviceID = 0;
1553 BYTE* dst = Stream_Pointer(s);
1554 Stream_Read_UINT32(s, deviceID);
1555 if (deviceID == SCARD_DEVICE_ID)
1557 ArrayList_Remove(rdpdr->blockedDevices, (
void*)(
size_t)deviceID);
1564 memmove(dst, Stream_ConstPointer(s), (count - x - 1) *
sizeof(UINT32));
1567 Stream_SetPosition(s, pos);
1568 Stream_Write_UINT32(s, count);
1576 static BOOL filter_smartcard_device_io_request(pf_channel_server_context* rdpdr,
wStream* s)
1578 UINT32 DeviceID = 0;
1579 WINPR_ASSERT(rdpdr);
1581 Stream_Read_UINT32(s, DeviceID);
1582 return ArrayList_Contains(rdpdr->blockedDevices, (
void*)(
size_t)DeviceID);
1585 static BOOL filter_smartcard_device_list_announce(pf_channel_server_context* rdpdr,
wStream* s)
1589 WINPR_ASSERT(rdpdr);
1590 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s,
sizeof(UINT32)))
1592 const size_t pos = Stream_GetPosition(s);
1593 Stream_Read_UINT32(s, count);
1598 for (UINT32 x = 0; x < count; x++)
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))
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))
1613 if (DeviceType == RDPDR_DTYP_SMARTCARD)
1615 ArrayList_Append(rdpdr->blockedDevices, (
void*)(
size_t)DeviceId);
1619 WLog_Print(rdpdr->log, WLOG_INFO,
"Filtering smartcard device 0x%08" PRIx32
"",
1622 memmove(dst, Stream_ConstPointer(s), Stream_GetRemainingLength(s));
1623 Stream_SetPosition(s, pos);
1624 Stream_Write_UINT32(s, count - 1);
1632 static BOOL filter_smartcard_device_list_announce_request(pf_channel_server_context* rdpdr,
1637 UINT16 component = 0;
1638 UINT16 packetid = 0;
1640 WINPR_ASSERT(rdpdr);
1641 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 8))
1644 pos = Stream_GetPosition(s);
1646 Stream_Read_UINT16(s, component);
1647 Stream_Read_UINT16(s, packetid);
1649 if (component != RDPDR_CTYP_CORE)
1654 case PAKID_CORE_DEVICELIST_ANNOUNCE:
1655 if (filter_smartcard_device_list_announce(rdpdr, s))
1658 case PAKID_CORE_DEVICELIST_REMOVE:
1659 if (filter_smartcard_device_list_remove(rdpdr, s))
1662 case PAKID_CORE_DEVICE_IOREQUEST:
1663 if (filter_smartcard_device_io_request(rdpdr, s))
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));
1683 Stream_SetPosition(s, pos);
1688 static void* stream_copy(
const void* obj)
1691 wStream* dst = Stream_New(NULL, Stream_Capacity(src));
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));
1700 static void stream_free(
void* obj)
1703 Stream_Free(s, TRUE);
1706 static const char* pf_channel_rdpdr_client_context(
void* arg)
1708 pClientContext* pc = arg;
1712 return "pc->pdata=null";
1713 return pc->pdata->session_id;
1716 BOOL pf_channel_rdpdr_client_new(pClientContext* pc)
1719 pf_channel_client_context* rdpdr = NULL;
1722 WINPR_ASSERT(pc->interceptContextMap);
1724 rdpdr = calloc(1,
sizeof(pf_channel_client_context));
1727 rdpdr->log = WLog_Get(RTAG);
1728 WINPR_ASSERT(rdpdr->log);
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))
1734 rdpdr->maxMajorVersion = RDPDR_VERSION_MAJOR;
1735 rdpdr->maxMinorVersion = RDPDR_VERSION_MINOR_RDP10X;
1736 rdpdr->state = STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST;
1738 rdpdr->queue = Queue_New(TRUE, 0, 0);
1741 obj = Queue_Object(rdpdr->queue);
1743 obj->fnObjectNew = stream_copy;
1744 obj->fnObjectFree = stream_free;
1745 if (!HashTable_Insert(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME, rdpdr))
1750 pf_channel_rdpdr_client_context_free(&rdpdr->common.base);
1754 void pf_channel_rdpdr_client_free(pClientContext* pc)
1757 WINPR_ASSERT(pc->interceptContextMap);
1758 HashTable_Remove(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1763 pf_channel_server_context* entry = (pf_channel_server_context*)base;
1767 (void)WTSVirtualChannelClose(entry->handle);
1768 pf_channel_rdpdr_common_context_free(&entry->common);
1769 ArrayList_Free(entry->blockedDevices);
1773 static const char* pf_channel_rdpdr_server_context(
void* arg)
1775 pServerContext* ps = arg;
1779 return "ps->pdata=null";
1780 return ps->pdata->session_id;
1783 BOOL pf_channel_rdpdr_server_new(pServerContext* ps)
1785 pf_channel_server_context* rdpdr = NULL;
1786 PULONG pSessionId = NULL;
1787 DWORD BytesReturned = 0;
1790 WINPR_ASSERT(ps->interceptContextMap);
1792 rdpdr = calloc(1,
sizeof(pf_channel_server_context));
1795 rdpdr->log = WLog_Get(RTAG);
1796 WINPR_ASSERT(rdpdr->log);
1797 WLog_SetContext(rdpdr->log, pf_channel_rdpdr_server_context, ps);
1799 if (!pf_channel_rdpdr_common_context_new(&rdpdr->common, pf_channel_rdpdr_server_context_free))
1801 rdpdr->state = STATE_SERVER_INITIAL;
1803 rdpdr->blockedDevices = ArrayList_New(FALSE);
1804 if (!rdpdr->blockedDevices)
1807 rdpdr->SessionId = WTS_CURRENT_SESSION;
1808 if (WTSQuerySessionInformationA(ps->vcm, WTS_CURRENT_SESSION, WTSSessionId, (LPSTR*)&pSessionId,
1811 rdpdr->SessionId = (DWORD)*pSessionId;
1812 WTSFreeMemory(pSessionId);
1815 rdpdr->handle = WTSVirtualChannelOpenEx(rdpdr->SessionId, RDPDR_SVC_CHANNEL_NAME, 0);
1816 if (rdpdr->handle == 0)
1818 if (!HashTable_Insert(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME, rdpdr))
1824 pf_channel_rdpdr_server_context_free(&rdpdr->common.base);
1828 void pf_channel_rdpdr_server_free(pServerContext* ps)
1831 WINPR_ASSERT(ps->interceptContextMap);
1832 HashTable_Remove(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1835 static pf_channel_server_context* get_channel(pServerContext* ps, BOOL send)
1837 pf_channel_server_context* rdpdr = NULL;
1839 WINPR_ASSERT(ps->interceptContextMap);
1841 rdpdr = HashTable_GetItemValue(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1844 SERVER_RXTX_LOG(send, WLog_Get(RTAG), WLOG_ERROR,
1845 "Channel %s missing context in interceptContextMap",
1846 RDPDR_SVC_CHANNEL_NAME);
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)
1857 pClientContext* pc = NULL;
1858 pf_channel_server_context* rdpdr = get_channel(ps, FALSE);
1862 WINPR_ASSERT(ps->pdata);
1865 s = rdpdr->common.buffer;
1867 if (flags & CHANNEL_FLAG_FIRST)
1868 Stream_SetPosition(s, 0);
1870 if (!Stream_EnsureRemainingCapacity(s, xsize))
1872 Stream_Write(s, xdata, xsize);
1874 if ((flags & CHANNEL_FLAG_LAST) == 0)
1877 Stream_SealLength(s);
1878 Stream_SetPosition(s, 0);
1880 if (Stream_Length(s) != totalSize)
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));
1889 rdpdr_dump_received_packet(rdpdr->log, WLOG_TRACE, s, proxy_client_rx);
1890 switch (rdpdr->state)
1892 case STATE_SERVER_EXPECT_CLIENT_ANNOUNCE_REPLY:
1893 if (rdpdr_process_client_announce_reply(rdpdr, s) != CHANNEL_RC_OK)
1895 rdpdr->state = STATE_SERVER_EXPECT_CLIENT_NAME_REQUEST;
1897 case STATE_SERVER_EXPECT_CLIENT_NAME_REQUEST:
1898 if (rdpdr_process_client_name_request(rdpdr, s, pc) != CHANNEL_RC_OK)
1900 if (rdpdr_send_server_capability_request(rdpdr) != CHANNEL_RC_OK)
1902 if (rdpdr_send_server_clientid_confirm(rdpdr) != CHANNEL_RC_OK)
1904 rdpdr->state = STATE_SERVER_EXPECT_EXPECT_CLIENT_CAPABILITY_RESPONE;
1906 case STATE_SERVER_EXPECT_EXPECT_CLIENT_CAPABILITY_RESPONE:
1907 if (rdpdr_process_client_capability_response(rdpdr, s) != CHANNEL_RC_OK)
1909 rdpdr->state = STATE_SERVER_CHANNEL_RUNNING;
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))
1916 if (!pf_channel_rdpdr_client_pass_message(ps, pc, channelId, channel_name, s))
1920 return pf_channel_smartcard_server_handle(ps, s);
1922 if (!pf_channel_rdpdr_client_pass_message(ps, pc, channelId, channel_name, s))
1927 case STATE_SERVER_INITIAL:
1928 SERVER_RX_LOG(rdpdr->log, WLOG_WARN,
"Invalid state %s",
1929 rdpdr_server_state_to_string(rdpdr->state));
1936 BOOL pf_channel_rdpdr_server_announce(pServerContext* ps)
1938 pf_channel_server_context* rdpdr = get_channel(ps, TRUE);
1942 WINPR_ASSERT(rdpdr->state == STATE_SERVER_INITIAL);
1943 if (rdpdr_server_send_announce_request(rdpdr) != CHANNEL_RC_OK)
1945 rdpdr->state = STATE_SERVER_EXPECT_CLIENT_ANNOUNCE_REPLY;
1949 BOOL pf_channel_rdpdr_client_reset(pClientContext* pc)
1951 pf_channel_client_context* rdpdr = NULL;
1954 WINPR_ASSERT(pc->pdata);
1955 WINPR_ASSERT(pc->interceptContextMap);
1957 rdpdr = HashTable_GetItemValue(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME);
1961 Queue_Clear(rdpdr->queue);
1963 rdpdr->state = STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST;
1968 static PfChannelResult pf_rdpdr_back_data(proxyData* pdata,
1969 const pServerStaticChannelContext* channel,
1970 const BYTE* xdata,
size_t xsize, UINT32 flags,
1973 WINPR_ASSERT(pdata);
1974 WINPR_ASSERT(channel);
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;
1980 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
1981 if (pf_channel_smartcard_client_emulate(pdata->pc))
1982 return PF_CHANNEL_RESULT_DROP;
1984 return PF_CHANNEL_RESULT_DROP;
1987 static PfChannelResult pf_rdpdr_front_data(proxyData* pdata,
1988 const pServerStaticChannelContext* channel,
1989 const BYTE* xdata,
size_t xsize, UINT32 flags,
1992 WINPR_ASSERT(pdata);
1993 WINPR_ASSERT(channel);
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;
1999 #if defined(WITH_PROXY_EMULATE_SMARTCARD)
2000 if (pf_channel_smartcard_client_emulate(pdata->pc))
2001 return PF_CHANNEL_RESULT_DROP;
2003 return PF_CHANNEL_RESULT_DROP;
2006 BOOL pf_channel_setup_rdpdr(pServerContext* ps, pServerStaticChannelContext* channel)
2008 channel->onBackData = pf_rdpdr_back_data;
2009 channel->onFrontData = pf_rdpdr_front_data;
2011 if (!pf_channel_rdpdr_server_new(ps))
2013 if (!pf_channel_rdpdr_server_announce(ps))
This struct contains function pointer to initialize/free objects.