From 306992250092b65dfcfa4964e0e75abc41967f1b Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Wed, 11 Dec 2013 03:22:00 -0800 Subject: [PATCH] chansrv: work on smartcard --- sesman/chansrv/pcsc/xrdp_pcsc.c | 40 ++++++++++++-------- sesman/chansrv/smartcard.c | 67 +++++++++++++++++---------------- sesman/chansrv/smartcard.h | 2 +- sesman/chansrv/smartcard_pcsc.c | 36 +++++++++--------- 4 files changed, 79 insertions(+), 66 deletions(-) diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c index e4bb0bfc..89c80534 100644 --- a/sesman/chansrv/pcsc/xrdp_pcsc.c +++ b/sesman/chansrv/pcsc/xrdp_pcsc.c @@ -618,6 +618,10 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LLOGLN(0, ("SCardStatus: error, not connected")); return SCARD_F_INTERNAL_ERROR; } + LLOGLN(10, (" hCard 0x%8.8x", hCard)); + LLOGLN(10, (" cchReaderLen %d", *pcchReaderLen)); + LLOGLN(10, (" cbAtrLen %d", *pcbAtrLen)); + cchReaderLen = *pcchReaderLen; msg = (char *) malloc(8192); SET_UINT32(msg, 0, hCard); @@ -648,10 +652,10 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, } pthread_mutex_unlock(&g_mutex); - LLOGLN(10, ("SCardStatus: cchReaderLen %d", *pcchReaderLen)); + LLOGLN(10, ("SCardStatus: cchReaderLen in %d", *pcchReaderLen)); offset = 0; *pcchReaderLen = GET_UINT32(msg, offset); - LLOGLN(10, ("SCardStatus: cchReaderLen %d", *pcchReaderLen)); + LLOGLN(10, ("SCardStatus: cchReaderLen out %d", *pcchReaderLen)); offset += 4; if (cchReaderLen > 0) { @@ -663,7 +667,7 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, memcpy(mszReaderName, msg + offset, to_copy); mszReaderName[to_copy] = 0; } - LLOGLN(10, ("SCardStatus: mszReaderName %s", mszReaderName)); + LLOGLN(10, ("SCardStatus: mszReaderName out %s", mszReaderName)); offset += *pcchReaderLen; *pdwState = GET_UINT32(msg, offset); LLOGLN(10, ("SCardStatus: dwState %d", *pdwState)); @@ -715,10 +719,10 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout, memset(msg + offset, 0, 100); memcpy(msg + offset, rgReaderStates[index].szReader, str_len); offset += 100; - LLOGLN(10, (" in dwCurrentState %d", rgReaderStates[index].dwCurrentState)); + LLOGLN(10, (" in dwCurrentState 0x%8.8x", rgReaderStates[index].dwCurrentState)); SET_UINT32(msg, offset, rgReaderStates[index].dwCurrentState); offset += 4; - LLOGLN(10, (" in dwEventState %d", rgReaderStates[index].dwEventState)); + LLOGLN(10, (" in dwEventState 0x%8.8x", rgReaderStates[index].dwEventState)); SET_UINT32(msg, offset, rgReaderStates[index].dwEventState); offset += 4; LLOGLN(10, (" in cbAtr %d", rgReaderStates[index].cbAtr)); @@ -793,9 +797,10 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, LLOGLN(0, ("SCardControl: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - LLOGLN(10, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode)); - LLOGLN(10, ("SCardControl: cbSendLength %d", cbSendLength)); - LLOGLN(10, ("SCardControl: cbRecvLength %d", cbRecvLength)); + LLOGLN(10, (" hCard 0x%8.8x", hCard)); + LLOGLN(10, (" dwControlCode 0x%8.8x", dwControlCode)); + LLOGLN(10, (" cbSendLength %d", cbSendLength)); + LLOGLN(10, (" cbRecvLength %d", cbRecvLength)); /* #define SCARD_CTL_CODE(code) (0x42000000 + (code)) control_code = (control_code & 0x3ffc) >> 2; @@ -805,7 +810,7 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, dwControlCode = dwControlCode - 0x42000000; dwControlCode = dwControlCode << 2; dwControlCode = dwControlCode | (49 << 16); - LLOGLN(10, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode)); + LLOGLN(10, (" MS dwControlCode 0x%8.8x", dwControlCode)); msg = (char *) malloc(8192); offset = 0; @@ -845,6 +850,7 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, pthread_mutex_unlock(&g_mutex); offset = 0; *lpBytesReturned = GET_UINT32(msg, offset); + LLOGLN(10, (" cbRecvLength %d", *lpBytesReturned)); offset += 4; memcpy(pbRecvBuffer, msg + offset, *lpBytesReturned); offset += *lpBytesReturned; @@ -873,14 +879,16 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, LLOGLN(0, ("SCardTransmit: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - LLOGLN(10, ("SCardTransmit: cbSendLength %d", cbSendLength)); - LLOGLN(10, ("SCardTransmit: pioRecvPci %p", pioRecvPci)); + LLOGLN(10, (" hCard 0x%8.8x", hCard)); + LLOGLN(10, (" cbSendLength %d", cbSendLength)); + LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength)); + LLOGLN(10, (" pioSendPci->dwProtocol %d", (int)(pioSendPci->dwProtocol))); + LLOGLN(10, (" pioSendPci->cbPciLength %d", (int)(pioSendPci->cbPciLength))); + LLOGLN(10, (" pioRecvPci %p", pioRecvPci)); if (pioRecvPci != 0) { - LLOGLN(10, ("SCardTransmit: pioRecvPci->dwProtocol %d", - (int)pioRecvPci->dwProtocol)); - LLOGLN(10, ("SCardTransmit: pioRecvPci->cbPciLength %d", - (int)pioRecvPci->cbPciLength)); + LLOGLN(10, (" pioRecvPci->dwProtocol %d", (int)(pioRecvPci->dwProtocol))); + LLOGLN(10, (" pioRecvPci->cbPciLength %d", (int)(pioRecvPci->cbPciLength))); } msg = (char *) malloc(8192); offset = 0; @@ -966,7 +974,7 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, } *pcbRecvLength = GET_UINT32(msg, offset); offset += 4; - LLOGLN(10, ("SCardTransmit: cbRecvLength %d", *pcbRecvLength)); + LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength)); memcpy(pbRecvBuffer, msg + offset, *pcbRecvLength); offset += *pcbRecvLength; status = GET_UINT32(msg, offset); diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c index 2a8fb3d1..e3eb52c1 100644 --- a/sesman/chansrv/smartcard.c +++ b/sesman/chansrv/smartcard.c @@ -190,7 +190,7 @@ static int APP_CC scard_send_Transmit(IRP *irp, tui32 sc_handle, 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, +static int APP_CC scard_send_Control(IRP* irp, 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); @@ -703,7 +703,7 @@ scard_send_transmit(struct trans *con, tui32 sc_handle, * Communicate directly with the smart card reader *****************************************************************************/ int APP_CC -scard_send_control(struct trans *con, tui32 context, tui32 sc_handle, +scard_send_control(struct trans *con, tui32 sc_handle, char *send_data, int send_bytes, int recv_bytes, int control_code) { @@ -723,7 +723,7 @@ scard_send_control(struct trans *con, tui32 context, tui32 sc_handle, irp->user_data = con; /* send IRP to client */ - scard_send_Control(irp, context, sc_handle, send_data, + scard_send_Control(irp, sc_handle, send_data, send_bytes, recv_bytes, control_code); return 0; @@ -1655,9 +1655,9 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle, 00 00 02 00 04 00 00 00 04 00 02 00 - 01 00 00 00 dwReaderLen - 00 00 00 00 dwAtrLen - 40 00 00 00 + 01 00 00 00 + 00 00 00 00 dwReaderLen + 40 00 00 00 dwAtrLen 04 00 00 00 07 00 00 00 04 00 00 00 @@ -1670,9 +1670,9 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle, out_uint32_le(s, 0x00020000); out_uint32_le(s, 0x00000004); out_uint32_le(s, 0x00020004); + out_uint32_le(s, 0x00000001); out_uint32_le(s, cchReaderLen); /* readerLen, see [MS-RDPESC] 4.11 */ out_uint32_le(s, cbAtrLen); /* atrLen, see [MS-RDPESC] 4.11 */ - out_uint32_le(s, 0x00000040); out_uint32_le(s, 0x00000004); out_uint32_le(s, 0x00000007); /* insert sc_handle */ @@ -1694,6 +1694,8 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle, bytes = (int) (s->end - s->data); + //g_hexdump(s->data, bytes); + /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); @@ -1712,8 +1714,8 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle, { /* see [MS-RDPESC] 3.1.4.30 */ - SMARTCARD* sc; - struct stream* s; + SMARTCARD *sc; + struct stream *s; int bytes; if ((sc = smartcards[irp->scard_index]) == NULL) @@ -1830,12 +1832,11 @@ scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data, #if 0 s_push_layer(s, mcs_hdr, 4); /* bytes, set later */ - //out_uint32_be(s, 0x58000000); out_uint32_be(s, 0x00000000); out_uint32_be(s, 0x04000000); - out_uint32_be(s, 0x00000200); + out_uint32_be(s, 0x00000200); // map 0 out_uint32_be(s, 0x04000000); - out_uint32_be(s, 0x04000200); + out_uint32_be(s, 0x04000200); // map 1 out_uint32_be(s, 0x01000000); out_uint32_be(s, 0x00000000); out_uint32_be(s, 0x00000000); @@ -1876,45 +1877,45 @@ scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data, out_uint32_le(s, 0x00000000); out_uint32_le(s, 4); - xstream_wr_u32_le(s, 0x00020000); /* map0 */ + out_uint32_le(s, 0x00020000); /* map0 */ out_uint32_le(s, 4); - xstream_wr_u32_le(s, 0x00020004); /* map1 */ + out_uint32_le(s, 0x00020004); /* map1 */ - xstream_wr_u32_le(s, send_ior->dwProtocol); - xstream_wr_u32_le(s, send_ior->cbPciLength - 8); + out_uint32_le(s, send_ior->dwProtocol); + out_uint32_le(s, send_ior->cbPciLength - 8); val = send_ior->extra_bytes > 0 ? 1 : 0; - xstream_wr_u32_le(s, val); /* map2 */ + out_uint32_le(s, val); /* map2 */ - xstream_wr_u32_le(s, send_bytes); + out_uint32_le(s, send_bytes); val = send_bytes > 0 ? 0x00020008 : 0; - xstream_wr_u32_le(s, val); /* map3 */ + out_uint32_le(s, val); /* map3 */ val = recv_ior->cbPciLength > 0 ? 0x0002000c : 0; - xstream_wr_u32_le(s, val); /* map 4 */ + out_uint32_le(s, val); /* map 4 */ - xstream_wr_u32_le(s, 0); // map5 - xstream_wr_u32_le(s, recv_bytes); + out_uint32_le(s, 0); // map5 + out_uint32_le(s, recv_bytes); /* map0 */ out_uint32_le(s, 4); out_uint32_le(s, 5); /* map1 */ - xstream_wr_u32_le(s, 4); - xstream_wr_u32_le(s, sc_handle); + out_uint32_le(s, 4); + out_uint32_le(s, sc_handle); if (send_ior->extra_bytes > 0) { - xstream_wr_u32_le(s, send_ior->extra_bytes); + out_uint32_le(s, send_ior->extra_bytes); out_uint8a(s, send_ior->extra_data, send_ior->extra_bytes); } if (send_bytes > 0) { - xstream_wr_u32_le(s, send_bytes); + out_uint32_le(s, send_bytes); out_uint8a(s, send_data, send_bytes); align_s(s, 4); } @@ -1922,13 +1923,13 @@ scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data, if (recv_ior->cbPciLength > 0) { /* map4 */ - xstream_wr_u32_le(s, recv_ior->dwProtocol); - xstream_wr_u32_le(s, recv_ior->cbPciLength); + out_uint32_le(s, recv_ior->dwProtocol); + out_uint32_le(s, recv_ior->cbPciLength - 8); val = recv_ior->extra_bytes > 0 ? 1 : 0; - xstream_wr_u32_le(s, val); /* map6*/ + out_uint32_le(s, val); /* map6*/ if (val) { - xstream_wr_u32_le(s, recv_ior->extra_bytes); + out_uint32_le(s, recv_ior->extra_bytes); out_uint8a(s, recv_ior->extra_data, recv_ior->extra_bytes); } } @@ -1964,7 +1965,7 @@ scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data, * Communicate directly with the smart card reader *****************************************************************************/ static int APP_CC -scard_send_Control(IRP *irp, tui32 context, tui32 sc_handle, char *send_data, +scard_send_Control(IRP *irp, tui32 sc_handle, char *send_data, int send_bytes, int recv_bytes, int control_code) { /* see [MS-RDPESC] 2.2.2.19 */ @@ -1999,7 +2000,7 @@ scard_send_Control(IRP *irp, tui32 context, tui32 sc_handle, char *send_data, out_uint32_le(s, 0x00000000); out_uint32_le(s, recv_bytes); out_uint32_le(s, 4); - out_uint32_le(s, context); + out_uint32_le(s, 0); /* context ? */ out_uint32_le(s, 4); out_uint32_le(s, sc_handle); if (send_bytes > 0) @@ -2026,6 +2027,8 @@ scard_send_Control(IRP *irp, tui32 context, tui32 sc_handle, char *send_data, bytes = (int) (s->end - s->data); + //g_hexdump(s->data, bytes); + /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h index 24ba2123..94abf2b6 100644 --- a/sesman/chansrv/smartcard.h +++ b/sesman/chansrv/smartcard.h @@ -139,7 +139,7 @@ int APP_CC scard_send_transmit(struct trans *con, tui32 sc_handle, struct xrdp_scard_io_request *send_ior, struct xrdp_scard_io_request *recv_ior); -int APP_CC scard_send_control(struct trans *con, tui32 context, tui32 sc_handle, +int APP_CC scard_send_control(struct trans *con, tui32 sc_handle, char *send_data, int send_bytes, int recv_bytes, int control_code); diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c index 246ee3e0..8bdbe745 100644 --- a/sesman/chansrv/smartcard_pcsc.c +++ b/sesman/chansrv/smartcard_pcsc.c @@ -155,7 +155,8 @@ scard_function_establish_context_return(struct trans *con, //g_hexdump(in_s->p, len); if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0) { - LLOGLN(0, ("scard_function_establish_context_return: opps")); + LLOGLN(0, ("scard_function_establish_context_return: opps " + "g_xrdp_pcsc_state 0x%8.8x, g_xrdp_pcsc_state")); return 1; } g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC; @@ -166,7 +167,8 @@ scard_function_establish_context_return(struct trans *con, in_uint32_le(in_s, context_len); if (context_len != 4) { - LLOGLN(0, ("scard_function_establish_context_return: opps")); + LLOGLN(0, ("scard_function_establish_context_return: opps " + "context_len %d", context_len)); return 1; } in_uint32_le(in_s, context); @@ -681,27 +683,29 @@ scard_function_transmit_return(struct trans *con, return 1; } g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_TR; - g_memset(&recv_ior, 0, sizeof(recv_ior)); cbRecvLength = 0; - + recvBuf = 0; if (status == 0) { in_uint8s(in_s, 20); in_uint32_le(in_s, val); - g_memset(&recv_ior, 0, sizeof(recv_ior)); if (val != 0) { /* pioRecvPci */ - LLOGLN(0, ("scard_function_transmit_return: pioRecvPci not zero!")); + in_uint8s(in_s, 8); + in_uint32_le(in_s, recv_ior.dwProtocol); + in_uint32_le(in_s, recv_ior.cbPciLength); + recv_ior.cbPciLength += 8; + in_uint32_le(in_s, recv_ior.extra_bytes); + if (recv_ior.extra_bytes > 0) + { + in_uint8p(in_s, recv_ior.extra_data, recv_ior.extra_bytes); + } } - in_uint8s(in_s, 4); - in_uint32_le(in_s, val); - cbRecvLength = 0; - recvBuf = 0; - if (val != 0) + in_uint32_le(in_s, cbRecvLength); + if (cbRecvLength > 0) { - in_uint32_le(in_s, cbRecvLength); in_uint8p(in_s, recvBuf, cbRecvLength); } } @@ -728,7 +732,6 @@ scard_function_transmit_return(struct trans *con, int APP_CC scard_process_control(struct trans *con, struct stream *in_s) { - tui32 context; int hCard; int send_bytes; int recv_bytes; @@ -750,9 +753,7 @@ scard_process_control(struct trans *con, struct stream *in_s) in_uint8p(in_s, send_data, send_bytes); in_uint32_le(in_s, recv_bytes); - context = 1; - - scard_send_control(con, context, hCard, send_data, send_bytes, recv_bytes, + scard_send_control(con, hCard, send_data, send_bytes, recv_bytes, control_code); return 0; @@ -997,7 +998,8 @@ scard_function_get_status_change_return(struct trans *con, //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")); + LLOGLN(0, ("scard_function_get_status_change_return: opps " + "g_xrdp_pcsc_state 0x%8.8x", g_xrdp_pcsc_state)); return 1; } g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_GSC;