chansrv: work on smartcard

ulab-next
Jay Sorg 11 years ago
parent fc31ae1f48
commit 675e1b86c4

@ -52,11 +52,22 @@ typedef struct _SCARD_IO_REQUEST
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0) do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
#define SCARD_ESTABLISH_CONTEXT 0x01 #define SCARD_ESTABLISH_CONTEXT 0x01
#define SCARD_RELEASE_CONTEXT 0x02 #define SCARD_RELEASE_CONTEXT 0x02
#define SCARD_LIST_READERS 0x03 #define SCARD_LIST_READERS 0x03
#define SCARD_CONNECT 0x04 #define SCARD_CONNECT 0x04
#define SCARD_GET_STATUS_CHANGE 0x0C #define SCARD_RECONNECT 0x05
#define SCARD_DISCONNECT 0x06
#define SCARD_BEGIN_TRANSACTION 0x07
#define SCARD_END_TRANSACTION 0x08
#define SCARD_TRANSMIT 0x09
#define SCARD_CONTROL 0x0A
#define SCARD_STATUS 0x0B
#define SCARD_GET_STATUS_CHANGE 0x0C
#define SCARD_CANCEL 0x0D
#define SCARD_CANCEL_TRANSACTION 0x0E
#define SCARD_GET_ATTRIB 0x0F
#define SCARD_SET_ATTRIB 0x10
#define SCARD_S_SUCCESS 0x00000000 #define SCARD_S_SUCCESS 0x00000000
#define SCARD_F_INTERNAL_ERROR ((LONG)0x80100001) #define SCARD_F_INTERNAL_ERROR ((LONG)0x80100001)
@ -417,7 +428,7 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
pthread_mutex_unlock(&g_mutex); pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR; return SCARD_F_INTERNAL_ERROR;
} }
if (code != SCARD_RELEASE_CONTEXT) if (code != SCARD_CONNECT)
{ {
LLOGLN(0, ("SCardConnect: error, bad code")); LLOGLN(0, ("SCardConnect: error, bad code"));
pthread_mutex_unlock(&g_mutex); pthread_mutex_unlock(&g_mutex);
@ -467,6 +478,11 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
PCSC_API LONG PCSC_API LONG
SCardBeginTransaction(SCARDHANDLE hCard) SCardBeginTransaction(SCARDHANDLE hCard)
{ {
char msg[256];
int code;
int bytes;
int status;
LLOGLN(0, ("SCardBeginTransaction:")); LLOGLN(0, ("SCardBeginTransaction:"));
if (g_sck == -1) if (g_sck == -1)
{ {
@ -474,8 +490,30 @@ SCardBeginTransaction(SCARDHANDLE hCard)
return SCARD_F_INTERNAL_ERROR; return SCARD_F_INTERNAL_ERROR;
} }
pthread_mutex_lock(&g_mutex); 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;
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); pthread_mutex_unlock(&g_mutex);
return SCARD_S_SUCCESS; status = GET_UINT32(msg, 0);
LLOGLN(10, ("SCardBeginTransaction: got status 0x%8.8x", status));
return status;
} }
/*****************************************************************************/ /*****************************************************************************/

@ -1163,6 +1163,8 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
/* insert reader name */ /* insert reader name */
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99); num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
xstream_wr_u32_le(s, 0);
xstream_wr_u32_le(s, 0);
xstream_wr_u32_le(s, num_chars); xstream_wr_u32_le(s, num_chars);
if (wide) if (wide)
{ {
@ -1178,6 +1180,7 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
xstream_wr_u8(s, w_reader_name[index]); xstream_wr_u8(s, w_reader_name[index]);
} }
} }
align_s(s, 4);
/* insert context */ /* insert context */
xstream_wr_u32_le(s, 4); xstream_wr_u32_le(s, 4);
@ -1670,6 +1673,7 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
tui32 IoStatus) tui32 IoStatus)
{ {
tui32 len; tui32 len;
struct trans *con;
log_debug("entered"); log_debug("entered");
@ -1689,7 +1693,9 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
/* get OutputBufferLen */ /* get OutputBufferLen */
xstream_rd_u32_le(s, len); 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"); log_debug("leaving");
} }

@ -56,6 +56,7 @@
#define XRDP_PCSC_STATE_GOT_RC (1 << 2) /* release context */ #define XRDP_PCSC_STATE_GOT_RC (1 << 2) /* release context */
#define XRDP_PCSC_STATE_GOT_GSC (1 << 3) /* get status change */ #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_C (1 << 4) /* connect */
#define XRDP_PCSC_STATE_GOT_BT (1 << 5) /* begin transaction */
/* TODO: put this in con */ /* 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;
@ -347,6 +348,61 @@ scard_process_connect(struct trans *con, struct stream *in_s)
return 0; return 0;
} }
/*****************************************************************************/
int APP_CC
scard_function_connect_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_C) == 0)
{
LLOGLN(0, ("scard_function_connect_return: opps"));
return 1;
}
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_uint32_le(in_s, hCard);
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
out_uint32_le(out_s, hCard);
out_uint32_le(out_s, dwActiveProtocol);
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, 0x04); /* SCARD_CONNECT 0x04 */
return trans_force_write(con);
}
/*****************************************************************************/
/* returns error */
int APP_CC
scard_process_begin_transaction(struct trans *con, struct stream *in_s)
{
int hCard;
LLOGLN(0, ("scard_process_begin_transaction:"));
if (g_xrdp_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;
in_uint32_le(in_s, hCard);
LLOGLN(0, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard));
scard_send_begin_transaction(con, hCard);
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
int APP_CC int APP_CC
@ -495,6 +551,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
case 0x07: /* SCARD_BEGIN_TRANSACTION */ case 0x07: /* SCARD_BEGIN_TRANSACTION */
LLOGLN(0, ("scard_process_msg: SCARD_BEGIN_TRANSACTION")); LLOGLN(0, ("scard_process_msg: SCARD_BEGIN_TRANSACTION"));
rv = scard_process_begin_transaction(con, in_s);
break; break;
case 0x08: /* SCARD_END_TRANSACTION */ case 0x08: /* SCARD_END_TRANSACTION */

@ -41,5 +41,8 @@ int APP_CC scard_function_list_readers_return(struct trans *con,
int APP_CC scard_function_get_status_change_return(struct trans *con, int APP_CC scard_function_get_status_change_return(struct trans *con,
struct stream *in_s, struct stream *in_s,
int len); int len);
int APP_CC scard_function_connect_return(struct trans *con,
struct stream *in_s,
int len);
#endif /* end #ifndef _SMARTCARD_PCSC_H */ #endif /* end #ifndef _SMARTCARD_PCSC_H */

Loading…
Cancel
Save