diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index 56aeb0bd..a257f907 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -100,8 +100,8 @@ struct xrdp_client_info char orders[32]; int order_flags_ex; int use_bulk_comp; - int use_fast_path; int pointer_flags; /* 0 color, 1 new, 2 no new */ + int use_fast_path; int require_credentials; /* when true, credentials *must* be passed on cmd line */ char client_addr[256]; char client_port[256]; diff --git a/configure.ac b/configure.ac index e8823350..6c0134e6 100644 --- a/configure.ac +++ b/configure.ac @@ -92,6 +92,11 @@ then [AC_MSG_ERROR([please install libjpeg-dev or libjpeg-devel])]) fi +if ! test -z "$enable_xrdpdebug" +then + CFLAGS="-g -O0" +fi + # checking for fuse if ! test -z "$enable_fuse" then diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c index 289f2c9c..0e2d90d2 100644 --- a/libxrdp/xrdp_orders.c +++ b/libxrdp/xrdp_orders.c @@ -207,6 +207,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size) } else { + xrdp_orders_init(self); return 0; } } @@ -469,7 +470,10 @@ xrdp_orders_rect(struct xrdp_orders *self, int x, int y, int cx, int cy, char *present_ptr; char *order_flags_ptr; - xrdp_orders_check(self, 23); + if (xrdp_orders_check(self, 23) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -637,7 +641,10 @@ xrdp_orders_screen_blt(struct xrdp_orders *self, int x, int y, char *present_ptr = (char *)NULL; char *order_flags_ptr = (char *)NULL; - xrdp_orders_check(self, 25); + if (xrdp_orders_check(self, 25) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -826,7 +833,10 @@ xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y, char *order_flags_ptr; struct xrdp_brush blank_brush; - xrdp_orders_check(self, 39); + if (xrdp_orders_check(self, 39) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -1040,7 +1050,10 @@ xrdp_orders_dest_blt(struct xrdp_orders *self, int x, int y, char *present_ptr; char *order_flags_ptr; - xrdp_orders_check(self, 21); + if (xrdp_orders_check(self, 21) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -1208,7 +1221,10 @@ xrdp_orders_line(struct xrdp_orders *self, int mix_mode, rop = 0x0d; /* R2_COPYPEN */ } - xrdp_orders_check(self, 32); + if (xrdp_orders_check(self, 32) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -1407,7 +1423,10 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id, char *present_ptr = (char *)NULL; char *order_flags_ptr = (char *)NULL; - xrdp_orders_check(self, 30); + if (xrdp_orders_check(self, 30) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -1614,7 +1633,10 @@ xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx, int srcformat, char* present_ptr; char* order_flags_ptr; - xrdp_orders_check(self, 80); + if (xrdp_orders_check(self, 80) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; if (self->orders_state.last_order != RDP_ORDER_COMPOSITE) @@ -1940,8 +1962,10 @@ xrdp_orders_text(struct xrdp_orders *self, char *present_ptr = (char *)NULL; char *order_flags_ptr = (char *)NULL; - //xrdp_orders_check(self, 100); - xrdp_orders_check(self, 44+data_len); + if (xrdp_orders_check(self, 44 + data_len) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD; @@ -2127,7 +2151,10 @@ xrdp_orders_send_palette(struct xrdp_orders *self, int *palette, int len; int i; - xrdp_orders_check(self, 2000); + if (xrdp_orders_check(self, 2000) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2187,7 +2214,10 @@ xrdp_orders_send_raw_bitmap(struct xrdp_orders *self, Bpp = (bpp + 7) / 8; bufsize = (width + e) * height * Bpp; - xrdp_orders_check(self, bufsize + 16); + if (xrdp_orders_check(self, bufsize + 16) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2294,7 +2324,10 @@ height(%d)", lines_sending, height); bufsize = (int)(s->p - p); Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 16); + if (xrdp_orders_check(self, bufsize + 16) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2360,7 +2393,10 @@ xrdp_orders_send_font(struct xrdp_orders *self, datasize = FONT_DATASIZE(font_char); flags = 8; } - xrdp_orders_check(self, datasize + 18); + if (xrdp_orders_check(self, datasize + 18) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2417,7 +2453,10 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self, Bpp = (bpp + 7) / 8; bufsize = (width + e) * height * Bpp; - xrdp_orders_check(self, bufsize + 14); + if (xrdp_orders_check(self, bufsize + 14) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2545,7 +2584,10 @@ height(%d)", lines_sending, height); bufsize = (int)(s->p - p); Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 14); + if (xrdp_orders_check(self, bufsize + 14) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2632,7 +2674,10 @@ xrdp_orders_out_v3(struct xrdp_orders *self, int cache_id, int cache_idx, int i; Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 30); + if (xrdp_orders_check(self, bufsize + 30) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2771,7 +2816,10 @@ xrdp_orders_send_brush(struct xrdp_orders *self, int width, int height, int order_flags = 0; int len = 0; - xrdp_orders_check(self, size + 12); + if (xrdp_orders_check(self, size + 12) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); @@ -2813,7 +2861,10 @@ xrdp_orders_send_create_os_surface(struct xrdp_orders *self, int id, bytes += num_del_list * 2; } - xrdp_orders_check(self, bytes); + if (xrdp_orders_check(self, bytes) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */ @@ -2854,7 +2905,10 @@ xrdp_orders_send_switch_os_surface(struct xrdp_orders *self, int id) int order_flags; int cache_id; - xrdp_orders_check(self, 3); + if (xrdp_orders_check(self, 3) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 0 << 2; /* type RDP_ORDER_ALTSEC_SWITCH_SURFACE */ diff --git a/libxrdp/xrdp_orders_rail.c b/libxrdp/xrdp_orders_rail.c index bd91b543..91d4b607 100644 --- a/libxrdp/xrdp_orders_rail.c +++ b/libxrdp/xrdp_orders_rail.c @@ -34,7 +34,10 @@ xrdp_orders_send_window_delete(struct xrdp_orders *self, int window_id) int field_present_flags; order_size = 11; - xrdp_orders_check(self, order_size); + if (xrdp_orders_check(self, order_size) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ @@ -64,7 +67,10 @@ xrdp_orders_send_window_cached_icon(struct xrdp_orders *self, int field_present_flags; order_size = 14; - xrdp_orders_check(self, order_size); + if (xrdp_orders_check(self, order_size) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ @@ -155,7 +161,10 @@ xrdp_orders_send_window_icon(struct xrdp_orders *self, order_size += icon_info->cmap_bytes + 2; } - xrdp_orders_check(self, order_size); + if (xrdp_orders_check(self, order_size) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ @@ -324,7 +333,10 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id, order_size += 8 * window_state->num_visibility_rects; } - xrdp_orders_check(self, order_size); + if (xrdp_orders_check(self, order_size) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ @@ -465,7 +477,10 @@ xrdp_orders_send_notify_delete(struct xrdp_orders *self, int window_id, int field_present_flags; order_size = 15; - xrdp_orders_check(self, order_size); + if (xrdp_orders_check(self, order_size) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ @@ -560,7 +575,10 @@ xrdp_orders_send_notify_new_update(struct xrdp_orders *self, order_size += 3; } - xrdp_orders_check(self, order_size); + if (xrdp_orders_check(self, order_size) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ @@ -651,7 +669,10 @@ xrdp_orders_send_monitored_desktop(struct xrdp_orders *self, order_size += mdo->num_window_ids * 4; } - xrdp_orders_check(self, order_size); + if (xrdp_orders_check(self, order_size) != 0) + { + return 1; + } self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c index b93dba12..502d3096 100644 --- a/sesman/chansrv/pcsc/xrdp_pcsc.c +++ b/sesman/chansrv/pcsc/xrdp_pcsc.c @@ -48,6 +48,14 @@ typedef struct _SCARD_IO_REQUEST unsigned long cbPciLength; } SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST; +#define SCARD_PROTOCOL_T0 0x0001 /**< T=0 active protocol. */ +#define SCARD_PROTOCOL_T1 0x0002 /**< T=1 active protocol. */ +#define SCARD_PROTOCOL_RAW 0x0004 /**< Raw active protocol. */ + +PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_T0, 8 }; +PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 }; +PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_RAW, 8 }; + #define LLOG_LEVEL 5 #define LLOGLN(_level, _args) \ do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0) @@ -284,7 +292,7 @@ SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, int bytes; int status; - LLOGLN(0, ("SCardEstablishContext:")); + LLOGLN(10, ("SCardEstablishContext:")); if (g_sck == -1) { if (connect_to_chansrv() != 0) @@ -332,7 +340,7 @@ SCardReleaseContext(SCARDCONTEXT hContext) int bytes; int status; - LLOGLN(0, ("SCardReleaseContext:")); + LLOGLN(10, ("SCardReleaseContext:")); if (g_sck == -1) { LLOGLN(0, ("SCardReleaseContext: error, not connected")); @@ -369,7 +377,7 @@ SCardReleaseContext(SCARDCONTEXT hContext) PCSC_API LONG SCardIsValidContext(SCARDCONTEXT hContext) { - LLOGLN(0, ("SCardIsValidContext:")); + LLOGLN(10, ("SCardIsValidContext:")); if (g_sck == -1) { LLOGLN(0, ("SCardIsValidContext: error, not connected")); @@ -392,13 +400,15 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, int status; int offset; - LLOGLN(0, ("SCardConnect:")); + LLOGLN(10, ("SCardConnect:")); + LLOGLN(10, ("SCardConnect: hContext %p szReader %s dwShareMode %d " + "dwPreferredProtocols %d", + (void*)hContext, szReader, dwShareMode, dwPreferredProtocols)); if (g_sck == -1) { LLOGLN(0, ("SCardConnect: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - pthread_mutex_lock(&g_mutex); offset = 0; SET_UINT32(msg, offset, hContext); offset += 4; @@ -409,12 +419,13 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, return SCARD_F_INTERNAL_ERROR; } memcpy(msg + offset, szReader, bytes); - memset(msg + bytes, 0, 100 - bytes); + memset(msg + offset + bytes, 0, 100 - bytes); offset += 100; SET_UINT32(msg, offset, 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")); @@ -463,15 +474,43 @@ SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, PCSC_API LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) { - LLOGLN(0, ("SCardDisconnect:")); + char msg[256]; + int code; + int bytes; + int status; + + LLOGLN(10, ("SCardDisconnect:")); if (g_sck == -1) { 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; + 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); - return SCARD_S_SUCCESS; + status = GET_UINT32(msg, 0); + LLOGLN(10, ("SCardDisconnect: got status 0x%8.8x", status)); + return status; } /*****************************************************************************/ @@ -483,7 +522,7 @@ SCardBeginTransaction(SCARDHANDLE hCard) int bytes; int status; - LLOGLN(0, ("SCardBeginTransaction:")); + LLOGLN(10, ("SCardBeginTransaction:")); if (g_sck == -1) { LLOGLN(0, ("SCardBeginTransaction: error, not connected")); @@ -520,15 +559,43 @@ SCardBeginTransaction(SCARDHANDLE hCard) PCSC_API LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition) { - LLOGLN(0, ("SCardEndTransaction:")); + char msg[256]; + int code; + int bytes; + int status; + + LLOGLN(10, ("SCardEndTransaction:")); if (g_sck == -1) { 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; + 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); - return SCARD_S_SUCCESS; + status = GET_UINT32(msg, 0); + LLOGLN(10, ("SCardEndTransaction: got status 0x%8.8x", status)); + return status; } /*****************************************************************************/ @@ -537,15 +604,83 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { - LLOGLN(0, ("SCardStatus:")); + char *msg; + int code; + int bytes; + int status; + int offset; + int cchReaderLen; + int to_copy; + + LLOGLN(10, ("SCardStatus:")); if (g_sck == -1) { LLOGLN(0, ("SCardStatus: error, not connected")); return SCARD_F_INTERNAL_ERROR; } + cchReaderLen = *pcchReaderLen; + msg = (char *) malloc(8192); + SET_UINT32(msg, 0, hCard); + SET_UINT32(msg, 4, cchReaderLen); + SET_UINT32(msg, 8, *pcbAtrLen); pthread_mutex_lock(&g_mutex); + if (send_message(SCARD_STATUS, msg, 12) != 0) + { + LLOGLN(0, ("SCardStatus: error, send_message")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + bytes = 8192; + if (get_message(&code, msg, &bytes) != 0) + { + LLOGLN(0, ("SCardStatus: error, get_message")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + if (code != SCARD_STATUS) + { + LLOGLN(0, ("SCardStatus: error, bad code")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } pthread_mutex_unlock(&g_mutex); - return SCARD_S_SUCCESS; + + LLOGLN(10, ("SCardStatus: cchReaderLen %d", *pcchReaderLen)); + offset = 0; + *pcchReaderLen = GET_UINT32(msg, offset); + LLOGLN(10, ("SCardStatus: cchReaderLen %d", *pcchReaderLen)); + offset += 4; + if (cchReaderLen > 0) + { + to_copy = cchReaderLen - 1; + if (*pcchReaderLen < to_copy) + { + to_copy = *pcchReaderLen; + } + memcpy(mszReaderName, msg + offset, to_copy); + mszReaderName[to_copy] = 0; + } + LLOGLN(10, ("SCardStatus: mszReaderName %s", mszReaderName)); + offset += *pcchReaderLen; + *pdwState = GET_UINT32(msg, offset); + LLOGLN(10, ("SCardStatus: dwState %d", *pdwState)); + offset += 4; + *pdwProtocol = GET_UINT32(msg, offset); + LLOGLN(10, ("SCardStatus: dwProtocol %d", *pdwProtocol)); + offset += 4; + *pcbAtrLen = GET_UINT32(msg, offset); + offset += 4; + LLOGLN(10, ("SCardStatus: cbAtrLen %d", *pcbAtrLen)); + memcpy(pbAtr, msg + offset, *pcbAtrLen); + offset += *pcbAtrLen; + status = GET_UINT32(msg, offset); + LLOGLN(10, ("SCardStatus: status %d", status)); + offset += 4; + free(msg); + return status; } /*****************************************************************************/ @@ -561,7 +696,7 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout, int str_len; int status; - LLOGLN(0, ("SCardGetStatusChange:")); + LLOGLN(10, ("SCardGetStatusChange:")); LLOGLN(10, (" dwTimeout %d cReaders %d", dwTimeout, cReaders)); if (g_sck == -1) { @@ -646,15 +781,76 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned) { - LLOGLN(0, ("SCardControl:")); + char *msg; + int bytes; + int code; + int offset; + int status = 0; + + LLOGLN(10, ("SCardControl:")); if (g_sck == -1) { 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)); + + /* #define SCARD_CTL_CODE(code) (0x42000000 + (code)) + control_code = (control_code & 0x3ffc) >> 2; + control_code = SCARD_CTL_CODE(control_code); */ + + /* PCSC to Windows control code conversion */ + dwControlCode = dwControlCode - 0x42000000; + dwControlCode = dwControlCode << 2; + dwControlCode = dwControlCode | (49 << 16); + LLOGLN(10, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode)); + + msg = (char *) malloc(8192); + offset = 0; + SET_UINT32(msg, offset, hCard); + offset += 4; + SET_UINT32(msg, offset, dwControlCode); + offset += 4; + SET_UINT32(msg, offset, cbSendLength); + offset += 4; + memcpy(msg + offset, pbSendBuffer, cbSendLength); + 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; + 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); - return SCARD_S_SUCCESS; + offset = 0; + *lpBytesReturned = GET_UINT32(msg, offset); + offset += 4; + memcpy(pbRecvBuffer, msg + offset, *lpBytesReturned); + offset += *lpBytesReturned; + status = GET_UINT32(msg, offset); + free(msg); + return status; } /*****************************************************************************/ @@ -664,15 +860,118 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) { - LLOGLN(0, ("SCardTransmit:")); + char *msg; + int bytes; + int code; + int offset; + int status; + int extra_len; + + LLOGLN(10, ("SCardTransmit:")); if (g_sck == -1) { LLOGLN(0, ("SCardTransmit: error, not connected")); return SCARD_F_INTERNAL_ERROR; } + LLOGLN(10, ("SCardTransmit: cbSendLength %d", cbSendLength)); + LLOGLN(10, ("SCardTransmit: pioRecvPci %p", pioRecvPci)); + if (pioRecvPci != 0) + { + LLOGLN(10, ("SCardTransmit: pioRecvPci->dwProtocol %d", + (int)pioRecvPci->dwProtocol)); + LLOGLN(10, ("SCardTransmit: pioRecvPci->cbPciLength %d", + (int)pioRecvPci->cbPciLength)); + } + msg = (char *) malloc(8192); + offset = 0; + SET_UINT32(msg, offset, hCard); + offset += 4; + SET_UINT32(msg, offset, pioSendPci->dwProtocol); + offset += 4; + SET_UINT32(msg, offset, pioSendPci->cbPciLength); + offset += 4; + extra_len = pioSendPci->cbPciLength - 8; + SET_UINT32(msg, offset, extra_len); + offset += 4; + memcpy(msg + offset, pioSendPci + 1, extra_len); + offset += extra_len; + SET_UINT32(msg, offset, cbSendLength); + offset += 4; + memcpy(msg + offset, pbSendBuffer, cbSendLength); + offset += cbSendLength; + if ((pioRecvPci == 0) || (pioRecvPci->cbPciLength < 8)) + { + SET_UINT32(msg, offset, 0); /* dwProtocol */ + offset += 4; + SET_UINT32(msg, offset, 0); /* cbPciLength */ + offset += 4; + SET_UINT32(msg, offset, 0); /* extra_len */ + offset += 4; + } + else + { + SET_UINT32(msg, offset, pioRecvPci->dwProtocol); + offset += 4; + SET_UINT32(msg, offset, pioRecvPci->cbPciLength); + offset += 4; + extra_len = pioRecvPci->cbPciLength - 8; + SET_UINT32(msg, offset, extra_len); + offset += 4; + memcpy(msg + offset, pioRecvPci + 1, extra_len); + offset += extra_len; + } + 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; + 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); - return SCARD_S_SUCCESS; + offset = 0; + if (pioRecvPci == 0) + { + offset += 8; + extra_len = GET_UINT32(msg, offset); + offset += 4; + offset += extra_len; + } + else + { + pioRecvPci->dwProtocol = GET_UINT32(msg, offset); + offset += 4; + pioRecvPci->cbPciLength = GET_UINT32(msg, offset); + offset += 4; + extra_len = GET_UINT32(msg, offset); + offset += 4; + offset += extra_len; + } + *pcbRecvLength = GET_UINT32(msg, offset); + offset += 4; + LLOGLN(10, ("SCardTransmit: cbRecvLength %d", *pcbRecvLength)); + memcpy(pbRecvBuffer, msg + offset, *pcbRecvLength); + offset += *pcbRecvLength; + status = GET_UINT32(msg, offset); + free(msg); + return status; } /*****************************************************************************/ @@ -680,7 +979,7 @@ PCSC_API LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups) { - LLOGLN(0, ("SCardListReaderGroups:")); + LLOGLN(10, ("SCardListReaderGroups:")); if (g_sck == -1) { LLOGLN(0, ("SCardListReaderGroups: error, not connected")); @@ -707,7 +1006,7 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, int index; char reader[100]; - LLOGLN(0, ("SCardListReaders:")); + LLOGLN(10, ("SCardListReaders:")); if (g_sck == -1) { LLOGLN(0, ("SCardListReaders: error, not connected")); @@ -742,7 +1041,8 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, offset = 0; num_readers = GET_UINT32(msg, offset); offset += 4; - LLOGLN(10, ("hi - mszReaders %p pcchReaders %p num_readers %d", mszReaders, pcchReaders, num_readers)); + LLOGLN(10, ("SCardListReaders: mszReaders %p pcchReaders %p num_readers %d", + mszReaders, pcchReaders, num_readers)); reader_names = (char *) malloc(8192); reader_names_index = 0; for (index = 0; index < num_readers; index++) @@ -836,9 +1136,10 @@ SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, } /*****************************************************************************/ -char * +PCSC_API char * pcsc_stringify_error(const long code) { + LLOGLN(10, ("pcsc_stringify_error: %d", (int)code)); switch (code) { case SCARD_S_SUCCESS: diff --git a/sesman/chansrv/pulse/pulse-notes.ubuntu.txt b/sesman/chansrv/pulse/pulse-notes.ubuntu.txt index c0e29c40..cb6ec90f 100644 --- a/sesman/chansrv/pulse/pulse-notes.ubuntu.txt +++ b/sesman/chansrv/pulse/pulse-notes.ubuntu.txt @@ -16,5 +16,19 @@ deb http://packages.medibuntu.org/ precise free non-free deb http://drbl.sourceforge.net/drbl-core drbl stable ---------------------- -apt-get install dpkg-dev -apt-get build-dep pulseaudio +do all this in a new directory + +root +sudo apt-get install dpkg-dev + +non root +apt-get source pulseaudio + +root +sudo apt-get build-dep pulseaudio + +cd pulseaudio-1.1 + +non root +dpkg-buildpackage -rfakeroot -uc -b + diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c index 9d55807d..29406d62 100644 --- a/sesman/chansrv/smartcard.c +++ b/sesman/chansrv/smartcard.c @@ -59,7 +59,7 @@ #define LOG_DEBUG 2 #ifndef LOG_LEVEL -#define LOG_LEVEL LOG_DEBUG +#define LOG_LEVEL LOG_INFO #endif #define log_error(_params...) \ @@ -160,37 +160,36 @@ extern int g_rdpdr_chan_id; /* in chansrv.c */ static struct stream * APP_CC scard_make_new_ioctl(IRP *irp, tui32 ioctl); static int APP_CC scard_add_new_device(tui32 device_id); static int APP_CC scard_get_free_slot(void); +#if 0 static void APP_CC scard_release_resources(void); +#endif static void APP_CC scard_send_EstablishContext(IRP* irp, int scope); static void APP_CC scard_send_ReleaseContext(IRP* irp, tui32 context); static void APP_CC scard_send_IsContextValid(IRP* irp, tui32 context); static void APP_CC scard_send_ListReaders(IRP* irp, tui32 context, int wide); - static void APP_CC scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout, tui32 num_readers, READER_STATE* rsa); - static void APP_CC scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs); - static void APP_CC scard_send_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs); - static void APP_CC scard_send_BeginTransaction(IRP* irp, tui32 sc_handle); -static void APP_CC scard_send_EndTransaction(IRP* irp, tui32 sc_handle); -static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle); - +static void APP_CC scard_send_EndTransaction(IRP* irp, tui32 sc_handle, + tui32 dwDisposition); +static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle, + int cchReaderLen, int cbAtrLen); static void APP_CC scard_send_Disconnect(IRP* irp, tui32 context, - tui32 sc_handle); - + tui32 sc_handle, int dwDisposition); static int APP_CC scard_send_Transmit(IRP* irp, tui32 sc_handle, - READER_STATE* rs); - + char *send_data, int send_bytes, + int recv_bytes, + struct xrdp_scard_io_request *send_ior, + struct xrdp_scard_io_request *recv_ior); static int APP_CC scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, - READER_STATE* rs); - + char *send_data, int send_bytes, + int recv_bytes, int control_code); static int APP_CC scard_send_Cancel(IRP* irp, tui32 context); - static int APP_CC scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs); @@ -577,7 +576,8 @@ 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(struct trans *con, tui32 sc_handle, + tui32 dwDisposition) { IRP *irp; @@ -595,7 +595,7 @@ scard_send_end_transaction(struct trans *con, tui32 sc_handle) irp->user_data = con; /* send IRP to client */ - scard_send_EndTransaction(irp, sc_handle); + scard_send_EndTransaction(irp, sc_handle, dwDisposition); return 0; } @@ -607,7 +607,8 @@ scard_send_end_transaction(struct trans *con, tui32 sc_handle) * @param wide TRUE if unicode string *****************************************************************************/ int APP_CC -scard_send_status(struct trans *con, int wide, tui32 sc_handle) +scard_send_status(struct trans *con, int wide, tui32 sc_handle, + int cchReaderLen, int cbAtrLen) { IRP *irp; @@ -625,7 +626,7 @@ scard_send_status(struct trans *con, int wide, tui32 sc_handle) irp->user_data = con; /* send IRP to client */ - scard_send_Status(irp, wide, sc_handle); + scard_send_Status(irp, wide, sc_handle, cchReaderLen, cbAtrLen); return 0; } @@ -637,7 +638,8 @@ 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(struct trans *con, tui32 context, tui32 sc_handle, + int dwDisposition) { IRP *irp; @@ -655,7 +657,7 @@ scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle) irp->user_data = con; /* send IRP to client */ - scard_send_Disconnect(irp, context, sc_handle); + scard_send_Disconnect(irp, context, sc_handle, dwDisposition); return 0; } @@ -665,7 +667,10 @@ 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, READER_STATE* rs) +scard_send_transmit(struct trans *con, 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) { IRP *irp; @@ -683,7 +688,8 @@ scard_send_transmit(struct trans *con, tui32 sc_handle, READER_STATE* rs) irp->user_data = con; /* send IRP to client */ - scard_send_Transmit(irp, sc_handle, rs); + scard_send_Transmit(irp, sc_handle, send_data, send_bytes, recv_bytes, + send_ior, recv_ior); return 0; } @@ -693,7 +699,8 @@ scard_send_transmit(struct trans *con, tui32 sc_handle, READER_STATE* rs) *****************************************************************************/ int APP_CC scard_send_control(struct trans *con, tui32 context, tui32 sc_handle, - READER_STATE* rs) + char *send_data, int send_bytes, + int recv_bytes, int control_code) { IRP *irp; @@ -711,7 +718,8 @@ 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, rs); + scard_send_Control(irp, context, sc_handle, send_data, + send_bytes, recv_bytes, control_code); return 0; } @@ -889,6 +897,7 @@ scard_get_free_slot(void) return -1; } +#if 0 /** * Release resources prior to shutting down *****************************************************************************/ @@ -906,6 +915,7 @@ scard_release_resources(void) } } } +#endif /** * @@ -1166,7 +1176,6 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout, tui32 ioctl; int bytes; int i; - int len; int num_chars; int index; twchar w_reader_name[100]; @@ -1269,7 +1278,6 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs) struct stream* s; tui32 ioctl; int bytes; - int len; int num_chars; int index; twchar w_reader_name[100]; @@ -1469,12 +1477,12 @@ scard_send_BeginTransaction(IRP *irp, tui32 sc_handle) * @param sc_handle handle to smartcard *****************************************************************************/ static void APP_CC -scard_send_EndTransaction(IRP *irp, tui32 sc_handle) +scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition) { /* see [MS-RDPESC] 3.1.4.32 */ - SMARTCARD* sc; - struct stream* s; + SMARTCARD *sc; + struct stream *s; int bytes; if ((sc = smartcards[irp->scard_index]) == NULL) @@ -1501,7 +1509,7 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle) */ xstream_seek(s, 24); - xstream_wr_u32_le(s, SCARD_LEAVE_CARD); + xstream_wr_u32_le(s, dwDisposition); xstream_seek(s, 8); /* insert handle */ @@ -1526,7 +1534,8 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle) * @param wide TRUE if unicode string *****************************************************************************/ static void APP_CC -scard_send_Status(IRP *irp, int wide, tui32 sc_handle) +scard_send_Status(IRP *irp, int wide, tui32 sc_handle, + int cchReaderLen, int cbAtrLen) { /* see [MS-RDPESC] 2.2.2.18 */ @@ -1541,11 +1550,12 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle) return; } - ioctl = (wide) ? SCARD_IOCTL_CONNECT_W : - SCARD_IOCTL_CONNECT_A; - + ioctl = wide ? SCARD_IOCTL_STATUS_W : SCARD_IOCTL_STATUS_A; if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL) + { + log_error("scard_make_new_ioctl"); return; + } /* * command format @@ -1564,8 +1574,8 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle) */ xstream_seek(s, 28); - xstream_wr_u32_le(s, -1); /* readerLen, see [MS-RDPESC] 4.11 */ - xstream_wr_u32_le(s, 36); /* atrLen, see [MS-RDPESC] 4.11 */ + xstream_wr_u32_le(s, cchReaderLen); /* readerLen, see [MS-RDPESC] 4.11 */ + xstream_wr_u32_le(s, cbAtrLen); /* atrLen, see [MS-RDPESC] 4.11 */ xstream_seek(s, 8); /* insert sc_handle */ @@ -1592,7 +1602,8 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle) * @param sc_handle handle to smartcard *****************************************************************************/ static void APP_CC -scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle) +scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle, + int dwDisposition) { /* see [MS-RDPESC] 3.1.4.30 */ @@ -1625,7 +1636,7 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle) */ xstream_seek(s, 24); - xstream_wr_u32_le(s, SCARD_RESET_CARD); + xstream_wr_u32_le(s, dwDisposition); /* insert context */ xstream_wr_u32_le(s, 4); @@ -1651,22 +1662,35 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle) * associated with a valid context. *****************************************************************************/ static int APP_CC -scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs) +scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data, + int send_bytes, int recv_bytes, + struct xrdp_scard_io_request *send_ior, + struct xrdp_scard_io_request *recv_ior) { /* see [MS-RDPESC] 2.2.2.19 */ SMARTCARD* sc; struct stream* s; int bytes; + int val; if ((sc = smartcards[irp->scard_index]) == NULL) { log_error("smartcards[%d] is NULL", irp->scard_index); - return; + return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_TRANSMIT)) == NULL) - return; + { + log_error("scard_make_new_ioctl"); + return 1; + } + + log_debug("send_bytes %d recv_bytes %d send dwProtocol %d cbPciLength %d " + "extra_bytes %d recv dwProtocol %d cbPciLength %d", send_bytes, + recv_bytes, send_ior->dwProtocol, send_ior->cbPciLength, + send_ior->extra_bytes, recv_ior->dwProtocol, recv_ior->cbPciLength, + recv_ior->extra_bytes); /* * command format @@ -1693,21 +1717,48 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs) */ xstream_seek(s, 12); - xstream_wr_u32_le(s, rs->map0); + xstream_wr_u32_le(s, 0); // map0 xstream_seek(s, 4); - xstream_wr_u32_le(s, rs->map1); - xstream_wr_u32_le(s, rs->dwProtocol); - xstream_wr_u32_le(s, rs->cbPciLength); - xstream_wr_u32_le(s, rs->map2); - xstream_wr_u32_le(s, rs->cbSendLength); - xstream_wr_u32_le(s, rs->map3); - xstream_wr_u32_le(s, rs->map4); - xstream_wr_u32_le(s, rs->map5); - xstream_wr_u32_le(s, rs->map6); - xstream_wr_u32_le(s, rs->cbRecvLength); + xstream_wr_u32_le(s, 0); // map1 + xstream_wr_u32_le(s, send_ior->dwProtocol); + xstream_wr_u32_le(s, send_ior->cbPciLength); + val = send_ior->extra_bytes > 0 ? 1 : 0; + xstream_wr_u32_le(s, val); // map2 + xstream_wr_u32_le(s, send_bytes); + val = send_bytes > 0 ? 1 : 0; + xstream_wr_u32_le(s, val); // map3 + val = recv_ior->cbPciLength > 0 ? 1 : 0; + xstream_wr_u32_le(s, val); // map 4 + xstream_wr_u32_le(s, 0); // map5 + xstream_wr_u32_le(s, recv_bytes); xstream_wr_u32_le(s, 4); xstream_wr_u32_le(s, sc_handle); + if (send_ior->extra_bytes > 0) + { + xstream_wr_u32_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_uint8a(s, send_data, send_bytes); + } + + if (recv_ior->cbPciLength > 0) + { + xstream_wr_u32_le(s, recv_ior->dwProtocol); + xstream_wr_u32_le(s, recv_ior->cbPciLength); + val = recv_ior->extra_bytes > 0 ? 1 : 0; + xstream_wr_u32_le(s, val); + if (val) + { + xstream_wr_u32_le(s, recv_ior->extra_bytes); + out_uint8a(s, recv_ior->extra_data, recv_ior->extra_bytes); + } + } + /* get stream len */ bytes = xstream_len(s); @@ -1717,28 +1768,34 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs) /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); + return 0; } /** * Communicate directly with the smart card reader *****************************************************************************/ static int APP_CC -scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs) +scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data, + int send_bytes, int recv_bytes, int control_code) { /* see [MS-RDPESC] 2.2.2.19 */ SMARTCARD* sc; struct stream* s; int bytes; + int val; if ((sc = smartcards[irp->scard_index]) == NULL) { log_error("smartcards[%d] is NULL", irp->scard_index); - return; + return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CONTROL)) == NULL) - return; + { + log_error("scard_make_new_ioctl"); + return 1; + } /* * command format @@ -1763,19 +1820,30 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs) */ xstream_seek(s, 12); - xstream_wr_u32_le(s, rs->map0); + xstream_wr_u32_le(s, 0); // map0 + xstream_seek(s, 4); + xstream_wr_u32_le(s, 0); // map1 + + xstream_wr_u32_le(s, control_code); + + xstream_wr_u32_le(s, send_bytes); + + val = send_bytes > 0 ? 1 : 0; + xstream_wr_u32_le(s, val); // map2 + xstream_wr_u32_le(s, 0); - xstream_wr_u32_le(s, rs->map1); - xstream_wr_u32_le(s, rs->dwControlCode); - xstream_wr_u32_le(s, rs->cbRecvLength); - xstream_wr_u32_le(s, rs->map2); - xstream_wr_u32_le(s, 0); - xstream_wr_u32_le(s, rs->cbOutBufferSize); + xstream_wr_u32_le(s, recv_bytes); xstream_wr_u32_le(s, 4); xstream_wr_u32_le(s, context); xstream_wr_u32_le(s, 4); xstream_wr_u32_le(s, sc_handle); + if (send_bytes > 0) + { + xstream_wr_u32_le(s, send_bytes); + out_uint8a(s, send_data, send_bytes); + } + /* get stream len */ bytes = xstream_len(s); @@ -1785,12 +1853,14 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs) /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); + return 0; } /** * Cancel any outstanding calls *****************************************************************************/ -static int APP_CC scard_send_Cancel(IRP* irp, tui32 context) +static int APP_CC +scard_send_Cancel(IRP* irp, tui32 context) { /* see [MS-RDPESC] 3.1.4.27 */ @@ -1801,11 +1871,14 @@ static int APP_CC scard_send_Cancel(IRP* irp, tui32 context) if ((sc = smartcards[irp->scard_index]) == NULL) { log_error("smartcards[%d] is NULL", irp->scard_index); - return; + return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CANCEL)) == NULL) - return; + { + log_error("scard_make_new_ioctl"); + return 1; + } /* * command format @@ -1832,6 +1905,7 @@ static int APP_CC scard_send_Cancel(IRP* irp, tui32 context) /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); + return 0; } /** @@ -1849,11 +1923,14 @@ scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs) if ((sc = smartcards[irp->scard_index]) == NULL) { log_error("smartcards[%d] is NULL", irp->scard_index); - return; + return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_GETATTRIB)) == NULL) - return; + { + log_error("scard_make_new_ioctl"); + return 1; + } /* * command format @@ -1888,6 +1965,7 @@ scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs) /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); + return 0; } /****************************************************************************** @@ -1960,11 +2038,16 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp, log_debug("leaving"); } -static void APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp, - tui32 DeviceId, tui32 CompletionId, - tui32 IoStatus) +/** + * + *****************************************************************************/ +static void +APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp, + tui32 DeviceId, tui32 CompletionId, + tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -1984,7 +2067,9 @@ static void APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_is_context_valid_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2081,9 +2166,11 @@ 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); devredir_irp_delete(irp); + log_debug("leaving"); } @@ -2096,6 +2183,7 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2115,7 +2203,9 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_reconnect_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2128,6 +2218,7 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2147,7 +2238,9 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_begin_transaction_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2160,6 +2253,7 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2179,7 +2273,9 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_end_transaction_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2192,6 +2288,7 @@ scard_handle_Status_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2211,7 +2308,9 @@ scard_handle_Status_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_status_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2224,6 +2323,7 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2243,7 +2343,9 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_disconnect_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2255,6 +2357,7 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2274,7 +2377,9 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_transmit_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2286,6 +2391,7 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId,tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2305,7 +2411,9 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_control_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2317,6 +2425,7 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2336,7 +2445,9 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_cancel_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } @@ -2348,6 +2459,7 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus) { tui32 len; + struct trans *con; log_debug("entered"); @@ -2367,6 +2479,8 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId, /* get OutputBufferLen */ xstream_rd_u32_le(s, len); - + con = (struct trans *) (irp->user_data); + scard_function_get_attrib_return(con, s, len); + devredir_irp_delete(irp); log_debug("leaving"); } diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h index 600aef04..88f4cdf6 100644 --- a/sesman/chansrv/smartcard.h +++ b/sesman/chansrv/smartcard.h @@ -48,6 +48,14 @@ #define SCARD_RESET_CARD 0x00000001 /* reset smart card */ #define SCARD_UNPOWER_CARD 0x00000002 /* turn off and reset card */ +struct xrdp_scard_io_request +{ + tui32 dwProtocol; + tui32 cbPciLength; + int extra_bytes; + char *extra_data; +}; + typedef struct reader_state { char reader_name[128]; @@ -118,15 +126,21 @@ int APP_CC scard_send_reconnect(struct trans *con, 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_status(struct trans *con, int wide, tui32 sc_handle); -int APP_CC scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle); +int APP_CC scard_send_end_transaction(struct trans *con, tui32 sc_handle, + tui32 dwDisposition); +int APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle, + int cchReaderLen, int cbAtrLen); +int APP_CC scard_send_disconnect(struct trans *con, tui32 context, + tui32 sc_handle, int dwDisposition); int APP_CC scard_send_transmit(struct trans *con, tui32 sc_handle, - READER_STATE* rs); + 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 context, tui32 sc_handle, - READER_STATE* rs); + char *send_data, int send_bytes, + int recv_bytes, int control_code); int APP_CC scard_send_cancel(struct trans *con, tui32 context); diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c index 62b3b722..29f60c8d 100644 --- a/sesman/chansrv/smartcard_pcsc.c +++ b/sesman/chansrv/smartcard_pcsc.c @@ -38,7 +38,7 @@ #if PCSC_STANDIN -#define LLOG_LEVEL 11 +#define LLOG_LEVEL 1 #define LLOGLN(_level, _args) \ do \ { \ @@ -57,6 +57,11 @@ #define XRDP_PCSC_STATE_GOT_GSC (1 << 3) /* get status change */ #define XRDP_PCSC_STATE_GOT_C (1 << 4) /* connect */ #define XRDP_PCSC_STATE_GOT_BT (1 << 5) /* begin transaction */ +#define XRDP_PCSC_STATE_GOT_ET (1 << 6) /* end transaction */ +#define XRDP_PCSC_STATE_GOT_TR (1 << 7) /* transmit */ +#define XRDP_PCSC_STATE_GOT_CO (1 << 8) /* control */ +#define XRDP_PCSC_STATE_GOT_D (1 << 9) /* disconnect */ +#define XRDP_PCSC_STATE_GOT_ST (1 << 10) /* get status */ /* TODO: put this in con */ static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE; @@ -69,8 +74,10 @@ struct pcsc_client struct trans *con; }; +#if 0 static struct pcsc_client *g_head = 0; static struct pcsc_client *g_tail = 0; +#endif static struct trans *g_lis = 0; static struct trans *g_con = 0; /* todo, remove this */ @@ -81,7 +88,7 @@ static int g_pub_file_fd = 0; int APP_CC scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout) { - LLOGLN(0, ("scard_pcsc_get_wait_objs")); + LLOGLN(10, ("scard_pcsc_get_wait_objs")); if (g_lis != 0) { trans_get_wait_objs(g_lis, objs, count); @@ -97,7 +104,7 @@ scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout) int APP_CC scard_pcsc_check_wait_objs(void) { - LLOGLN(0, ("scard_pcsc_check_wait_objs")); + LLOGLN(10, ("scard_pcsc_check_wait_objs")); if (g_lis != 0) { trans_check_wait_objs(g_lis); @@ -116,7 +123,7 @@ scard_process_establish_context(struct trans *con, struct stream *in_s) { int dwScope; - LLOGLN(0, ("scard_process_establish_context:")); + LLOGLN(10, ("scard_process_establish_context:")); if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) { LLOGLN(0, ("scard_process_establish_context: opps")); @@ -124,7 +131,7 @@ scard_process_establish_context(struct trans *con, struct stream *in_s) } g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_EC; in_uint32_le(in_s, dwScope); - LLOGLN(0, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope)); + LLOGLN(10, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope)); scard_send_establish_context(con, dwScope); return 0; } @@ -141,7 +148,7 @@ scard_function_establish_context_return(struct trans *con, tui32 context_len; struct stream *out_s; - LLOGLN(0, ("scard_function_establish_context_return:")); + LLOGLN(10, ("scard_function_establish_context_return:")); if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0) { LLOGLN(0, ("scard_function_establish_context_return: opps")); @@ -156,7 +163,7 @@ scard_function_establish_context_return(struct trans *con, return 1; } in_uint32_le(in_s, context); - LLOGLN(0, ("scard_function_establish_context_return: context 0x%8.8x", 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); out_uint32_le(out_s, context); @@ -176,7 +183,7 @@ scard_process_release_context(struct trans *con, struct stream *in_s) { int hContext; - LLOGLN(0, ("scard_process_release_context:")); + LLOGLN(10, ("scard_process_release_context:")); if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) { LLOGLN(0, ("scard_process_establish_context: opps")); @@ -184,7 +191,7 @@ scard_process_release_context(struct trans *con, struct stream *in_s) } g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RC; in_uint32_le(in_s, hContext); - LLOGLN(0, ("scard_process_release_context: hContext 0x%8.8x", hContext)); + LLOGLN(10, ("scard_process_release_context: hContext 0x%8.8x", hContext)); scard_send_release_context(con, hContext); return 0; } @@ -198,9 +205,8 @@ scard_function_release_context_return(struct trans *con, { int bytes; struct stream *out_s; - tui32 context; - LLOGLN(0, ("scard_function_release_context_return:")); + LLOGLN(10, ("scard_function_release_context_return:")); if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0) { LLOGLN(0, ("scard_function_release_context_return: opps")); @@ -225,7 +231,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s) { int hContext; - LLOGLN(0, ("scard_process_list_readers:")); + LLOGLN(10, ("scard_process_list_readers:")); if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) { LLOGLN(0, ("scard_process_list_readers: opps")); @@ -233,7 +239,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s) } g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR; in_uint32_le(in_s, hContext); - LLOGLN(0, ("scard_process_list_readers: dwScope 0x%8.8x", hContext)); + LLOGLN(10, ("scard_process_list_readers: dwScope 0x%8.8x", hContext)); scard_send_list_readers(con, hContext, 1); return 0; } @@ -254,10 +260,10 @@ scard_function_list_readers_return(struct trans *con, char lreader_name[16][100]; LLOGLN(10, ("scard_function_list_readers_return:")); - g_hexdump(in_s->p, len); + //g_hexdump(in_s->p, len); if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0) { - LLOGLN(10, ("scard_function_list_readers_return: opps")); + LLOGLN(0, ("scard_function_list_readers_return: opps")); return 1; } g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR; @@ -267,7 +273,7 @@ scard_function_list_readers_return(struct trans *con, in_uint8s(in_s, 28); len -= 28; in_uint32_le(in_s, len); - g_writeln("len %d", len); + //g_writeln("len %d", len); rn_index = 0; readers = 0; while (len > 0) @@ -279,7 +285,7 @@ scard_function_list_readers_return(struct trans *con, if (reader_name[0] != 0) { g_wcstombs(lreader_name[readers], reader_name, 99); - g_writeln("1 %s", lreader_name[readers]); + //g_writeln("1 %s", lreader_name[readers]); g_memset(reader_name, 0, sizeof(reader_name)); readers++; } @@ -297,7 +303,7 @@ scard_function_list_readers_return(struct trans *con, if (reader_name[0] != 0) { g_wcstombs(lreader_name[readers], reader_name, 99); - g_writeln("2 %s", lreader_name[readers]); + //g_writeln("2 %s", lreader_name[readers]); g_memset(reader_name, 0, sizeof(reader_name)); readers++; } @@ -308,7 +314,7 @@ scard_function_list_readers_return(struct trans *con, out_uint32_le(out_s, readers); for (index = 0; index < readers; index++) { - g_writeln("3 - %s", lreader_name[index]); + //g_writeln("3 - %s", lreader_name[index]); out_uint8a(out_s, lreader_name[index], 100); } out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ @@ -326,10 +332,9 @@ int APP_CC scard_process_connect(struct trans *con, struct stream *in_s) { int hContext; - char szReader[100]; READER_STATE rs; - LLOGLN(0, ("scard_process_connect:")); + LLOGLN(10, ("scard_process_connect:")); if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C) { LLOGLN(0, ("scard_process_connect: opps")); @@ -338,11 +343,11 @@ scard_process_connect(struct trans *con, struct stream *in_s) g_memset(&rs, 0, sizeof(rs)); g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_C; in_uint32_le(in_s, hContext); - in_uint8a(in_s, szReader, 100); + in_uint8a(in_s, rs.reader_name, 100); in_uint32_le(in_s, rs.dwShareMode); in_uint32_le(in_s, rs.dwPreferredProtocols); - LLOGLN(0, ("scard_process_connect: dwShareMode 0x%8.8x " - "dwPreferredProtocols 0x%8.8x", rs.dwShareMode, + 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); return 0; @@ -359,7 +364,7 @@ scard_function_connect_return(struct trans *con, int bytes; struct stream *out_s; - g_hexdump(in_s->p, len); + //g_hexdump(in_s->p, len); if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C) == 0) { LLOGLN(0, ("scard_function_connect_return: opps")); @@ -368,8 +373,9 @@ scard_function_connect_return(struct trans *con, g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_C; in_uint8s(in_s, 36); in_uint32_le(in_s, dwActiveProtocol); - in_uint8s(in_s, 36); + in_uint8s(in_s, 4); in_uint32_le(in_s, hCard); + LLOGLN(10, ("scard_function_connect_return: hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol)); out_s = trans_get_out_s(con, 8192); s_push_layer(out_s, iso_hdr, 8); out_uint32_le(out_s, hCard); @@ -383,6 +389,66 @@ scard_function_connect_return(struct trans *con, return trans_force_write(con); } +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_process_disconnect(struct trans *con, struct stream *in_s) +{ + int hContext; + int hCard; + int dwDisposition; + + LLOGLN(10, ("scard_process_disconnect:")); + if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_D) + { + LLOGLN(0, ("scard_process_disconnect: opps")); + return 1; + } + g_xrdp_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); + + return 0; +} + +/*****************************************************************************/ +int APP_CC +scard_function_disconnect_return(struct trans *con, + struct stream *in_s, + int len) +{ + int dwActiveProtocol; + int hCard; + int bytes; + struct stream *out_s; + + //g_hexdump(in_s->p, len); + if ((g_xrdp_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; + in_uint8s(in_s, 36); + in_uint32_le(in_s, dwActiveProtocol); + in_uint8s(in_s, 4); + in_uint32_le(in_s, hCard); + LLOGLN(10, ("scard_function_connect_return: hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol)); + out_s = trans_get_out_s(con, 8192); + s_push_layer(out_s, iso_hdr, 8); + out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ + s_mark_end(out_s); + bytes = (int) (out_s->end - out_s->data); + s_pop_layer(out_s, iso_hdr); + out_uint32_le(out_s, bytes - 8); + out_uint32_le(out_s, 0x06); /* SCARD_DISCONNECT 0x06 */ + return trans_force_write(con); +} + /*****************************************************************************/ /* returns error */ int APP_CC @@ -390,7 +456,7 @@ scard_process_begin_transaction(struct trans *con, struct stream *in_s) { int hCard; - LLOGLN(0, ("scard_process_begin_transaction:")); + LLOGLN(10, ("scard_process_begin_transaction:")); if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT) { LLOGLN(0, ("scard_process_begin_transaction: opps")); @@ -398,11 +464,395 @@ scard_process_begin_transaction(struct trans *con, struct stream *in_s) } g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_BT; in_uint32_le(in_s, hCard); - LLOGLN(0, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard)); + LLOGLN(10, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard)); scard_send_begin_transaction(con, hCard); return 0; } +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_function_begin_transaction_return(struct trans *con, + struct stream *in_s, + int len) +{ + struct stream *out_s; + int bytes; + + //g_hexdump(in_s->p, len); + if ((g_xrdp_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; + + out_s = trans_get_out_s(con, 8192); + s_push_layer(out_s, iso_hdr, 8); + out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ + s_mark_end(out_s); + bytes = (int) (out_s->end - out_s->data); + s_pop_layer(out_s, iso_hdr); + out_uint32_le(out_s, bytes - 8); + out_uint32_le(out_s, 0x07); /* SCARD_BEGIN_TRANSACTION 0x07 */ + return trans_force_write(con); +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_process_end_transaction(struct trans *con, struct stream *in_s) +{ + int hCard; + int dwDisposition; + + LLOGLN(10, ("scard_process_end_transaction:")); + if (g_xrdp_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; + 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); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_function_end_transaction_return(struct trans *con, + struct stream *in_s, + int len) +{ + struct stream *out_s; + int bytes; + + //g_hexdump(in_s->p, len); + if ((g_xrdp_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; + + out_s = trans_get_out_s(con, 8192); + s_push_layer(out_s, iso_hdr, 8); + out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ + s_mark_end(out_s); + bytes = (int) (out_s->end - out_s->data); + s_pop_layer(out_s, iso_hdr); + out_uint32_le(out_s, bytes - 8); + out_uint32_le(out_s, 0x08); /* SCARD_END_TRANSACTION 0x08 */ + return trans_force_write(con); +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_function_cancel_return(struct trans *con, + struct stream *in_s, + int len) +{ + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_function_get_attrib_return(struct trans *con, + struct stream *in_s, + int len) +{ + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_process_transmit(struct trans *con, struct stream *in_s) +{ + int hCard; + int recv_bytes; + int send_bytes; + char *send_data; + struct xrdp_scard_io_request send_ior; + struct xrdp_scard_io_request recv_ior; + + LLOGLN(10, ("scard_process_transmit:")); + if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR) + { + LLOGLN(0, ("scard_process_transmit: opps")); + return 1; + } + g_xrdp_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); + in_uint32_le(in_s, send_ior.cbPciLength); + in_uint32_le(in_s, send_ior.extra_bytes); + in_uint8p(in_s, send_ior.extra_data, send_ior.extra_bytes); + in_uint32_le(in_s, send_bytes); + in_uint8p(in_s, send_data, send_bytes); + in_uint32_le(in_s, recv_ior.dwProtocol); + in_uint32_le(in_s, recv_ior.cbPciLength); + in_uint32_le(in_s, recv_ior.extra_bytes); + in_uint8p(in_s, recv_ior.extra_data, recv_ior.extra_bytes); + in_uint32_le(in_s, recv_bytes); + LLOGLN(10, ("scard_process_transmit: send dwProtocol %d cbPciLength %d " + "recv dwProtocol %d cbPciLength %d send_bytes %d ", + send_ior.dwProtocol, send_ior.cbPciLength, recv_ior.dwProtocol, + 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, + &send_ior, &recv_ior); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_function_transmit_return(struct trans *con, + struct stream *in_s, + int len) +{ + struct stream *out_s; + int bytes; + int val; + int cbRecvLength; + struct xrdp_scard_io_request recv_ior; + char *recvBuf; + + LLOGLN(10, ("scard_function_transmit_return:")); + //g_hexdump(in_s->p, len); + if ((g_xrdp_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; + + 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, 4); + in_uint32_le(in_s, val); + cbRecvLength = 0; + recvBuf = 0; + if (val != 0) + { + in_uint32_le(in_s, cbRecvLength); + in_uint8p(in_s, recvBuf, cbRecvLength); + } + LLOGLN(10, ("scard_function_transmit_return: cbRecvLength %d", cbRecvLength)); + out_s = trans_get_out_s(con, 8192); + s_push_layer(out_s, iso_hdr, 8); + out_uint32_le(out_s, recv_ior.dwProtocol); + out_uint32_le(out_s, recv_ior.cbPciLength); + out_uint32_le(out_s, recv_ior.extra_bytes); + out_uint8a(out_s, recv_ior.extra_data, recv_ior.extra_bytes); + out_uint32_le(out_s, cbRecvLength); + out_uint8a(out_s, recvBuf, cbRecvLength); + out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ + s_mark_end(out_s); + bytes = (int) (out_s->end - out_s->data); + s_pop_layer(out_s, iso_hdr); + out_uint32_le(out_s, bytes - 8); + out_uint32_le(out_s, 0x09); /* SCARD_TRANSMIT 0x09 */ + return trans_force_write(con); +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_process_control(struct trans *con, struct stream *in_s) +{ + tui32 context; + int hCard; + int send_bytes; + int recv_bytes; + int control_code; + char *send_data; + + LLOGLN(10, ("scard_process_control:")); + if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO) + { + LLOGLN(0, ("scard_process_control: opps")); + return 1; + } + g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_CO; + LLOGLN(10, ("scard_process_control:")); + + in_uint32_le(in_s, hCard); + in_uint32_le(in_s, control_code); + in_uint32_le(in_s, send_bytes); + 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, + control_code); + + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_function_control_return(struct trans *con, + struct stream *in_s, + int len) +{ + struct stream *out_s; + int bytes; + int cbRecvLength; + char *recvBuf; + + //g_hexdump(in_s->p, len); + if ((g_xrdp_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; + + in_uint8s(in_s, 28); + in_uint32_le(in_s, cbRecvLength); + in_uint8p(in_s, recvBuf, cbRecvLength); + + LLOGLN(10, ("scard_function_control_return: cbRecvLength %d", cbRecvLength)); + out_s = trans_get_out_s(con, 8192); + s_push_layer(out_s, iso_hdr, 8); + out_uint32_le(out_s, cbRecvLength); + out_uint8a(out_s, recvBuf, cbRecvLength); + out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ + s_mark_end(out_s); + bytes = (int) (out_s->end - out_s->data); + s_pop_layer(out_s, iso_hdr); + out_uint32_le(out_s, bytes - 8); + out_uint32_le(out_s, 0x0A); /* SCARD_CONTROL 0x0A */ + return trans_force_write(con); +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_process_status(struct trans *con, struct stream *in_s) +{ + int hCard; + int cchReaderLen; + int cbAtrLen; + + LLOGLN(10, ("scard_process_status:")); + if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST) + { + LLOGLN(0, ("scard_process_status: opps")); + return 1; + } + g_xrdp_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); + + return 0; +} + +#define MS_SCARD_UNKNOWN 0 +#define MS_SCARD_ABSENT 1 +#define MS_SCARD_PRESENT 2 +#define MS_SCARD_SWALLOWED 3 +#define MS_SCARD_POWERED 4 +#define MS_SCARD_NEGOTIABLE 5 +#define MS_SCARD_SPECIFIC 6 + +#define PC_SCARD_UNKNOWN 0x0001 /**< Unknown state */ +#define PC_SCARD_ABSENT 0x0002 /**< Card is absent */ +#define PC_SCARD_PRESENT 0x0004 /**< Card is present */ +#define PC_SCARD_SWALLOWED 0x0008 /**< Card not powered */ +#define PC_SCARD_POWERED 0x0010 /**< Card is powered */ +#define PC_SCARD_NEGOTIABLE 0x0020 /**< Ready for PTS */ +#define PC_SCARD_SPECIFIC 0x0040 /**< PTS has been set */ + +static int g_ms2pc[] = { PC_SCARD_UNKNOWN, PC_SCARD_ABSENT, + PC_SCARD_PRESENT, PC_SCARD_SWALLOWED, + PC_SCARD_POWERED, PC_SCARD_NEGOTIABLE, + PC_SCARD_SPECIFIC }; + +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_function_status_return(struct trans *con, + struct stream *in_s, + int len) +{ + struct stream *out_s; + int index; + int bytes; + int dwReaderLen; + int dwState; + int dwProtocol; + int dwAtrLen; + char attr[32]; + twchar reader_name[100]; + char lreader_name[100]; + + //g_hexdump(in_s->p, len); + if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST) == 0) + { + LLOGLN(0, ("scard_function_status_return: opps")); + return 1; + } + g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_ST; + in_uint8s(in_s, 20); + in_uint32_le(in_s, dwReaderLen); + in_uint8s(in_s, 4); + in_uint32_le(in_s, dwState); + dwState = g_ms2pc[dwState % 6]; + in_uint32_le(in_s, dwProtocol); + in_uint8a(in_s, attr, 32); + in_uint32_le(in_s, dwAtrLen); + in_uint32_le(in_s, dwReaderLen); + dwReaderLen /= 2; + g_memset(reader_name, 0, sizeof(reader_name)); + g_memset(lreader_name, 0, sizeof(lreader_name)); + for (index = 0; index < dwReaderLen; index++) + { + in_uint16_le(in_s, reader_name[index]); + } + g_wcstombs(lreader_name, reader_name, 99); + LLOGLN(10, ("scard_function_status_return: dwAtrLen %d dwReaderLen %d " + "dwProtocol %d dwState %d name %s", + dwAtrLen, dwReaderLen, dwProtocol, dwState, lreader_name)); + out_s = trans_get_out_s(con, 8192); + s_push_layer(out_s, iso_hdr, 8); + dwReaderLen = g_strlen(lreader_name); + out_uint32_le(out_s, dwReaderLen); + out_uint8a(out_s, lreader_name, dwReaderLen); + out_uint32_le(out_s, dwState); + out_uint32_le(out_s, dwProtocol); + out_uint32_le(out_s, dwAtrLen); + out_uint8a(out_s, attr, dwAtrLen); + out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */ + s_mark_end(out_s); + bytes = (int) (out_s->end - out_s->data); + s_pop_layer(out_s, iso_hdr); + out_uint32_le(out_s, bytes - 8); + out_uint32_le(out_s, 0x0B); /* SCARD_STATUS 0x0B */ + return trans_force_write(con); +} + /*****************************************************************************/ /* returns error */ int APP_CC @@ -414,7 +864,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s) int cReaders; READER_STATE *rsa; - LLOGLN(0, ("scard_process_get_status_change:")); + LLOGLN(10, ("scard_process_get_status_change:")); if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC) { LLOGLN(0, ("scard_process_get_status_change: opps")); @@ -447,7 +897,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s) in_uint8a(in_s, rsa[index].atr, 36); } - LLOGLN(0, ("scard_process_get_status_change: hContext 0x%8.8x dwTimeout " + 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; @@ -474,8 +924,8 @@ scard_function_get_status_change_return(struct trans *con, tui8 atr[36]; struct stream *out_s; - LLOGLN(0, ("scard_function_get_status_change_return:")); - g_hexdump(in_s->p, len); + LLOGLN(10, ("scard_function_get_status_change_return:")); + //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")); @@ -511,6 +961,25 @@ scard_function_get_status_change_return(struct trans *con, return 0; } +/*****************************************************************************/ +/* returns error */ +int APP_CC +scard_function_is_context_valid_return(struct trans *con, + struct stream *in_s, + int len) +{ + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC scard_function_reconnect_return(struct trans *con, + struct stream *in_s, + int len) +{ + return 0; +} + /*****************************************************************************/ /* returns error */ int APP_CC @@ -518,26 +987,26 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command) { int rv; - LLOGLN(0, ("scard_process_msg: command 0x%4.4x", command)); + LLOGLN(10, ("scard_process_msg: command 0x%4.4x", command)); rv = 0; switch (command) { case 0x01: /* SCARD_ESTABLISH_CONTEXT */ - LLOGLN(0, ("scard_process_msg: SCARD_ESTABLISH_CONTEXT")); + LLOGLN(10, ("scard_process_msg: SCARD_ESTABLISH_CONTEXT")); rv = scard_process_establish_context(con, in_s); break; case 0x02: /* SCARD_RELEASE_CONTEXT */ - LLOGLN(0, ("scard_process_msg: SCARD_RELEASE_CONTEXT")); + LLOGLN(10, ("scard_process_msg: SCARD_RELEASE_CONTEXT")); rv = scard_process_release_context(con, in_s); break; case 0x03: /* SCARD_LIST_READERS */ - LLOGLN(0, ("scard_process_msg: SCARD_LIST_READERS")); + LLOGLN(10, ("scard_process_msg: SCARD_LIST_READERS")); rv = scard_process_list_readers(con, in_s); break; case 0x04: /* SCARD_CONNECT */ - LLOGLN(0, ("scard_process_msg: SCARD_CONNECT")); + LLOGLN(10, ("scard_process_msg: SCARD_CONNECT")); rv = scard_process_connect(con, in_s); break; @@ -546,32 +1015,37 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command) break; case 0x06: /* SCARD_DISCONNECT */ - LLOGLN(0, ("scard_process_msg: SCARD_DISCONNECT")); + LLOGLN(10, ("scard_process_msg: SCARD_DISCONNECT")); + rv = scard_process_disconnect(con, in_s); break; case 0x07: /* SCARD_BEGIN_TRANSACTION */ - LLOGLN(0, ("scard_process_msg: SCARD_BEGIN_TRANSACTION")); + LLOGLN(10, ("scard_process_msg: SCARD_BEGIN_TRANSACTION")); rv = scard_process_begin_transaction(con, in_s); break; case 0x08: /* SCARD_END_TRANSACTION */ - LLOGLN(0, ("scard_process_msg: SCARD_END_TRANSACTION")); + LLOGLN(10, ("scard_process_msg: SCARD_END_TRANSACTION")); + rv = scard_process_end_transaction(con, in_s); break; case 0x09: /* SCARD_TRANSMIT */ - LLOGLN(0, ("scard_process_msg: SCARD_TRANSMIT")); + LLOGLN(10, ("scard_process_msg: SCARD_TRANSMIT")); + rv = scard_process_transmit(con, in_s); break; case 0x0A: /* SCARD_CONTROL */ - LLOGLN(0, ("scard_process_msg: SCARD_CONTROL")); + LLOGLN(10, ("scard_process_msg: SCARD_CONTROL")); + rv = scard_process_control(con, in_s); break; case 0x0B: /* SCARD_STATUS */ - LLOGLN(0, ("scard_process_msg: SCARD_STATUS")); + LLOGLN(10, ("scard_process_msg: SCARD_STATUS")); + rv = scard_process_status(con, in_s); break; case 0x0C: /* SCARD_GET_STATUS_CHANGE */ - LLOGLN(0, ("scard_process_msg: SCARD_GET_STATUS_CHANGE")); + LLOGLN(10, ("scard_process_msg: SCARD_GET_STATUS_CHANGE")); rv = scard_process_get_status_change(con, in_s); break; @@ -605,12 +1079,11 @@ int DEFAULT_CC my_pcsc_trans_data_in(struct trans *trans) { struct stream *s; - int id; int size; int command; int error; - LLOGLN(0, ("my_pcsc_trans_data_in:")); + LLOGLN(10, ("my_pcsc_trans_data_in:")); if (trans == 0) { return 0; @@ -622,7 +1095,7 @@ my_pcsc_trans_data_in(struct trans *trans) s = trans_get_in_s(trans); in_uint32_le(s, size); in_uint32_le(s, command); - LLOGLN(0, ("my_pcsc_trans_data_in: size %d command %d", size, command)); + LLOGLN(10, ("my_pcsc_trans_data_in: size %d command %d", size, command)); error = trans_force_read(trans, size); if (error == 0) { @@ -636,7 +1109,7 @@ my_pcsc_trans_data_in(struct trans *trans) int DEFAULT_CC my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans) { - LLOGLN(0, ("my_pcsc_trans_conn_in:")); + LLOGLN(10, ("my_pcsc_trans_conn_in:")); if (trans == 0) { @@ -655,13 +1128,7 @@ my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans) g_con = new_trans; g_con->trans_data_in = my_pcsc_trans_data_in; -#if 1 g_con->header_size = 8; -#else - g_con->header_size = RXSHAREDSEGMENT_BYTES; - LLOGLN(0, ("my_pcsc_trans_conn_in: sizeof sharedSegmentMsg is %d", - sizeof(sharedSegmentMsg))); -#endif return 0; } @@ -673,7 +1140,6 @@ scard_pcsc_init(void) char *home; int disp; int error; - int index; LLOGLN(0, ("scard_pcsc_init:")); if (g_lis == 0) diff --git a/sesman/chansrv/smartcard_pcsc.h b/sesman/chansrv/smartcard_pcsc.h index 94effea9..bd5b9090 100644 --- a/sesman/chansrv/smartcard_pcsc.h +++ b/sesman/chansrv/smartcard_pcsc.h @@ -38,11 +38,52 @@ int APP_CC scard_function_list_readers_return(struct trans *con, struct stream *in_s, int len); +int APP_CC scard_function_transmit_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_control_return(struct trans *con, + struct stream *in_s, + int len); + int APP_CC scard_function_get_status_change_return(struct trans *con, struct stream *in_s, int len); + int APP_CC scard_function_connect_return(struct trans *con, struct stream *in_s, int len); +int APP_CC scard_function_status_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_begin_transaction_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_end_transaction_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_is_context_valid_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_reconnect_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_disconnect_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_cancel_return(struct trans *con, + struct stream *in_s, + int len); + +int APP_CC scard_function_get_attrib_return(struct trans *con, + struct stream *in_s, + int len); + #endif /* end #ifndef _SMARTCARD_PCSC_H */