From d926a5becd9814f55025a58fb4bb9263c6a24dbb Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Mon, 16 Sep 2013 00:16:21 -0700 Subject: [PATCH] chansrv: work on smartcard --- sesman/chansrv/smartcard.c | 194 +++++++------ sesman/chansrv/smartcard.h | 2 +- sesman/chansrv/smartcard_pcsc.c | 464 ++++++++++++-------------------- sesman/chansrv/smartcard_pcsc.h | 11 +- 4 files changed, 275 insertions(+), 396 deletions(-) diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c index f694484f..b97ffca6 100644 --- a/sesman/chansrv/smartcard.c +++ b/sesman/chansrv/smartcard.c @@ -155,63 +155,64 @@ extern int g_rdpdr_chan_id; /* in chansrv.c */ /****************************************************************************** ** static functions local to this file ** ******************************************************************************/ -static struct stream *scard_make_new_ioctl(IRP *irp, tui32 ioctl); -static int scard_add_new_device(tui32 device_id); -static int scard_get_free_slot(void); -static void scard_release_resources(void); -static void scard_send_EstablishContext(IRP* irp, int scope); -static void scard_send_ReleaseContext(IRP* irp, tui32 context); -static void scard_send_ListReaders(IRP* irp, tui32 context, int wide); - -static void scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, - tui32 timeout, tui32 num_readers, - READER_STATE* rsa); - -static void scard_send_Connect(IRP* irp, tui32 context, int wide, - READER_STATE* rs); - -static void scard_send_BeginTransaction(IRP* irp, tui32 sc_handle); -static void scard_send_EndTransaction(IRP* irp, tui32 sc_handle); -static void scard_send_Status(IRP* irp, int wide, tui32 sc_handle); -static void scard_send_Disconnect(IRP* irp, tui32 context, tui32 sc_handle); +static struct stream * APP_CC scard_make_new_ioctl(IRP *irp, tui32 ioctl); +static int APP_CC scard_add_new_device(tui32 device_id); +static int APP_CC scard_get_free_slot(void); +static void APP_CC scard_release_resources(void); +static void APP_CC scard_send_EstablishContext(IRP* irp, int scope); +static void APP_CC scard_send_ReleaseContext(IRP* irp, tui32 context); +static void APP_CC scard_send_ListReaders(IRP* irp, tui32 context, int wide); + +static void APP_CC scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, + tui32 timeout, tui32 num_readers, + READER_STATE* rsa); + +static void APP_CC scard_send_Connect(IRP* irp, tui32 context, int wide, + READER_STATE* rs); + +static void APP_CC scard_send_BeginTransaction(IRP* irp, tui32 sc_handle); +static void APP_CC scard_send_EndTransaction(IRP* irp, tui32 sc_handle); +static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle); +static void APP_CC scard_send_Disconnect(IRP* irp, tui32 context, + tui32 sc_handle); /****************************************************************************** ** local callbacks into this module ** ******************************************************************************/ -static void scard_handle_EstablishContext_Return(struct stream *s, IRP *irp, +static void APP_CC scard_handle_EstablishContext_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); -static void scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp, +static void APP_CC scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); -static void scard_handle_ListReaders_Return(struct stream *s, IRP *irp, +static void APP_CC scard_handle_ListReaders_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); -static void scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp, +static void APP_CC scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); -static void scard_handle_Connect_Return(struct stream *s, IRP *irp, +static void APP_CC scard_handle_Connect_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); -static void scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp, +static void APP_CC scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); -static void scard_handle_EndTransaction_Return(struct stream *s, IRP *irp, +static void APP_CC scard_handle_EndTransaction_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); -static void scard_handle_Status_Return(struct stream *s, IRP *irp, +static void APP_CC scard_handle_Status_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); -static void scard_handle_Disconnect_Return(struct stream *s, IRP *irp, +static void APP_CC scard_handle_Disconnect_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); @@ -310,8 +311,8 @@ scard_send_irp_establish_context(struct trans *con, int scope) /** * Release a previously established Smart Card context *****************************************************************************/ -int -APP_CC scard_send_release_context(struct trans *con, tui32 context) +int APP_CC +scard_send_irp_release_context(struct trans *con, tui32 context) { IRP *irp; @@ -432,8 +433,8 @@ scard_send_irp_connect(struct trans *con, tui32 context, int wide, * * @param con connection to client *****************************************************************************/ -int -APP_CC scard_send_begin_transaction(struct trans *con, tui32 sc_handle) +int APP_CC +scard_send_begin_transaction(struct trans *con, tui32 sc_handle) { IRP *irp; @@ -463,8 +464,8 @@ APP_CC scard_send_begin_transaction(struct trans *con, tui32 sc_handle) * @param con connection to client * @param sc_handle handle to smartcard *****************************************************************************/ -int -APP_CC scard_send_end_transaction(struct trans *con, tui32 sc_handle) +int APP_CC +scard_send_end_transaction(struct trans *con, tui32 sc_handle) { IRP *irp; @@ -493,8 +494,8 @@ APP_CC scard_send_end_transaction(struct trans *con, tui32 sc_handle) * @param con connection to client * @param wide TRUE if unicode string *****************************************************************************/ -int -APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle) +int APP_CC +scard_send_status(struct trans *con, int wide, tui32 sc_handle) { IRP *irp; @@ -523,8 +524,8 @@ APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle) * @param con connection to client * @param sc_handle handle to smartcard *****************************************************************************/ -int -APP_CC scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle) +int APP_CC +scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle) { IRP *irp; @@ -718,7 +719,7 @@ scard_send_EstablishContext(IRP *irp, int scope) /** * Release a previously established Smart Card context *****************************************************************************/ -static void +static void APP_CC scard_send_ReleaseContext(IRP* irp, tui32 context) { /* see [MS-RDPESC] 3.1.4.2 */ @@ -856,6 +857,21 @@ scard_send_ListReaders(IRP *irp, tui32 context, int wide) */ } +/*****************************************************************************/ +static int +align_s(struct stream *s, int bytes) +{ + int i32; + + i32 = (int) (s->p - s->data); + while ((i32 % bytes) != 0) + { + out_uint8s(s, 1); + i32 = (int) (s->p - s->data); + } + return 0; +} + /** * Get change in status * @@ -865,7 +881,7 @@ scard_send_ListReaders(IRP *irp, tui32 context, int wide) * @param num_readers number of entries in rsa * @param rsa array of READER_STATEs *****************************************************************************/ -static void +static void APP_CC scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout, tui32 num_readers, READER_STATE* rsa) { @@ -932,6 +948,7 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout, { xstream_wr_u16_le(s, w_reader_name[index]); } + align_s(s, 4); } } else @@ -948,6 +965,7 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout, { xstream_wr_u8(s, w_reader_name[index]); } + align_s(s, 4); } } @@ -969,8 +987,8 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout, * @param wide TRUE if unicode string * @param rs reader state *****************************************************************************/ -static void scard_send_Connect(IRP* irp, tui32 context, int wide, - READER_STATE* rs) +static void APP_CC +scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs) { /* see [MS-RDPESC] 2.2.2.13 for ASCII */ /* see [MS-RDPESC] 2.2.2.14 for Wide char */ @@ -1021,12 +1039,16 @@ static void scard_send_Connect(IRP* irp, tui32 context, int wide, if (wide) { for (index = 0; index < num_chars; index++) + { xstream_wr_u16_le(s, w_reader_name[index]); + } } else { for (index = 0; index < num_chars; index++) + { xstream_wr_u8(s, w_reader_name[index]); + } } /* insert context */ @@ -1050,13 +1072,13 @@ static void scard_send_Connect(IRP* irp, tui32 context, int wide, * * @param con connection to client *****************************************************************************/ -static void -scard_send_BeginTransaction(IRP* irp, tui32 sc_handle) +static void APP_CC +scard_send_BeginTransaction(IRP *irp, tui32 sc_handle) { /* see [MS-RDPESC] 4.9 */ - SMARTCARD* sc; - struct stream* s; + SMARTCARD *sc; + struct stream *s; int bytes; if ((sc = smartcards[irp->scard_index]) == NULL) @@ -1104,8 +1126,8 @@ scard_send_BeginTransaction(IRP* irp, tui32 sc_handle) * @param con connection to client * @param sc_handle handle to smartcard *****************************************************************************/ -static void -scard_send_EndTransaction(IRP* irp, tui32 sc_handle) +static void APP_CC +scard_send_EndTransaction(IRP *irp, tui32 sc_handle) { /* see [MS-RDPESC] 3.1.4.32 */ @@ -1161,13 +1183,13 @@ scard_send_EndTransaction(IRP* irp, tui32 sc_handle) * @param con connection to client * @param wide TRUE if unicode string *****************************************************************************/ -static void -scard_send_Status(IRP* irp, int wide, tui32 sc_handle) +static void APP_CC +scard_send_Status(IRP *irp, int wide, tui32 sc_handle) { /* see [MS-RDPESC] 2.2.2.18 */ - SMARTCARD* sc; - struct stream* s; + SMARTCARD *sc; + struct stream *s; int bytes; tui32 ioctl; @@ -1227,8 +1249,8 @@ scard_send_Status(IRP* irp, int wide, tui32 sc_handle) * @param con connection to client * @param sc_handle handle to smartcard *****************************************************************************/ -static void -scard_send_Disconnect(IRP* irp, tui32 context, tui32 sc_handle) +static void APP_CC +scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle) { /* see [MS-RDPESC] 3.1.4.30 */ @@ -1296,57 +1318,27 @@ scard_handle_EstablishContext_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus) { - tui32 context; - tui32 len; - int tmp; - SMARTCARD *sc; + tui32 len; + struct trans *con; log_debug("entered"); - /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { log_error("DeviceId/CompletionId do not match those in IRP"); return; } - if (IoStatus != 0) { log_error("failed to establish context - device not usable"); /* LK_TODO delete irp and smartcard entry */ return; } - - sc = smartcards[irp->scard_index]; - /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - - /* LK_TODO */ - g_hexdump(s->p, len); - - xstream_rd_u32_le(s, tmp); /* should be len 8, LE, V1 */ - xstream_rd_u32_le(s, tmp); /* marshalling flag */ - xstream_rd_u32_le(s, tmp); /* ?? */ - xstream_rd_u32_le(s, tmp); /* ?? */ - xstream_rd_u32_le(s, tmp); /* ?? */ - xstream_rd_u32_le(s, tmp); /* ?? */ - xstream_rd_u32_le(s, tmp); /* ?? */ - xstream_rd_u32_le(s, len); /* len of context in bytes, always 4 */ - xstream_rd_u32_le(s, context); - - if (LOG_LEVEL == LOG_DEBUG) - log_debug("dumping: )", context); - - // LK_TODO delete this - //irp->callback = scard_handle_ListReaders_Return; - - scard_function_establish_context_return((struct trans *) (irp->user_data), - context); - + con = (struct trans *) (irp->user_data); + scard_function_establish_context_return(con, s, len); devredir_irp_delete(irp); - - /* LK_TODO need to delete IRP */ log_debug("leaving"); } @@ -1359,26 +1351,26 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); - /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { log_error("DeviceId/CompletionId do not match those in IRP"); return; } - if (IoStatus != 0) { log_error("ReleaseContext failed, device not usable"); /* LK_TODO delete irp and smartcard entry */ return; } - /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_release_context_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -1391,28 +1383,26 @@ scard_handle_ListReaders_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); - /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { log_error("DeviceId/CompletionId do not match those in IRP"); return; } - if (IoStatus != 0) { log_error("failed to list readers - device not usable"); /* LK_TODO delete irp and smartcard entry */ return; } - /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - - scard_function_list_readers_return((struct trans *) irp->user_data, - s, len); + con = (struct trans *) (irp->user_data); + scard_function_list_readers_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -1425,26 +1415,26 @@ scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); - /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { log_error("DeviceId/CompletionId do not match those in IRP"); return; } - if (IoStatus != 0) { log_error("failed to get status change - device not usable"); /* LK_TODO delete irp and smartcard entry */ return; } - /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_get_status_change_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h index 1927b2e0..44d4fcbc 100644 --- a/sesman/chansrv/smartcard.h +++ b/sesman/chansrv/smartcard.h @@ -74,7 +74,7 @@ int APP_CC scard_check_wait_objs(void); int APP_CC scard_init(void); int APP_CC scard_deinit(void); int APP_CC scard_send_irp_establish_context(struct trans *con, int scope); -int APP_CC scard_send_release_context(struct trans *con, tui32 context); +int APP_CC scard_send_irp_release_context(struct trans *con, tui32 context); int APP_CC scard_send_irp_list_readers(struct trans *con, tui32 context, int wide); int APP_CC scard_send_irp_get_status_change(struct trans *con, tui32 context, diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c index 2f11c517..ded872cb 100644 --- a/sesman/chansrv/smartcard_pcsc.c +++ b/sesman/chansrv/smartcard_pcsc.c @@ -50,74 +50,13 @@ } \ while (0) -/* using pcsc-lite-1.7.4 */ - -struct establish_struct -{ - tui32 dwScope; - tui32 hContext; - tui32 rv; -}; - -struct release_struct -{ - tui32 hContext; - tui32 rv; -}; - -/** Major version of the current message protocol */ -#define PROTOCOL_VERSION_MAJOR 4 -/** Minor version of the current message protocol */ -#define PROTOCOL_VERSION_MINOR 2 - -struct version_struct -{ - tsi32 major; /**< IPC major \ref PROTOCOL_VERSION_MAJOR */ - tsi32 minor; /**< IPC minor \ref PROTOCOL_VERSION_MINOR */ - tui32 rv; -}; - -#define SCARD_S_SUCCESS 0x00000000 /**< No error was encountered. */ -#define SCARD_F_INTERNAL_ERROR 0x80100001 /**< An internal consistency - * check failed. */ -#define SCARD_E_TIMEOUT 0x8010000A /**< The user-specified timeout - * value has expired. */ - -#define MAX_READERNAME 100 -#define MAX_ATR_SIZE 33 - -struct pubReaderStatesList -{ - char readerName[MAX_READERNAME]; /**< reader name */ - tui32 eventCounter; /**< number of card events */ - tui32 readerState; /**< SCARD_* bit field */ - tsi32 readerSharing; /**< PCSCLITE_SHARING_* sharing status */ - tui8 cardAtr[MAX_ATR_SIZE]; /**< ATR */ - tui32 cardAtrLength; /**< ATR length */ - tui32 cardProtocol; /**< SCARD_PROTOCOL_* value */ -}; - -#define PCSCLITE_MAX_READERS_CONTEXTS 16 - -static int g_num_readers = 0; -/* pcsc list */ -static struct pubReaderStatesList - g_pcsc_reader_states[PCSCLITE_MAX_READERS_CONTEXTS]; -/* rdp list */ -static READER_STATE g_xrdp_reader_states[PCSCLITE_MAX_READERS_CONTEXTS]; - -struct wait_reader_state_change -{ - tui32 timeOut; /**< timeout in ms */ - tui32 rv; -}; - #define XRDP_PCSC_STATE_NONE 0 -#define XRDP_PCSC_STATE_GOT_RSC (1 << 0) /* read state change */ -#define XRDP_PCSC_STATE_GOT_EC (1 << 1) /* establish context */ -#define XRDP_PCSC_STATE_GOT_LR (1 << 2) /* list readers */ -#define XRDP_PCSC_STATE_GOT_RC (1 << 3) /* release context */ +#define XRDP_PCSC_STATE_GOT_EC (1 << 0) /* establish context */ +#define XRDP_PCSC_STATE_GOT_LR (1 << 1) /* list readers */ +#define XRDP_PCSC_STATE_GOT_RC (1 << 2) /* release context */ +#define XRDP_PCSC_STATE_GOT_GSC (1 << 3) /* get status change */ +/* TODO: put this in con */ static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE; extern int g_display_num; /* in chansrv.c */ @@ -135,7 +74,6 @@ static struct trans *g_lis = 0; static struct trans *g_con = 0; /* todo, remove this */ static char g_pcsclite_ipc_dir[256] = ""; static int g_pub_file_fd = 0; -static char g_pub_file_name[256] = ""; /*****************************************************************************/ int APP_CC @@ -174,7 +112,7 @@ scard_pcsc_check_wait_objs(void) int APP_CC scard_process_establish_context(struct trans *con, struct stream *in_s) { - struct establish_struct in_es; + int dwScope; LLOGLN(0, ("scard_process_establish_context:")); if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) @@ -183,112 +121,122 @@ scard_process_establish_context(struct trans *con, struct stream *in_s) return 1; } g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_EC; - in_uint8a(in_s, &in_es, sizeof(in_es)); - LLOGLN(0, ("scard_process_establish_context: dwScope 0x%8.8x", - in_es.dwScope)); - scard_send_irp_establish_context(con, in_es.dwScope); + in_uint32_le(in_s, dwScope); + LLOGLN(0, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope)); + scard_send_irp_establish_context(con, dwScope); return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_establish_context_return(struct trans *con, tui32 context) +scard_function_establish_context_return(struct trans *con, + struct stream *in_s, + int len) { - struct establish_struct out_es; + int bytes; + tui32 context; + tui32 context_len; struct stream *out_s; - LLOGLN(0, ("scard_function_establish_context_return: context %d", - context)); + LLOGLN(0, ("scard_function_establish_context_return:")); if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0) { LLOGLN(0, ("scard_function_establish_context_return: opps")); return 1; } g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC; - out_es.dwScope = 0; - out_es.hContext = context; - out_es.rv = SCARD_S_SUCCESS; + in_uint8s(in_s, 28); + in_uint32_le(in_s, context_len); + if (context_len != 4) + { + LLOGLN(0, ("scard_function_establish_context_return: opps")); + return 1; + } + in_uint32_le(in_s, context); + LLOGLN(0, ("scard_function_establish_context_return: context 0x%8.8x", context)); out_s = trans_get_out_s(con, 8192); - out_uint8a(out_s, &out_es, sizeof(out_es)); + s_push_layer(out_s, iso_hdr, 8); + out_uint32_le(out_s, context); + out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ s_mark_end(out_s); + bytes = (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, 0x01); /* SCARD_ESTABLISH_CONTEXT 0x01 */ return trans_force_write(con); } /*****************************************************************************/ /* returns error */ int APP_CC -scard_process_release_context(struct stream *in_s) +scard_process_release_context(struct trans *con, struct stream *in_s) { - struct release_struct in_rs; - struct release_struct out_rs; - struct stream *out_s; + int hContext; LLOGLN(0, ("scard_process_release_context:")); - in_uint8a(in_s, &in_rs, sizeof(in_rs)); - LLOGLN(0, ("scard_process_release_context: hContext %d", in_rs.hContext)); - - /* TODO: use XRDP_PCSC_STATE_GOT_RC */ - - out_rs.hContext = in_rs.hContext; - out_rs.rv = SCARD_S_SUCCESS; - out_s = trans_get_out_s(g_con, 8192); - out_uint8a(out_s, &out_rs, sizeof(out_rs)); - s_mark_end(out_s); - return trans_force_write(g_con); + if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) + { + LLOGLN(0, ("scard_process_establish_context: opps")); + return 1; + } + g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RC; + in_uint32_le(in_s, hContext); + LLOGLN(0, ("scard_process_release_context: hContext 0x%8.8x", hContext)); + scard_send_irp_release_context(con, hContext); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -scard_process_version(struct trans *con, struct stream *in_s) +scard_function_release_context_return(struct trans *con, + struct stream *in_s, + int len) { + int bytes; struct stream *out_s; - struct version_struct in_version; - struct version_struct out_version; - - LLOGLN(0, ("scard_process_version:")); - in_uint8a(in_s, &in_version, sizeof(in_version)); - /* todo: check if version is compatible */ - LLOGLN(0, ("scard_process_version: version major %d minor %d", - in_version.major, in_version.minor)); + tui32 context; + + LLOGLN(0, ("scard_function_release_context_return:")); + if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0) + { + LLOGLN(0, ("scard_function_release_context_return: opps")); + return 1; + } + g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_RC; out_s = trans_get_out_s(con, 8192); - out_version.major = PROTOCOL_VERSION_MAJOR; - out_version.minor = PROTOCOL_VERSION_MINOR; - out_version.rv = SCARD_S_SUCCESS; - out_uint8a(out_s, &out_version, sizeof(out_version)); + s_push_layer(out_s, iso_hdr, 8); + out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ s_mark_end(out_s); + bytes = (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, 0x02); /* SCARD_RELEASE_CONTEXT 0x02 */ return trans_force_write(con); } /*****************************************************************************/ /* returns error */ int APP_CC -scard_process_get_readers_state(struct trans *con, struct stream *in_s) +scard_process_list_readers(struct trans *con, struct stream *in_s) { - //struct stream *out_s; - - LLOGLN(0, ("scard_process_get_readers_state:")); - - //out_s = trans_get_out_s(con, 8192); - //out_uint8a(out_s, g_pcsc_reader_states, sizeof(g_pcsc_reader_states)); - //s_mark_end(out_s); - //return trans_force_write(con); + int hContext; + LLOGLN(0, ("scard_process_list_readers:")); if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) { - LLOGLN(0, ("scard_process_get_readers_state: opps")); + LLOGLN(0, ("scard_process_list_readers: opps")); return 1; } g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR; - - scard_send_irp_list_readers(con, JAY_TODO_CONTEXT, JAY_TODO_WIDE); - + in_uint32_le(in_s, hContext); + LLOGLN(0, ("scard_process_list_readers: dwScope 0x%8.8x", hContext)); + scard_send_irp_list_readers(con, hContext, 1); return 0; } /*****************************************************************************/ -/* returns error */ int APP_CC scard_function_list_readers_return(struct trans *con, struct stream *in_s, @@ -298,23 +246,28 @@ scard_function_list_readers_return(struct trans *con, int chr; int readers; int rn_index; - char reader_name[100]; + int index; + int bytes; + twchar reader_name[100]; + char lreader_name[16][100]; + LLOGLN(10, ("scard_function_list_readers_return:")); g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0) { - LLOGLN(0, ("scard_function_list_readers_return: opps")); + LLOGLN(10, ("scard_function_list_readers_return: opps")); return 1; } g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR; + g_memset(reader_name, 0, sizeof(reader_name)); + g_memset(lreader_name, 0, sizeof(lreader_name)); in_uint8s(in_s, 28); len -= 28; in_uint32_le(in_s, len); g_writeln("len %d", len); rn_index = 0; - readers = 1; + readers = 0; while (len > 0) { in_uint16_le(in_s, chr); @@ -323,7 +276,9 @@ scard_function_list_readers_return(struct trans *con, { if (reader_name[0] != 0) { - g_writeln("1 %s", reader_name); + g_wcstombs(lreader_name[readers], reader_name, 99); + g_writeln("1 %s", lreader_name[readers]); + g_memset(reader_name, 0, sizeof(reader_name)); readers++; } reader_name[0] = 0; @@ -339,181 +294,136 @@ scard_function_list_readers_return(struct trans *con, { if (reader_name[0] != 0) { - g_writeln("2 %s", reader_name); + g_wcstombs(lreader_name[readers], reader_name, 99); + g_writeln("2 %s", lreader_name[readers]); + g_memset(reader_name, 0, sizeof(reader_name)); readers++; } } -#if 0 - g_strcpy(g_reader_states[0].readerName, "ACS AET65 00 00"); - g_reader_states[0].readerState = 0x14; - g_reader_states[0].cardProtocol = 3; - - g_reader_states[0].cardAtrLength = 10; - g_reader_states[0].cardAtr[0] = 0x3B; - g_reader_states[0].cardAtr[1] = 0x95; - g_reader_states[0].cardAtr[2] = 0x95; - g_reader_states[0].cardAtr[3] = 0x40; - g_reader_states[0].cardAtr[4] = 0xFF; - g_reader_states[0].cardAtr[5] = 0xD0; - g_reader_states[0].cardAtr[6] = 0x00; - g_reader_states[0].cardAtr[7] = 0x54; - g_reader_states[0].cardAtr[8] = 0x01; - g_reader_states[0].cardAtr[9] = 0x32; - - //g_reader_states[0].eventCounter++; out_s = trans_get_out_s(con, 8192); - out_uint8a(out_s, g_reader_states, sizeof(g_reader_states)); - s_mark_end(out_s); - return trans_force_write(con); -#endif - return 0; -} - -/*****************************************************************************/ -/* callback from chansrv when timeout occurs */ -void DEFAULT_CC -scard_read_state_chage_timeout(void* data) -{ - struct trans *con; - struct stream *out_s; - struct wait_reader_state_change out_rsc; - - LLOGLN(0, ("scard_read_state_chage_timeout:")); - con = (struct trans *) data; - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RSC) + s_push_layer(out_s, iso_hdr, 8); + out_uint32_le(out_s, readers); + for (index = 0; index < readers; index++) { - out_s = trans_get_out_s(con, 8192); - out_rsc.timeOut = 0; - out_rsc.rv = SCARD_S_SUCCESS; - out_uint8a(out_s, &out_rsc, sizeof(out_rsc)); - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_RSC; - s_mark_end(out_s); - trans_force_write(con); - } - else - { - LLOGLN(0, ("scard_read_state_chage_timeout: already stopped")); + g_writeln("3 - %s", lreader_name[index]); + out_uint8a(out_s, lreader_name[index], 100); } + out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ + s_mark_end(out_s); + bytes = (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, 0x03); /* SCARD_LIST_READERS 0x03 */ + return trans_force_write(con); } /*****************************************************************************/ /* returns error */ int APP_CC -scard_process_read_state_change(struct trans *con, struct stream *in_s) +scard_process_get_status_change(struct trans *con, struct stream *in_s) { - struct wait_reader_state_change in_rsc; - struct stream *out_s; int index; + int hContext; + int dwTimeout; + int cReaders; + READER_STATE *rsa; - LLOGLN(0, ("scard_process_read_state_change:")); - in_uint8a(in_s, &in_rsc, sizeof(in_rsc)); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RSC) + LLOGLN(0, ("scard_process_get_status_change:")); + if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC) { - LLOGLN(0, ("scard_process_read_state_change: opps")); - return 0; + LLOGLN(0, ("scard_process_get_status_change: opps")); + return 1; } - -#if 0 - for (index = 0; index < 16; index++) + in_uint32_le(in_s, hContext); + in_uint32_le(in_s, dwTimeout); + in_uint32_le(in_s, cReaders); + if ((cReaders < 0) || (cReaders > 16)) { - //g_memcpy(rd[index].reader_name, g_pcsc_reader_states[index].readerName, 99); - g_strncpy(rd[index].reader_name, "Gemalto PC Twin Reader 00 00", 99); - rd[index].current_state = g_pcsc_reader_states[index].readerState; - rd[index].event_state = g_pcsc_reader_states[index].eventCounter; - rd[index].atr_len = g_pcsc_reader_states[index].cardAtrLength; - g_memcpy(rd[index].atr, g_pcsc_reader_states[index].cardAtr, 33); + LLOGLN(0, ("scard_process_get_status_change: bad cReaders %d", cReaders)); + return 1; } -#endif + rsa = (READER_STATE *) g_malloc(sizeof(READER_STATE) * cReaders, 1); - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RSC; - scard_send_irp_get_status_change(con, JAY_TODO_CONTEXT, 1, in_rsc.timeOut, g_num_readers, - g_xrdp_reader_states); + for (index = 0; index < cReaders; index++) + { + in_uint8a(in_s, rsa[index].reader_name, 100); + LLOGLN(10, ("scard_process_get_status_change: reader_name %s", + rsa[index].reader_name)); + in_uint32_le(in_s, rsa[index].current_state); + LLOGLN(10, ("scard_process_get_status_change: current_state %d", + rsa[index].current_state)); + in_uint32_le(in_s, rsa[index].event_state); + LLOGLN(10, ("scard_process_get_status_change: event_state %d", + rsa[index].event_state)); + in_uint32_le(in_s, rsa[index].atr_len); + LLOGLN(10, ("scard_process_get_status_change: atr_len %d", + rsa[index].atr_len)); + in_uint8a(in_s, rsa[index].atr, 36); + } - LLOGLN(0, ("scard_process_read_state_change: timeout %d rv %d", - in_rsc.timeOut, in_rsc.rv)); + LLOGLN(0, ("scard_process_get_status_change: hContext 0x%8.8x dwTimeout " + "%d cReaders %d", hContext, dwTimeout, cReaders)); - add_timeout(in_rsc.timeOut, scard_read_state_chage_timeout, con); + g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_GSC; - return 0; -} + scard_send_irp_get_status_change(con, hContext, 1, dwTimeout, cReaders, rsa); -/*****************************************************************************/ -/* returns error */ -int APP_CC -scard_process_stop_read_state_change(struct trans *con, struct stream *in_s) -{ - struct wait_reader_state_change in_rsc; - struct wait_reader_state_change out_rsc; - struct stream *out_s; + g_free(rsa); - LLOGLN(0, ("scard_process_stop_read_state_change:")); - in_uint8a(in_s, &in_rsc, sizeof(in_rsc)); - LLOGLN(0, ("scard_process_stop_read_state_change: timeout %d rv %d", - in_rsc.timeOut, in_rsc.rv)); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RSC) - { - out_s = trans_get_out_s(con, 8192); - out_rsc.timeOut = in_rsc.timeOut; - out_rsc.rv = SCARD_S_SUCCESS; - out_uint8a(out_s, &out_rsc, sizeof(out_rsc)); - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_RSC; - s_mark_end(out_s); - return trans_force_write(con); - } - else - { - LLOGLN(0, ("scard_process_stop_read_state_change: already stopped")); - } return 0; } /*****************************************************************************/ -/* returns error */ int APP_CC scard_function_get_status_change_return(struct trans *con, struct stream *in_s, int len) { - struct stream *out_s; - int num_readers; + int bytes; int index; - int current_state; - int event_state; - int atr_len; - char atr[36]; + int cReaders; + tui32 current_state; + tui32 event_state; + tui32 atr_len; /* number of bytes in atr[] */ + tui8 atr[36]; + struct stream *out_s; LLOGLN(0, ("scard_function_get_status_change_return:")); - - //g_hexdump(in_s->p, len); - + g_hexdump(in_s->p, len); + if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC) == 0) + { + LLOGLN(0, ("scard_function_establish_context_return: opps")); + return 1; + } + g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_GSC; in_uint8s(in_s, 28); - in_uint32_le(in_s, num_readers); - LLOGLN(0, (" num_reader %d", num_readers)); - - g_num_readers = num_readers; - - for (index = 0; index < num_readers; index++) + in_uint32_le(in_s, cReaders); + if (cReaders > 0) { - in_uint32_le(in_s, current_state); - in_uint32_le(in_s, event_state); - in_uint32_le(in_s, atr_len); - in_uint8a(in_s, atr, 36); - LLOGLN(0, (" current_state 0x%8.8x event_state 0x%8.8x " - "atr_len 0x%8.8x", current_state, event_state, atr_len)); - g_xrdp_reader_states[index].current_state = current_state; - g_xrdp_reader_states[index].event_state = event_state; - g_xrdp_reader_states[index].atr_len = atr_len; - g_memcpy(g_xrdp_reader_states[index].atr, atr, 36); - + out_s = trans_get_out_s(con, 8192); + s_push_layer(out_s, iso_hdr, 8); + out_uint32_le(out_s, cReaders); + for (index = 0; index < cReaders; index++) + { + in_uint32_le(in_s, current_state); + out_uint32_le(out_s, current_state); + in_uint32_le(in_s, event_state); + out_uint32_le(out_s, event_state); + in_uint32_le(in_s, atr_len); + out_uint32_le(out_s, atr_len); + in_uint8a(in_s, atr, 36); + out_uint8a(out_s, atr, 36); + } + out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ + s_mark_end(out_s); + bytes = (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, 0x0C); /* SCARD_ESTABLISH_CONTEXT 0x0C */ + return trans_force_write(con); } - //out_s = trans_get_out_s(con, 8192); - //out_uint8a(out_s, g_reader_states, sizeof(g_reader_states)); - //s_mark_end(out_s); - //return trans_force_write(con); - return 0; - } /*****************************************************************************/ @@ -533,11 +443,12 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command) break; case 0x02: /* SCARD_RELEASE_CONTEXT */ LLOGLN(0, ("scard_process_msg: SCARD_RELEASE_CONTEXT")); - rv = scard_process_release_context(in_s); + rv = scard_process_release_context(con, in_s); break; case 0x03: /* SCARD_LIST_READERS */ LLOGLN(0, ("scard_process_msg: SCARD_LIST_READERS")); + rv = scard_process_list_readers(con, in_s); break; case 0x04: /* SCARD_CONNECT */ @@ -574,6 +485,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command) case 0x0C: /* SCARD_GET_STATUS_CHANGE */ LLOGLN(0, ("scard_process_msg: SCARD_GET_STATUS_CHANGE")); + rv = scard_process_get_status_change(con, in_s); break; case 0x0D: /* SCARD_CANCEL */ @@ -592,22 +504,6 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command) LLOGLN(0, ("scard_process_msg: SCARD_SET_ATTRIB")); break; - case 0x11: /* CMD_VERSION */ - LLOGLN(0, ("scard_process_msg: CMD_VERSION")); - rv = scard_process_version(con, in_s); - break; - case 0x12: /* CMD_GET_READERS_STATE */ - LLOGLN(0, ("scard_process_msg: CMD_GET_READERS_STATE")); - rv = scard_process_get_readers_state(con, in_s); - break; - case 0x13: /* CMD_WAIT_READER_STATE_CHANGE */ - LLOGLN(0, ("scard_process_msg: CMD_WAIT_READER_STATE_CHANGE")); - rv = scard_process_read_state_change(con, in_s); - break; - case 0x14: /* CMD_STOP_WAITING_READER_STATE_CHANGE */ - LLOGLN(0, ("scard_process_msg: CMD_STOP_WAITING_READER_STATE_CHANGE")); - rv = scard_process_stop_read_state_change(con, in_s); - break; default: LLOGLN(0, ("scard_process_msg: unknown mtype 0x%4.4x", command)); rv = 1; @@ -693,8 +589,6 @@ scard_pcsc_init(void) int index; LLOGLN(0, ("scard_pcsc_init:")); - g_memset(g_pcsc_reader_states, 0, sizeof(g_pcsc_reader_states)); - g_memset(g_xrdp_reader_states, 0, sizeof(g_xrdp_reader_states)); if (g_lis == 0) { g_lis = trans_create(2, 8192, 8192); @@ -725,14 +619,6 @@ scard_pcsc_init(void) port)); return 1; } - g_snprintf(g_pub_file_name, 255, "%s/pcscd.pub", g_pcsclite_ipc_dir); - g_pub_file_fd = g_file_open(g_pub_file_name); - index = 0; - while (index < 65537) - { - g_file_write(g_pub_file_fd, "", 1); - index++; - } } return 0; } @@ -749,8 +635,6 @@ scard_pcsc_deinit(void) g_file_close(g_pub_file_fd); g_pub_file_fd = 0; - g_file_delete(g_pub_file_name); - g_pub_file_name[0] = 0; if (g_remove_dir(g_pcsclite_ipc_dir) != 0) { diff --git a/sesman/chansrv/smartcard_pcsc.h b/sesman/chansrv/smartcard_pcsc.h index fd842a80..81bf5046 100644 --- a/sesman/chansrv/smartcard_pcsc.h +++ b/sesman/chansrv/smartcard_pcsc.h @@ -28,13 +28,18 @@ int APP_CC scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout); int APP_CC scard_pcsc_check_wait_objs(void); int APP_CC scard_pcsc_init(void); int APP_CC scard_pcsc_deinit(void); -int APP_CC scard_function_establish_context_return(struct trans *con, tui32 context); - +int APP_CC scard_function_establish_context_return(struct trans *con, + struct stream *in_s, + int len); +int APP_CC scard_function_release_context_return(struct trans *con, + struct stream *in_s, + int len); int APP_CC scard_function_list_readers_return(struct trans *con, struct stream *in_s, int len); int APP_CC scard_function_get_status_change_return(struct trans *con, - struct stream *in_s, int len); + struct stream *in_s, + int len); #endif /* end #ifndef _SMARTCARD_PCSC_H */