From 3e4d30df6c407e659c4f1f2d7e3576cfbcbf0a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Moreau?= Date: Tue, 8 Apr 2014 18:55:50 -0400 Subject: [PATCH] channels/smartcard: fix ListReaders mszGroups parsing --- channels/smartcard/client/smartcard_pack.c | 62 ++++++++++++++-------- winpr/libwinpr/smartcard/smartcard_pcsc.c | 20 ++++++- winpr/libwinpr/smartcard/smartcard_pcsc.h | 1 + 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index 557c2624e..62625afc8 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -443,6 +443,7 @@ UINT32 smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co UINT32 smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Call* call) { UINT32 status; + UINT32 count; UINT32 mszGroupsNdrPtr; call->mszGroups = NULL; @@ -460,35 +461,54 @@ UINT32 smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* } Stream_Read_UINT32(s, call->cBytes); /* cBytes (4 bytes) */ - - if (Stream_GetRemainingLength(s) < call->cBytes) - { - WLog_Print(smartcard->log, WLOG_WARN, "ListReaders_Call is too short: Actual: %d, Expected: %d", - (int) Stream_GetRemainingLength(s), call->cBytes); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, mszGroupsNdrPtr); /* mszGroupsNdrPtr (4 bytes) */ - Stream_Read_UINT32(s, call->fmszReadersIsNULL); /* fmszReadersIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cchReaders); /* cchReaders (4 bytes) */ - if (Stream_GetRemainingLength(s) < 4) - { - WLog_Print(smartcard->log, WLOG_WARN, "ListReaders_Call is too short: %d", - (int) Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - if (mszGroupsNdrPtr) - { - WLog_Print(smartcard->log, WLOG_WARN, "ListReaders_Call unimplemented mszGroups parsing"); - } - status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->Context)); if (status) return status; + + if ((mszGroupsNdrPtr && !call->cBytes) || (!mszGroupsNdrPtr && call->cBytes)) + { + WLog_Print(smartcard->log, WLOG_WARN, + "ListReaders_Call mszGroupsNdrPtr (0x%08X) and cBytes (0x%08X) inconsistency", + (int) mszGroupsNdrPtr, (int) call->cBytes); + return STATUS_INVALID_PARAMETER; + } + + if (mszGroupsNdrPtr) + { + Stream_Read_UINT32(s, count); /* NdrCount (4 bytes) */ + + if (count != call->cBytes) + { + WLog_Print(smartcard->log, WLOG_WARN, + "ListReaders_Call NdrCount (0x%08X) and cBytes (0x%08X) inconsistency", + (int) count, (int) call->cBytes); + return STATUS_INVALID_PARAMETER; + } + + if (Stream_GetRemainingLength(s) < call->cBytes) + { + WLog_Print(smartcard->log, WLOG_WARN, "ListReaders_Call is too short: Actual: %d, Expected: %d", + (int) Stream_GetRemainingLength(s), call->cBytes); + return STATUS_BUFFER_TOO_SMALL; + } + + call->mszGroups = (BYTE*) calloc(1, call->cBytes + 4); + + if (!call->mszGroups) + { + WLog_Print(smartcard->log, WLOG_WARN, "ListReaders_Call out of memory error (mszGroups)"); + return STATUS_NO_MEMORY; + } + + Stream_Read(s, call->mszGroups, call->cBytes); + + smartcard_unpack_read_size_align(smartcard, s, call->cBytes, 4); + } return SCARD_S_SUCCESS; } diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 7c5d1605c..f778054f4 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -28,6 +28,8 @@ #include "smartcard_pcsc.h" +static BOOL g_SCardAutoAllocate = FALSE; + static HMODULE g_PCSCModule = NULL; static PCSCFunctionTable g_PCSC = { 0 }; @@ -989,7 +991,8 @@ extern PCSCFunctionTable g_PCSC_Link; extern int PCSC_InitializeSCardApi_Link(void); int PCSC_InitializeSCardApi(void) -{ +{ +#if 0 if (PCSC_InitializeSCardApi_Link() >= 0) { g_PCSC.pfnSCardEstablishContext = g_PCSC_Link.pfnSCardEstablishContext; @@ -1013,8 +1016,13 @@ int PCSC_InitializeSCardApi(void) return 1; } +#endif +#ifdef __MACOSX__ + g_PCSCModule = LoadLibraryA("/System/Library/Frameworks/PCSC.framework/PCSC"); +#else g_PCSCModule = LoadLibraryA("libpcsclite.so"); +#endif if (!g_PCSCModule) return -1; @@ -1033,10 +1041,18 @@ int PCSC_InitializeSCardApi(void) g_PCSC.pfnSCardTransmit = (void*) GetProcAddress(g_PCSCModule, "SCardTransmit"); g_PCSC.pfnSCardListReaderGroups = (void*) GetProcAddress(g_PCSCModule, "SCardListReaderGroups"); g_PCSC.pfnSCardListReaders = (void*) GetProcAddress(g_PCSCModule, "SCardListReaders"); - g_PCSC.pfnSCardFreeMemory = (void*) GetProcAddress(g_PCSCModule, "SCardFreeMemory"); g_PCSC.pfnSCardCancel = (void*) GetProcAddress(g_PCSCModule, "SCardCancel"); g_PCSC.pfnSCardGetAttrib = (void*) GetProcAddress(g_PCSCModule, "SCardGetAttrib"); g_PCSC.pfnSCardSetAttrib = (void*) GetProcAddress(g_PCSCModule, "SCardSetAttrib"); + + g_PCSC.pfnSCardFreeMemory = NULL; + +#ifndef __MACOSX__ + g_PCSC.pfnSCardFreeMemory = (void*) GetProcAddress(g_PCSCModule, "SCardFreeMemory"); +#endif + + if (g_PCSC.pfnSCardFreeMemory) + g_SCardAutoAllocate = TRUE; return 1; } diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.h b/winpr/libwinpr/smartcard/smartcard_pcsc.h index 35169fd48..abc6c5300 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.h +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.h @@ -20,6 +20,7 @@ #ifndef WINPR_SMARTCARD_PCSC_PRIVATE_H #define WINPR_SMARTCARD_PCSC_PRIVATE_H +#include #include struct _PCSCFunctionTable