diff options
Diffstat (limited to 'sesman/chansrv')
-rw-r--r-- | sesman/chansrv/pcsc/xrdp_pcsc.c | 189 | ||||
-rw-r--r-- | sesman/chansrv/smartcard.c | 146 | ||||
-rw-r--r-- | sesman/chansrv/smartcard.h | 30 | ||||
-rw-r--r-- | sesman/chansrv/smartcard_pcsc.c | 632 | ||||
-rw-r--r-- | sesman/chansrv/smartcard_pcsc.h | 30 |
5 files changed, 710 insertions, 317 deletions
diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c index 43a95b5f..eed4787e 100644 --- a/sesman/chansrv/pcsc/xrdp_pcsc.c +++ b/sesman/chansrv/pcsc/xrdp_pcsc.c @@ -243,16 +243,20 @@ send_message(int code, char *data, int bytes) { char header[8]; + pthread_mutex_lock(&g_mutex); SET_UINT32(header, 0, bytes); SET_UINT32(header, 4, code); if (send(g_sck, header, 8, 0) != 8) { + pthread_mutex_unlock(&g_mutex); return 1; } if (send(g_sck, data, bytes, 0) != bytes) { + pthread_mutex_unlock(&g_mutex); return 1; } + pthread_mutex_unlock(&g_mutex); return 0; } @@ -262,9 +266,49 @@ get_message(int *code, char *data, int *bytes) { char header[8]; int max_bytes; + int error; + int max; + int lcode; + struct timeval time; + fd_set rd_set; + + LLOGLN(10, ("get_message:")); + max = g_sck + 1; + while (1) + { + LLOGLN(10, ("get_message: loop")); + time.tv_sec = 1; + time.tv_usec = 0; + FD_ZERO(&rd_set); + FD_SET(((unsigned int)g_sck), &rd_set); + error = select(max, &rd_set, 0, 0, &time); + if (error == 1) + { + pthread_mutex_lock(&g_mutex); + time.tv_sec = 0; + time.tv_usec = 0; + FD_ZERO(&rd_set); + FD_SET(((unsigned int)g_sck), &rd_set); + error = select(max, &rd_set, 0, 0, &time); + if (error == 1) + { + if (recv(g_sck, header, 8, MSG_PEEK) == 8) + { + lcode = GET_UINT32(header, 4); + if (lcode == *code) + { + /* still have mutex lock */ + break; + } + } + } + pthread_mutex_unlock(&g_mutex); + } + } if (recv(g_sck, header, 8, 0) != 8) { + pthread_mutex_unlock(&g_mutex); return 1; } max_bytes = *bytes; @@ -272,12 +316,15 @@ get_message(int *code, char *data, int *bytes) *code = GET_UINT32(header, 4); if (*bytes > max_bytes) { + pthread_mutex_unlock(&g_mutex); return 1; } if (recv(g_sck, data, *bytes, 0) != *bytes) { + pthread_mutex_unlock(&g_mutex); return 1; } + pthread_mutex_unlock(&g_mutex); return 0; } @@ -302,28 +349,24 @@ SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, return SCARD_F_INTERNAL_ERROR; } } - pthread_mutex_lock(&g_mutex); SET_UINT32(msg, 0, dwScope); if (send_message(SCARD_ESTABLISH_CONTEXT, msg, 4) != 0) { LLOGLN(0, ("SCardEstablishContext: error, send_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } bytes = 256; + code = SCARD_ESTABLISH_CONTEXT; if (get_message(&code, msg, &bytes) != 0) { LLOGLN(0, ("SCardEstablishContext: error, get_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } if ((code != SCARD_ESTABLISH_CONTEXT) || (bytes != 8)) { LLOGLN(0, ("SCardEstablishContext: error, bad code")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_unlock(&g_mutex); context = GET_UINT32(msg, 0); status = GET_UINT32(msg, 4); LLOGLN(10, ("SCardEstablishContext: got context 0x%8.8x", context)); @@ -346,28 +389,24 @@ SCardReleaseContext(SCARDCONTEXT hContext) LLOGLN(0, ("SCardReleaseContext: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); SET_UINT32(msg, 0, hContext); if (send_message(SCARD_RELEASE_CONTEXT, msg, 4) != 0) { LLOGLN(0, ("SCardReleaseContext: error, send_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } bytes = 256; + code = SCARD_RELEASE_CONTEXT; if (get_message(&code, msg, &bytes) != 0) { LLOGLN(0, ("SCardReleaseContext: error, get_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } if ((code != SCARD_RELEASE_CONTEXT) || (bytes != 4)) { LLOGLN(0, ("SCardReleaseContext: error, bad code")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_unlock(&g_mutex); status = GET_UINT32(msg, 0); LLOGLN(10, ("SCardReleaseContext: got status 0x%8.8x", status)); return status; @@ -383,8 +422,6 @@ SCardIsValidContext(SCARDCONTEXT hContext) LLOGLN(0, ("SCardIsValidContext: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); - pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -425,27 +462,23 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, offset += 4; SET_UINT32(msg, offset, dwPreferredProtocols); offset += 4; - pthread_mutex_lock(&g_mutex); if (send_message(SCARD_CONNECT, msg, offset) != 0) { LLOGLN(0, ("SCardConnect: error, send_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } bytes = 256; + code = SCARD_CONNECT; if (get_message(&code, msg, &bytes) != 0) { LLOGLN(0, ("SCardConnect: error, get_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } if (code != SCARD_CONNECT) { LLOGLN(0, ("SCardConnect: error, bad code")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_unlock(&g_mutex); *phCard = GET_UINT32(msg, 0); *pdwActiveProtocol = GET_UINT32(msg, 4); status = GET_UINT32(msg, 8); @@ -465,8 +498,6 @@ SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, LLOGLN(0, ("SCardReconnect: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); - pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -485,29 +516,25 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) LLOGLN(0, ("SCardDisconnect: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); SET_UINT32(msg, 0, hCard); SET_UINT32(msg, 4, dwDisposition); if (send_message(SCARD_DISCONNECT, msg, 8) != 0) { LLOGLN(0, ("SCardDisconnect: error, send_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } bytes = 256; + code = SCARD_DISCONNECT; if (get_message(&code, msg, &bytes) != 0) { LLOGLN(0, ("SCardDisconnect: error, get_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } if ((code != SCARD_DISCONNECT) || (bytes != 4)) { LLOGLN(0, ("SCardDisconnect: error, bad code")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_unlock(&g_mutex); status = GET_UINT32(msg, 0); LLOGLN(10, ("SCardDisconnect: got status 0x%8.8x", status)); return status; @@ -528,28 +555,24 @@ SCardBeginTransaction(SCARDHANDLE hCard) LLOGLN(0, ("SCardBeginTransaction: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); SET_UINT32(msg, 0, hCard); if (send_message(SCARD_BEGIN_TRANSACTION, msg, 4) != 0) { LLOGLN(0, ("SCardBeginTransaction: error, send_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } bytes = 256; + code = SCARD_BEGIN_TRANSACTION; if (get_message(&code, msg, &bytes) != 0) { LLOGLN(0, ("SCardBeginTransaction: error, get_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } if ((code != SCARD_BEGIN_TRANSACTION) || (bytes != 4)) { LLOGLN(0, ("SCardBeginTransaction: error, bad code")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_unlock(&g_mutex); status = GET_UINT32(msg, 0); LLOGLN(10, ("SCardBeginTransaction: got status 0x%8.8x", status)); return status; @@ -570,29 +593,25 @@ SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition) LLOGLN(0, ("SCardEndTransaction: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); SET_UINT32(msg, 0, hCard); SET_UINT32(msg, 4, dwDisposition); if (send_message(SCARD_END_TRANSACTION, msg, 8) != 0) { LLOGLN(0, ("SCardEndTransaction: error, send_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } bytes = 256; + code = SCARD_END_TRANSACTION; if (get_message(&code, msg, &bytes) != 0) { LLOGLN(0, ("SCardEndTransaction: error, get_message")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } if ((code != SCARD_END_TRANSACTION) || (bytes != 4)) { LLOGLN(0, ("SCardEndTransaction: error, bad code")); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_unlock(&g_mutex); status = GET_UINT32(msg, 0); LLOGLN(10, ("SCardEndTransaction: got status 0x%8.8x", status)); return status; @@ -627,30 +646,26 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, 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; + code = SCARD_STATUS; 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); LLOGLN(10, ("SCardStatus: cchReaderLen in %d", *pcchReaderLen)); offset = 0; @@ -693,12 +708,17 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout, LPSCARD_READERSTATE rgReaderStates, DWORD cReaders) { char *msg; + const char *rname; int bytes; int code; int index; int offset; int str_len; int status; + int dwCurrentState; + int dwEventState; + int cbAtr; + char atr[36]; LLOGLN(10, ("SCardGetStatusChange:")); LLOGLN(10, (" dwTimeout %d cReaders %d", dwTimeout, cReaders)); @@ -714,69 +734,79 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout, offset = 12; for (index = 0; index < cReaders; index++) { - if (rgReaderStates[index].dwCurrentState == 0) /* SCARD_STATE_UNAWARE */ + rname = rgReaderStates[index].szReader; + if (strcmp(rname, "\\\\?PnP?\\Notification") == 0) + { + LLOGLN(10, (" found \\\\?PnP?\\Notification")); + dwCurrentState = 0x00010000; + dwEventState = 0; + cbAtr = 0; + memset(atr, 0, 36); + } + else { - rgReaderStates[index].dwEventState = 0; - rgReaderStates[index].cbAtr = 0; + dwCurrentState = rgReaderStates[index].dwCurrentState; + dwEventState = rgReaderStates[index].dwEventState; + cbAtr = rgReaderStates[index].cbAtr; + memset(atr, 0, 36); + memcpy(atr, rgReaderStates[index].rgbAtr, 33); } - str_len = strlen(rgReaderStates[index].szReader); + str_len = strlen(rname); str_len = LMIN(str_len, 99); memset(msg + offset, 0, 100); - memcpy(msg + offset, rgReaderStates[index].szReader, str_len); - LLOGLN(10, (" in szReader %s", rgReaderStates[index].szReader)); + memcpy(msg + offset, rname, str_len); + LLOGLN(10, (" in szReader %s", rname)); offset += 100; - LLOGLN(10, (" in dwCurrentState 0x%8.8x", rgReaderStates[index].dwCurrentState)); - SET_UINT32(msg, offset, rgReaderStates[index].dwCurrentState); + LLOGLN(10, (" in dwCurrentState 0x%8.8x", dwCurrentState)); + SET_UINT32(msg, offset, dwCurrentState); offset += 4; - LLOGLN(10, (" in dwEventState 0x%8.8x", rgReaderStates[index].dwEventState)); - SET_UINT32(msg, offset, rgReaderStates[index].dwEventState); + LLOGLN(10, (" in dwEventState 0x%8.8x", dwEventState)); + SET_UINT32(msg, offset, dwEventState); offset += 4; - LLOGLN(10, (" in cbAtr %d", rgReaderStates[index].cbAtr)); - SET_UINT32(msg, offset, rgReaderStates[index].cbAtr); + LLOGLN(10, (" in cbAtr %d", cbAtr)); + SET_UINT32(msg, offset, cbAtr); offset += 4; - memset(msg + offset, 0, 36); - memcpy(msg + offset, rgReaderStates[index].rgbAtr, 33); + memcpy(msg + offset, atr, 36); offset += 36; } - pthread_mutex_lock(&g_mutex); if (send_message(SCARD_GET_STATUS_CHANGE, msg, offset) != 0) { LLOGLN(0, ("SCardGetStatusChange: error, send_message")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } bytes = 8192; + code = SCARD_GET_STATUS_CHANGE; if (get_message(&code, msg, &bytes) != 0) { LLOGLN(0, ("SCardGetStatusChange: error, get_message")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } if (code != SCARD_GET_STATUS_CHANGE) { LLOGLN(0, ("SCardGetStatusChange: error, bad code")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_unlock(&g_mutex); cReaders = GET_UINT32(msg, 0); offset = 4; LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", cReaders)); for (index = 0; index < cReaders; index++) { LLOGLN(10, (" out szReader %s", rgReaderStates[index].szReader)); - rgReaderStates[index].dwCurrentState = GET_UINT32(msg, offset); + dwCurrentState = GET_UINT32(msg, offset); + rgReaderStates[index].dwCurrentState = dwCurrentState; offset += 4; - LLOGLN(10, (" out dwCurrentState 0x%8.8x", rgReaderStates[index].dwCurrentState)); - rgReaderStates[index].dwEventState = GET_UINT32(msg, offset); + LLOGLN(10, (" out dwCurrentState 0x%8.8x", dwCurrentState)); + dwEventState = GET_UINT32(msg, offset); + rgReaderStates[index].dwEventState = dwEventState; offset += 4; - LLOGLN(10, (" out dwEventState 0x%8.8x", rgReaderStates[index].dwEventState)); - rgReaderStates[index].cbAtr = GET_UINT32(msg, offset); + LLOGLN(10, (" out dwEventState 0x%8.8x", dwEventState)); + cbAtr = GET_UINT32(msg, offset); + rgReaderStates[index].cbAtr = cbAtr; offset += 4; - LLOGLN(10, (" out cbAtr %d", rgReaderStates[index].cbAtr)); + LLOGLN(10, (" out cbAtr %d", cbAtr)); memcpy(rgReaderStates[index].rgbAtr, msg + offset, 33); offset += 36; } @@ -831,30 +861,26 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, offset += cbSendLength; SET_UINT32(msg, offset, cbRecvLength); offset += 4; - pthread_mutex_lock(&g_mutex); if (send_message(SCARD_CONTROL, msg, offset) != 0) { LLOGLN(0, ("SCardControl: error, send_message")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } bytes = 8192; + code = SCARD_CONTROL; if (get_message(&code, msg, &bytes) != 0) { LLOGLN(0, ("SCardControl: error, get_message")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } if (code != SCARD_CONTROL) { LLOGLN(0, ("SCardControl: error, bad code")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_unlock(&g_mutex); offset = 0; *lpBytesReturned = GET_UINT32(msg, offset); LLOGLN(10, (" cbRecvLength %d", *lpBytesReturned)); @@ -937,30 +963,26 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, } SET_UINT32(msg, offset, *pcbRecvLength); offset += 4; - pthread_mutex_lock(&g_mutex); if (send_message(SCARD_TRANSMIT, msg, offset) != 0) { LLOGLN(0, ("SCardTransmit: error, send_message")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } bytes = 8192; + code = SCARD_TRANSMIT; if (get_message(&code, msg, &bytes) != 0) { LLOGLN(0, ("SCardTransmit: error, get_message")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } if (code != SCARD_TRANSMIT) { LLOGLN(0, ("SCardTransmit: error, bad code")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_unlock(&g_mutex); offset = 0; if (pioRecvPci == 0) { @@ -1000,8 +1022,6 @@ SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups, LLOGLN(0, ("SCardListReaderGroups: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); - pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -1033,7 +1053,6 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, return SCARD_F_INTERNAL_ERROR; } msg = (char *) malloc(8192); - pthread_mutex_lock(&g_mutex); offset = 0; SET_UINT32(msg, offset, hContext); offset += 4; @@ -1053,25 +1072,22 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, { LLOGLN(0, ("SCardListReaders: error, send_message")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } bytes = 8192; + code = SCARD_LIST_READERS; if (get_message(&code, msg, &bytes) != 0) { LLOGLN(0, ("SCardListReaders: error, get_message")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } if (code != SCARD_LIST_READERS) { LLOGLN(0, ("SCardListReaders: error, bad code")); free(msg); - pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_unlock(&g_mutex); offset = 0; llen = GET_UINT32(msg, offset); offset += 4; @@ -1095,10 +1111,11 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, reader_names[reader_names_index] = 0; reader_names_index++; status = GET_UINT32(msg, offset); + LLOGLN(10, ("SCardListReaders: status 0x%8.8x", status)); offset += 4; if (mszReaders == 0) { - reader_names_index = llen; + reader_names_index = llen / 2; } if (pcchReaders != 0) { @@ -1123,8 +1140,6 @@ SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem) LLOGLN(0, ("SCardFreeMemory: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); - pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -1138,8 +1153,6 @@ SCardCancel(SCARDCONTEXT hContext) LLOGLN(0, ("SCardCancel: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); - pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -1154,8 +1167,6 @@ SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LLOGLN(0, ("SCardGetAttrib: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); - pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -1170,8 +1181,6 @@ SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, LLOGLN(0, ("SCardSetAttrib: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); - pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c index e1bbbf78..edd97803 100644 --- a/sesman/chansrv/smartcard.c +++ b/sesman/chansrv/smartcard.c @@ -337,7 +337,7 @@ scard_deinit(void) * *****************************************************************************/ int APP_CC -scard_send_establish_context(struct trans *con, int scope) +scard_send_establish_context(void *user_data, int scope) { IRP *irp; @@ -352,7 +352,7 @@ scard_send_establish_context(struct trans *con, int scope) irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_EstablishContext_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_EstablishContext(irp, scope); @@ -364,7 +364,7 @@ scard_send_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) +scard_send_release_context(void *user_data, tui32 context) { IRP *irp; @@ -379,7 +379,7 @@ scard_send_release_context(struct trans *con, tui32 context) irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_ReleaseContext_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_ReleaseContext(irp, context); @@ -391,7 +391,7 @@ scard_send_release_context(struct trans *con, tui32 context) * Checks if a previously established context is still valid *****************************************************************************/ int APP_CC -scard_send_is_valid_context(struct trans *con, tui32 context) +scard_send_is_valid_context(void *user_data, tui32 context) { IRP *irp; @@ -406,7 +406,7 @@ scard_send_is_valid_context(struct trans *con, tui32 context) irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_IsContextValid_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_IsContextValid(irp, context); @@ -418,7 +418,7 @@ scard_send_is_valid_context(struct trans *con, tui32 context) * *****************************************************************************/ int APP_CC -scard_send_list_readers(struct trans *con, tui32 context, char *groups, +scard_send_list_readers(void *user_data, tui32 context, char *groups, int cchReaders, int wide) { IRP *irp; @@ -433,7 +433,7 @@ scard_send_list_readers(struct trans *con, tui32 context, char *groups, irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_ListReaders_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_ListReaders(irp, context, groups, cchReaders, wide); @@ -451,7 +451,7 @@ scard_send_list_readers(struct trans *con, tui32 context, char *groups, * @param rsa array of READER_STATEs *****************************************************************************/ int APP_CC -scard_send_get_status_change(struct trans *con, tui32 context, int wide, +scard_send_get_status_change(void *user_data, tui32 context, int wide, tui32 timeout, tui32 num_readers, READER_STATE* rsa) { @@ -468,7 +468,7 @@ scard_send_get_status_change(struct trans *con, tui32 context, int wide, irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_GetStatusChange_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_GetStatusChange(irp, context, wide, timeout, num_readers, rsa); @@ -483,7 +483,7 @@ scard_send_get_status_change(struct trans *con, tui32 context, int wide, * @param wide TRUE if unicode string *****************************************************************************/ int APP_CC -scard_send_connect(struct trans *con, tui32 context, int wide, +scard_send_connect(void *user_data, tui32 context, int wide, READER_STATE* rs) { IRP *irp; @@ -499,7 +499,7 @@ scard_send_connect(struct trans *con, tui32 context, int wide, irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_Connect_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_Connect(irp, context, wide, rs); @@ -519,7 +519,7 @@ scard_send_connect(struct trans *con, tui32 context, int wide, * rs.init_type *****************************************************************************/ int APP_CC -scard_send_reconnect(struct trans *con, tui32 context, tui32 sc_handle, +scard_send_reconnect(void *user_data, tui32 context, tui32 sc_handle, READER_STATE* rs) { IRP *irp; @@ -535,7 +535,7 @@ scard_send_reconnect(struct trans *con, tui32 context, tui32 sc_handle, irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_Reconnect_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_Reconnect(irp, context, sc_handle, rs); @@ -550,7 +550,7 @@ scard_send_reconnect(struct trans *con, tui32 context, tui32 sc_handle, * @param con connection to client *****************************************************************************/ int APP_CC -scard_send_begin_transaction(struct trans *con, tui32 sc_handle) +scard_send_begin_transaction(void *user_data, tui32 sc_handle) { IRP *irp; @@ -565,7 +565,7 @@ scard_send_begin_transaction(struct trans *con, tui32 sc_handle) irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_BeginTransaction_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_BeginTransaction(irp, sc_handle); @@ -581,7 +581,7 @@ scard_send_begin_transaction(struct trans *con, tui32 sc_handle) * @param sc_handle handle to smartcard *****************************************************************************/ int APP_CC -scard_send_end_transaction(struct trans *con, tui32 sc_handle, +scard_send_end_transaction(void *user_data, tui32 sc_handle, tui32 dwDisposition) { IRP *irp; @@ -597,7 +597,7 @@ scard_send_end_transaction(struct trans *con, tui32 sc_handle, irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_EndTransaction_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_EndTransaction(irp, sc_handle, dwDisposition); @@ -612,7 +612,7 @@ 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(void *user_data, int wide, tui32 sc_handle, int cchReaderLen, int cbAtrLen) { IRP *irp; @@ -628,7 +628,7 @@ scard_send_status(struct trans *con, int wide, tui32 sc_handle, irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_Status_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_Status(irp, wide, sc_handle, cchReaderLen, cbAtrLen); @@ -643,7 +643,7 @@ scard_send_status(struct trans *con, int wide, tui32 sc_handle, * @param sc_handle handle to smartcard *****************************************************************************/ int APP_CC -scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle, +scard_send_disconnect(void *user_data, tui32 context, tui32 sc_handle, int dwDisposition) { IRP *irp; @@ -659,7 +659,7 @@ scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle, irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_Disconnect_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_Disconnect(irp, context, sc_handle, dwDisposition); @@ -672,7 +672,7 @@ scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle, * associated with a valid context. *****************************************************************************/ int APP_CC -scard_send_transmit(struct trans *con, tui32 sc_handle, +scard_send_transmit(void *user_data, 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) @@ -690,7 +690,7 @@ scard_send_transmit(struct trans *con, tui32 sc_handle, irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_Transmit_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_Transmit(irp, sc_handle, send_data, send_bytes, recv_bytes, @@ -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 sc_handle, +scard_send_control(void *user_data, tui32 sc_handle, char *send_data, int send_bytes, int recv_bytes, int control_code) { @@ -720,7 +720,7 @@ scard_send_control(struct trans *con, tui32 sc_handle, irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_Control_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_Control(irp, sc_handle, send_data, @@ -733,7 +733,7 @@ scard_send_control(struct trans *con, tui32 sc_handle, * Cancel any outstanding calls *****************************************************************************/ int APP_CC -scard_send_cancel(struct trans *con, tui32 context) +scard_send_cancel(void *user_data, tui32 context) { IRP *irp; @@ -748,7 +748,7 @@ scard_send_cancel(struct trans *con, tui32 context) irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_Cancel_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_Cancel(irp, context); @@ -760,7 +760,7 @@ scard_send_cancel(struct trans *con, tui32 context) * Get reader attributes *****************************************************************************/ int APP_CC -scard_send_get_attrib(struct trans *con, tui32 sc_handle, READER_STATE* rs) +scard_send_get_attrib(void *user_data, tui32 sc_handle, READER_STATE* rs) { IRP *irp; @@ -775,7 +775,7 @@ scard_send_get_attrib(struct trans *con, tui32 sc_handle, READER_STATE* rs) irp->CompletionId = g_completion_id++; irp->DeviceId = g_device_id; irp->callback = scard_handle_GetAttrib_Return; - irp->user_data = con; + irp->user_data = user_data; /* send IRP to client */ scard_send_GetAttrib(irp, sc_handle, rs); @@ -2060,24 +2060,20 @@ scard_send_Cancel(IRP *irp, tui32 context) return 1; } - /* - * command format - * - * ...... - * 20 bytes padding - * u32 4 bytes len 8, LE, v1 - * u32 4 bytes filler - * 16 bytes unused (s->p currently pointed here at unused[0]) - * u32 4 bytes context len - * u32 4 bytes context - */ - - xstream_seek(s, 16); - xstream_wr_u32_le(s, 4); - xstream_wr_u32_le(s, context); + s_push_layer(s, mcs_hdr, 4); /* bytes, set later */ + out_uint32_le(s, 0x00000000); + out_uint32_le(s, 0x00000004); + out_uint32_le(s, 0x00020000); + out_uint32_le(s, 4); + out_uint32_le(s, context); 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; @@ -2171,7 +2167,6 @@ scard_handle_EstablishContext_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); /* sanity check */ @@ -2182,8 +2177,7 @@ scard_handle_EstablishContext_Return(struct stream *s, IRP *irp, } /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - con = (struct trans *) (irp->user_data); - scard_function_establish_context_return(con, s, len, IoStatus); + scard_function_establish_context_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2197,7 +2191,6 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); /* sanity check */ @@ -2208,8 +2201,7 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp, } /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - con = (struct trans *) (irp->user_data); - scard_function_release_context_return(con, s, len, IoStatus); + scard_function_release_context_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2223,7 +2215,6 @@ APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2236,8 +2227,7 @@ 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, IoStatus); + scard_function_is_context_valid_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2251,7 +2241,6 @@ scard_handle_ListReaders_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); /* sanity check */ @@ -2262,8 +2251,7 @@ scard_handle_ListReaders_Return(struct stream *s, IRP *irp, } /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - con = (struct trans *) (irp->user_data); - scard_function_list_readers_return(con, s, len, IoStatus); + scard_function_list_readers_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2277,7 +2265,6 @@ scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); /* sanity check */ @@ -2288,8 +2275,7 @@ scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp, } /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - con = (struct trans *) (irp->user_data); - scard_function_get_status_change_return(con, s, len, IoStatus); + scard_function_get_status_change_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2303,7 +2289,6 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2317,8 +2302,7 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - con = (struct trans *) (irp->user_data); - scard_function_connect_return(con, s, len, IoStatus); + scard_function_connect_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); @@ -2333,7 +2317,6 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2346,8 +2329,7 @@ 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, IoStatus); + scard_function_reconnect_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2361,7 +2343,6 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2374,8 +2355,7 @@ 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, IoStatus); + scard_function_begin_transaction_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2389,7 +2369,6 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2402,8 +2381,7 @@ 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, IoStatus); + scard_function_end_transaction_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2417,7 +2395,6 @@ scard_handle_Status_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2430,8 +2407,7 @@ 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, IoStatus); + scard_function_status_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2445,7 +2421,6 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2458,8 +2433,7 @@ 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, IoStatus); + scard_function_disconnect_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2472,7 +2446,6 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2485,8 +2458,7 @@ 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, IoStatus); + scard_function_transmit_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2499,7 +2471,6 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId,tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2512,8 +2483,7 @@ 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, IoStatus); + scard_function_control_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2526,7 +2496,6 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2539,8 +2508,7 @@ 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, IoStatus); + scard_function_cancel_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } @@ -2553,7 +2521,6 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus) { tui32 len; - struct trans *con; log_debug("entered"); @@ -2566,8 +2533,7 @@ 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, IoStatus); + scard_function_get_attrib_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); log_debug("leaving"); } diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h index 94abf2b6..437bbdbf 100644 --- a/sesman/chansrv/smartcard.h +++ b/sesman/chansrv/smartcard.h @@ -110,42 +110,42 @@ int APP_CC scard_get_wait_objs(tbus *objs, int *count, int *timeout); 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_establish_context(struct trans *con, int scope); -int APP_CC scard_send_release_context(struct trans *con, tui32 context); -int APP_CC scard_send_is_valid_context(struct trans *con, tui32 context); -int APP_CC scard_send_list_readers(struct trans *con, tui32 context, +int APP_CC scard_send_establish_context(void *user_data, int scope); +int APP_CC scard_send_release_context(void *user_data, tui32 context); +int APP_CC scard_send_is_valid_context(void *user_data, tui32 context); +int APP_CC scard_send_list_readers(void *user_data, tui32 context, char *groups, int cchReaders, int wide); -int APP_CC scard_send_get_status_change(struct trans *con, tui32 context, +int APP_CC scard_send_get_status_change(void *user_data, tui32 context, int wide, tui32 timeout, tui32 num_readers, READER_STATE* rsa); -int APP_CC scard_send_connect(struct trans *con, tui32 context, int wide, +int APP_CC scard_send_connect(void *user_data, tui32 context, int wide, READER_STATE* rs); -int APP_CC scard_send_reconnect(struct trans *con, tui32 context, +int APP_CC scard_send_reconnect(void *user_data, tui32 context, tui32 sc_handle, READER_STATE* rs); -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, +int APP_CC scard_send_begin_transaction(void *user_data, tui32 sc_handle); +int APP_CC scard_send_end_transaction(void *user_data, 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(void *user_data, int wide, tui32 sc_handle, int cchReaderLen, int cbAtrLen); -int APP_CC scard_send_disconnect(struct trans *con, tui32 context, +int APP_CC scard_send_disconnect(void *user_data, tui32 context, tui32 sc_handle, int dwDisposition); -int APP_CC scard_send_transmit(struct trans *con, tui32 sc_handle, +int APP_CC scard_send_transmit(void *user_data, 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); -int APP_CC scard_send_control(struct trans *con, tui32 sc_handle, +int APP_CC scard_send_control(void *user_data, tui32 sc_handle, char *send_data, int send_bytes, int recv_bytes, int control_code); -int APP_CC scard_send_cancel(struct trans *con, tui32 context); +int APP_CC scard_send_cancel(void *user_data, tui32 context); -int APP_CC scard_send_get_attrib(struct trans *con, tui32 sc_handle, +int APP_CC scard_send_get_attrib(void *user_data, tui32 sc_handle, READER_STATE* rs); /* diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c index ebf52c82..95c01a04 100644 --- a/sesman/chansrv/smartcard_pcsc.c +++ b/sesman/chansrv/smartcard_pcsc.c @@ -35,6 +35,7 @@ #include "devredir.h" #include "trans.h" #include "chansrv.h" +#include "list.h" #if PCSC_STANDIN @@ -63,42 +64,242 @@ #define XRDP_PCSC_STATE_GOT_D (1 << 9) /* disconnect */ #define XRDP_PCSC_STATE_GOT_ST (1 << 10) /* get status */ +#if 0 /* TODO: put this in con */ -static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE; +static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE; /* 0 */ static int g_xrdp_pcsc_extra1; +#endif extern int g_display_num; /* in chansrv.c */ +static int g_uds_client_id = 0; /* auto incremented for each unix domain + socket connection */ + +struct pcsc_card /* item for list of open cards in one context */ +{ + tui32 card; +}; + +struct pcsc_context +{ + tui32 context; + struct list *cards; /* these need to be released on close */ +}; + /*****************************************************************************/ -struct pcsc_client +struct pcsc_uds_client { + int uds_client_id; /* from g_uds_client_id */ struct trans *con; + struct list *contexts; /* struct pcsc_context */ + int pcsc_state; + int pcsc_extra1; }; -#if 0 -static struct pcsc_client *g_head = 0; -static struct pcsc_client *g_tail = 0; -#endif +static struct list *g_uds_clients = 0; /* struct pcsc_uds_client */ static struct trans *g_lis = 0; +#if 0 static struct trans *g_con = 0; /* todo, remove this */ +#endif static char g_pcsclite_ipc_dir[256] = ""; static char g_pcsclite_ipc_file[256] = ""; -static int g_pub_file_fd = 0; + +/*****************************************************************************/ +/* got a new unix domain socket connection */ +static struct pcsc_uds_client * +create_uds_client(struct trans *con) +{ + struct pcsc_uds_client *uds_client; + + LLOGLN(10, ("create_uds_client:")); + if (con == 0) + { + return 0; + } + uds_client = g_malloc(sizeof(struct pcsc_uds_client), 1); + if (uds_client == 0) + { + return 0; + } + g_uds_client_id++; + uds_client->uds_client_id = g_uds_client_id; + uds_client->con = con; + con->callback_data = uds_client; + return uds_client; +} + +/*****************************************************************************/ +static struct pcsc_uds_client * +get_uds_client_by_id(int uds_client_id) +{ + struct pcsc_uds_client *uds_client; + int index; + + LLOGLN(10, ("get_uds_client_by_id:")); + if (uds_client_id == 0) + { + LLOGLN(10, ("get_uds_client_by_id: uds_client_id zero")); + return 0; + } + if (g_uds_clients == 0) + { + LLOGLN(10, ("get_uds_client_by_id: g_uds_clients is nil")); + return 0; + } + LLOGLN(10, (" count %d", g_uds_clients->count)); + for (index = 0; index < g_uds_clients->count; index++) + { + uds_client = (struct pcsc_uds_client *) + list_get_item(g_uds_clients, index); + if (uds_client->uds_client_id == uds_client_id) + { + return uds_client; + } + } + LLOGLN(10, ("get_uds_client_by_id: can't find uds_client_id %d", + uds_client_id)); + return 0; +} + +/*****************************************************************************/ +static int +free_uds_client(struct pcsc_uds_client *uds_client) +{ + int i; + int j; + struct pcsc_context *context; + struct pcsc_card *card; + + LLOGLN(10, ("free_uds_client:")); + if (uds_client == 0) + { + return 0; + } + if (uds_client->contexts != 0) + { + for (i = 0; i < uds_client->contexts->count; i++) + { + context = (struct pcsc_context *) + list_get_item(uds_client->contexts, i); + if (context != 0) + { + if (context->cards != 0) + { + for (j = 0; j < context->cards->count; j++) + { + card = (struct pcsc_card *) + list_get_item(context->cards, j); + if (card != 0) + { + /* TODO: send free card to client */ + g_free(card); + } + } + list_delete(context->cards); + } + LLOGLN(10, (" left over context 0x%8.8x", context->context)); + scard_send_cancel(0, context->context); + scard_send_release_context(0, context->context); + g_free(context); + } + } + list_delete(uds_client->contexts); + } + trans_delete(uds_client->con); + g_free(uds_client); + return 0; +} + +/*****************************************************************************/ +static int +uds_client_add_context(struct pcsc_uds_client *uds_client, tui32 context) +{ + struct pcsc_context *pcscContext; + + LLOGLN(10, ("uds_client_add_context:")); + pcscContext = (struct pcsc_context * ) + g_malloc(sizeof(struct pcsc_context), 1); + if (pcscContext == 0) + { + LLOGLN(0, ("uds_client_add_context: error")); + return 1; + } + pcscContext->context = context; + if (uds_client->contexts == 0) + { + uds_client->contexts = list_create(); + if (uds_client->contexts == 0) + { + LLOGLN(0, ("uds_client_add_context: error")); + return 1; + } + } + list_add_item(uds_client->contexts, (tintptr) pcscContext); + return 0; +} + +/*****************************************************************************/ +static int +uds_client_remove_context(struct pcsc_uds_client *uds_client, tui32 context) +{ + int index; + struct pcsc_context *pcscContext; + + LLOGLN(10, ("uds_client_remove_context:")); + if (uds_client->contexts == 0) + { + LLOGLN(0, ("uds_client_remove_context: error")); + return 1; + } + for (index = 0; index < uds_client->contexts->count; index++) + { + pcscContext = (struct pcsc_context *) + list_get_item(uds_client->contexts, index); + if (pcscContext != 0) + { + if (pcscContext->context == context) + { + list_remove_item(uds_client->contexts, index); + g_free(pcscContext); + return 0; + } + } + } + LLOGLN(10, ("uds_client_remove_context: not found")); + return 1; +} /*****************************************************************************/ int APP_CC scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout) { - LLOGLN(10, ("scard_pcsc_get_wait_objs")); + struct pcsc_uds_client *uds_client; + int index; + + LLOGLN(10, ("scard_pcsc_get_wait_objs:")); if (g_lis != 0) { trans_get_wait_objs(g_lis, objs, count); } +#if 0 if (g_con != 0) { trans_get_wait_objs(g_con, objs, count); } +#endif + if (g_uds_clients != 0) + { + for (index = 0; index < g_uds_clients->count; index++) + { + uds_client = (struct pcsc_uds_client *) + list_get_item(g_uds_clients, index); + if (uds_client != 0) + { + trans_get_wait_objs(uds_client->con, objs, count); + } + } + } return 0; } @@ -106,6 +307,9 @@ scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout) int APP_CC scard_pcsc_check_wait_objs(void) { + struct pcsc_uds_client *uds_client; + int index; + LLOGLN(10, ("scard_pcsc_check_wait_objs:")); if (g_lis != 0) { @@ -114,6 +318,7 @@ scard_pcsc_check_wait_objs(void) LLOGLN(0, ("scard_pcsc_check_wait_objs: g_lis trans_check_wait_objs error")); } } +#if 0 if (g_con != 0) { if (trans_check_wait_objs(g_con) != 0) @@ -125,6 +330,26 @@ scard_pcsc_check_wait_objs(void) g_xrdp_pcsc_state = 0; } } +#endif + if (g_uds_clients != 0) + { + index = 0; + while (index < g_uds_clients->count) + { + uds_client = (struct pcsc_uds_client *) + list_get_item(g_uds_clients, index); + if (uds_client != 0) + { + if (trans_check_wait_objs(uds_client->con) != 0) + { + free_uds_client(uds_client); + list_remove_item(g_uds_clients, index); + continue; + } + } + index++; + } + } return 0; } @@ -134,42 +359,58 @@ int APP_CC scard_process_establish_context(struct trans *con, struct stream *in_s) { int dwScope; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_establish_context:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_EC) { LLOGLN(0, ("scard_process_establish_context: opps")); return 1; } - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_EC; + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_EC; in_uint32_le(in_s, dwScope); LLOGLN(10, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope)); - scard_send_establish_context(con, dwScope); + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_establish_context(user_data, dwScope); return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_establish_context_return(struct trans *con, +scard_function_establish_context_return(void *user_data, struct stream *in_s, int len, int status) { int bytes; + int uds_client_id; tui32 context; tui32 context_len; struct stream *out_s; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_establish_context_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - //g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_establish_context_return: " + "get_uds_client_by_id failed")); + return 1; + } + con = uds_client->con; + if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0) { LLOGLN(0, ("scard_function_establish_context_return: opps " - "g_xrdp_pcsc_state 0x%8.8x, g_xrdp_pcsc_state")); + "uds_client->pcsc_state 0x%8.8x", uds_client->pcsc_state)); return 1; } - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC; context = 0; if (status == 0) { @@ -182,8 +423,9 @@ scard_function_establish_context_return(struct trans *con, return 1; } in_uint32_le(in_s, context); - LLOGLN(10, ("scard_function_establish_context_return: context 0x%8.8x", - context)); + uds_client_add_context(uds_client, context); + LLOGLN(10, ("scard_function_establish_context_return: " + "context 0x%8.8x", context)); } out_s = trans_get_out_s(con, 8192); s_push_layer(out_s, iso_hdr, 8); @@ -203,38 +445,56 @@ int APP_CC scard_process_release_context(struct trans *con, struct stream *in_s) { int hContext; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_release_context:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->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; + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_RC; in_uint32_le(in_s, hContext); LLOGLN(10, ("scard_process_release_context: hContext 0x%8.8x", hContext)); - scard_send_release_context(con, hContext); + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_release_context(user_data, hContext); + uds_client_remove_context(uds_client, hContext); return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_release_context_return(struct trans *con, +scard_function_release_context_return(void *user_data, struct stream *in_s, int len, int status) { int bytes; + int uds_client_id; struct stream *out_s; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_release_context_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_release_context_return: " + "get_uds_client_by_id failed")); + return 1; + } + con = uds_client->con; + if ((uds_client->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; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_RC; out_s = trans_get_out_s(con, 8192); s_push_layer(out_s, iso_hdr, 8); out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */ @@ -255,30 +515,34 @@ scard_process_list_readers(struct trans *con, struct stream *in_s) int bytes_groups; int cchReaders; char *groups; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_list_readers:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_LR) { LLOGLN(0, ("scard_process_list_readers: opps")); return 1; } - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR; + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_LR; in_uint32_le(in_s, hContext); in_uint32_le(in_s, bytes_groups); groups = (char *) g_malloc(bytes_groups + 1, 1); in_uint8a(in_s, groups, bytes_groups); in_uint32_le(in_s, cchReaders); - g_xrdp_pcsc_extra1 = cchReaders; + uds_client->pcsc_extra1 = cchReaders; LLOGLN(10, ("scard_process_list_readers: hContext 0x%8.8x cchReaders %d", hContext, cchReaders)); - scard_send_list_readers(con, hContext, groups, cchReaders, 1); + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_list_readers(user_data, hContext, groups, cchReaders, 1); g_free(groups); return 0; } /*****************************************************************************/ int APP_CC -scard_function_list_readers_return(struct trans *con, +scard_function_list_readers_return(void *user_data, struct stream *in_s, int len, int status) { @@ -290,20 +554,33 @@ scard_function_list_readers_return(struct trans *con, int bytes; int cchReaders; int llen; + int uds_client_id; twchar reader_name[100]; char lreader_name[16][100]; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_list_readers_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - //g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_list_readers_return: " + "get_uds_client_by_id failed, could not find id %d", + uds_client_id)); + return 1; + } + con = uds_client->con; + if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0) { LLOGLN(0, ("scard_function_list_readers_return: opps")); return 1; } - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR; - cchReaders = g_xrdp_pcsc_extra1; + cchReaders = uds_client->pcsc_extra1; g_memset(reader_name, 0, sizeof(reader_name)); g_memset(lreader_name, 0, sizeof(lreader_name)); @@ -358,6 +635,10 @@ scard_function_list_readers_return(struct trans *con, { out_uint8a(out_s, lreader_name[index], 100); } + //if (readers == 0) + //{ + // status = 0x8010002E; /* SCARD_E_NO_READERS_AVAILABLE */ + //} out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */ s_mark_end(out_s); bytes = (int) (out_s->end - out_s->data); @@ -374,15 +655,18 @@ scard_process_connect(struct trans *con, struct stream *in_s) { int hContext; READER_STATE rs; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_connect:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_C) { LLOGLN(0, ("scard_process_connect: opps")); return 1; } g_memset(&rs, 0, sizeof(rs)); - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_C; + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_C; in_uint32_le(in_s, hContext); in_uint8a(in_s, rs.reader_name, 100); in_uint32_le(in_s, rs.dwShareMode); @@ -390,30 +674,43 @@ scard_process_connect(struct trans *con, struct stream *in_s) LLOGLN(10, ("scard_process_connect: rs.reader_name %s dwShareMode 0x%8.8x " "dwPreferredProtocols 0x%8.8x", rs.reader_name, rs.dwShareMode, rs.dwPreferredProtocols)); - scard_send_connect(con, hContext, 1, &rs); + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_connect(user_data, hContext, 1, &rs); return 0; } /*****************************************************************************/ int APP_CC -scard_function_connect_return(struct trans *con, +scard_function_connect_return(void *user_data, struct stream *in_s, int len, int status) { int dwActiveProtocol; int hCard; int bytes; + int uds_client_id; struct stream *out_s; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_connect_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - //g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_connect_return: " + "get_uds_client_by_id failed")); + return 1; + } + con = uds_client->con; + if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_C) == 0) { LLOGLN(0, ("scard_function_connect_return: opps")); return 1; } - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_C; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_C; dwActiveProtocol = 0; hCard = 0; if (status == 0) @@ -445,44 +742,59 @@ scard_process_disconnect(struct trans *con, struct stream *in_s) int hContext; int hCard; int dwDisposition; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_disconnect:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_D) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_D) { LLOGLN(0, ("scard_process_disconnect: opps")); return 1; } - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_D; + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_D; in_uint32_le(in_s, hCard); in_uint32_le(in_s, dwDisposition); hContext = 1; - - scard_send_disconnect(con, hContext, hCard, dwDisposition); + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_disconnect(user_data, hContext, hCard, dwDisposition); return 0; } /*****************************************************************************/ int APP_CC -scard_function_disconnect_return(struct trans *con, +scard_function_disconnect_return(void *user_data, struct stream *in_s, int len, int status) { int dwActiveProtocol; int hCard; int bytes; + int uds_client_id; struct stream *out_s; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_disconnect_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - //g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_D) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_disconnect_return: " + "get_uds_client_by_id failed")); + return 1; + } + con = uds_client->con; + if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_D) == 0) { LLOGLN(0, ("scard_function_connect_return: opps")); return 1; } - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_D; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_D; dwActiveProtocol = 0; hCard = 0; if (status == 0) @@ -511,39 +823,55 @@ int APP_CC scard_process_begin_transaction(struct trans *con, struct stream *in_s) { int hCard; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_begin_transaction:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_BT) { LLOGLN(0, ("scard_process_begin_transaction: opps")); return 1; } - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_BT; + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_BT; in_uint32_le(in_s, hCard); LLOGLN(10, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard)); - scard_send_begin_transaction(con, hCard); + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_begin_transaction(user_data, hCard); return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_begin_transaction_return(struct trans *con, +scard_function_begin_transaction_return(void *user_data, struct stream *in_s, int len, int status) { struct stream *out_s; int bytes; + int uds_client_id; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_begin_transaction_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - //g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_begin_transaction_return: " + "get_uds_client_by_id failed")); + return 1; + } + con = uds_client->con; + if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_BT) == 0) { LLOGLN(0, ("scard_function_begin_transaction_return: opps")); return 1; } - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_BT; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_BT; out_s = trans_get_out_s(con, 8192); s_push_layer(out_s, iso_hdr, 8); out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */ @@ -562,40 +890,56 @@ scard_process_end_transaction(struct trans *con, struct stream *in_s) { int hCard; int dwDisposition; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_end_transaction:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ET) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_ET) { LLOGLN(0, ("scard_process_end_transaction: opps")); return 1; } - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_ET; + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_ET; in_uint32_le(in_s, hCard); in_uint32_le(in_s, dwDisposition); LLOGLN(10, ("scard_process_end_transaction: hCard 0x%8.8x", hCard)); - scard_send_end_transaction(con, hCard, dwDisposition); + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_end_transaction(user_data, hCard, dwDisposition); return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_end_transaction_return(struct trans *con, +scard_function_end_transaction_return(void *user_data, struct stream *in_s, int len, int status) { struct stream *out_s; int bytes; + int uds_client_id; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_end_transaction_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - //g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ET) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_end_transaction_return: " + "get_uds_client_by_id failed")); + return 1; + } + con = uds_client->con; + if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_ET) == 0) { LLOGLN(0, ("scard_function_end_transaction_return: opps")); return 1; } - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_ET; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_ET; out_s = trans_get_out_s(con, 8192); s_push_layer(out_s, iso_hdr, 8); @@ -611,17 +955,19 @@ scard_function_end_transaction_return(struct trans *con, /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_cancel_return(struct trans *con, +scard_function_cancel_return(void *user_data, struct stream *in_s, int len, int status) { + LLOGLN(10, ("scard_function_cancel_return:")); + //g_hexdump(in_s->p, len); return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_get_attrib_return(struct trans *con, +scard_function_get_attrib_return(void *user_data, struct stream *in_s, int len, int status) { @@ -639,14 +985,17 @@ scard_process_transmit(struct trans *con, struct stream *in_s) char *send_data; struct xrdp_scard_io_request send_ior; struct xrdp_scard_io_request recv_ior; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_transmit:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_TR) { LLOGLN(0, ("scard_process_transmit: opps")); return 1; } - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_TR; + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_TR; LLOGLN(10, ("scard_process_transmit:")); in_uint32_le(in_s, hCard); in_uint32_le(in_s, send_ior.dwProtocol); @@ -666,7 +1015,8 @@ scard_process_transmit(struct trans *con, struct stream *in_s) recv_ior.cbPciLength, send_bytes)); //g_hexdump(in_s->p, send_bytes); LLOGLN(10, ("scard_process_transmit: recv_bytes %d", recv_bytes)); - scard_send_transmit(con, hCard, send_data, send_bytes, recv_bytes, + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_transmit(user_data, hCard, send_data, send_bytes, recv_bytes, &send_ior, &recv_ior); return 0; } @@ -674,7 +1024,7 @@ scard_process_transmit(struct trans *con, struct stream *in_s) /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_transmit_return(struct trans *con, +scard_function_transmit_return(void *user_data, struct stream *in_s, int len, int status) { @@ -682,18 +1032,30 @@ scard_function_transmit_return(struct trans *con, int bytes; int val; int cbRecvLength; + int uds_client_id; struct xrdp_scard_io_request recv_ior; char *recvBuf; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_transmit_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - //g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_transmit_return: " + "get_uds_client_by_id failed")); + return 1; + } + con = uds_client->con; + if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_TR) == 0) { LLOGLN(0, ("scard_function_transmit_return: opps")); return 1; } - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_TR; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_TR; g_memset(&recv_ior, 0, sizeof(recv_ior)); cbRecvLength = 0; recvBuf = 0; @@ -752,14 +1114,17 @@ scard_process_control(struct trans *con, struct stream *in_s) int recv_bytes; int control_code; char *send_data; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_control:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_CO) { LLOGLN(0, ("scard_process_control: opps")); return 1; } - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_CO; + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_CO; LLOGLN(10, ("scard_process_control:")); in_uint32_le(in_s, hCard); @@ -768,7 +1133,8 @@ 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); - scard_send_control(con, hCard, send_data, send_bytes, recv_bytes, + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_control(user_data, hCard, send_data, send_bytes, recv_bytes, control_code); return 0; @@ -777,7 +1143,7 @@ scard_process_control(struct trans *con, struct stream *in_s) /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_control_return(struct trans *con, +scard_function_control_return(void *user_data, struct stream *in_s, int len, int status) { @@ -785,16 +1151,28 @@ scard_function_control_return(struct trans *con, int bytes; int cbRecvLength; char *recvBuf; + int uds_client_id; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_control_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - //g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_control_return: " + "get_uds_client_by_id failed")); + return 1; + } + con = uds_client->con; + if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_CO) == 0) { LLOGLN(0, ("scard_function_control_return: opps")); return 1; } - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_CO; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_CO; cbRecvLength = 0; recvBuf = 0; if (status == 0) @@ -825,20 +1203,24 @@ scard_process_status(struct trans *con, struct stream *in_s) int hCard; int cchReaderLen; int cbAtrLen; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_status:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_ST) { LLOGLN(0, ("scard_process_status: opps")); return 1; } - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_ST; + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_ST; 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); + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_status(user_data, 1, hCard, cchReaderLen, cbAtrLen); return 0; } @@ -867,7 +1249,7 @@ static int g_ms2pc[] = { PC_SCARD_UNKNOWN, PC_SCARD_ABSENT, /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_status_return(struct trans *con, +scard_function_status_return(void *user_data, struct stream *in_s, int len, int status) { @@ -881,16 +1263,28 @@ scard_function_status_return(struct trans *con, char attr[32]; twchar reader_name[100]; char lreader_name[100]; + int uds_client_id; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_status_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - //g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_status_return: " + "get_uds_client_by_id failed")); + return 1; + } + con = uds_client->con; + if ((uds_client->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; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_ST; dwReaderLen = 0; dwState = 0; dwProtocol = 0; @@ -947,13 +1341,17 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s) int dwTimeout; int cReaders; READER_STATE *rsa; + struct pcsc_uds_client *uds_client; + void *user_data; LLOGLN(10, ("scard_process_get_status_change:")); - if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC) + uds_client = (struct pcsc_uds_client *) (con->callback_data); + if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_GSC) { LLOGLN(0, ("scard_process_get_status_change: opps")); return 1; } + uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_GSC; in_uint32_le(in_s, hContext); in_uint32_le(in_s, dwTimeout); in_uint32_le(in_s, cReaders); @@ -984,9 +1382,8 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s) LLOGLN(10, ("scard_process_get_status_change: hContext 0x%8.8x dwTimeout " "%d cReaders %d", hContext, dwTimeout, cReaders)); - g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_GSC; - - scard_send_get_status_change(con, hContext, 1, dwTimeout, cReaders, rsa); + user_data = (void *) (tintptr) (uds_client->uds_client_id); + scard_send_get_status_change(user_data, hContext, 1, dwTimeout, cReaders, rsa); g_free(rsa); @@ -995,7 +1392,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s) /*****************************************************************************/ int APP_CC -scard_function_get_status_change_return(struct trans *con, +scard_function_get_status_change_return(void *user_data, struct stream *in_s, int len, int status) { @@ -1007,17 +1404,29 @@ scard_function_get_status_change_return(struct trans *con, tui32 atr_len; /* number of bytes in atr[] */ tui8 atr[36]; struct stream *out_s; + int uds_client_id; + struct pcsc_uds_client *uds_client; + struct trans *con; LLOGLN(10, ("scard_function_get_status_change_return:")); LLOGLN(10, (" status 0x%8.8x", status)); - //g_hexdump(in_s->p, len); - if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC) == 0) + uds_client_id = (int) (tintptr) user_data; + uds_client = (struct pcsc_uds_client *) + get_uds_client_by_id(uds_client_id); + if (uds_client == 0) + { + LLOGLN(0, ("scard_function_get_status_change_return: " + "get_uds_client_by_id failed")); + return 1; + } + con = uds_client->con; + if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_GSC) == 0) { LLOGLN(0, ("scard_function_get_status_change_return: opps " - "g_xrdp_pcsc_state 0x%8.8x", g_xrdp_pcsc_state)); + "g_xrdp_pcsc_state 0x%8.8x", uds_client->pcsc_state)); return 1; } - g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_GSC; + uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_GSC; out_s = trans_get_out_s(con, 8192); s_push_layer(out_s, iso_hdr, 8); @@ -1060,7 +1469,7 @@ scard_function_get_status_change_return(struct trans *con, /*****************************************************************************/ /* returns error */ int APP_CC -scard_function_is_context_valid_return(struct trans *con, +scard_function_is_context_valid_return(void *user_data, struct stream *in_s, int len, int status) { @@ -1069,7 +1478,7 @@ scard_function_is_context_valid_return(struct trans *con, /*****************************************************************************/ /* returns error */ -int APP_CC scard_function_reconnect_return(struct trans *con, +int APP_CC scard_function_reconnect_return(void *user_data, struct stream *in_s, int len, int status) { @@ -1184,10 +1593,6 @@ my_pcsc_trans_data_in(struct trans *trans) { return 0; } - if (trans != g_con) - { - return 1; - } s = trans_get_in_s(trans); in_uint32_le(s, size); in_uint32_le(s, command); @@ -1195,7 +1600,7 @@ my_pcsc_trans_data_in(struct trans *trans) error = trans_force_read(trans, size); if (error == 0) { - error = scard_process_msg(g_con, s, command); + error = scard_process_msg(trans, s, command); } return error; } @@ -1205,6 +1610,8 @@ my_pcsc_trans_data_in(struct trans *trans) int DEFAULT_CC my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans) { + struct pcsc_uds_client *uds_client; + LLOGLN(10, ("my_pcsc_trans_conn_in:")); if (trans == 0) @@ -1222,9 +1629,26 @@ my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans) return 1; } + uds_client = create_uds_client(new_trans); + if (uds_client == 0) + { + return 1; + } + uds_client->con->trans_data_in = my_pcsc_trans_data_in; + uds_client->con->header_size = 8; + + if (g_uds_clients == 0) + { + g_uds_clients = list_create(); + } + list_add_item(g_uds_clients, (tbus)uds_client); + +#if 0 g_con = new_trans; g_con->trans_data_in = my_pcsc_trans_data_in; g_con->header_size = 8; +#endif + return 0; } @@ -1287,12 +1711,6 @@ scard_pcsc_deinit(void) g_lis = 0; } - if (g_pub_file_fd != 0) - { - g_file_close(g_pub_file_fd); - g_pub_file_fd = 0; - } - if (g_pcsclite_ipc_dir[0] != 0) { g_file_delete(g_pcsclite_ipc_file); diff --git a/sesman/chansrv/smartcard_pcsc.h b/sesman/chansrv/smartcard_pcsc.h index 34c74063..b7ca2183 100644 --- a/sesman/chansrv/smartcard_pcsc.h +++ b/sesman/chansrv/smartcard_pcsc.h @@ -28,61 +28,61 @@ 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, +int APP_CC scard_function_establish_context_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_release_context_return(struct trans *con, +int APP_CC scard_function_release_context_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_list_readers_return(struct trans *con, +int APP_CC scard_function_list_readers_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_transmit_return(struct trans *con, +int APP_CC scard_function_transmit_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_control_return(struct trans *con, +int APP_CC scard_function_control_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_get_status_change_return(struct trans *con, +int APP_CC scard_function_get_status_change_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_connect_return(struct trans *con, +int APP_CC scard_function_connect_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_status_return(struct trans *con, +int APP_CC scard_function_status_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_begin_transaction_return(struct trans *con, +int APP_CC scard_function_begin_transaction_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_end_transaction_return(struct trans *con, +int APP_CC scard_function_end_transaction_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_is_context_valid_return(struct trans *con, +int APP_CC scard_function_is_context_valid_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_reconnect_return(struct trans *con, +int APP_CC scard_function_reconnect_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_disconnect_return(struct trans *con, +int APP_CC scard_function_disconnect_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_cancel_return(struct trans *con, +int APP_CC scard_function_cancel_return(void *user_data, struct stream *in_s, int len, int status); -int APP_CC scard_function_get_attrib_return(struct trans *con, +int APP_CC scard_function_get_attrib_return(void *user_data, struct stream *in_s, int len, int status); |