From 55e23d1ff4c11adc70fa51429ef2028a987c5626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 8 Apr 2014 11:32:48 -0400 Subject: [PATCH] channels/smartcard: fix padding functions --- .../smartcard/client/smartcard_operations.c | 18 +++--- channels/smartcard/client/smartcard_pack.c | 56 +++++++++++++++---- channels/smartcard/client/smartcard_pack.h | 5 +- 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 56a60a5b8..299c070fc 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1292,14 +1292,6 @@ void smartcard_irp_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp) break; } - /** - * [MS-RPCE] 2.2.6.3 Primitive Type Serialization - * The type MUST be aligned on an 8-byte boundary. If the size of the - * primitive type is not a multiple of 8 bytes, the data MUST be padded. - */ - - smartcard_pack_write_offset_align(smartcard, irp->output, 8); - if ((result != SCARD_S_SUCCESS) /* && (result != SCARD_E_TIMEOUT) */) { WLog_Print(smartcard->log, WLOG_WARN, @@ -1322,7 +1314,17 @@ void smartcard_irp_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp) smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result); } + /** + * [MS-RPCE] 2.2.6.3 Primitive Type Serialization + * The type MUST be aligned on an 8-byte boundary. If the size of the + * primitive type is not a multiple of 8 bytes, the data MUST be padded. + */ + + smartcard_pack_write_size_align(smartcard, irp->output, + Stream_GetPosition(irp->output) - (RDPDR_DEVICE_IO_RESPONSE_LENGTH + 4), 8); + Stream_SealLength(irp->output); + outputBufferLength = Stream_Length(irp->output) - RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4; objectBufferLength = outputBufferLength - RDPDR_DEVICE_IO_RESPONSE_LENGTH; Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH); diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index 4bd7fa66c..4a5989581 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -145,6 +145,20 @@ UINT32 smartcard_unpack_read_offset_align(SMARTCARD_DEVICE* smartcard, wStream* return pad; } +UINT32 smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment) +{ + UINT32 pad; + + pad = size; + size = (size + alignment - 1) & ~(alignment - 1); + pad = size - pad; + + if (pad) + Stream_Seek(s, pad); + + return pad; +} + UINT32 smartcard_pack_write_offset_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 alignment) { UINT32 pad; @@ -162,6 +176,20 @@ UINT32 smartcard_pack_write_offset_align(SMARTCARD_DEVICE* smartcard, wStream* s return pad; } +UINT32 smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment) +{ + UINT32 pad; + + pad = size; + size = (size + alignment - 1) & ~(alignment - 1); + pad = size - pad; + + if (pad) + Stream_Zero(s, pad); + + return pad; +} + UINT32 smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context) { if (Stream_GetRemainingLength(s) < 4) @@ -471,7 +499,7 @@ UINT32 smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* Stream_Write_UINT32(s, 0x00020008); /* mszNdrPtr (4 bytes) */ Stream_Write_UINT32(s, ret->cBytes); /* mszNdrLen (4 bytes) */ Stream_Write(s, ret->msz, ret->cBytes); - smartcard_pack_write_offset_align(smartcard, s, 4); + smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4); return SCARD_S_SUCCESS; } @@ -527,7 +555,7 @@ UINT32 smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, call->szReader = malloc(count + 1); Stream_Read(s, call->szReader, count); - smartcard_unpack_read_offset_align(smartcard, s, 4); + smartcard_unpack_read_size_align(smartcard, s, count, 4); call->szReader[count] = '\0'; smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->Common.Context)); @@ -564,7 +592,7 @@ UINT32 smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, call->szReader = malloc((count + 1) * 2); Stream_Read(s, call->szReader, (count * 2)); - smartcard_unpack_read_offset_align(smartcard, s, 4); + smartcard_unpack_read_size_align(smartcard, s, (count * 2), 4); call->szReader[count] = '\0'; smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->Common.Context)); @@ -722,6 +750,10 @@ UINT32 smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wS Stream_Read_UINT32(s, readerState->Common.cbAtr); /* cbAtr (4 bytes) */ Stream_Read(s, readerState->Common.rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */ Stream_Seek_UINT32(s); /* rgbAtr [32..36] (4 bytes) */ + + /* what is this used for? */ + readerState->Common.dwCurrentState &= 0x0000FFFF; + readerState->Common.dwEventState = 0; } for (index = 0; index < call->cReaders; index++) @@ -748,7 +780,7 @@ UINT32 smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wS readerState->szReader = malloc(count + 1); Stream_Read(s, readerState->szReader, count); - smartcard_unpack_read_offset_align(smartcard, s, 4); + smartcard_unpack_read_size_align(smartcard, s, count, 4); readerState->szReader[count] = '\0'; if (!readerState->szReader) @@ -828,6 +860,10 @@ UINT32 smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wS Stream_Read_UINT32(s, readerState->Common.cbAtr); /* cbAtr (4 bytes) */ Stream_Read(s, readerState->Common.rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */ Stream_Seek_UINT32(s); /* rgbAtr [32..36] (4 bytes) */ + + /* what is this used for? */ + readerState->Common.dwCurrentState &= 0x0000FFFF; + readerState->Common.dwEventState = 0; } for (index = 0; index < call->cReaders; index++) @@ -854,7 +890,7 @@ UINT32 smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wS readerState->szReader = malloc((count + 1) * 2); Stream_Read(s, readerState->szReader, (count * 2)); - smartcard_unpack_read_offset_align(smartcard, s, 4); + smartcard_unpack_read_size_align(smartcard, s, (count * 2), 4); readerState->szReader[count] = '\0'; if (!readerState->szReader) @@ -930,7 +966,7 @@ UINT32 smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, Stat 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); + smartcard_pack_write_size_align(smartcard, s, ret->cbAtrLen, 4); return SCARD_S_SUCCESS; } @@ -974,7 +1010,7 @@ UINT32 smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, Sta Stream_Write_UINT32(s, ret->cBytes); /* mszReaderNamesNdrLen (4 bytes) */ Stream_Write(s, ret->mszReaderNames, ret->cBytes); - smartcard_pack_write_offset_align(smartcard, s, 4); + smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4); return SCARD_S_SUCCESS; } @@ -1018,7 +1054,7 @@ UINT32 smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, else Stream_Write(s, ret->pbAttr, ret->cbAttrLen); /* pbAttr */ - smartcard_pack_write_offset_align(smartcard, s, 4); + smartcard_pack_write_size_align(smartcard, s, ret->cbAttrLen, 4); return SCARD_S_SUCCESS; } @@ -1089,7 +1125,7 @@ UINT32 smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, Co if (ret->cbOutBufferSize > 0) { Stream_Write(s, ret->pvOutBuffer, ret->cbOutBufferSize); /* pvOutBuffer */ - smartcard_pack_write_offset_align(smartcard, s, 4); + smartcard_pack_write_size_align(smartcard, s, ret->cbOutBufferSize, 4); } return SCARD_S_SUCCESS; @@ -1324,7 +1360,7 @@ UINT32 smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, T Stream_EnsureRemainingCapacity(s, ret->cbRecvLength); Stream_Write(s, ret->pbRecvBuffer, ret->cbRecvLength); - smartcard_pack_write_offset_align(smartcard, s, 4); + smartcard_pack_write_size_align(smartcard, s, ret->cbRecvLength, 4); } return SCARD_S_SUCCESS; diff --git a/channels/smartcard/client/smartcard_pack.h b/channels/smartcard/client/smartcard_pack.h index 55e901a24..0b93e9366 100644 --- a/channels/smartcard/client/smartcard_pack.h +++ b/channels/smartcard/client/smartcard_pack.h @@ -119,7 +119,7 @@ typedef struct _ReaderState_Common_Call DWORD dwCurrentState; DWORD dwEventState; /* [range] */ DWORD cbAtr; - BYTE rgbAtr[ 36 ]; + BYTE rgbAtr[36]; } ReaderState_Common_Call; typedef struct _ReaderStateA @@ -423,6 +423,9 @@ typedef struct _WriteCacheW_Call UINT32 smartcard_unpack_read_offset_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 alignment); UINT32 smartcard_pack_write_offset_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 alignment); +UINT32 smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment); +UINT32 smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment); + UINT32 smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s); UINT32 smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);