diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c index 170941d59..a3c94e129 100644 --- a/sesman/chansrv/pcsc/xrdp_pcsc.c +++ b/sesman/chansrv/pcsc/xrdp_pcsc.c @@ -1166,7 +1166,7 @@ PCSC_API LONG SCardListReaders(SCARDCONTEXT hContext, /* @unused */ LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) { - char msg[8192]; + char msg[256]; unsigned int code; unsigned int bytes; unsigned int offset; @@ -1209,7 +1209,7 @@ SCardListReaders(SCARDCONTEXT hContext, /* @unused */ LPCSTR mszGroups, bytes = sizeof(msg); code = SCARD_LIST_READERS; - if (get_message(&code, msg, &bytes) != 0) + if (get_message(&code, msg, &bytes) != 0 || bytes < 8) { LLOGLN(0, ("SCardListReaders: error, get_message")); return SCARD_F_INTERNAL_ERROR; @@ -1249,6 +1249,11 @@ SCardListReaders(SCARDCONTEXT hContext, /* @unused */ LPCSTR mszGroups, { ReturnCode = SCARD_E_INSUFFICIENT_BUFFER; } + else if ((bytes - offset) < cBytes) + { + LLOGLN(0, ("SCardListReaders: error, missing buffer")); + ReturnCode = SCARD_F_INTERNAL_ERROR; + } else { memcpy(mszReaders, msg + offset, cBytes); @@ -1284,13 +1289,102 @@ PCSC_API LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen) { + char msg[256]; + unsigned int code; + unsigned int bytes; + unsigned int offset; + LONG ReturnCode; + unsigned int fpbAttrIsNULL = (pbAttr == NULL); + unsigned int cbAttrLen; + LLOGLN(0, ("SCardGetAttrib:")); if (g_sck == -1) { LLOGLN(0, ("SCardGetAttrib: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - return SCARD_S_SUCCESS; + + if (pcbAttrLen == NULL) + { + return SCARD_E_INVALID_PARAMETER; + } + + if (*pcbAttrLen == SCARD_AUTOALLOCATE && fpbAttrIsNULL) + { + return SCARD_E_INVALID_PARAMETER; + } + + offset = 0; + SET_UINT32(msg, offset, hCard); + offset += 4; + SET_UINT32(msg, offset, dwAttrId); + offset += 4; + SET_UINT32(msg, offset, fpbAttrIsNULL); + offset += 4; + SET_UINT32(msg, offset, *pcbAttrLen); + offset += 4; + + if (send_message(SCARD_GET_ATTRIB, msg, offset) != 0) + { + LLOGLN(0, ("SCardGetAttrib: error, send_message")); + return SCARD_F_INTERNAL_ERROR; + } + + bytes = sizeof(msg); + code = SCARD_GET_ATTRIB; + if (get_message(&code, msg, &bytes) != 0 || bytes < 8) + { + LLOGLN(0, ("SCardGetAttrib: error, get_message")); + return SCARD_F_INTERNAL_ERROR; + } + if (code != SCARD_GET_ATTRIB) + { + LLOGLN(0, ("SCardGetAttrib: error, bad code")); + return SCARD_F_INTERNAL_ERROR; + } + offset = 0; + ReturnCode = GET_UINT32(msg, offset); + LLOGLN(10, ("SCardListReaders: status 0x%8.8x", (int)ReturnCode)); + offset += 4; + cbAttrLen = GET_UINT32(msg, offset); + offset += 4; + + if (ReturnCode == SCARD_S_SUCCESS) + { + // auto-allocate memory, if the user has requested it + if (*pcbAttrLen == SCARD_AUTOALLOCATE) + { + LPBYTE attr_out; + if ((attr_out = (LPBYTE)malloc(cbAttrLen)) == NULL) + { + return SCARD_E_NO_MEMORY; + } + *(LPBYTE *)pbAttr = attr_out; // Pass pointer to user + pbAttr = attr_out; // Use pointer ourselves + *pcbAttrLen = cbAttrLen; + } + + if (fpbAttrIsNULL) + { + // Do nothing - user wants length + } + else if (*pcbAttrLen < cbAttrLen) + { + ReturnCode = SCARD_E_INSUFFICIENT_BUFFER; + } + else if ((bytes - offset) < cbAttrLen) + { + LLOGLN(0, ("SCardGetAttrib: error, missing buffer")); + ReturnCode = SCARD_F_INTERNAL_ERROR; + } + else + { + memcpy(pbAttr, msg + offset, cbAttrLen); + } + *pcbAttrLen = cbAttrLen; + } + + return ReturnCode; } /*****************************************************************************/ diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.h b/sesman/chansrv/pcsc/xrdp_pcsc.h index d7653bf20..abe1db5a0 100644 --- a/sesman/chansrv/pcsc/xrdp_pcsc.h +++ b/sesman/chansrv/pcsc/xrdp_pcsc.h @@ -44,10 +44,9 @@ enum pcsc_message_code SCARD_STATUS = 0x0B, SCARD_GET_STATUS_CHANGE = 0x0C, SCARD_CANCEL = 0x0D, - SCARD_CANCEL_TRANSACTION = 0x0E, - SCARD_GET_ATTRIB = 0x0F, - SCARD_SET_ATTRIB = 0x10, - SCARD_IS_VALID_CONTEXT = 0x11 + SCARD_GET_ATTRIB = 0x0E, + SCARD_SET_ATTRIB = 0x0F, + SCARD_IS_VALID_CONTEXT = 0x10 }; /* @@ -282,7 +281,6 @@ enum pcsc_message_code // | xx+12 ATR // + xx+48 // -// // ***************************************************************************** // C A N C E L // ***************************************************************************** @@ -296,5 +294,23 @@ enum pcsc_message_code // 0 Header, code SCARD_CANCEL // 8 ReturnCode // +// ***************************************************************************** +// G E T A T T R I B +// ***************************************************************************** +// Request (See [MS-RDPESC] 2.2.2.21) :- +// Offset Value +// 0 Header, code SCARD_GET_ATTRIB +// 8 hCard +// 12 dwAttrId +// 16 fpbAttrIsNULL +// 20 cbAttrLen +// +// Response (See [MS-RDPESC] 2.2.3.12) :- +// Offset Value +// 0 Header, code SCARD_GET_ATTRIB +// 8 ReturnCode +// 12 cbAttrLen +// 16 pbAttr (if fpbAttrIsNULL is not set) +// #endif // XRDP_PCSC_H diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c index 68443040c..f51649f7e 100644 --- a/sesman/chansrv/smartcard.c +++ b/sesman/chansrv/smartcard.c @@ -241,6 +241,12 @@ scard_function_get_status_change_return(struct scard_client *client, struct stream *in_s, unsigned int len, unsigned int status); +static int +scard_function_get_attrib_return(struct scard_client *client, + struct sc_call_data *call_data, + struct stream *in_s, + unsigned int len, unsigned int status); + static int scard_function_common_context_return(struct scard_client *client, void *vcall_data, struct stream *in_s, @@ -2063,6 +2069,131 @@ scard_send_cancel(struct scard_client *client, } } +/*****************************************************************************/ +void +scard_send_get_attrib(struct scard_client *client, + get_attrib_cb_t callback, + intptr_t closure, + unsigned int app_hcard, + unsigned int dwAttrId, + unsigned int fpbAttrIsNULL, + unsigned int cbAttrLen) +{ + struct redir_scardhandle hCard; + + /* Get the RDP-level context */ + if (!scdata_lookup_card_mapping(client, app_hcard, &hCard)) + { + callback(client, closure, XSCARD_E_INVALID_HANDLE, 0, NULL); + } + else + { + struct stream *s; + + s = alloc_irp_and_ioctl(scdata_get_client_id(client), + (void *)callback, + closure, + scard_function_get_attrib_return, + 0, + SCARD_IOCTL_GETATTRIB, 64); + if (s == NULL) + { + LOG(LOG_LEVEL_ERROR, "system out of memory"); + callback(client, closure, XSCARD_E_NO_MEMORY, 0, NULL); + } + else + { + /* see [MS-RDPESC] 2.2.2.21 + * + * IDL:- + * + * typedef struct _REDIR_SCARDCONTEXT { + * [range(0,16)] unsigned long cbContext; + * [unique] [size_is(cbContext)] byte *pbContext; + * } REDIR_SCARDCONTEXT; + * + * typedef struct _REDIR_SCARDHANDLE { + * REDIR_SCARDCONTEXT Context; + * [range(0,16)] unsigned long cbHandle; + * [size_is(cbHandle)] byte *pbHandle; + * } REDIR_SCARDHANDLE; + * + * typedef struct _GetAttrib_Call { + * REDIR_SCARDHANDLE hCard; + * unsigned long dwAttrId; + * long fpbAttrIsNULL; + * unsigned long cbAttrLen; + * } GetAttrib_Call; + * + * Type summary:- + * hCard.Context.cbContext Unsigned 32-bit word + * hCard.Context.pbContext Embedded full pointer to conformant + * array of bytes + * hCard.cbHandle Unsigned 32-bit word + * hCard.pbHandle Embedded full pointer to conformant + * array of bytes + * dwAttrId 32-bit word + * fpAttrIsNULL 32-bit word + * cbAttrLen 32-bit word + * + * NDR:- + * + * Offset Decription + * 0 hCard.Context.cbContext + * 4 hCard.Context.pbContext Referent Identifier + * 8 hCard.cbHandle + * 12 hCard.pbHandle Referent Identifier + * 16 dwAttrId + * 20 fpAttrIsNULL + * 24 cbAttrLen + * 28 length of context in bytes + * 32 Context data (up to 16 bytes) + * ?? length of handle in bytes + * ?? Handle data (up to 16 bytes) + */ + int bytes; + unsigned int ref_id = REFERENT_ID_BASE; /* Next referent ID */ + + s_push_layer(s, mcs_hdr, 4); /* bytes, set later */ + out_uint32_le(s, 0x00000000); + + out_redir_scardhandle_part1(s, &hCard, &ref_id); + + // unsigned long dwAttrId; + out_uint32_le(s, dwAttrId); + // long fpbAttrIsNULL; + out_uint32_le(s, fpbAttrIsNULL); + // unsigned long cbAttrLen; + out_uint32_le(s, cbAttrLen); + + // Now add the data pointed to by the referents + out_redir_scardhandle_part2(s, &hCard); + + out_align_s(s, 8); // [MS-RPCE] 2.2.6.2 */ + + s_mark_end(s); + + s_pop_layer(s, mcs_hdr); + bytes = (int) (s->end - s->p); + bytes -= 8; + out_uint32_le(s, bytes); + + s_pop_layer(s, iso_hdr); + bytes = (int) (s->end - s->p); + bytes -= 28; + out_uint32_le(s, bytes); + + bytes = (int) (s->end - s->data); + + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", s->data, bytes); + + /* send to client */ + send_channel_data(g_rdpdr_chan_id, s->data, bytes); + free_stream(s); + } + } +} + /** * Sends one of several calls which take a context and return a uint32_t *****************************************************************************/ @@ -2574,6 +2705,10 @@ scard_function_long_return(struct scard_client *client, in_uint32_le(in_s, ReturnCode); } + else + { + ReturnCode = XSCARD_E_PROTO_MISMATCH; + } LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_long_return: result %d", ReturnCode); } @@ -2616,7 +2751,11 @@ scard_function_release_context_return(struct scard_client *client, if (status == 0) { - if (s_check_rem_and_log(in_s, 8 + 8 + 4, "[MS-RDPESC] Long_Return")) + if (!s_check_rem_and_log(in_s, 8 + 8 + 4, "[MS-RDPESC] Long_Return")) + { + ReturnCode = XSCARD_E_PROTO_MISMATCH; + } + else { /* Skip headers, setting mcs_hdr to point to the NDR * constructed type header so we can use in_align_s() */ @@ -2685,8 +2824,12 @@ scard_function_list_readers_return(struct scard_client *client, { unsigned int cBytes = 0; - if (s_check_rem_and_log(in_s, 8 + 8 + 4 + 4 + 4 + 4, - "[MS-RDPESC] ListReaders_return(1)")) + if (!s_check_rem_and_log(in_s, 8 + 8 + 4 + 4 + 4 + 4, + "[MS-RDPESC] ListReaders_return(1)")) + { + ReturnCode = XSCARD_E_PROTO_MISMATCH; + } + else { /* Skip headers, setting mcs_hdr to point to the NDR * constructed type header so we can use in_align_s() */ @@ -2698,8 +2841,12 @@ scard_function_list_readers_return(struct scard_client *client, in_uint8s(in_s, 4); // msz pointer Referent Identifier in_uint8s(in_s, 4); // copy of msz length // Get the length of the required UTF-8 string - if (s_check_rem_and_log(in_s, cBytes, - "[MS-RDPESC] ListReaders_return(2)")) + if (!s_check_rem_and_log(in_s, cBytes, + "[MS-RDPESC] ListReaders_return(2)")) + { + ReturnCode = XSCARD_E_PROTO_MISMATCH; + } + else { utf8len = in_utf16_le_fixed_as_utf8_length(in_s, cBytes / 2); } @@ -2811,6 +2958,7 @@ scard_function_connect_return(struct scard_client *client, 4, // dwActiveProtocol "[MS-RDPESC] Connect_Return(1)")) { + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } /* Skip headers, setting mcs_hdr to point to the NDR @@ -2922,6 +3070,10 @@ scard_function_reconnect_return(struct scard_client *client, { if (!s_check_rem_and_log(in_s, 8 + 8 + 4 + 4, "[MS-RDPESC] Reconnect_Return")) + { + ReturnCode = XSCARD_E_PROTO_MISMATCH; + } + else { /* Skip headers, setting mcs_hdr to point to the NDR * constructed type header so we can use in_align_s() */ @@ -3007,7 +3159,7 @@ scard_function_transmit_return(struct scard_client *client, if (!s_check_rem_and_log(in_s, 8 + 8 + 4 + 4 + 4 + 4, "[MS-RDPESC] Transmit_Return")) { - ReturnCode = XSCARD_F_INTERNAL_ERROR; + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } /* Skip headers, setting mcs_hdr to point to the NDR @@ -3025,7 +3177,7 @@ scard_function_transmit_return(struct scard_client *client, if (!s_check_rem_and_log(in_s, 4 + 4 + 4, "[MS-RDPESC] Transmit_Return(2)")) { - ReturnCode = XSCARD_F_INTERNAL_ERROR; + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } in_uint32_le(in_s, ioRecvPci.dwProtocol); @@ -3040,7 +3192,7 @@ scard_function_transmit_return(struct scard_client *client, if (!s_check_rem_and_log(in_s, 4 + cbRecvLength, "[MS-RDPESC] Transmit_Return(2)")) { - ReturnCode = XSCARD_F_INTERNAL_ERROR; + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } in_uint8s(in_s, 4); @@ -3052,7 +3204,7 @@ scard_function_transmit_return(struct scard_client *client, if (!s_check_rem_and_log(in_s, 4 + ioRecvPci.cbExtraBytes, "[MS-RDPESC] Transmit_Return(3)")) { - ReturnCode = XSCARD_F_INTERNAL_ERROR; + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } in_uint8s(in_s, 4); @@ -3116,7 +3268,7 @@ scard_function_control_return(struct scard_client *client, if (!s_check_rem_and_log(in_s, 8 + 8 + 4 + 4 + 4, "[MS-RDPESC] Control_Return")) { - ReturnCode = XSCARD_F_INTERNAL_ERROR; + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } /* Skip headers, setting mcs_hdr to point to the NDR @@ -3138,7 +3290,7 @@ scard_function_control_return(struct scard_client *client, if (!s_check_rem_and_log(in_s, 4 + cbOutBufferSize, "[MS-RDPESC] Control_Return(2)")) { - ReturnCode = XSCARD_F_INTERNAL_ERROR; + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } in_uint8s(in_s, 4); @@ -3210,6 +3362,7 @@ scard_function_status_return(struct scard_client *client, if (!s_check_rem_and_log(in_s, 8 + 8 + 4 + 4 + 4 + 4 + 4 + 32 + 4, "[MS-RDPESC] Status_Return(1)")) { + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } /* Skip headers, setting mcs_hdr to point to the NDR @@ -3234,6 +3387,7 @@ scard_function_status_return(struct scard_client *client, if (!s_check_rem_and_log(in_s, 4 + cBytes, "[MS-RDPESC] Status_Return(2)")) { + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } in_uint8s(in_s, 4); // cBytes copy @@ -3335,6 +3489,7 @@ scard_function_get_status_change_return(struct scard_client *client, if (!s_check_rem_and_log(in_s, 8 + 8 + 4 + 4 + 4, "[MS-RDPESC] GetStatusChange_Return(1)")) { + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } @@ -3352,6 +3507,7 @@ scard_function_get_status_change_return(struct scard_client *client, if (!s_check_rem_and_log(in_s, 48 * cReaders, "[MS-RDPESC] GetStatusChange_Return(2)")) { + ReturnCode = XSCARD_E_PROTO_MISMATCH; goto done; } rgReaderStates = (struct reader_state_return *) @@ -3380,6 +3536,83 @@ scard_function_get_status_change_return(struct scard_client *client, } +/*****************************************************************************/ +static int +scard_function_get_attrib_return(struct scard_client *client, + struct sc_call_data *call_data, + struct stream *in_s, + unsigned int len, unsigned int status) +{ + /* see [MS-RDPESC] 2.2.3.12 + * + * IDL:- + * + * typedef struct _GetAttrib_Return { + * long ReturnCode; + * [range(0,65536)] unsigned long cbAttrLen; + * [unique] [size_is(cbAttrLen)] byte *pbAttr; + * } GetAttrib_Return; + * + * NDR:- + * + * Offset Decription + * 0 ReturnCode + * 4 cbAttrLen + * 8 Referent Identifier for pbAttr (could be NULL) + * if (pbAttr != NULL) + * | 12 copy of cbAttrLen + * | 16 pbAttr + */ + + unsigned int ReturnCode = HRESULT_TO_SCARD_STATUS(status); + + unsigned int cbAttrLen = 0; + unsigned int attr_ref; + const char *pbAttr = NULL; + + get_attrib_cb_t user_callback = (get_attrib_cb_t)call_data->user_callback; + + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_get_attrib_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); + + if (status != 0) + { + goto done; + } + + if (!s_check_rem_and_log(in_s, 8 + 8 + 4 + 4, + "[MS-RDPESC] GetAttrib_Return(1)")) + { + ReturnCode = XSCARD_E_PROTO_MISMATCH; + goto done; + } + + /* Skip headers, setting mcs_hdr to point to the NDR + * constructed type header so we can use in_align_s() */ + in_uint8s(in_s, 8); /* [MS-RPCE] 2.2.6.1 */ + s_push_layer(in_s, mcs_hdr, 8); /* [MS-RPCE] 2.2.6.2 */ + + in_uint32_le(in_s, ReturnCode); + in_uint32_le(in_s, cbAttrLen); + in_uint32_le(in_s, attr_ref); + if (cbAttrLen > 0 && attr_ref != 0) + { + if (!s_check_rem_and_log(in_s, 4 + cbAttrLen, + "[MS-RDPESC] GetAttrib_Return(2)")) + { + ReturnCode = XSCARD_E_PROTO_MISMATCH; + goto done; + } + in_uint8s(in_s, 4); + in_uint8p(in_s, pbAttr, cbAttrLen); + } + +done: + return user_callback(client, call_data->closure, + ReturnCode, cbAttrLen, pbAttr); +} + + /*****************************************************************************/ /* returns error */ static int @@ -3413,7 +3646,11 @@ scard_function_common_context_return(struct scard_client *client, if (status == 0) { - if (s_check_rem_and_log(in_s, 8 + 8 + 4, "[MS-RDPESC] Long_Return")) + if (!s_check_rem_and_log(in_s, 8 + 8 + 4, "[MS-RDPESC] Long_Return")) + { + ReturnCode = XSCARD_E_PROTO_MISMATCH; + } + else { /* Skip headers, setting mcs_hdr to point to the NDR * constructed type header so we can use in_align_s() */ diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h index dc32ed676..fbc3c52da 100644 --- a/sesman/chansrv/smartcard.h +++ b/sesman/chansrv/smartcard.h @@ -131,6 +131,12 @@ typedef int (*get_status_change_cb_t)( unsigned int cReaders, struct reader_state_return *rgReaderStates); +typedef int (*get_attrib_cb_t)(struct scard_client *client, + intptr_t closure, + unsigned int ReturnCode, + unsigned int cbAttrLen, + const char *pbAttr); + /*****************************************************************************/ /* Structures used to hold call state while waiting for the * client to respond */ @@ -459,6 +465,24 @@ scard_send_cancel(struct scard_client *client, intptr_t closure, unsigned int app_context); +/** + * Sends a get_attrib to the RDP client ([MS-RDPESC] 2.2.2.21) + * + * @param client client + * @param callback How to be notified of the result + * @param closure Additional state info for the caller + * @param app_hcard call parameter + * @param app_hcard call parameter + */ +void +scard_send_get_attrib(struct scard_client *client, + get_attrib_cb_t callback, + intptr_t closure, + unsigned int app_hcard, + unsigned int dwAttrId, + unsigned int fpbAttrIsNULL, + unsigned int cbAttrLen); + /** * Sends a is valid context call to the RDP client * @@ -473,10 +497,6 @@ scard_send_common_context_long_return( struct scard_client *client, struct common_context_long_return_call *call_data); -#if 0 -int scard_send_get_attrib(void *user_data, char *card, int card_bytes, - READER_STATE *rs); -#endif /* * Notes: * SCardTransmit - partially done diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c index 4299bca4a..05b1b7b5e 100644 --- a/sesman/chansrv/smartcard_pcsc.c +++ b/sesman/chansrv/smartcard_pcsc.c @@ -1249,6 +1249,81 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s) return rv; } +/*****************************************************************************/ +static int +send_get_attrib_return(struct scard_client *client, + intptr_t closure, + unsigned int ReturnCode, + unsigned int cbAttrLen, + const char *pbAttr) +{ + struct pcsc_uds_client *uds_client = GET_PCSC_CLIENT(client); + struct trans *con = uds_client->con; + unsigned int stream_size = 64; + if (cbAttrLen > 0 && pbAttr != NULL) + { + stream_size += cbAttrLen; + } + struct stream *out_s = trans_get_out_s(con, stream_size); + if (out_s == NULL) + { + return 1; + } + + s_push_layer(out_s, iso_hdr, 8); + out_uint32_le(out_s, ReturnCode); /* XSCARD_S_SUCCESS status */ + out_uint32_le(out_s, cbAttrLen); /* cReaders */ + if (cbAttrLen > 0 && pbAttr != NULL) + { + out_uint8a(out_s, pbAttr, cbAttrLen); + } + + s_mark_end(out_s); + unsigned int bytes = (unsigned int) (out_s->end - out_s->data); + s_pop_layer(out_s, iso_hdr); + out_uint32_le(out_s, bytes - 8); + out_uint32_le(out_s, SCARD_GET_STATUS_CHANGE); + return trans_force_write(con); +} + +/*****************************************************************************/ +int +scard_process_get_attrib(struct trans *con, struct stream *in_s) +{ + int rv = 0; + struct pcsc_uds_client *uds_client; + struct scard_client *scard_client; + + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_attrib:"); + uds_client = (struct pcsc_uds_client *) (con->callback_data); + scard_client = uds_client->scard_client; + + if (!s_check_rem_and_log(in_s, 4 + 4 + 4 + 4, "Reading SCARD_GET_ATTRIB")) + { + send_get_attrib_return(scard_client, 0, + XSCARD_F_INTERNAL_ERROR, 0, NULL); + rv = 1; + } + else + { + unsigned int app_hcard; + unsigned int dwAttrId; + unsigned int fpAttrIsNULL; + unsigned int cbAttrLen; + + in_uint32_le(in_s, app_hcard); + in_uint32_le(in_s, dwAttrId); + in_uint32_le(in_s, fpAttrIsNULL); + in_uint32_le(in_s, cbAttrLen); + + scard_send_get_attrib(scard_client, send_get_attrib_return, 0, + app_hcard, dwAttrId, fpAttrIsNULL, cbAttrLen); + + } + return rv; +} + + /*****************************************************************************/ static int send_cancel_return(struct scard_client *client, @@ -1288,16 +1363,6 @@ scard_process_cancel(struct trans *con, struct stream *in_s) return rv; } -/*****************************************************************************/ -/* returns error */ -int -scard_function_get_attrib_return(void *user_data, - struct stream *in_s, - int len, int status) -{ - return 0; -} - #if 0 #define MS_SCARD_UNKNOWN 0 #define MS_SCARD_ABSENT 1 @@ -1400,12 +1465,9 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command) rv = scard_process_cancel(con, in_s); break; - case SCARD_CANCEL_TRANSACTION: - LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_CANCEL_TRANSACTION"); - break; - case SCARD_GET_ATTRIB: LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_GET_ATTRIB"); + rv = scard_process_get_attrib(con, in_s); break; case SCARD_SET_ATTRIB: diff --git a/sesman/chansrv/smartcard_pcsc.h b/sesman/chansrv/smartcard_pcsc.h index a2020829f..95926a67b 100644 --- a/sesman/chansrv/smartcard_pcsc.h +++ b/sesman/chansrv/smartcard_pcsc.h @@ -29,8 +29,4 @@ int scard_pcsc_check_wait_objs(void); int scard_pcsc_init(void); int scard_pcsc_deinit(void); -int scard_function_get_attrib_return(void *user_data, - struct stream *in_s, - int len, int status); - #endif /* end #ifndef _SMARTCARD_PCSC_H */