diff options
author | Jay Sorg <jay.sorg@gmail.com> | 2013-10-19 15:36:57 -0700 |
---|---|---|
committer | Jay Sorg <jay.sorg@gmail.com> | 2013-10-19 15:36:57 -0700 |
commit | 62bdacda9bd43e2904f0d3a25b4cd26569a1a792 (patch) | |
tree | f1d9eeb82fe7d8ae30dd1c036330529994e5ff63 | |
parent | b69c144c7dc1cbd2d6bed5ac905f5a896719a6fb (diff) | |
download | xrdp-proprietary-62bdacda9bd43e2904f0d3a25b4cd26569a1a792.tar.gz xrdp-proprietary-62bdacda9bd43e2904f0d3a25b4cd26569a1a792.zip |
chansrv: work on smartcard
-rw-r--r-- | sesman/chansrv/pcsc/xrdp_pcsc.c | 82 | ||||
-rw-r--r-- | sesman/chansrv/smartcard.c | 114 | ||||
-rw-r--r-- | sesman/chansrv/smartcard.h | 3 | ||||
-rw-r--r-- | sesman/chansrv/smartcard_pcsc.c | 160 | ||||
-rw-r--r-- | sesman/chansrv/smartcard_pcsc.h | 30 |
5 files changed, 332 insertions, 57 deletions
diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c index 65be347c..d49e253b 100644 --- a/sesman/chansrv/pcsc/xrdp_pcsc.c +++ b/sesman/chansrv/pcsc/xrdp_pcsc.c @@ -393,8 +393,9 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, int offset; LLOGLN(0, ("SCardConnect:")); - LLOGLN(0, ("SCardConnect: hContext %p szReader %s dwShareMode %d dwPreferredProtocols %d", - hContext, szReader, dwShareMode, dwPreferredProtocols)); + LLOGLN(0, ("SCardConnect: hContext %p szReader %s dwShareMode %d " + "dwPreferredProtocols %d", + (void*)hContext, szReader, dwShareMode, dwPreferredProtocols)); if (g_sck == -1) { LLOGLN(0, ("SCardConnect: error, not connected")); @@ -595,15 +596,83 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { + char *msg; + int code; + int bytes; + int status; + int offset; + int cchReaderLen; + int to_copy; + LLOGLN(0, ("SCardStatus:")); if (g_sck == -1) { LLOGLN(0, ("SCardStatus: error, not connected")); return SCARD_F_INTERNAL_ERROR; } + cchReaderLen = *pcchReaderLen; + msg = (char *) malloc(8192); + SET_UINT32(msg, 0, hCard); + SET_UINT32(msg, 4, cchReaderLen); + SET_UINT32(msg, 8, *pcbAtrLen); pthread_mutex_lock(&g_mutex); + if (send_message(SCARD_STATUS, msg, 12) != 0) + { + LLOGLN(0, ("SCardStatus: error, send_message")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + bytes = 8192; + if (get_message(&code, msg, &bytes) != 0) + { + LLOGLN(0, ("SCardStatus: error, get_message")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + if (code != SCARD_STATUS) + { + LLOGLN(0, ("SCardStatus: error, bad code")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } pthread_mutex_unlock(&g_mutex); - return SCARD_S_SUCCESS; + + LLOGLN(0, ("SCardStatus: cchReaderLen %d", *pcchReaderLen)); + offset = 0; + *pcchReaderLen = GET_UINT32(msg, offset); + LLOGLN(0, ("SCardStatus: cchReaderLen %d", *pcchReaderLen)); + offset += 4; + if (cchReaderLen > 0) + { + to_copy = cchReaderLen - 1; + if (*pcchReaderLen < to_copy) + { + to_copy = *pcchReaderLen; + } + memcpy(mszReaderName, msg + offset, to_copy); + mszReaderName[to_copy] = 0; + } + LLOGLN(0, ("SCardStatus: mszReaderName %s", mszReaderName)); + offset += *pcchReaderLen; + *pdwState = GET_UINT32(msg, offset); + LLOGLN(0, ("SCardStatus: dwState %d", *pdwState)); + offset += 4; + *pdwProtocol = GET_UINT32(msg, offset); + LLOGLN(0, ("SCardStatus: dwProtocol %d", *pdwProtocol)); + offset += 4; + *pcbAtrLen = GET_UINT32(msg, offset); + offset += 4; + LLOGLN(0, ("SCardStatus: cbAtrLen %d", *pcbAtrLen)); + memcpy(pbAtr, msg + offset, *pcbAtrLen); + offset += *pcbAtrLen; + status = GET_UINT32(msg, offset); + LLOGLN(0, ("SCardStatus: status %d", status)); + offset += 4; + free(msg); + return status; } /*****************************************************************************/ @@ -716,9 +785,14 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, LLOGLN(0, ("SCardControl: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - LLOGLN(0, ("SCardControl: dwControlCode %d", dwControlCode)); + LLOGLN(0, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode)); LLOGLN(0, ("SCardControl: cbSendLength %d", cbSendLength)); LLOGLN(0, ("SCardControl: cbRecvLength %d", cbRecvLength)); + dwControlCode = dwControlCode & ~0x42000000; + dwControlCode = dwControlCode << 2; + dwControlCode = dwControlCode | (49 << 16); + LLOGLN(0, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode)); + msg = (char *) malloc(8192); offset = 0; SET_UINT32(msg, offset, hCard); diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c index e22c5eb5..c40b24a4 100644 --- a/sesman/chansrv/smartcard.c +++ b/sesman/chansrv/smartcard.c @@ -160,42 +160,36 @@ extern int g_rdpdr_chan_id; /* in chansrv.c */ 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); +#if 0 static void APP_CC scard_release_resources(void); +#endif 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_IsContextValid(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_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, 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, tui32 dwDisposition); -static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle); - +static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle, + int cchReaderLen, int cbAtrLen); static void APP_CC scard_send_Disconnect(IRP* irp, tui32 context, tui32 sc_handle, int dwDisposition); - static int APP_CC scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data, int send_bytes, int recv_bytes, struct xrdp_scard_io_request *send_ior, struct xrdp_scard_io_request *recv_ior); - static int APP_CC scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data, int send_bytes, int recv_bytes, int control_code); - static int APP_CC scard_send_Cancel(IRP* irp, tui32 context); - static int APP_CC scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs); @@ -613,7 +607,8 @@ scard_send_end_transaction(struct trans *con, tui32 sc_handle, * @param wide TRUE if unicode string *****************************************************************************/ int APP_CC -scard_send_status(struct trans *con, int wide, tui32 sc_handle) +scard_send_status(struct trans *con, int wide, tui32 sc_handle, + int cchReaderLen, int cbAtrLen) { IRP *irp; @@ -631,7 +626,7 @@ scard_send_status(struct trans *con, int wide, tui32 sc_handle) irp->user_data = con; /* send IRP to client */ - scard_send_Status(irp, wide, sc_handle); + scard_send_Status(irp, wide, sc_handle, cchReaderLen, cbAtrLen); return 0; } @@ -902,6 +897,7 @@ scard_get_free_slot(void) return -1; } +#if 0 /** * Release resources prior to shutting down *****************************************************************************/ @@ -919,6 +915,7 @@ scard_release_resources(void) } } } +#endif /** * @@ -1179,7 +1176,6 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout, tui32 ioctl; int bytes; int i; - int len; int num_chars; int index; twchar w_reader_name[100]; @@ -1282,7 +1278,6 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs) struct stream* s; tui32 ioctl; int bytes; - int len; int num_chars; int index; twchar w_reader_name[100]; @@ -1539,7 +1534,8 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition) * @param wide TRUE if unicode string *****************************************************************************/ static void APP_CC -scard_send_Status(IRP *irp, int wide, tui32 sc_handle) +scard_send_Status(IRP *irp, int wide, tui32 sc_handle, + int cchReaderLen, int cbAtrLen) { /* see [MS-RDPESC] 2.2.2.18 */ @@ -1554,11 +1550,12 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle) return; } - ioctl = (wide) ? SCARD_IOCTL_CONNECT_W : - SCARD_IOCTL_CONNECT_A; - + ioctl = wide ? SCARD_IOCTL_STATUS_W : SCARD_IOCTL_STATUS_A; if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL) + { + log_error("scard_make_new_ioctl"); return; + } /* * command format @@ -1577,8 +1574,8 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle) */ xstream_seek(s, 28); - xstream_wr_u32_le(s, -1); /* readerLen, see [MS-RDPESC] 4.11 */ - xstream_wr_u32_le(s, 36); /* atrLen, see [MS-RDPESC] 4.11 */ + xstream_wr_u32_le(s, cchReaderLen); /* readerLen, see [MS-RDPESC] 4.11 */ + xstream_wr_u32_le(s, cbAtrLen); /* atrLen, see [MS-RDPESC] 4.11 */ xstream_seek(s, 8); /* insert sc_handle */ @@ -1680,11 +1677,14 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data, if ((sc = smartcards[irp->scard_index]) == NULL) { log_error("smartcards[%d] is NULL", irp->scard_index); - return; + return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_TRANSMIT)) == NULL) - return; + { + log_error("scard_make_new_ioctl"); + return 1; + } log_debug("send_bytes %d recv_bytes %d send dwProtocol %d cbPciLength %d " "extra_bytes %d recv dwProtocol %d cbPciLength %d", send_bytes, @@ -1768,6 +1768,7 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data, /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); + return 0; } /** @@ -1787,11 +1788,14 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data, if ((sc = smartcards[irp->scard_index]) == NULL) { log_error("smartcards[%d] is NULL", irp->scard_index); - return; + return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CONTROL)) == NULL) - return; + { + log_error("scard_make_new_ioctl"); + return 1; + } /* * command format @@ -1849,6 +1853,7 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data, /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); + return 0; } /** @@ -1866,11 +1871,14 @@ scard_send_Cancel(IRP* irp, tui32 context) if ((sc = smartcards[irp->scard_index]) == NULL) { log_error("smartcards[%d] is NULL", irp->scard_index); - return; + return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CANCEL)) == NULL) - return; + { + log_error("scard_make_new_ioctl"); + return 1; + } /* * command format @@ -1897,6 +1905,7 @@ scard_send_Cancel(IRP* irp, tui32 context) /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); + return 0; } /** @@ -1914,11 +1923,14 @@ scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs) if ((sc = smartcards[irp->scard_index]) == NULL) { log_error("smartcards[%d] is NULL", irp->scard_index); - return; + return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_GETATTRIB)) == NULL) - return; + { + log_error("scard_make_new_ioctl"); + return 1; + } /* * command format @@ -1953,6 +1965,7 @@ scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs) /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); + return 0; } /****************************************************************************** @@ -2025,11 +2038,16 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp, log_debug("leaving"); } -static void APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp, - tui32 DeviceId, tui32 CompletionId, - tui32 IoStatus) +/** + * + *****************************************************************************/ +static void +APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp, + tui32 DeviceId, tui32 CompletionId, + tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2049,7 +2067,9 @@ static void APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_is_context_valid_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2163,6 +2183,7 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2182,7 +2203,9 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_reconnect_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2215,11 +2238,9 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - con = (struct trans *) (irp->user_data); scard_function_begin_transaction_return(con, s, len); devredir_irp_delete(irp); - log_debug("leaving"); } @@ -2252,11 +2273,9 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - con = (struct trans *) (irp->user_data); scard_function_end_transaction_return(con, s, len); devredir_irp_delete(irp); - log_debug("leaving"); } @@ -2269,6 +2288,7 @@ scard_handle_Status_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2288,7 +2308,9 @@ scard_handle_Status_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_status_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2321,11 +2343,9 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - con = (struct trans *) (irp->user_data); scard_function_disconnect_return(con, s, len); devredir_irp_delete(irp); - log_debug("leaving"); } @@ -2357,11 +2377,9 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - con = (struct trans *) (irp->user_data); scard_function_transmit_return(con, s, len); devredir_irp_delete(irp); - log_debug("leaving"); } @@ -2393,11 +2411,9 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - con = (struct trans *) (irp->user_data); scard_function_control_return(con, s, len); devredir_irp_delete(irp); - log_debug("leaving"); } @@ -2409,6 +2425,7 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2428,7 +2445,9 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_cancel_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2440,6 +2459,7 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2459,6 +2479,8 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_get_attrib_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h index 432cc80b..88f4cdf6 100644 --- a/sesman/chansrv/smartcard.h +++ b/sesman/chansrv/smartcard.h @@ -128,7 +128,8 @@ int APP_CC scard_send_reconnect(struct trans *con, tui32 context, int APP_CC scard_send_begin_transaction(struct trans *con, tui32 sc_handle); int APP_CC scard_send_end_transaction(struct trans *con, tui32 sc_handle, tui32 dwDisposition); -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, + int cchReaderLen, int cbAtrLen); int APP_CC scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle, int dwDisposition); diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c index 02cdf312..f605d539 100644 --- a/sesman/chansrv/smartcard_pcsc.c +++ b/sesman/chansrv/smartcard_pcsc.c @@ -61,6 +61,7 @@ #define XRDP_PCSC_STATE_GOT_TR (1 << 7) /* transmit */ #define XRDP_PCSC_STATE_GOT_CO (1 << 8) /* control */ #define XRDP_PCSC_STATE_GOT_D (1 << 9) /* disconnect */ +#define XRDP_PCSC_STATE_GOT_ST (1 << 10) /* get status */ /* TODO: put this in con */ static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE; @@ -73,8 +74,10 @@ struct pcsc_client struct trans *con; }; +#if 0 static struct pcsc_client *g_head = 0; static struct pcsc_client *g_tail = 0; +#endif static struct trans *g_lis = 0; static struct trans *g_con = 0; /* todo, remove this */ @@ -202,7 +205,6 @@ scard_function_release_context_return(struct trans *con, { int bytes; struct stream *out_s; - tui32 context; LLOGLN(0, ("scard_function_release_context_return:")); if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0) @@ -550,6 +552,26 @@ scard_function_end_transaction_return(struct trans *con, /*****************************************************************************/ /* returns error */ int APP_CC +scard_function_cancel_return(struct trans *con, + struct stream *in_s, + int len) +{ + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_function_get_attrib_return(struct trans *con, + struct stream *in_s, + int len) +{ + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC scard_process_transmit(struct trans *con, struct stream *in_s) { int hCard; @@ -600,7 +622,6 @@ scard_function_transmit_return(struct trans *con, struct stream *out_s; int bytes; int val; - int got_recv_pci; int cbRecvLength; struct xrdp_scard_io_request recv_ior; char *recvBuf; @@ -617,11 +638,9 @@ scard_function_transmit_return(struct trans *con, in_uint8s(in_s, 20); in_uint32_le(in_s, val); g_memset(&recv_ior, 0, sizeof(recv_ior)); - got_recv_pci = 0; if (val != 0) { /* pioRecvPci */ - got_recv_pci = 1; LLOGLN(0, ("scard_function_transmit_return: pioRecvPci not zero!")); } in_uint8s(in_s, 4); @@ -727,6 +746,117 @@ scard_function_control_return(struct trans *con, /*****************************************************************************/ /* returns error */ int APP_CC +scard_process_status(struct trans *con, struct stream *in_s) +{ + int hCard; + int cchReaderLen; + int cbAtrLen; + + LLOGLN(0, ("scard_process_status:")); + if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST) + { + LLOGLN(0, ("scard_process_control: opps")); + return 1; + } + g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_ST; + LLOGLN(0, ("scard_process_control:")); + + in_uint32_le(in_s, hCard); + in_uint32_le(in_s, cchReaderLen); + in_uint32_le(in_s, cbAtrLen); + + scard_send_status(con, 1, hCard, cchReaderLen, cbAtrLen); + + return 0; +} + +#define MS_SCARD_UNKNOWN 0 +#define MS_SCARD_ABSENT 1 +#define MS_SCARD_PRESENT 2 +#define MS_SCARD_SWALLOWED 3 +#define MS_SCARD_POWERED 4 +#define MS_SCARD_NEGOTIABLE 5 +#define MS_SCARD_SPECIFIC 6 + +#define PC_SCARD_UNKNOWN 0x0001 /**< Unknown state */ +#define PC_SCARD_ABSENT 0x0002 /**< Card is absent */ +#define PC_SCARD_PRESENT 0x0004 /**< Card is present */ +#define PC_SCARD_SWALLOWED 0x0008 /**< Card not powered */ +#define PC_SCARD_POWERED 0x0010 /**< Card is powered */ +#define PC_SCARD_NEGOTIABLE 0x0020 /**< Ready for PTS */ +#define PC_SCARD_SPECIFIC 0x0040 /**< PTS has been set */ + +static int g_ms2pc[] = { PC_SCARD_UNKNOWN, PC_SCARD_ABSENT, + PC_SCARD_PRESENT, PC_SCARD_SWALLOWED, + PC_SCARD_POWERED, PC_SCARD_NEGOTIABLE, + PC_SCARD_SPECIFIC }; + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_function_status_return(struct trans *con, + struct stream *in_s, + int len) +{ + struct stream *out_s; + int index; + int bytes; + int dwReaderLen; + int dwState; + int dwProtocol; + int dwAtrLen; + char attr[32]; + twchar reader_name[100]; + char lreader_name[100]; + + g_hexdump(in_s->p, len); + if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST) == 0) + { + LLOGLN(0, ("scard_function_status_return: opps")); + return 1; + } + g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_ST; + in_uint8s(in_s, 20); + in_uint32_le(in_s, dwReaderLen); + in_uint8s(in_s, 4); + in_uint32_le(in_s, dwState); + dwState = g_ms2pc[dwState % 6]; + in_uint32_le(in_s, dwProtocol); + in_uint8a(in_s, attr, 32); + in_uint32_le(in_s, dwAtrLen); + in_uint32_le(in_s, dwReaderLen); + dwReaderLen /= 2; + g_memset(reader_name, 0, sizeof(reader_name)); + g_memset(lreader_name, 0, sizeof(lreader_name)); + for (index = 0; index < dwReaderLen; index++) + { + in_uint16_le(in_s, reader_name[index]); + } + g_wcstombs(lreader_name, reader_name, 99); + LLOGLN(0, ("scard_function_status_return: dwAtrLen %d dwReaderLen %d " + "dwProtocol %d dwState %d name %s", + dwAtrLen, dwReaderLen, dwProtocol, dwState, lreader_name)); + out_s = trans_get_out_s(con, 8192); + s_push_layer(out_s, iso_hdr, 8); + dwReaderLen = g_strlen(lreader_name); + out_uint32_le(out_s, dwReaderLen); + out_uint8a(out_s, lreader_name, dwReaderLen); + out_uint32_le(out_s, dwState); + out_uint32_le(out_s, dwProtocol); + out_uint32_le(out_s, dwAtrLen); + out_uint8a(out_s, attr, dwAtrLen); + 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, 0x0B); /* SCARD_STATUS 0x0B */ + return trans_force_write(con); +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC scard_process_get_status_change(struct trans *con, struct stream *in_s) { int index; @@ -835,6 +965,25 @@ scard_function_get_status_change_return(struct trans *con, /*****************************************************************************/ /* returns error */ int APP_CC +scard_function_is_context_valid_return(struct trans *con, + struct stream *in_s, + int len) +{ + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC scard_function_reconnect_return(struct trans *con, + struct stream *in_s, + int len) +{ + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC scard_process_msg(struct trans *con, struct stream *in_s, int command) { int rv; @@ -893,6 +1042,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command) case 0x0B: /* SCARD_STATUS */ LLOGLN(0, ("scard_process_msg: SCARD_STATUS")); + rv = scard_process_status(con, in_s); break; case 0x0C: /* SCARD_GET_STATUS_CHANGE */ @@ -930,7 +1080,6 @@ int DEFAULT_CC my_pcsc_trans_data_in(struct trans *trans) { struct stream *s; - int id; int size; int command; int error; @@ -998,7 +1147,6 @@ scard_pcsc_init(void) char *home; int disp; int error; - int index; LLOGLN(0, ("scard_pcsc_init:")); if (g_lis == 0) diff --git a/sesman/chansrv/smartcard_pcsc.h b/sesman/chansrv/smartcard_pcsc.h index d5447cff..bd5b9090 100644 --- a/sesman/chansrv/smartcard_pcsc.h +++ b/sesman/chansrv/smartcard_pcsc.h @@ -49,11 +49,41 @@ int APP_CC scard_function_control_return(struct trans *con, int APP_CC scard_function_get_status_change_return(struct trans *con, struct stream *in_s, int len); + int APP_CC scard_function_connect_return(struct trans *con, struct stream *in_s, int len); + +int APP_CC scard_function_status_return(struct trans *con, + struct stream *in_s, + int len); + int APP_CC scard_function_begin_transaction_return(struct trans *con, struct stream *in_s, int len); +int APP_CC scard_function_end_transaction_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_is_context_valid_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_reconnect_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_disconnect_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_cancel_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_get_attrib_return(struct trans *con, + struct stream *in_s, + int len); + #endif /* end #ifndef _SMARTCARD_PCSC_H */ |