From b614a2da37d10383d87535437f7921eeeb9117ff Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 22 Dec 2022 12:14:30 +0100 Subject: [PATCH] [server,proxy] improve rdpdr channel logging --- server/proxy/channels/pf_channel_rdpdr.c | 400 +++++++++++-------- server/proxy/channels/pf_channel_smartcard.c | 13 +- server/proxy/channels/pf_channel_smartcard.h | 7 +- 3 files changed, 249 insertions(+), 171 deletions(-) diff --git a/server/proxy/channels/pf_channel_rdpdr.c b/server/proxy/channels/pf_channel_rdpdr.c index 5c099a134..21f8f6e5f 100644 --- a/server/proxy/channels/pf_channel_rdpdr.c +++ b/server/proxy/channels/pf_channel_rdpdr.c @@ -71,6 +71,7 @@ typedef struct UINT16 maxMajorVersion; UINT16 maxMinorVersion; wQueue* queue; + wLog* log; } pf_channel_client_context; typedef enum @@ -89,8 +90,69 @@ typedef struct DWORD SessionId; HANDLE handle; wArrayList* blockedDevices; + wLog* log; } pf_channel_server_context; +#define proxy_client "[proxy<-->client]" +#define proxy_server "[proxy<-->server]" + +#define proxy_client_rx proxy_client " receive" +#define proxy_client_tx proxy_client " send" +#define proxy_server_rx proxy_server " receive" +#define proxy_server_tx proxy_server " send" + +#define SERVER_RX_LOG(log, lvl, fmt, ...) WLog_Print(log, lvl, proxy_client_rx fmt, ##__VA_ARGS__) +#define CLIENT_RX_LOG(log, lvl, fmt, ...) WLog_Print(log, lvl, proxy_server_rx fmt, ##__VA_ARGS__) +#define SERVER_TX_LOG(log, lvl, fmt, ...) WLog_Print(log, lvl, proxy_client_tx fmt, ##__VA_ARGS__) +#define CLIENT_TX_LOG(log, lvl, fmt, ...) WLog_Print(log, lvl, proxy_server_tx fmt, ##__VA_ARGS__) +#define RX_LOG(srv, lvl, fmt, ...) \ + do \ + { \ + if (srv) \ + { \ + SERVER_RX_LOG(lvl, fmt, ##__VA_ARGS__); \ + } \ + else \ + { \ + CLIENT_RX_LOG(lvl, fmt, ##__VA_ARGS__); \ + } \ + } while (0) + +#define SERVER_RXTX_LOG(send, log, lvl, fmt, ...) \ + do \ + { \ + if (send) \ + { \ + SERVER_TX_LOG(log, lvl, fmt, ##__VA_ARGS__); \ + } \ + else \ + { \ + SERVER_RX_LOG(log, lvl, fmt, ##__VA_ARGS__); \ + } \ + } while (0) + +#define Stream_CheckAndLogRequiredLengthSrv(log, s, len) \ + Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, len, \ + proxy_client_rx " %s(%s:%" PRIuz ")", __FUNCTION__, \ + __FILE__, __LINE__) +#define Stream_CheckAndLogRequiredLengthClient(log, s, len) \ + Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, len, \ + proxy_server_rx " %s(%s:%" PRIuz ")", __FUNCTION__, \ + __FILE__, __LINE__) +#define Stream_CheckAndLogRequiredLengthRx(srv, log, s, len) \ + ({ \ + BOOL res; \ + if (srv) \ + { \ + res = Stream_CheckAndLogRequiredLengthSrv(log, s, len); \ + } \ + else \ + { \ + res = Stream_CheckAndLogRequiredLengthClient(log, s, len); \ + } \ + res; \ + }) + static const char* rdpdr_server_state_to_string(pf_channel_server_state state) { switch (state) @@ -155,17 +217,19 @@ static wStream* rdpdr_server_get_send_buffer(pf_channel_server_context* rdpdr, U return rdpdr_get_send_buffer(&rdpdr->common, component, PacketID, capacity); } -static UINT rdpdr_client_send(pClientContext* pc, wStream* s) +static UINT rdpdr_client_send(wLog* log, pClientContext* pc, wStream* s) { UINT16 channelId; + WINPR_ASSERT(log); WINPR_ASSERT(pc); WINPR_ASSERT(s); WINPR_ASSERT(pc->context.instance); if (!pc->connected) { - WLog_WARN(TAG, "Ignoring channel %s message, not connected!", RDPDR_SVC_CHANNEL_NAME); + CLIENT_TX_LOG(log, WLOG_WARN, "Ignoring channel %s message, not connected!", + RDPDR_SVC_CHANNEL_NAME); return CHANNEL_RC_OK; } @@ -176,7 +240,7 @@ static UINT rdpdr_client_send(pClientContext* pc, wStream* s) return ERROR_INTERNAL_ERROR; Stream_SealLength(s); - rdpdr_dump_send_packet(WLog_Get(TAG), WLOG_TRACE, s, "proxy-client"); + rdpdr_dump_send_packet(log, WLOG_TRACE, s, proxy_server_tx); WINPR_ASSERT(pc->context.instance->SendChannelData); if (!pc->context.instance->SendChannelData(pc->context.instance, channelId, Stream_Buffer(s), Stream_Length(s))) @@ -197,21 +261,22 @@ static UINT rdpdr_seal_send_free_request(pf_channel_server_context* context, wSt len = Stream_Length(s); WINPR_ASSERT(len <= ULONG_MAX); + rdpdr_dump_send_packet(context->log, WLOG_TRACE, s, proxy_client_tx); status = WTSVirtualChannelWrite(context->handle, (char*)Stream_Buffer(s), (ULONG)len, NULL); return (status) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } -static BOOL rdpdr_process_server_header(wStream* s, UINT16 component, UINT16 PacketId, - size_t expect) +static BOOL rdpdr_process_server_header(BOOL server, wLog* log, wStream* s, UINT16 component, + UINT16 PacketId, size_t expect) { UINT16 rpacketid, rcomponent; WINPR_ASSERT(s); - if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) + if (!Stream_CheckAndLogRequiredLengthRx(server, log, s, 4)) { - WLog_WARN(TAG, "RDPDR_HEADER[%s | %s]: expected length 4, got %" PRIuz, - rdpdr_component_string(component), rdpdr_packetid_string(PacketId), - Stream_GetRemainingLength(s)); + RX_LOG(server, log, WLOG_WARN, "RDPDR_HEADER[%s | %s]: expected length 4, got %" PRIuz, + rdpdr_component_string(component), rdpdr_packetid_string(PacketId), + Stream_GetRemainingLength(s)); return FALSE; } @@ -220,42 +285,41 @@ static BOOL rdpdr_process_server_header(wStream* s, UINT16 component, UINT16 Pac if (rcomponent != component) { - WLog_WARN(TAG, "RDPDR_HEADER[%s | %s]: got component %s", rdpdr_component_string(component), - rdpdr_packetid_string(PacketId), rdpdr_component_string(rcomponent)); + RX_LOG(server, log, WLOG_WARN, "RDPDR_HEADER[%s | %s]: got component %s", + rdpdr_component_string(component), rdpdr_packetid_string(PacketId), + rdpdr_component_string(rcomponent)); return FALSE; } if (rpacketid != PacketId) { - WLog_WARN(TAG, "RDPDR_HEADER[%s | %s]: got PacketID %s", rdpdr_component_string(component), - rdpdr_packetid_string(PacketId), rdpdr_packetid_string(rpacketid)); + RX_LOG(server, log, WLOG_WARN, "RDPDR_HEADER[%s | %s]: got PacketID %s", + rdpdr_component_string(component), rdpdr_packetid_string(PacketId), + rdpdr_packetid_string(rpacketid)); return FALSE; } - if (!Stream_CheckAndLogRequiredLength(TAG, s, expect)) + if (!Stream_CheckAndLogRequiredLengthRx(server, log, s, expect)) { - WLog_WARN(TAG, - "RDPDR_HEADER[%s | %s] not enought data, expected %" PRIuz ", " - "got %" PRIuz, - rdpdr_component_string(component), rdpdr_packetid_string(PacketId), expect, - Stream_GetRemainingLength(s)); + RX_LOG(server, log, WLOG_WARN, + "RDPDR_HEADER[%s | %s] not enought data, expected %" PRIuz ", " + "got %" PRIuz, + rdpdr_component_string(component), rdpdr_packetid_string(PacketId), expect, + Stream_GetRemainingLength(s)); return ERROR_INVALID_DATA; } - WLog_DBG(TAG, "RDPDR_HEADER[%s | %s] -> got %" PRIuz " bytes", - rdpdr_component_string(component), rdpdr_packetid_string(PacketId), - Stream_GetRemainingLength(s)); return TRUE; } -static BOOL rdpdr_check_version(UINT16 versionMajor, UINT16 versionMinor, UINT16 component, - UINT16 PacketId) +static BOOL rdpdr_check_version(BOOL server, wLog* log, UINT16 versionMajor, UINT16 versionMinor, + UINT16 component, UINT16 PacketId) { if (versionMajor != RDPDR_VERSION_MAJOR) { - WLog_WARN(TAG, "[%s | %s] expected MajorVersion %" PRIu16 ", got %" PRIu16, - rdpdr_component_string(component), rdpdr_packetid_string(PacketId), - RDPDR_VERSION_MAJOR, versionMajor); + RX_LOG(server, log, WLOG_WARN, "[%s | %s] expected MajorVersion %" PRIu16 ", got %" PRIu16, + rdpdr_component_string(component), rdpdr_packetid_string(PacketId), + RDPDR_VERSION_MAJOR, versionMajor); return FALSE; } switch (versionMinor) @@ -268,9 +332,9 @@ static BOOL rdpdr_check_version(UINT16 versionMajor, UINT16 versionMinor, UINT16 break; default: { - WLog_WARN(TAG, "[%s | %s] unsupported MinorVersion %" PRIu16, - rdpdr_component_string(component), rdpdr_packetid_string(PacketId), - versionMinor); + RX_LOG(server, log, WLOG_WARN, "[%s | %s] unsupported MinorVersion %" PRIu16, + rdpdr_component_string(component), rdpdr_packetid_string(PacketId), + versionMinor); return FALSE; } } @@ -284,14 +348,14 @@ static UINT rdpdr_process_server_announce_request(pf_channel_client_context* rdp WINPR_ASSERT(rdpdr); WINPR_ASSERT(s); - if (!rdpdr_process_server_header(s, component, packetid, 8)) + if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, component, packetid, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, rdpdr->common.versionMajor); Stream_Read_UINT16(s, rdpdr->common.versionMinor); - if (!rdpdr_check_version(rdpdr->common.versionMajor, rdpdr->common.versionMinor, component, - packetid)) + if (!rdpdr_check_version(FALSE, rdpdr->log, rdpdr->common.versionMajor, + rdpdr->common.versionMinor, component, packetid)) return ERROR_INVALID_DATA; /* Limit maximum channel protocol version to the one set by proxy server */ @@ -304,7 +368,6 @@ static UINT rdpdr_process_server_announce_request(pf_channel_client_context* rdp rdpdr->common.versionMinor = rdpdr->maxMinorVersion; Stream_Read_UINT32(s, rdpdr->common.clientID); - WLog_DBG(TAG, "[receive] server->client clientID=0x%08" PRIx32, rdpdr->common.clientID); return CHANNEL_RC_OK; } @@ -318,7 +381,6 @@ static UINT rdpdr_server_send_announce_request(pf_channel_server_context* contex Stream_Write_UINT16(s, context->common.versionMajor); /* VersionMajor (2 bytes) */ Stream_Write_UINT16(s, context->common.versionMinor); /* VersionMinor (2 bytes) */ Stream_Write_UINT32(s, context->common.clientID); /* ClientId (4 bytes) */ - WLog_DBG(TAG, "[send] server->client clientID=0x%08" PRIx32, context->common.clientID); return rdpdr_seal_send_free_request(context, s); } @@ -332,20 +394,20 @@ static UINT rdpdr_process_client_announce_reply(pf_channel_server_context* rdpdr WINPR_ASSERT(rdpdr); WINPR_ASSERT(s); - if (!rdpdr_process_server_header(s, component, packetid, 8)) + if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, versionMajor); Stream_Read_UINT16(s, versionMinor); - if (!rdpdr_check_version(versionMajor, versionMinor, component, packetid)) + if (!rdpdr_check_version(TRUE, rdpdr->log, versionMajor, versionMinor, component, packetid)) return ERROR_INVALID_DATA; if ((rdpdr->common.versionMajor != versionMajor) || (rdpdr->common.versionMinor != versionMinor)) { - WLog_WARN( - TAG, + SERVER_RX_LOG( + rdpdr->log, WLOG_WARN, "[%s | %s] downgrading version from %" PRIu16 ".%" PRIu16 " to %" PRIu16 ".%" PRIu16, rdpdr_component_string(component), rdpdr_packetid_string(packetid), rdpdr->common.versionMajor, rdpdr->common.versionMinor, versionMajor, versionMinor); @@ -353,12 +415,12 @@ static UINT rdpdr_process_client_announce_reply(pf_channel_server_context* rdpdr rdpdr->common.versionMinor = versionMinor; } Stream_Read_UINT32(s, clientID); - WLog_DBG(TAG, "[receive] client->server clientID=0x%08" PRIx32, clientID); if (rdpdr->common.clientID != clientID) { - WLog_WARN(TAG, "[%s | %s] changing clientID 0x%08" PRIu32 " to 0x%08" PRIu32, - rdpdr_component_string(component), rdpdr_packetid_string(packetid), - rdpdr->common.clientID, clientID); + SERVER_RX_LOG(rdpdr->log, WLOG_WARN, + "[%s | %s] changing clientID 0x%08" PRIu32 " to 0x%08" PRIu32, + rdpdr_component_string(component), rdpdr_packetid_string(packetid), + rdpdr->common.clientID, clientID); rdpdr->common.clientID = clientID; } @@ -375,8 +437,7 @@ static UINT rdpdr_send_client_announce_reply(pClientContext* pc, pf_channel_clie Stream_Write_UINT16(s, rdpdr->common.versionMajor); Stream_Write_UINT16(s, rdpdr->common.versionMinor); Stream_Write_UINT32(s, rdpdr->common.clientID); - WLog_DBG(TAG, "[send] client->server clientID=0x%08" PRIx32, rdpdr->common.clientID); - return rdpdr_client_send(pc, s); + return rdpdr_client_send(rdpdr->log, pc, s); } static UINT rdpdr_process_client_name_request(pf_channel_server_context* rdpdr, wStream* s, @@ -390,7 +451,8 @@ static UINT rdpdr_process_client_name_request(pf_channel_server_context* rdpdr, WINPR_ASSERT(s); WINPR_ASSERT(pc); - if (!rdpdr_process_server_header(s, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_NAME, 12)) + if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, RDPDR_CTYP_CORE, PAKID_CORE_CLIENT_NAME, + 12)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, unicodeFlag); @@ -399,12 +461,12 @@ static UINT rdpdr_process_client_name_request(pf_channel_server_context* rdpdr, Stream_Read_UINT32(s, codePage); WINPR_UNUSED(codePage); /* Field is ignored */ Stream_Read_UINT32(s, rdpdr->common.computerNameLen); - if (!Stream_CheckAndLogRequiredLength(TAG, s, rdpdr->common.computerNameLen)) + if (!Stream_CheckAndLogRequiredLengthSrv(rdpdr->log, s, rdpdr->common.computerNameLen)) { - WLog_WARN(TAG, "[%s | %s]: missing data, got " PRIu32 ", expected %" PRIu32, - rdpdr_component_string(RDPDR_CTYP_CORE), - rdpdr_packetid_string(PAKID_CORE_CLIENT_NAME), Stream_GetRemainingLength(s), - rdpdr->common.computerNameLen); + SERVER_RX_LOG( + rdpdr->log, WLOG_WARN, "[%s | %s]: missing data, got " PRIu32 ", expected %" PRIu32, + rdpdr_component_string(RDPDR_CTYP_CORE), rdpdr_packetid_string(PAKID_CORE_CLIENT_NAME), + Stream_GetRemainingLength(s), rdpdr->common.computerNameLen); return ERROR_INVALID_DATA; } tmp = realloc(rdpdr->common.computerName.v, rdpdr->common.computerNameLen); @@ -452,22 +514,25 @@ static UINT rdpdr_send_client_name_request(pClientContext* pc, pf_channel_client Stream_Write_UINT32(s, 0); /* codePage, must be set to zero */ Stream_Write_UINT32(s, rdpdr->common.computerNameLen); Stream_Write(s, rdpdr->common.computerName.v, rdpdr->common.computerNameLen); - return rdpdr_client_send(pc, s); + return rdpdr_client_send(rdpdr->log, pc, s); } -#define rdpdr_ignore_capset(s, length) rdpdr_ignore_capset_((s), length, __FUNCTION__) -static UINT rdpdr_ignore_capset_(wStream* s, size_t capabilityLength, const char* fkt) +#define rdpdr_ignore_capset(srv, log, s, length) \ + rdpdr_ignore_capset_((srv), (log), (s), length, __FUNCTION__) +static UINT rdpdr_ignore_capset_(BOOL srv, wLog* log, wStream* s, size_t capabilityLength, + const char* fkt) { WINPR_ASSERT(s); if (capabilityLength < 4) { - WLog_ERR(TAG, "[%s] invalid capabilityLength %" PRIu16 " < 4", fkt, capabilityLength); + RX_LOG(srv, log, WLOG_ERROR, "[%s] invalid capabilityLength %" PRIu16 " < 4", fkt, + capabilityLength); return ERROR_INVALID_DATA; } - if (!Stream_CheckAndLogRequiredLengthEx(TAG, WLOG_ERROR, s, capabilityLength - 4U, - "%s::capabilityLength", fkt)) + if (!Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_ERROR, s, capabilityLength - 4U, + "%s::capabilityLength", fkt)) return ERROR_INVALID_DATA; Stream_Seek(s, capabilityLength - 4U); @@ -478,33 +543,33 @@ static UINT rdpdr_client_process_general_capset(pf_channel_client_context* rdpdr size_t length) { WINPR_UNUSED(rdpdr); - return rdpdr_ignore_capset(s, length); + return rdpdr_ignore_capset(FALSE, rdpdr->log, s, length); } static UINT rdpdr_process_printer_capset(pf_channel_client_context* rdpdr, wStream* s, size_t length) { WINPR_UNUSED(rdpdr); - return rdpdr_ignore_capset(s, length); + return rdpdr_ignore_capset(FALSE, rdpdr->log, s, length); } static UINT rdpdr_process_port_capset(pf_channel_client_context* rdpdr, wStream* s, size_t length) { WINPR_UNUSED(rdpdr); - return rdpdr_ignore_capset(s, length); + return rdpdr_ignore_capset(FALSE, rdpdr->log, s, length); } static UINT rdpdr_process_drive_capset(pf_channel_client_context* rdpdr, wStream* s, size_t length) { WINPR_UNUSED(rdpdr); - return rdpdr_ignore_capset(s, length); + return rdpdr_ignore_capset(FALSE, rdpdr->log, s, length); } static UINT rdpdr_process_smartcard_capset(pf_channel_client_context* rdpdr, wStream* s, size_t length) { WINPR_UNUSED(rdpdr); - return rdpdr_ignore_capset(s, length); + return rdpdr_ignore_capset(FALSE, rdpdr->log, s, length); } static UINT rdpdr_process_server_core_capability_request(pf_channel_client_context* rdpdr, @@ -516,26 +581,24 @@ static UINT rdpdr_process_server_core_capability_request(pf_channel_client_conte WINPR_ASSERT(rdpdr); - if (!rdpdr_process_server_header(s, RDPDR_CTYP_CORE, PAKID_CORE_SERVER_CAPABILITY, 4)) + if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE, + PAKID_CORE_SERVER_CAPABILITY, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, numCapabilities); Stream_Seek(s, 2); /* pad (2 bytes) */ - WLog_DBG(TAG, "[server] got %" PRIu16 " capabilities:", numCapabilities); for (i = 0; i < numCapabilities; i++) { UINT16 capabilityType; UINT16 capabilityLength; - if (!Stream_CheckAndLogRequiredLength(TAG, s, 2 * sizeof(UINT16))) + if (!Stream_CheckAndLogRequiredLengthClient(rdpdr->log, s, 2 * sizeof(UINT16))) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilityType); Stream_Read_UINT16(s, capabilityLength); - WLog_DBG(TAG, "[server] [%" PRIu16 "] got capability %s [%" PRIu16 "]", i, - rdpdr_cap_type_string(capabilityType), capabilityLength); switch (capabilityType) { case CAP_GENERAL_TYPE: @@ -672,58 +735,57 @@ static UINT rdpdr_process_client_capability_response(pf_channel_server_context* UINT16 numCapabilities, x; WINPR_ASSERT(rdpdr); - if (!rdpdr_process_server_header(s, component, packetid, 4)) + if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, numCapabilities); Stream_Seek_UINT16(s); /* padding */ - WLog_DBG(TAG, "[client] got %" PRIu16 " capabilities:", numCapabilities); for (x = 0; x < numCapabilities; x++) { UINT16 capabilityType; UINT16 capabilityLength; - if (!Stream_CheckAndLogRequiredLength(TAG, s, 2 * sizeof(UINT16))) + if (!Stream_CheckAndLogRequiredLengthSrv(rdpdr->log, s, 2 * sizeof(UINT16))) { - WLog_WARN(TAG, - "[%s | %s] invalid capability length 0x" PRIu16 ", expected at least %" PRIuz, - rdpdr_component_string(component), rdpdr_packetid_string(packetid), - Stream_GetRemainingLength(s), sizeof(UINT16)); + SERVER_RX_LOG(rdpdr->log, WLOG_WARN, + "[%s | %s] invalid capability length 0x" PRIu16 + ", expected at least %" PRIuz, + rdpdr_component_string(component), rdpdr_packetid_string(packetid), + Stream_GetRemainingLength(s), sizeof(UINT16)); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, capabilityType); Stream_Read_UINT16(s, capabilityLength); - WLog_DBG(TAG, "[client] [%" PRIu16 "] got capability %s [%" PRIu16 "]", x, - rdpdr_cap_type_string(capabilityType), capabilityLength); switch (capabilityType) { case CAP_GENERAL_TYPE: - status = rdpdr_ignore_capset(s, capabilityLength); + status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, capabilityLength); break; case CAP_PRINTER_TYPE: - status = rdpdr_ignore_capset(s, capabilityLength); + status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, capabilityLength); break; case CAP_PORT_TYPE: - status = rdpdr_ignore_capset(s, capabilityLength); + status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, capabilityLength); break; case CAP_DRIVE_TYPE: - status = rdpdr_ignore_capset(s, capabilityLength); + status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, capabilityLength); break; case CAP_SMARTCARD_TYPE: - status = rdpdr_ignore_capset(s, capabilityLength); + status = rdpdr_ignore_capset(TRUE, rdpdr->log, s, capabilityLength); break; default: - WLog_WARN(TAG, "[%s | %s] invalid capability type 0x%04" PRIx16, - rdpdr_component_string(component), rdpdr_packetid_string(packetid), - capabilityType); + SERVER_RX_LOG(rdpdr->log, WLOG_WARN, + "[%s | %s] invalid capability type 0x%04" PRIx16, + rdpdr_component_string(component), rdpdr_packetid_string(packetid), + capabilityType); status = ERROR_INVALID_DATA; break; } @@ -757,7 +819,7 @@ static UINT rdpdr_send_client_capability_response(pClientContext* pc, return CHANNEL_RC_NO_MEMORY; if (!rdpdr_write_smartcard_capset(&rdpdr->common, s)) return CHANNEL_RC_NO_MEMORY; - return rdpdr_client_send(pc, s); + return rdpdr_client_send(rdpdr->log, pc, s); } static UINT rdpdr_send_server_clientid_confirm(pf_channel_server_context* rdpdr) @@ -770,7 +832,6 @@ static UINT rdpdr_send_server_clientid_confirm(pf_channel_server_context* rdpdr) Stream_Write_UINT16(s, rdpdr->common.versionMajor); Stream_Write_UINT16(s, rdpdr->common.versionMinor); Stream_Write_UINT32(s, rdpdr->common.clientID); - WLog_DBG(TAG, "[send] server->client clientID=0x%08" PRIx32, rdpdr->common.clientID); return rdpdr_seal_send_free_request(rdpdr, s); } @@ -783,37 +844,39 @@ static UINT rdpdr_process_server_clientid_confirm(pf_channel_client_context* rdp WINPR_ASSERT(rdpdr); WINPR_ASSERT(s); - if (!rdpdr_process_server_header(s, RDPDR_CTYP_CORE, PAKID_CORE_CLIENTID_CONFIRM, 8)) + if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE, + PAKID_CORE_CLIENTID_CONFIRM, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, versionMajor); Stream_Read_UINT16(s, versionMinor); - if (!rdpdr_check_version(versionMajor, versionMinor, RDPDR_CTYP_CORE, + if (!rdpdr_check_version(FALSE, rdpdr->log, versionMajor, versionMinor, RDPDR_CTYP_CORE, PAKID_CORE_CLIENTID_CONFIRM)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, clientID); - WLog_DBG(TAG, "[receive] server->client clientID=0x%08" PRIx32, clientID); if ((versionMajor != rdpdr->common.versionMajor) || (versionMinor != rdpdr->common.versionMinor)) { - WLog_WARN(TAG, - "[%s | %s] Version mismatch, sent %" PRIu16 ".%" PRIu16 ", downgraded to %" PRIu16 - ".%" PRIu16, - rdpdr_component_string(RDPDR_CTYP_CORE), - rdpdr_packetid_string(PAKID_CORE_CLIENTID_CONFIRM), rdpdr->common.versionMajor, - rdpdr->common.versionMinor, versionMajor, versionMinor); + CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, + "[%s | %s] Version mismatch, sent %" PRIu16 ".%" PRIu16 + ", downgraded to %" PRIu16 ".%" PRIu16, + rdpdr_component_string(RDPDR_CTYP_CORE), + rdpdr_packetid_string(PAKID_CORE_CLIENTID_CONFIRM), + rdpdr->common.versionMajor, rdpdr->common.versionMinor, versionMajor, + versionMinor); rdpdr->common.versionMajor = versionMajor; rdpdr->common.versionMinor = versionMinor; } if (clientID != rdpdr->common.clientID) { - WLog_WARN(TAG, "[%s | %s] clientID mismatch, sent 0x%08" PRIx32 ", changed to 0x%08" PRIx32, - rdpdr_component_string(RDPDR_CTYP_CORE), - rdpdr_packetid_string(PAKID_CORE_CLIENTID_CONFIRM), rdpdr->common.clientID, - clientID); + CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, + "[%s | %s] clientID mismatch, sent 0x%08" PRIx32 ", changed to 0x%08" PRIx32, + rdpdr_component_string(RDPDR_CTYP_CORE), + rdpdr_packetid_string(PAKID_CORE_CLIENTID_CONFIRM), rdpdr->common.clientID, + clientID); rdpdr->common.clientID = clientID; } @@ -834,18 +897,18 @@ rdpdr_process_server_capability_request_or_clientid_confirm(pf_channel_client_co if ((rdpdr->flags & mask) == mask) { - WLog_WARN(TAG, "[%s]: already past this state, abort!", __FUNCTION__); + CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, "[%s]: already past this state, abort!", __FUNCTION__); return FALSE; } - if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) + if (!Stream_CheckAndLogRequiredLengthClient(rdpdr->log, s, 4)) return FALSE; Stream_Read_UINT16(s, component); if (rcomponent != component) { - WLog_WARN(TAG, "[%s]: got component %s, expected %s", __FUNCTION__, - rdpdr_component_string(component), rdpdr_component_string(rcomponent)); + CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, "[%s]: got component %s, expected %s", __FUNCTION__, + rdpdr_component_string(component), rdpdr_component_string(rcomponent)); return FALSE; } Stream_Read_UINT16(s, packetid); @@ -856,8 +919,8 @@ rdpdr_process_server_capability_request_or_clientid_confirm(pf_channel_client_co case PAKID_CORE_SERVER_CAPABILITY: if (rdpdr->flags & STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST) { - WLog_WARN(TAG, "[%s]: got duplicate packetid %s", __FUNCTION__, - rdpdr_packetid_string(packetid)); + CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, "[%s]: got duplicate packetid %s", + __FUNCTION__, rdpdr_packetid_string(packetid)); return FALSE; } rdpdr->flags |= STATE_CLIENT_EXPECT_SERVER_CORE_CAPABILITY_REQUEST; @@ -866,8 +929,8 @@ rdpdr_process_server_capability_request_or_clientid_confirm(pf_channel_client_co default: if (rdpdr->flags & STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM) { - WLog_WARN(TAG, "[%s]: got duplicate packetid %s", __FUNCTION__, - rdpdr_packetid_string(packetid)); + CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, "[%s]: got duplicate packetid %s", + __FUNCTION__, rdpdr_packetid_string(packetid)); return FALSE; } rdpdr->flags |= STATE_CLIENT_EXPECT_SERVER_CLIENT_ID_CONFIRM; @@ -893,7 +956,7 @@ static UINT rdpdr_send_emulated_scard_device_list_announce_request(pClientContex Stream_Write_UINT32(s, 6); Stream_Write(s, "SCARD\0", 6); - return rdpdr_client_send(pc, s); + return rdpdr_client_send(rdpdr->log, pc, s); } static UINT rdpdr_send_emulated_scard_device_remove(pClientContext* pc, @@ -909,7 +972,7 @@ static UINT rdpdr_send_emulated_scard_device_remove(pClientContext* pc, Stream_Write_UINT32( s, SCARD_DEVICE_ID); /* deviceID -> reserve highest value for the emulated smartcard */ - return rdpdr_client_send(pc, s); + return rdpdr_client_send(rdpdr->log, pc, s); } static UINT rdpdr_process_server_device_announce_response(pf_channel_client_context* rdpdr, @@ -923,7 +986,7 @@ static UINT rdpdr_process_server_device_announce_response(pf_channel_client_cont WINPR_ASSERT(rdpdr); WINPR_ASSERT(s); - if (!rdpdr_process_server_header(s, component, packetid, 8)) + if (!rdpdr_process_server_header(TRUE, rdpdr->log, s, component, packetid, 8)) return ERROR_INVALID_DATA; Stream_Read_UINT32(s, deviceID); @@ -931,29 +994,33 @@ static UINT rdpdr_process_server_device_announce_response(pf_channel_client_cont if (deviceID != SCARD_DEVICE_ID) { - WLog_WARN(TAG, "[%s | %s] deviceID mismatch, sent 0x%08" PRIx32 ", changed to 0x%08" PRIx32, - rdpdr_component_string(component), rdpdr_packetid_string(packetid), - SCARD_DEVICE_ID, deviceID); + CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, + "[%s | %s] deviceID mismatch, sent 0x%08" PRIx32 ", changed to 0x%08" PRIx32, + rdpdr_component_string(component), rdpdr_packetid_string(packetid), + SCARD_DEVICE_ID, deviceID); } else if (resultCode != 0) { - WLog_WARN(TAG, "[%s | %s] deviceID 0x%08" PRIx32 " resultCode=0x%08" PRIx32, - rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID, - resultCode); + CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, + "[%s | %s] deviceID 0x%08" PRIx32 " resultCode=0x%08" PRIx32, + rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID, + resultCode); } else - WLog_DBG(TAG, - "[%s | %s] deviceID 0x%08" PRIx32 " resultCode=0x%08" PRIx32 - " -> emulated smartcard redirected!", - rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID, - resultCode); + CLIENT_RX_LOG(rdpdr->log, WLOG_DEBUG, + "[%s | %s] deviceID 0x%08" PRIx32 " resultCode=0x%08" PRIx32 + " -> emulated smartcard redirected!", + rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID, + resultCode); return CHANNEL_RC_OK; } #endif -static BOOL pf_channel_rdpdr_client_send_to_server(pServerContext* ps, wStream* s) +static BOOL pf_channel_rdpdr_client_send_to_server(pf_channel_client_context* rdpdr, + pServerContext* ps, wStream* s) { + WINPR_ASSERT(rdpdr); if (ps) { UINT16 server_channel_id = WTSChannelGetId(ps->context.peer, RDPDR_SVC_CHANNEL_NAME); @@ -964,10 +1031,13 @@ static BOOL pf_channel_rdpdr_client_send_to_server(pServerContext* ps, wStream* if (server_channel_id == 0) return TRUE; + size_t len = Stream_Length(s); + Stream_SetPosition(s, len); + rdpdr_dump_send_packet(rdpdr->log, WLOG_TRACE, s, proxy_client_tx); WINPR_ASSERT(ps->context.peer); WINPR_ASSERT(ps->context.peer->SendChannelData); return ps->context.peer->SendChannelData(ps->context.peer, server_channel_id, - Stream_Buffer(s), Stream_Length(s)); + Stream_Buffer(s), len); } return TRUE; } @@ -984,7 +1054,7 @@ static BOOL rdpdr_process_server_loggedon_request(pServerContext* ps, pClientCon return FALSE; if (rdpdr_send_emulated_scard_device_list_announce_request(pc, rdpdr) != CHANNEL_RC_OK) return FALSE; - return pf_channel_rdpdr_client_send_to_server(ps, s); + return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s); } static BOOL filter_smartcard_io_requests(pf_channel_client_context* rdpdr, wStream* s, @@ -1074,12 +1144,12 @@ BOOL pf_channel_send_client_queue(pClientContext* pc, pf_channel_client_context* const size_t len = Stream_Length(s); Stream_SetPosition(s, len); - rdpdr_dump_send_packet(WLog_Get(TAG), WLOG_TRACE, s, "proxy-client-queue"); + rdpdr_dump_send_packet(rdpdr->log, WLOG_TRACE, s, proxy_server_tx " (queue) "); WINPR_ASSERT(pc->context.instance->SendChannelData); if (!pc->context.instance->SendChannelData(pc->context.instance, channelId, Stream_Buffer(s), len)) { - WLog_WARN(TAG, "xxxxxx TODO: Failed to send data!"); + CLIENT_TX_LOG(rdpdr->log, WLOG_ERROR, "xxxxxx TODO: Failed to send data!"); } Stream_Free(s, TRUE); } @@ -1134,8 +1204,9 @@ BOOL pf_channel_rdpdr_client_handle(pClientContext* pc, UINT16 channelId, const Stream_SetPosition(s, 0); if (!Stream_EnsureRemainingCapacity(s, xsize)) { - WLog_ERR(TAG, "[%s]: Channel %s [0x%04" PRIx16 "] not enough memory [need %" PRIuz "]", - __FUNCTION__, channel_name, channelId, xsize); + CLIENT_RX_LOG(rdpdr->log, WLOG_ERROR, + "[%s]: Channel %s [0x%04" PRIx16 "] not enough memory [need %" PRIuz "]", + __FUNCTION__, channel_name, channelId, xsize); return FALSE; } Stream_Write(s, xdata, xsize); @@ -1146,14 +1217,14 @@ BOOL pf_channel_rdpdr_client_handle(pClientContext* pc, UINT16 channelId, const Stream_SetPosition(s, 0); if (Stream_Length(s) != totalSize) { - WLog_WARN(TAG, - "Received invalid %s channel data (server -> proxy), expected %" PRIuz - "bytes, got %" PRIuz, - channel_name, totalSize, Stream_Length(s)); + CLIENT_RX_LOG(rdpdr->log, WLOG_WARN, + "Received invalid %s channel data (server -> proxy), expected %" PRIuz + "bytes, got %" PRIuz, + channel_name, totalSize, Stream_Length(s)); return FALSE; } - rdpdr_dump_received_packet(WLog_Get(TAG), WLOG_TRACE, s, "proxy-client"); + rdpdr_dump_received_packet(rdpdr->log, WLOG_TRACE, s, proxy_server_rx); switch (rdpdr->state) { case STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST: @@ -1190,7 +1261,7 @@ BOOL pf_channel_rdpdr_client_handle(pClientContext* pc, UINT16 channelId, const #if defined(WITH_PROXY_EMULATE_SMARTCARD) if (!pf_channel_smartcard_client_emulate(pc) || !filter_smartcard_io_requests(rdpdr, s, &packetid)) - return pf_channel_rdpdr_client_send_to_server(ps, s); + return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s); else { switch (packetid) @@ -1204,11 +1275,12 @@ BOOL pf_channel_rdpdr_client_handle(pClientContext* pc, UINT16 channelId, const rdpdr, RDPDR_CTYP_CORE, PAKID_CORE_DEVICE_IOCOMPLETION, 0); WINPR_ASSERT(out); - if (!rdpdr_process_server_header(s, RDPDR_CTYP_CORE, + if (!rdpdr_process_server_header(FALSE, rdpdr->log, s, RDPDR_CTYP_CORE, PAKID_CORE_DEVICE_IOREQUEST, 20)) return FALSE; - if (!pf_channel_smartcard_client_handle(pc, s, out, rdpdr_client_send)) + if (!pf_channel_smartcard_client_handle(rdpdr->log, pc, s, out, + rdpdr_client_send)) return FALSE; } break; @@ -1225,25 +1297,26 @@ BOOL pf_channel_rdpdr_client_handle(pClientContext* pc, UINT16 channelId, const case PAKID_CORE_DEVICE_REPLY: break; default: - WLog_ERR(TAG, - "[%s]: Channel %s [0x%04" PRIx16 - "] we´ve reached an impossible state %s! [%s] aliens invaded!", - __FUNCTION__, channel_name, channelId, - rdpdr_client_state_to_string(rdpdr->state), - rdpdr_packetid_string(packetid)); + CLIENT_RX_LOG( + rdpdr->log, WLOG_ERROR, + "[%s]: Channel %s [0x%04" PRIx16 + "] we´ve reached an impossible state %s! [%s] aliens invaded!", + __FUNCTION__, channel_name, channelId, + rdpdr_client_state_to_string(rdpdr->state), + rdpdr_packetid_string(packetid)); return FALSE; } } break; #else - return pf_channel_rdpdr_client_send_to_server(ps, s); + return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s); #endif default: - WLog_ERR(TAG, - "[%s]: Channel %s [0x%04" PRIx16 - "] we´ve reached an impossible state %s! aliens invaded!", - __FUNCTION__, channel_name, channelId, - rdpdr_client_state_to_string(rdpdr->state)); + CLIENT_RX_LOG(rdpdr->log, WLOG_ERROR, + "[%s]: Channel %s [0x%04" PRIx16 + "] we´ve reached an impossible state %s! aliens invaded!", + __FUNCTION__, channel_name, channelId, + rdpdr_client_state_to_string(rdpdr->state)); return FALSE; } @@ -1489,6 +1562,7 @@ BOOL pf_channel_rdpdr_client_new(pClientContext* pc) rdpdr = calloc(1, sizeof(pf_channel_client_context)); if (!rdpdr) return FALSE; + rdpdr->log = WLog_Get(TAG); if (!pf_channel_rdpdr_common_context_new(&rdpdr->common, pf_channel_rdpdr_client_context_free)) goto fail; @@ -1540,6 +1614,7 @@ BOOL pf_channel_rdpdr_server_new(pServerContext* ps) rdpdr = calloc(1, sizeof(pf_channel_server_context)); if (!rdpdr) return FALSE; + rdpdr->log = WLog_Get(TAG); if (!pf_channel_rdpdr_common_context_new(&rdpdr->common, pf_channel_rdpdr_server_context_free)) goto fail; rdpdr->state = STATE_SERVER_INITIAL; @@ -1572,7 +1647,7 @@ void pf_channel_rdpdr_server_free(pServerContext* ps) HashTable_Remove(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME); } -static pf_channel_server_context* get_channel(pServerContext* ps) +static pf_channel_server_context* get_channel(pServerContext* ps, BOOL send) { pf_channel_server_context* rdpdr; WINPR_ASSERT(ps); @@ -1581,8 +1656,9 @@ static pf_channel_server_context* get_channel(pServerContext* ps) rdpdr = HashTable_GetItemValue(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME); if (!rdpdr) { - WLog_ERR(TAG, "[%s]: Channel %s missing context in interceptContextMap", __FUNCTION__, - RDPDR_SVC_CHANNEL_NAME); + SERVER_RXTX_LOG(send, rdpdr->log, WLOG_ERROR, + "[%s]: Channel %s missing context in interceptContextMap", __FUNCTION__, + RDPDR_SVC_CHANNEL_NAME); return NULL; } @@ -1594,7 +1670,7 @@ BOOL pf_channel_rdpdr_server_handle(pServerContext* ps, UINT16 channelId, const { wStream* s; pClientContext* pc; - pf_channel_server_context* rdpdr = get_channel(ps); + pf_channel_server_context* rdpdr = get_channel(ps, FALSE); if (!rdpdr) return FALSE; @@ -1618,13 +1694,14 @@ BOOL pf_channel_rdpdr_server_handle(pServerContext* ps, UINT16 channelId, const if (Stream_Length(s) != totalSize) { - WLog_WARN(TAG, - "Received invalid %s channel data (client -> proxy), expected %" PRIuz - "bytes, got %" PRIuz, - channel_name, totalSize, Stream_Length(s)); + SERVER_RX_LOG(rdpdr->log, WLOG_WARN, + "Received invalid %s channel data (client -> proxy), expected %" PRIuz + "bytes, got %" PRIuz, + channel_name, totalSize, Stream_Length(s)); return FALSE; } + rdpdr_dump_received_packet(rdpdr->log, WLOG_TRACE, s, proxy_client_rx); switch (rdpdr->state) { case STATE_SERVER_EXPECT_CLIENT_ANNOUNCE_REPLY: @@ -1663,7 +1740,8 @@ BOOL pf_channel_rdpdr_server_handle(pServerContext* ps, UINT16 channelId, const break; default: case STATE_SERVER_INITIAL: - WLog_WARN(TAG, "Invalid state %s", rdpdr_server_state_to_string(rdpdr->state)); + SERVER_RX_LOG(rdpdr->log, WLOG_WARN, "Invalid state %s", + rdpdr_server_state_to_string(rdpdr->state)); return FALSE; } @@ -1672,7 +1750,7 @@ BOOL pf_channel_rdpdr_server_handle(pServerContext* ps, UINT16 channelId, const BOOL pf_channel_rdpdr_server_announce(pServerContext* ps) { - pf_channel_server_context* rdpdr = get_channel(ps); + pf_channel_server_context* rdpdr = get_channel(ps, TRUE); if (!rdpdr) return FALSE; @@ -1712,10 +1790,7 @@ static PfChannelResult pf_rdpdr_back_data(proxyData* pdata, if (!pf_channel_rdpdr_client_handle(pdata->pc, channel->back_channel_id, channel->channel_name, xdata, xsize, flags, totalSize)) - { - WLog_ERR(TAG, "error treating client back data"); return PF_CHANNEL_RESULT_ERROR; - } #if defined(WITH_PROXY_EMULATE_SMARTCARD) if (pf_channel_smartcard_client_emulate(pdata->pc)) @@ -1734,10 +1809,7 @@ static PfChannelResult pf_rdpdr_front_data(proxyData* pdata, if (!pf_channel_rdpdr_server_handle(pdata->ps, channel->front_channel_id, channel->channel_name, xdata, xsize, flags, totalSize)) - { - WLog_ERR(TAG, "error treating front data"); return PF_CHANNEL_RESULT_ERROR; - } #if defined(WITH_PROXY_EMULATE_SMARTCARD) if (pf_channel_smartcard_client_emulate(pdata->pc)) diff --git a/server/proxy/channels/pf_channel_smartcard.c b/server/proxy/channels/pf_channel_smartcard.c index cc2ba33f7..96cdfa1da 100644 --- a/server/proxy/channels/pf_channel_smartcard.c +++ b/server/proxy/channels/pf_channel_smartcard.c @@ -54,7 +54,8 @@ typedef struct SMARTCARD_OPERATION op; wStream* out; pClientContext* pc; - UINT (*send_fkt)(pClientContext*, wStream*); + wLog* log; + pf_scard_send_fkt_t send_fkt; } pf_channel_client_queue_element; static pf_channel_client_context* scard_get_client_context(pClientContext* pc) @@ -121,7 +122,7 @@ static VOID irp_thread(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK W if (rc == CHANNEL_RC_OK) { if (pf_channel_client_write_iostatus(arg->e->out, &arg->e->op, ioStatus)) - arg->e->send_fkt(arg->e->pc, arg->e->out); + arg->e->send_fkt(arg->e->log, arg->e->pc, arg->e->out); } } queue_free(arg->e); @@ -156,8 +157,8 @@ fail: return FALSE; } -BOOL pf_channel_smartcard_client_handle(pClientContext* pc, wStream* s, wStream* out, - UINT (*send_fkt)(pClientContext*, wStream*)) +BOOL pf_channel_smartcard_client_handle(wLog* log, pClientContext* pc, wStream* s, wStream* out, + pf_scard_send_fkt_t send_fkt) { BOOL rc = FALSE; LONG status; @@ -167,12 +168,14 @@ BOOL pf_channel_smartcard_client_handle(pClientContext* pc, wStream* s, wStream* pf_channel_client_queue_element e = { 0 }; pf_channel_client_context* scard = scard_get_client_context(pc); + WINPR_ASSERT(log); WINPR_ASSERT(send_fkt); WINPR_ASSERT(s); if (!scard) return FALSE; + e.log = log; e.pc = pc; e.out = out; e.send_fkt = send_fkt; @@ -247,7 +250,7 @@ BOOL pf_channel_smartcard_client_handle(pClientContext* pc, wStream* s, wStream* break; } - rc = send_fkt(pc, out) == CHANNEL_RC_OK; + rc = send_fkt(log, pc, out) == CHANNEL_RC_OK; fail: smartcard_operation_free(&e.op, FALSE); diff --git a/server/proxy/channels/pf_channel_smartcard.h b/server/proxy/channels/pf_channel_smartcard.h index e50632a54..975636d01 100644 --- a/server/proxy/channels/pf_channel_smartcard.h +++ b/server/proxy/channels/pf_channel_smartcard.h @@ -21,16 +21,19 @@ #ifndef FREERDP_SERVER_PROXY_SCARD_H #define FREERDP_SERVER_PROXY_SCARD_H +#include #include +typedef UINT (*pf_scard_send_fkt_t)(wLog* log, pClientContext*, wStream*); + BOOL pf_channel_smartcard_client_new(pClientContext* pc); void pf_channel_smartcard_client_free(pClientContext* pc); BOOL pf_channel_smartcard_client_reset(pClientContext* pc); BOOL pf_channel_smartcard_client_emulate(pClientContext* pc); -BOOL pf_channel_smartcard_client_handle(pClientContext* pc, wStream* s, wStream* out, - UINT (*send_fkt)(pClientContext*, wStream*)); +BOOL pf_channel_smartcard_client_handle(wLog* log, pClientContext* pc, wStream* s, wStream* out, + pf_scard_send_fkt_t fkt); BOOL pf_channel_smartcard_server_handle(pServerContext* ps, wStream* s); #endif /* FREERDP_SERVER_PROXY_SCARD_H */