From: Marc-André Moreau Date: Mon, 7 Apr 2014 05:19:58 +0000 (-0400) Subject: channels/smartcard: more unpacking X-Git-Tag: 1.2.0-beta1+android7~74^2~44 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e75b9aa9fad915991b6a9a40d3c665292a193d68;p=platform%2Fupstream%2Ffreerdp.git channels/smartcard: more unpacking --- diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 02c1a33..c32c1b8 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -159,14 +159,6 @@ static void smartcard_output_alignment(IRP* irp, UINT32 seed) Stream_Zero(irp->output, add); } -static void smartcard_output_repos(IRP* irp, UINT32 written) -{ - UINT32 add = (4 - (written % 4)) % 4; - - if (add > 0) - Stream_Zero(irp->output, add); -} - size_t smartcard_multi_string_length_a(const char* msz) { char* p = (char*) msz; @@ -685,49 +677,29 @@ static UINT32 smartcard_State(SMARTCARD_DEVICE* smartcard, IRP* irp) SCARDCONTEXT hContext; State_Call call; State_Return ret; - DWORD readerLen; - char* readerName = NULL; - BYTE atr[SCARD_ATR_LENGTH]; status = smartcard_unpack_state_call(smartcard, irp->input, &call); if (status) - goto finish; + return status; hCard = (ULONG_PTR) call.hCard.pbHandle; hContext = (ULONG_PTR) call.hCard.Context.pbContext; - readerLen = SCARD_AUTOALLOCATE; - - ret.rgAtr = atr; ret.cbAtrLen = SCARD_ATR_LENGTH; - status = SCardStatusA(hCard, (LPSTR) &readerName, &readerLen, - &ret.dwState, &ret.dwProtocol, ret.rgAtr, &ret.cbAtrLen); + status = SCardState(hCard, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.rgAtr, &ret.cbAtrLen); if (status != SCARD_S_SUCCESS) { Stream_Zero(irp->output, 256); - goto finish; + return status; } - Stream_Write_UINT32(irp->output, ret.dwState); /* dwState (4 bytes) */ - Stream_Write_UINT32(irp->output, ret.dwProtocol); /* dwProtocol (4 bytes) */ - Stream_Write_UINT32(irp->output, ret.cbAtrLen); /* cbAtrLen (4 bytes) */ - Stream_Write_UINT32(irp->output, 0x00000001); /* rgAtrPointer (4 bytes) */ - Stream_Write_UINT32(irp->output, ret.cbAtrLen); /* rgAtrLength (4 bytes) */ - Stream_Write(irp->output, ret.rgAtr, ret.cbAtrLen); /* rgAtr */ - - smartcard_output_repos(irp, ret.cbAtrLen); + smartcard_pack_state_return(smartcard, irp->output, &ret); smartcard_output_alignment(irp, 8); -finish: - if (readerName) - { - SCardFreeMemory(hContext, readerName); - } - return status; } @@ -910,15 +882,7 @@ static UINT32 smartcard_Control(SMARTCARD_DEVICE* smartcard, IRP* irp) call.pvInBuffer, (DWORD) call.cbInBufferSize, ret.pvOutBuffer, (DWORD) call.cbOutBufferSize, &ret.cbOutBufferSize); - Stream_Write_UINT32(irp->output, (UINT32) ret.cbOutBufferSize); /* cbOutBufferSize (4 bytes) */ - Stream_Write_UINT32(irp->output, 0x00000004); /* pvOutBufferPointer (4 bytes) */ - Stream_Write_UINT32(irp->output, ret.cbOutBufferSize); /* pvOutBufferLength (4 bytes) */ - - if (ret.cbOutBufferSize > 0) - { - Stream_Write(irp->output, ret.pvOutBuffer, ret.cbOutBufferSize); /* pvOutBuffer */ - smartcard_output_repos(irp, ret.cbOutBufferSize); - } + smartcard_pack_control_return(smartcard, irp->output, &ret); smartcard_output_alignment(irp, 8); @@ -984,30 +948,17 @@ static UINT32 smartcard_GetAttrib(SMARTCARD_DEVICE* smartcard, IRP* irp) { status = SCARD_E_INSUFFICIENT_BUFFER; } + call.cbAttrLen = cbAttrLen; + ret.cbAttrLen = call.cbAttrLen; if (status != SCARD_S_SUCCESS) { Stream_Zero(irp->output, 256); goto finish; } - else - { - ret.cbAttrLen = call.cbAttrLen; - Stream_Write_UINT32(irp->output, ret.cbAttrLen); /* cbAttrLen (4 bytes) */ - Stream_Write_UINT32(irp->output, 0x00020000); /* pbAttrPointer (4 bytes) */ - Stream_Write_UINT32(irp->output, ret.cbAttrLen); /* pbAttrLength (4 bytes) */ - - if (!ret.pbAttr) - Stream_Zero(irp->output, ret.cbAttrLen); /* pbAttr */ - else - Stream_Write(irp->output, ret.pbAttr, ret.cbAttrLen); /* pbAttr */ - - smartcard_output_repos(irp, ret.cbAttrLen); - /* align to multiple of 4 */ - Stream_Write_UINT32(irp->output, 0); - } + smartcard_pack_get_attrib_return(smartcard, irp->output, &ret); smartcard_output_alignment(irp, 8); diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index 262c55f..adcf897 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -885,6 +885,19 @@ UINT32 smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, Stat return SCARD_S_SUCCESS; } +UINT32 smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, State_Return* ret) +{ + Stream_Write_UINT32(s, ret->dwState); /* dwState (4 bytes) */ + Stream_Write_UINT32(s, ret->dwProtocol); /* dwProtocol (4 bytes) */ + Stream_Write_UINT32(s, ret->cbAtrLen); /* cbAtrLen (4 bytes) */ + Stream_Write_UINT32(s, 0x00020020); /* rgAtrNdrPtr (4 bytes) */ + Stream_Write_UINT32(s, ret->cbAtrLen); /* rgAtrLength (4 bytes) */ + Stream_Write(s, ret->rgAtr, ret->cbAtrLen); /* rgAtr */ + smartcard_pack_write_offset_align(smartcard, s, 4); + + return SCARD_S_SUCCESS; +} + UINT32 smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Call* call) { UINT32 status; @@ -957,6 +970,22 @@ UINT32 smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, return SCARD_S_SUCCESS; } +UINT32 smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Return* ret) +{ + Stream_Write_UINT32(s, ret->cbAttrLen); /* cbAttrLen (4 bytes) */ + Stream_Write_UINT32(s, 0x00020080); /* pbAttrPointer (4 bytes) */ + Stream_Write_UINT32(s, ret->cbAttrLen); /* pbAttrLength (4 bytes) */ + + if (!ret->pbAttr) + Stream_Zero(s, ret->cbAttrLen); /* pbAttr */ + else + Stream_Write(s, ret->pbAttr, ret->cbAttrLen); /* pbAttr */ + + smartcard_pack_write_offset_align(smartcard, s, 4); + + return SCARD_S_SUCCESS; +} + UINT32 smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call) { UINT32 status; @@ -1014,6 +1043,21 @@ UINT32 smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co return SCARD_S_SUCCESS; } +UINT32 smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Return* ret) +{ + Stream_Write_UINT32(s, ret->cbOutBufferSize); /* cbOutBufferSize (4 bytes) */ + Stream_Write_UINT32(s, 0x00020040); /* pvOutBufferPointer (4 bytes) */ + Stream_Write_UINT32(s, ret->cbOutBufferSize); /* pvOutBufferLength (4 bytes) */ + + if (ret->cbOutBufferSize > 0) + { + Stream_Write(s, ret->pvOutBuffer, ret->cbOutBufferSize); /* pvOutBuffer */ + smartcard_pack_write_offset_align(smartcard, s, 4); + } + + return SCARD_S_SUCCESS; +} + UINT32 smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Call* call) { UINT32 status; diff --git a/channels/smartcard/client/smartcard_pack.h b/channels/smartcard/client/smartcard_pack.h index 36321bb..75b1d00 100644 --- a/channels/smartcard/client/smartcard_pack.h +++ b/channels/smartcard/client/smartcard_pack.h @@ -269,7 +269,7 @@ typedef struct _State_Return DWORD dwState; DWORD dwProtocol; /* [range] */ DWORD cbAtrLen; - /* [size_is][unique] */ BYTE *rgAtr; + /* [size_is][unique] */ BYTE rgAtr[36]; } State_Return; typedef struct _Status_Call @@ -463,13 +463,16 @@ UINT32 smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wS UINT32 smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeW_Call* call); UINT32 smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_Call* call); +UINT32 smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, State_Return* ret); UINT32 smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Call* call); UINT32 smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Return* ret); UINT32 smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Call* call); +UINT32 smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Return* ret); UINT32 smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call); +UINT32 smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Return* ret); UINT32 smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Call* call); UINT32 smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Return* ret); diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 26a5ee7..0812252 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -649,7 +649,30 @@ WINSCARDAPI LONG WINAPI PCSC_SCardCancelTransaction(SCARDHANDLE hCard) WINSCARDAPI LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { - return 0; + LONG status = SCARD_S_SUCCESS; + + if (g_PCSC.pfnSCardStatus) + { + SCARDCONTEXT hContext = 0; + LPSTR mszReaderNames = NULL; + DWORD cchReaderLen = SCARD_AUTOALLOCATE; + + status = g_PCSC.pfnSCardStatus(hCard, (LPSTR) &mszReaderNames, &cchReaderLen, + pdwState, pdwProtocol, pbAtr, pcbAtrLen); + status = PCSC_MapErrorCodeToWinSCard(status); + + if (mszReaderNames) + { + if (g_PCSC.pfnSCardFreeMemory) + { + hContext = PCSC_GetSmartCardContextFromHandle(hCard); + + g_PCSC.pfnSCardFreeMemory(hContext, mszReaderNames); + } + } + } + + return status; } WINSCARDAPI LONG WINAPI PCSC_SCardStatusA(SCARDHANDLE hCard,