From 4011fafc51b48c9b68aee5423720c497993c5642 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 30 Sep 2013 13:29:40 +0200 Subject: [PATCH 1/8] Now storing established context and using it for messages without provided context. --- channels/smartcard/client/smartcard_main.h | 12 +- .../smartcard/client/smartcard_operations.c | 214 ++++++++++++++---- 2 files changed, 176 insertions(+), 50 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.h b/channels/smartcard/client/smartcard_main.h index 320292be2..c910014af 100644 --- a/channels/smartcard/client/smartcard_main.h +++ b/channels/smartcard/client/smartcard_main.h @@ -30,6 +30,12 @@ #include #include +#define BOOL PCSC_BOOL +#include +#include +#include +#undef BOOL + /* * When using Windows Server 2008 R2 as the Terminal Services (TS) * server, and with a smart card reader connected to the TS client machine @@ -106,8 +112,10 @@ struct _SMARTCARD_DEVICE HANDLE irpEvent; HANDLE stopEvent; - LIST* CompletionIds; - HANDLE CompletionIdsMutex; + LIST* CompletionIds; + HANDLE CompletionIdsMutex; + + SCARDCONTEXT hContext; }; typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE; diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 81d0583d0..3f4502089 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -79,6 +79,100 @@ #define WIN_FILE_DEVICE_SMARTCARD 0x00000031 +#if defined(DEBUG_SCARD) && (DEBUG_SCARD) +static char *ioctl_to_string(DWORD code) +{ + static char res[100]; + char *rc; + + switch(code) + { + case SCARD_IOCTL_ESTABLISH_CONTEXT: + rc = "SCARD_IOCTL_ESTABLISH_CONTEXT"; + break; + case SCARD_IOCTL_IS_VALID_CONTEXT: + rc = "SCARD_IOCTL_IS_VALID_CONTEXT"; + break; + case SCARD_IOCTL_RELEASE_CONTEXT: + rc = "SCARD_IOCTL_RELEASE_CONTEXT"; + break; + case SCARD_IOCTL_LIST_READERS: + rc = "SCARD_IOCTL_LIST_READERS"; + break; + case SCARD_IOCTL_LIST_READERS + 4: + rc = "SCARD_IOCTL_LIST_READERS + 4"; + break; + case SCARD_IOCTL_LIST_READER_GROUPS: + rc = "SCARD_IOCTL_LIST_READER_GROUPS"; + break; + case SCARD_IOCTL_LIST_READER_GROUPS + 4: + rc = "SCARD_IOCTL_LIST_READER_GROUPS + 4"; + break; + case SCARD_IOCTL_GET_STATUS_CHANGE: + rc = "SCARD_IOCTL_GET_STATUS_CHANGE"; + break; + case SCARD_IOCTL_GET_STATUS_CHANGE + 4: + rc = "SCARD_IOCTL_GET_STATUS_CHANGE + 4"; + break; + case SCARD_IOCTL_CANCEL: + rc = "SCARD_IOCTL_CANCEL"; + break; + case SCARD_IOCTL_CONNECT: + rc = "SCARD_IOCTL_CONNECT"; + break; + case SCARD_IOCTL_CONNECT + 4: + rc = "SCARD_IOCTL_CONNECT + 4"; + break; + case SCARD_IOCTL_RECONNECT: + rc = "SCARD_IOCTL_RECONNECT"; + break; + case SCARD_IOCTL_DISCONNECT: + rc = "SCARD_IOCTL_DISCONNECT"; + break; + case SCARD_IOCTL_BEGIN_TRANSACTION: + rc = "SCARD_IOCTL_BEGIN_TRANSACTION"; + break; + case SCARD_IOCTL_END_TRANSACTION: + rc = "SCARD_IOCTL_END_TRANSACTION"; + break; + case SCARD_IOCTL_STATE: + rc = "SCARD_IOCTL_STATE"; + break; + case SCARD_IOCTL_STATUS: + rc = "SCARD_IOCTL_STATUS"; + break; + case SCARD_IOCTL_STATUS + 4: + rc = "SCARD_IOCTL_STATUS + 4"; + break; + case SCARD_IOCTL_TRANSMIT: + rc = "SCARD_IOCTL_TRANSMIT"; + break; + case SCARD_IOCTL_CONTROL: + rc = "SCARD_IOCTL_CONTROL"; + break; + case SCARD_IOCTL_GETATTRIB: + rc = "SCARD_IOCTL_GETATTRIB"; + break; + case SCARD_IOCTL_ACCESS_STARTED_EVENT: + rc = "SCARD_IOCTL_ACCESS_STARTED_EVENT"; + break; + case SCARD_IOCTL_LOCATE_CARDS_BY_ATR: + rc = "SCARD_IOCTL_LOCATE_CARDS_BY_ATR"; + break; + case SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4: + rc = "SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4"; + break; + default: + rc = "UNKNOWN"; + break; + } + + memset(res, 0, sizeof(res)); + strncpy(res, rc, strlen(rc)); + return res; +} +#endif + static UINT32 handle_CommonTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) { UINT8 version; @@ -183,7 +277,6 @@ static UINT32 handle_Context(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } - Stream_Seek(irp->input, len); if (len > Stream_GetRemainingLength(irp->input)) @@ -259,8 +352,8 @@ static UINT32 handle_RedirContextRef(SMARTCARD_DEVICE* scard, IRP* irp, Stream_Read_UINT32(irp->input, len); if (len != 4) { - DEBUG_WARN("length violation %d [%d]", 4, - Stream_GetRemainingLength(irp->input)); + DEBUG_WARN("length violation %d [%d], expect=%d", len, + Stream_GetRemainingLength(irp->input), 4); return SCARD_F_INTERNAL_ERROR; } @@ -317,7 +410,7 @@ static BOOL check_reader_is_forwarded(SMARTCARD_DEVICE *scard, const char *reade BOOL rc = TRUE; char *name = _strdup(readerName); char *str, *strpos=NULL, *strstatus=NULL; - long pos, status, cpos, ret; + long pos, cpos, ret; assert(scard); assert(readerName); @@ -617,7 +710,8 @@ static UINT32 handle_EstablishContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t Stream_Write_UINT32(irp->output, 4); Stream_Write_UINT32(irp->output, hContext); - /* TODO: store hContext in allowed context list */ + /* store hContext in allowed context list */ + scard->hContext = hContext; smartcard_output_alignment(irp, 8); return status; @@ -645,6 +739,7 @@ static UINT32 handle_ReleaseContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t in return status; status = SCardReleaseContext(hContext); + memset(&scard->hContext, 0, sizeof(scard->hContext)); if (status) DEBUG_SCARD("%s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); @@ -699,6 +794,10 @@ static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, UINT32 status; SCARDCONTEXT hContext; DWORD dwReaders; + UINT32 cBytes; + INT32 fmszReadersIsNULL; + UINT32 cchReaders; + LPTSTR mszGroups = NULL; char *readerList = NULL, *walker; int elemLength, dataLength; int pos, poslen1, poslen2, allowed_pos; @@ -715,31 +814,77 @@ static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, if (status) goto finish; - /* Ensure, that the capacity expected is actually available. */ - if (Stream_GetRemainingLength(irp->input) < 0x10) + if (Stream_GetRemainingLength(irp->input) < 4) { - DEBUG_WARN("length violation %d [%d]", 0x10, + DEBUG_WARN("length violation %d [%d]", 4, Stream_GetRemainingLength(irp->input)); status = SCARD_F_INTERNAL_ERROR; goto finish; } - Stream_Seek(irp->input, 0x10); + Stream_Read_UINT32(irp->input, cBytes); - /* Read RedirScardcontextRef */ - status = handle_RedirContextRef(scard, irp, &inlen, &hContext); - if (status) + /* Ensure, that the capacity expected is actually available. */ + if (Stream_GetRemainingLength(irp->input) < cBytes) + { + DEBUG_WARN("length violation %d [%d]", cBytes, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; goto finish; + } + if (cBytes) + { + mszGroups = malloc(cBytes); + Stream_Read(irp->input, mszGroups, cBytes); + } + + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } + Stream_Read_UINT32(irp->input, fmszReadersIsNULL); + + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } + Stream_Read_UINT32(irp->input, cchReaders); + + /* TODO: This hack is necessary, because after a successful connect + * there is no redirected handle available any more in the packets + * that are sent from some software. */ + inlen = Stream_GetRemainingLength(irp->input); + if(12 == inlen) + { + UINT32 tmp; + + Stream_Read_UINT32(irp->input, tmp); + /* Read RedirScardcontextRef */ + status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + if (status) + goto finish; + } + else + { + DEBUG_WARN("Using stored context, not provided."); + hContext = scard->hContext; + } /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ #ifdef SCARD_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; - status = SCardListReaders(hContext, NULL, (LPSTR) &readerList, &dwReaders); + status = SCardListReaders(hContext, mszGroups, (LPSTR) &readerList, &dwReaders); #else - status = SCardListReaders(hContext, NULL, NULL, &dwReaders); + status = SCardListReaders(hContext, mszGroups, NULL, &dwReaders); readerList = malloc(dwReaders); - status = SCardListReaders(hContext, NULL, readerList, &dwReaders); + status = SCardListReaders(hContext, mszGroups, readerList, &dwReaders); #endif if (status != SCARD_S_SUCCESS) { @@ -807,6 +952,9 @@ finish: #endif } + if (mszGroups) + free(mszGroups); + return status; } @@ -1546,23 +1694,6 @@ finish: return status; } -static void Stream_Dump(wStream *s) -{ - size_t size = Stream_GetRemainingLength(s); - int i; - - fprintf(stderr, "-------------------------- Start [%s] [%zd] ------------------------", - __func__, size); - for(i=0; ipointer[i]); - if (i % 80 == 0) - fprintf(stderr, "\n"); - } - fprintf(stderr, "\n"); - fprintf(stderr, "-------------------------- End [%s] ------------------------", __func__); -} - static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { LONG status; @@ -1625,18 +1756,6 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) if (status) goto finish; - DEBUG_WARN("dwProtocol=%X, cbPciLength=%d, pioSendPciBufferPtr=%d, cbSendLength=%d, ptrSendBuffer=%d, ptrIoRecvPciBuffer=%d, recvBufferIsNULL=%d, cbRecvLength=%d", - ioSendPci.rq->dwProtocol, - ioSendPci.rq->cbPciLength, - pioSendPciBufferPtr, - cbSendLength, - ptrSendBuffer, - ptrIoRecvPciBuffer, - recvBufferIsNULL, - cbRecvLength); - - Stream_Dump(irp->input); - /* Check, if there is data available from the ipSendPci element */ if (pioSendPciBufferPtr) { @@ -2373,7 +2492,9 @@ void smartcard_device_control(SMARTCARD_DEVICE* scard, IRP* irp) /* body. input_len contains the length of the remaining data * that can be read from the current position of irp->input, * so pass it on ;) */ - DEBUG_SCARD("ioctl %08X", ioctl_code); + DEBUG_SCARD("ioctl '%s' [%08X], length=%d [%d]", + ioctl_to_string(ioctl_code), ioctl_code, input_len, + Stream_GetRemainingLength(irp->input)); switch (ioctl_code) { case SCARD_IOCTL_ESTABLISH_CONTEXT: @@ -2502,9 +2623,6 @@ void smartcard_device_control(SMARTCARD_DEVICE* scard, IRP* irp) Stream_SetPosition(irp->output, pos); -#ifdef WITH_DEBUG_SCARD - winpr_HexDump(Stream_Buffer(irp->output), Stream_GetPosition(irp->output)); -#endif irp->IoStatus = 0; irp->Complete(irp); From 05a4f541bdce55aa7b9928516fcdbc14e91b9a46 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 30 Sep 2013 14:49:19 +0200 Subject: [PATCH 2/8] Refactored, now using cached handles, if the context or card handles are NULL. --- channels/smartcard/client/smartcard_main.c | 2 +- channels/smartcard/client/smartcard_main.h | 1 + .../smartcard/client/smartcard_operations.c | 335 +++++++++--------- 3 files changed, 174 insertions(+), 164 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index eccf6bfcc..b0a82934b 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -315,7 +315,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { char* name; char* path; - int i, length, ck; + int length, ck; RDPDR_SMARTCARD* device; SMARTCARD_DEVICE* smartcard; diff --git a/channels/smartcard/client/smartcard_main.h b/channels/smartcard/client/smartcard_main.h index c910014af..4acacbd23 100644 --- a/channels/smartcard/client/smartcard_main.h +++ b/channels/smartcard/client/smartcard_main.h @@ -116,6 +116,7 @@ struct _SMARTCARD_DEVICE HANDLE CompletionIdsMutex; SCARDCONTEXT hContext; + SCARDHANDLE hCard; }; typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE; diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 3f4502089..4859b69a6 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -173,7 +173,7 @@ static char *ioctl_to_string(DWORD code) } #endif -static UINT32 handle_CommonTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) +static UINT32 handle_CommonTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp) { UINT8 version; UINT8 endianess; @@ -182,7 +182,6 @@ static UINT32 handle_CommonTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp, size_t assert(scard); assert(irp); assert(irp->input); - assert(inlen); if (Stream_GetRemainingLength(irp->input) < 8) { @@ -213,20 +212,16 @@ static UINT32 handle_CommonTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp, size_t return SCARD_F_INTERNAL_ERROR; } - assert(*inlen >= 8); - *inlen -= 8; - return 0; } -static UINT32 handle_PrivateTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) +static UINT32 handle_PrivateTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp) { UINT32 len; assert(scard); assert(irp); assert(irp->input); - assert(inlen); if (Stream_GetRemainingLength(irp->input) < 8) { @@ -247,20 +242,16 @@ static UINT32 handle_PrivateTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp, size_t return SCARD_F_INTERNAL_ERROR; } - assert(*inlen >= 8); - *inlen -= 8; - return 0; } -static UINT32 handle_Context(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) +static UINT32 handle_Context(SMARTCARD_DEVICE* scard, IRP* irp, int *redirect) { UINT32 len; assert(scard); assert(irp); assert(irp->input); - assert(inlen); if (Stream_GetRemainingLength(irp->input) < 4) { @@ -278,6 +269,11 @@ static UINT32 handle_Context(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) return SCARD_F_INTERNAL_ERROR; } Stream_Seek(irp->input, len); + if (!len) + { + DEBUG_WARN("Context handle is NULL, using from cache."); + *redirect |= 0x01; + } if (len > Stream_GetRemainingLength(irp->input)) { @@ -286,14 +282,10 @@ static UINT32 handle_Context(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) return SCARD_F_INTERNAL_ERROR; } - assert(*inlen >= 4 + len); - *inlen -= 4; - *inlen -= len; - return 0; } -static UINT32 handle_CardHandle(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) +static UINT32 handle_CardHandle(SMARTCARD_DEVICE* scard, IRP* irp, int *redirect) { UINT32 status; UINT32 len; @@ -301,9 +293,9 @@ static UINT32 handle_CardHandle(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen assert(scard); assert(irp); assert(irp->input); - assert(inlen); + assert(redirect); - status = handle_Context(scard, irp, inlen); + status = handle_Context(scard, irp, redirect); if (status) return status; @@ -321,26 +313,35 @@ static UINT32 handle_CardHandle(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } - Stream_Seek(irp->input, len); - assert(*inlen >= len + 4); - *inlen -= len + 4; + if (!len) + { + DEBUG_WARN("Card handle is NULL, using from cache."); + *redirect |= 0x02; + } return 0; } static UINT32 handle_RedirContextRef(SMARTCARD_DEVICE* scard, IRP* irp, - size_t *inlen, SCARDCONTEXT* hContext) + int redirect, SCARDCONTEXT* hContext) { UINT32 len; assert(scard); assert(irp); assert(irp->input); - assert(inlen); assert(hContext); + /* No context provided, use stored. */ + if (redirect & 0x01) + { + DEBUG_WARN("No context provided, using stored context."); + *hContext = scard->hContext; + return 0; + } + /* Extract context handle. */ if (Stream_GetRemainingLength(irp->input) < 4) { @@ -350,31 +351,38 @@ static UINT32 handle_RedirContextRef(SMARTCARD_DEVICE* scard, IRP* irp, } Stream_Read_UINT32(irp->input, len); - if (len != 4) + if (len > Stream_GetRemainingLength(irp->input)) { - DEBUG_WARN("length violation %d [%d], expect=%d", len, - Stream_GetRemainingLength(irp->input), 4); + DEBUG_WARN("length violation %d [%d]", len, + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } - Stream_Read_UINT32(irp->input, *hContext); - DEBUG_SCARD("hContext=%p", *hContext); + memset(hContext, 0, sizeof(SCARDCONTEXT)); + Stream_Read(irp->input, hContext, len); - assert(*inlen >= 8); - *inlen -= 8; + DEBUG_SCARD("hContext=%p", *hContext); return 0; } static UINT32 handle_RedirHandleRef(SMARTCARD_DEVICE* scard, IRP* irp, - size_t *inlen, SCARDCONTEXT* hContext, SCARDHANDLE *hHandle) + int redirect, SCARDCONTEXT* hContext, SCARDHANDLE *hHandle) { UINT32 len, status; - status = handle_RedirContextRef(scard, irp, inlen, hContext); + status = handle_RedirContextRef(scard, irp, redirect, hContext); if (status) return status; + /* Use stored card handle. */ + if (redirect & 0x02) + { + DEBUG_WARN("No card handle provided, using stored handle."); + *hHandle = scard->hCard; + return 0; + } + if (Stream_GetRemainingLength(irp->input) < 4) { DEBUG_WARN("length violation %d [%d]", 4, @@ -396,12 +404,10 @@ static UINT32 handle_RedirHandleRef(SMARTCARD_DEVICE* scard, IRP* irp, return SCARD_F_INTERNAL_ERROR; } + memset(hHandle, 0, sizeof(SCARDHANDLE)); Stream_Read_UINT32(irp->input, *hHandle); DEBUG_SCARD("hCard=%p", *hHandle); - assert(*inlen >= len + 4); - *inlen -= len + 4; - return 0; } @@ -677,17 +683,17 @@ static UINT32 smartcard_map_state(UINT32 state) return state; } -static UINT32 handle_EstablishContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_EstablishContext(SMARTCARD_DEVICE* scard, IRP* irp) { UINT32 status; UINT32 scope; SCARDCONTEXT hContext = -1; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) return status; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) return status; @@ -717,24 +723,25 @@ static UINT32 handle_EstablishContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t return status; } -static UINT32 handle_ReleaseContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_ReleaseContext(SMARTCARD_DEVICE* scard, IRP* irp) { + int redirect = 0; UINT32 status; SCARDCONTEXT hContext = -1; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) return status; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) return status; - status = handle_Context(scard, irp, &inlen); + status = handle_Context(scard, irp, &redirect); if (status) return status; - status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + status = handle_RedirContextRef(scard, irp, redirect, &hContext); if (status) return status; @@ -751,24 +758,25 @@ static UINT32 handle_ReleaseContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t in return status; } -static UINT32 handle_IsValidContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_IsValidContext(SMARTCARD_DEVICE* scard, IRP* irp) { + int redirect = 0; UINT32 status; SCARDCONTEXT hContext; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) return status; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) return status; - status = handle_Context(scard, irp, &inlen); + status = handle_Context(scard, irp, &redirect); if (status) return status; - status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + status = handle_RedirContextRef(scard, irp, redirect, &hContext); if (status) return status; @@ -788,9 +796,9 @@ static UINT32 handle_IsValidContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t in return status; } -static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, - size_t inlen, BOOL wide) +static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wide) { + int redirect = 0; UINT32 status; SCARDCONTEXT hContext; DWORD dwReaders; @@ -802,15 +810,15 @@ static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, int elemLength, dataLength; int pos, poslen1, poslen2, allowed_pos; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) goto finish; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) goto finish; - status = handle_Context(scard, irp, &inlen); + status = handle_Context(scard, irp, &redirect); if (status) goto finish; @@ -854,26 +862,13 @@ static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, goto finish; } Stream_Read_UINT32(irp->input, cchReaders); + + Stream_Seek(irp->input, 4); - /* TODO: This hack is necessary, because after a successful connect - * there is no redirected handle available any more in the packets - * that are sent from some software. */ - inlen = Stream_GetRemainingLength(irp->input); - if(12 == inlen) - { - UINT32 tmp; - - Stream_Read_UINT32(irp->input, tmp); - /* Read RedirScardcontextRef */ - status = handle_RedirContextRef(scard, irp, &inlen, &hContext); - if (status) - goto finish; - } - else - { - DEBUG_WARN("Using stored context, not provided."); - hContext = scard->hContext; - } + /* Read RedirScardcontextRef */ + status = handle_RedirContextRef(scard, irp, redirect, &hContext); + if (status) + goto finish; /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ @@ -958,8 +953,9 @@ finish: return status; } -static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BOOL wide) +static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wide) { + int redirect = 0; int i; LONG status; SCARDCONTEXT hContext; @@ -967,15 +963,15 @@ static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, size_t i DWORD readerCount = 0; SCARD_READERSTATE *readerStates = NULL, *cur; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) goto finish; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) goto finish; - status = handle_Context(scard, irp, &inlen); + status = handle_Context(scard, irp, &redirect); if (status) goto finish; @@ -995,7 +991,7 @@ static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, size_t i Stream_Seek(irp->input, 4); /* Get context */ - status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + status = handle_RedirContextRef(scard, irp, redirect, &hContext); if (status) goto finish; @@ -1133,24 +1129,25 @@ finish: return status; } -static UINT32 handle_Cancel(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen) +static UINT32 handle_Cancel(SMARTCARD_DEVICE *scard, IRP* irp) { + int redirect = 0; LONG status; SCARDCONTEXT hContext; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) return status; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) return status; - status = handle_Context(scard, irp, &inlen); + status = handle_Context(scard, irp, &redirect); if (status) return status; - status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + status = handle_RedirContextRef(scard, irp, redirect, &hContext); if (status) return status; @@ -1166,8 +1163,9 @@ static UINT32 handle_Cancel(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen) return status; } -static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BOOL wide) +static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wide) { + int redirect = 0; LONG status; SCARDCONTEXT hContext; char* readerName = NULL; @@ -1176,11 +1174,11 @@ static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BO DWORD dwActiveProtocol = 0; SCARDHANDLE hCard; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) goto finish; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) goto finish; @@ -1195,7 +1193,7 @@ static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BO Stream_Seek(irp->input, 4); /* Read common data */ - status = handle_Context(scard, irp, &inlen); + status = handle_Context(scard, irp, &redirect); if (status) goto finish; @@ -1214,7 +1212,7 @@ static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BO if (status) goto finish; - status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + status = handle_RedirContextRef(scard, irp, redirect, &hContext); if (status) goto finish; @@ -1236,6 +1234,7 @@ static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BO DEBUG_WARN("Failure: %s 0x%08x", pcsc_stringify_error(status), (unsigned) status); else DEBUG_SCARD("Success 0x%08x", (unsigned) hCard); + scard->hCard = hCard; Stream_Write_UINT32(irp->output, 0x00000000); Stream_Write_UINT32(irp->output, 0x00000000); @@ -1254,8 +1253,9 @@ finish: return status; } -static UINT32 handle_Reconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_Reconnect(SMARTCARD_DEVICE* scard, IRP* irp) { + int redirect = 0; LONG status; SCARDCONTEXT hContext; SCARDHANDLE hCard; @@ -1264,15 +1264,15 @@ static UINT32 handle_Reconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) DWORD dwInitialization = 0; DWORD dwActiveProtocol = 0; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) return status; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) return status; - status = handle_CardHandle(scard, irp, &inlen); + status = handle_CardHandle(scard, irp, &redirect); if (status) return status; @@ -1287,7 +1287,7 @@ static UINT32 handle_Reconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) Stream_Read_UINT32(irp->input, dwPreferredProtocol); Stream_Read_UINT32(irp->input, dwInitialization); - status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + status = handle_RedirHandleRef(scard, irp, redirect, &hContext, &hCard); if (status) return status; @@ -1315,22 +1315,23 @@ static UINT32 handle_Reconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) return status; } -static UINT32 handle_Disconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_Disconnect(SMARTCARD_DEVICE* scard, IRP* irp) { + int redirect = 0; LONG status; SCARDCONTEXT hContext; SCARDHANDLE hCard; DWORD dwDisposition = 0; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) return status; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) return status; - status = handle_CardHandle(scard, irp, &inlen); + status = handle_CardHandle(scard, irp, &redirect); if (status) return status; @@ -1343,7 +1344,7 @@ static UINT32 handle_Disconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) Stream_Read_UINT32(irp->input, dwDisposition); - status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + status = handle_RedirHandleRef(scard, irp, redirect, &hContext, &hCard); if (status) return status; @@ -1362,27 +1363,29 @@ static UINT32 handle_Disconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); else DEBUG_SCARD("Success"); + memset(&scard->hCard, 0, sizeof(scard->hCard)); smartcard_output_alignment(irp, 8); return status; } -static UINT32 handle_BeginTransaction(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_BeginTransaction(SMARTCARD_DEVICE* scard, IRP* irp) { + int redirect = 0; LONG status; SCARDHANDLE hCard; SCARDCONTEXT hContext; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) return status; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) return status; - status = handle_CardHandle(scard, irp, &inlen); + status = handle_CardHandle(scard, irp, &redirect); if (status) return status; @@ -1394,7 +1397,7 @@ static UINT32 handle_BeginTransaction(SMARTCARD_DEVICE* scard, IRP* irp, size_t } Stream_Seek(irp->input, 4); - status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + status = handle_RedirHandleRef(scard, irp, redirect, &hContext, &hCard); if (status) return status; @@ -1416,22 +1419,23 @@ static UINT32 handle_BeginTransaction(SMARTCARD_DEVICE* scard, IRP* irp, size_t return status; } -static UINT32 handle_EndTransaction(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_EndTransaction(SMARTCARD_DEVICE* scard, IRP* irp) { + int redirect = 0; LONG status; SCARDHANDLE hCard; SCARDCONTEXT hContext; DWORD dwDisposition = 0; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) return status; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) return status; - status = handle_CardHandle(scard, irp, &inlen); + status = handle_CardHandle(scard, irp, &redirect); if (status) return status; @@ -1443,7 +1447,7 @@ static UINT32 handle_EndTransaction(SMARTCARD_DEVICE* scard, IRP* irp, size_t in } Stream_Read_UINT32(irp->input, dwDisposition); - status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + status = handle_RedirHandleRef(scard, irp, redirect, &hContext, &hCard); if (status) return status; @@ -1465,8 +1469,9 @@ static UINT32 handle_EndTransaction(SMARTCARD_DEVICE* scard, IRP* irp, size_t in return status; } -static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp) { + int redirect = 0; LONG status; SCARDHANDLE hCard; SCARDCONTEXT hContext; @@ -1480,15 +1485,15 @@ static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) int i; #endif - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) goto finish; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) goto finish; - status = handle_CardHandle(scard, irp, &inlen); + status = handle_CardHandle(scard, irp, &redirect); if (status) goto finish; @@ -1502,9 +1507,8 @@ static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) Stream_Seek(irp->input, 4); Stream_Seek_UINT32(irp->input); /* atrLen */ - inlen -= 8; - status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + status = handle_RedirHandleRef(scard, irp, redirect, &hContext, &hCard); if (status) goto finish; @@ -1568,8 +1572,9 @@ finish: return status; } -static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL wide) +static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, BOOL wide) { + int redirect = 0; LONG status; SCARDHANDLE hCard; SCARDCONTEXT hContext; @@ -1585,15 +1590,15 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL int i; #endif - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) goto finish; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) goto finish; - status = handle_CardHandle(scard, irp, &inlen); + status = handle_CardHandle(scard, irp, &redirect); if (status) goto finish; @@ -1608,7 +1613,7 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL Stream_Read_UINT32(irp->input, readerLen); Stream_Read_UINT32(irp->input, atrLen); - status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + status = handle_RedirHandleRef(scard, irp, redirect, &hContext, &hCard); if (status) goto finish; @@ -1694,8 +1699,9 @@ finish: return status; } -static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp) { + int redirect = 0; LONG status; SCARDHANDLE hCard; SCARDCONTEXT hContext; @@ -1719,15 +1725,15 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) ioSendPci.v = NULL; ioRecvPci.v = NULL; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) goto finish; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) goto finish; - status = handle_CardHandle(scard, irp, &inlen); + status = handle_CardHandle(scard, irp, &redirect); if (status) goto finish; @@ -1752,7 +1758,7 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) Stream_Read_UINT32(irp->input, recvBufferIsNULL); Stream_Read_UINT32(irp->input, cbRecvLength); - status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + status = handle_RedirHandleRef(scard, irp, redirect, &hContext, &hCard); if (status) goto finish; @@ -1926,8 +1932,9 @@ finish: return status; } -static UINT32 handle_Control(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_Control(SMARTCARD_DEVICE* scard, IRP* irp) { + int redirect = 0; LONG status; SCARDCONTEXT hContext; SCARDHANDLE hCard; @@ -1940,15 +1947,15 @@ static UINT32 handle_Control(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) DWORD nBytesReturned; DWORD outBufferSize; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) goto finish; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) goto finish; - status = handle_CardHandle(scard, irp, &inlen); + status = handle_CardHandle(scard, irp, &redirect); if (status) goto finish; @@ -1966,7 +1973,7 @@ static UINT32 handle_Control(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) Stream_Read_UINT32(irp->input, fpvOutBufferIsNULL); Stream_Read_UINT32(irp->input, outBufferSize); - status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + status = handle_RedirHandleRef(scard, irp, redirect, &hContext, &hCard); if (status) goto finish; @@ -2042,8 +2049,9 @@ finish: return status; } -static UINT32 handle_GetAttrib(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_GetAttrib(SMARTCARD_DEVICE* scard, IRP* irp) { + int redirect = 0; LONG status; SCARDHANDLE hCard; SCARDCONTEXT hContext; @@ -2052,15 +2060,15 @@ static UINT32 handle_GetAttrib(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) DWORD attrLen = 0; BYTE* pbAttr = NULL; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) return status; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) return status; - status = handle_CardHandle(scard, irp, &inlen); + status = handle_CardHandle(scard, irp, &redirect); if (status) return status; @@ -2075,7 +2083,7 @@ static UINT32 handle_GetAttrib(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) Stream_Seek(irp->input, 0x4); Stream_Read_UINT32(irp->input, dwAttrLen); - status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + status = handle_RedirHandleRef(scard, irp, redirect, &hContext, &hCard); if (status) return status; @@ -2184,7 +2192,7 @@ static UINT32 handle_GetAttrib(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) return status; } -static UINT32 handle_AccessStartedEvent(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) +static UINT32 handle_AccessStartedEvent(SMARTCARD_DEVICE* scard, IRP* irp) { if (Stream_GetRemainingLength(irp->input) < 4) @@ -2219,8 +2227,9 @@ typedef struct _SERVER_SCARD_ATRMASK } SERVER_SCARD_ATRMASK; -static UINT32 handle_LocateCardsByATR(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BOOL wide) +static UINT32 handle_LocateCardsByATR(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wide) { + int redirect = 0; LONG status; int i, j, k; SCARDCONTEXT hContext; @@ -2232,15 +2241,15 @@ static UINT32 handle_LocateCardsByATR(SMARTCARD_DEVICE* scard, IRP* irp, size_t SERVER_SCARD_ATRMASK* curAtr = NULL; SERVER_SCARD_ATRMASK* pAtrMasks = NULL; - status = handle_CommonTypeHeader(scard, irp, &inlen); + status = handle_CommonTypeHeader(scard, irp); if (status) return status; - status = handle_PrivateTypeHeader(scard, irp, &inlen); + status = handle_PrivateTypeHeader(scard, irp); if (status) return status; - status = handle_Context(scard, irp, &inlen); + status = handle_Context(scard, irp, &redirect); if (status) return status; @@ -2252,7 +2261,7 @@ static UINT32 handle_LocateCardsByATR(SMARTCARD_DEVICE* scard, IRP* irp, size_t } Stream_Seek(irp->input, 4); - status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + status = handle_RedirContextRef(scard, irp, redirect, &hContext); if (status) return status; @@ -2498,22 +2507,22 @@ void smartcard_device_control(SMARTCARD_DEVICE* scard, IRP* irp) switch (ioctl_code) { case SCARD_IOCTL_ESTABLISH_CONTEXT: - result = handle_EstablishContext(scard, irp, input_len); + result = handle_EstablishContext(scard, irp); break; case SCARD_IOCTL_IS_VALID_CONTEXT: - result = handle_IsValidContext(scard, irp, input_len); + result = handle_IsValidContext(scard, irp); break; case SCARD_IOCTL_RELEASE_CONTEXT: - result = handle_ReleaseContext(scard, irp, input_len); + result = handle_ReleaseContext(scard, irp); break; case SCARD_IOCTL_LIST_READERS: - result = handle_ListReaders(scard, irp, input_len, 0); + result = handle_ListReaders(scard, irp, 0); break; case SCARD_IOCTL_LIST_READERS + 4: - result = handle_ListReaders(scard, irp, input_len, 1); + result = handle_ListReaders(scard, irp, 1); break; case SCARD_IOCTL_LIST_READER_GROUPS: @@ -2523,71 +2532,71 @@ void smartcard_device_control(SMARTCARD_DEVICE* scard, IRP* irp) break; case SCARD_IOCTL_GET_STATUS_CHANGE: - result = handle_GetStatusChange(scard, irp, input_len, 0); + result = handle_GetStatusChange(scard, irp, 0); break; case SCARD_IOCTL_GET_STATUS_CHANGE + 4: - result = handle_GetStatusChange(scard, irp, input_len, 1); + result = handle_GetStatusChange(scard, irp, 1); break; case SCARD_IOCTL_CANCEL: - result = handle_Cancel(scard, irp, input_len); + result = handle_Cancel(scard, irp); break; case SCARD_IOCTL_CONNECT: - result = handle_Connect(scard, irp, input_len, 0); + result = handle_Connect(scard, irp, 0); break; case SCARD_IOCTL_CONNECT + 4: - result = handle_Connect(scard, irp, input_len, 1); + result = handle_Connect(scard, irp, 1); break; case SCARD_IOCTL_RECONNECT: - result = handle_Reconnect(scard, irp, input_len); + result = handle_Reconnect(scard, irp); break; case SCARD_IOCTL_DISCONNECT: - result = handle_Disconnect(scard, irp, input_len); + result = handle_Disconnect(scard, irp); break; case SCARD_IOCTL_BEGIN_TRANSACTION: - result = handle_BeginTransaction(scard, irp, input_len); + result = handle_BeginTransaction(scard, irp); break; case SCARD_IOCTL_END_TRANSACTION: - result = handle_EndTransaction(scard, irp, input_len); + result = handle_EndTransaction(scard, irp); break; case SCARD_IOCTL_STATE: - result = handle_State(scard, irp, input_len); + result = handle_State(scard, irp); break; case SCARD_IOCTL_STATUS: - result = handle_Status(scard, irp, input_len, 0); + result = handle_Status(scard, irp, 0); break; case SCARD_IOCTL_STATUS + 4: - result = handle_Status(scard, irp, input_len, 1); + result = handle_Status(scard, irp, 1); break; case SCARD_IOCTL_TRANSMIT: - result = handle_Transmit(scard, irp, input_len); + result = handle_Transmit(scard, irp); break; case SCARD_IOCTL_CONTROL: - result = handle_Control(scard, irp, input_len); + result = handle_Control(scard, irp); break; case SCARD_IOCTL_GETATTRIB: - result = handle_GetAttrib(scard, irp, input_len); + result = handle_GetAttrib(scard, irp); break; case SCARD_IOCTL_ACCESS_STARTED_EVENT: - result = handle_AccessStartedEvent(scard, irp, input_len); + result = handle_AccessStartedEvent(scard, irp); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR: - result = handle_LocateCardsByATR(scard, irp, input_len, 0); + result = handle_LocateCardsByATR(scard, irp, 0); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4: - result = handle_LocateCardsByATR(scard, irp, input_len, 1); + result = handle_LocateCardsByATR(scard, irp, 1); break; default: From a9b5d91fd9c51792ffcde8c3dc99977930791e8e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 1 Oct 2013 12:06:46 +0200 Subject: [PATCH 3/8] Removed printf. --- channels/smartcard/client/smartcard_operations.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 4859b69a6..b3839ef30 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -786,10 +786,6 @@ static UINT32 handle_IsValidContext(SMARTCARD_DEVICE* scard, IRP* irp) DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); else DEBUG_SCARD("Success context: 0x%08x", (unsigned) hContext); - if (status) - printf("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); - else - printf("Success context: 0x%08x", (unsigned) hContext); smartcard_output_alignment(irp, 8); From dc95a8a31202f2dfa4e88c016defa083e49a8b8f Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 1 Oct 2013 12:11:46 +0200 Subject: [PATCH 4/8] Fixed a command line handling bug crashing the client. --- client/common/cmdline.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index dbe26d978..9fa8fe48f 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include #include @@ -418,7 +420,7 @@ int freerdp_client_add_dynamic_channel(rdpSettings* settings, int count, char** return 0; } -char** freerdp_command_line_parse_comma_separated_values(char* list, int* count) +static char** freerdp_command_line_parse_comma_separated_values(char* list, int* count) { char** p; char* str; @@ -428,6 +430,9 @@ char** freerdp_command_line_parse_comma_separated_values(char* list, int* count) nArgs = nCommas = 0; + assert(NULL != count); + + *count = 0; if (!list) return NULL; @@ -456,7 +461,7 @@ char** freerdp_command_line_parse_comma_separated_values(char* list, int* count) return p; } -char** freerdp_command_line_parse_comma_separated_values_offset(char* list, int* count) +static char** freerdp_command_line_parse_comma_separated_values_offset(char* list, int* count) { char** p; From de835018f4dd3e86fa2fb9d99291ef33bd749b3e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 1 Oct 2013 12:17:55 +0200 Subject: [PATCH 5/8] Fixed invalid preprocessor check. --- channels/smartcard/client/smartcard_operations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index b3839ef30..e5b1ecd5c 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -79,7 +79,7 @@ #define WIN_FILE_DEVICE_SMARTCARD 0x00000031 -#if defined(DEBUG_SCARD) && (DEBUG_SCARD) +#if defined(WITH_DEBUG_SCARD) static char *ioctl_to_string(DWORD code) { static char res[100]; From 29dd9ce861533b68902bc332956464b9a26da69e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 1 Oct 2013 13:09:52 +0200 Subject: [PATCH 6/8] Resource clean up unified in functions to avoid accidental leaks. --- .../smartcard/client/smartcard_operations.c | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index e5b1ecd5c..3981266e8 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1112,15 +1112,23 @@ static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wid Stream_Write(irp->output, cur->rgbAtr, 32); Stream_Zero(irp->output, 4); - - free((void *)cur->szReader); } smartcard_output_alignment(irp, 8); finish: if (readerStates) + { + for (i = 0; i < readerCount; i++) + { + cur = &readerStates[i]; + + if (cur->szReader) + free(cur->szReader); + cur->szReader = NULL; + } free(readerStates); + } return status; } @@ -2154,8 +2162,8 @@ static UINT32 handle_GetAttrib(SMARTCARD_DEVICE* scard, IRP* irp) if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned int) status); - free(pbAttr); - return smartcard_output_return(irp, status); + status = smartcard_output_return(irp, status); + goto finish; } else { @@ -2179,6 +2187,7 @@ static UINT32 handle_GetAttrib(SMARTCARD_DEVICE* scard, IRP* irp) } smartcard_output_alignment(irp, 8); +finish: #ifdef SCARD_AUTOALLOCATE SCardFreeMemory(hContext, pbAttr); #else @@ -2282,12 +2291,6 @@ static UINT32 handle_LocateCardsByATR(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wi readerStates = malloc(readerCount * sizeof(SCARD_READERSTATE)); ZeroMemory(readerStates, readerCount * sizeof(SCARD_READERSTATE)); - if (!readerStates) - { - free(pAtrMasks); - return smartcard_output_return(irp, SCARD_E_NO_MEMORY); - } - for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; @@ -2340,10 +2343,8 @@ static UINT32 handle_LocateCardsByATR(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wi { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); - - free(readerStates); - free(pAtrMasks); - return smartcard_output_return(irp, status); + status = smartcard_output_return(irp, status); + goto finish; } DEBUG_SCARD("Success"); @@ -2380,14 +2381,23 @@ static UINT32 handle_LocateCardsByATR(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wi Stream_Write(irp->output, cur->rgbAtr, 32); Stream_Zero(irp->output, 4); - - free((void*) cur->szReader); } smartcard_output_alignment(irp, 8); - free(readerStates); - free(pAtrMasks); +finish: + for (i = 0, cur = readerStates; i < readerCount; i++, cur++) + { + if (cur->szReader) + free((void*) cur->szReader); + cur->szReader = NULL; + } + + if (readerStates) + free(readerStates); + + if (pAtrMasks) + free(pAtrMasks); return status; } From 918797914b10661760ea3b00cdec38b66283b4de Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 1 Oct 2013 14:41:59 +0200 Subject: [PATCH 7/8] Fixed accidental double free by realloc. --- .../smartcard/client/smartcard_operations.c | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 3981266e8..30e82956b 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1796,12 +1796,21 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp) status = SCARD_F_INTERNAL_ERROR; goto finish; } - tmp = realloc(ioSendPci.v, ioSendPci.rq->cbPciLength); - if (!tmp) - goto finish; - ioSendPci.v = tmp; - Stream_Read(irp->input, &ioSendPci.rq[1], ioSendPci.rq->cbPciLength); + /* Invalid length received. */ + if (!ioSendPci.rq->cbPciLength) + { + if (ioSendPci.v) + free(ioSendPci.v); + ioSendPci.v = NULL; + } + else + { + tmp = realloc(ioSendPci.v, ioSendPci.rq->cbPciLength); + ioSendPci.v = tmp; + + Stream_Read(irp->input, &ioSendPci.rq[1], ioSendPci.rq->cbPciLength); + } } else ioSendPci.rq->cbPciLength = sizeof(SCARD_IO_REQUEST); @@ -1879,12 +1888,19 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp) /* Read data, see * http://msdn.microsoft.com/en-us/library/windows/desktop/aa379807%28v=vs.85%29.aspx */ - tmp = realloc(ioRecvPci.v, ioRecvPci.rq->cbPciLength); - if (!tmp) - goto finish; - ioRecvPci.v = tmp; - - Stream_Read(irp->input, &ioRecvPci.rq[1], ioRecvPci.rq->cbPciLength); + if (!ioRecvPci.rq->cbPciLength) + { + if (ioRecvPci.v) + free(ioRecvPci.v); + ioRecvPci.v = NULL; + } + else + { + tmp = realloc(ioRecvPci.v, ioRecvPci.rq->cbPciLength); + ioRecvPci.v = tmp; + + Stream_Read(irp->input, &ioRecvPci.rq[1], ioRecvPci.rq->cbPciLength); + } pPioRecvPci = ioRecvPci.rq; } From c5b3ee9b85b869fbe27bad1a9aa762833e6d6924 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 2 Oct 2013 16:48:54 +0200 Subject: [PATCH 8/8] Fixed length check against wrong variable. --- channels/smartcard/client/smartcard_operations.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 30e82956b..296b8d543 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1869,10 +1869,10 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp) /* Just check for too few bytes, there may be more actual * data than is used due to padding. */ - if (linkedLen < ioSendPci.rq->cbPciLength) + if (linkedLen < ioRecvPci.rq->cbPciLength) { DEBUG_WARN("SCARD_IO_REQUEST with invalid extra byte length %d [%d]", - ioSendPci.rq->cbPciLength - sizeof(SCARD_IO_REQUEST), linkedLen); + ioRecvPci.rq->cbPciLength - sizeof(SCARD_IO_REQUEST), linkedLen); status = SCARD_F_INTERNAL_ERROR; goto finish; }