summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2013-09-14 12:57:34 -0700
committerJay Sorg <jay.sorg@gmail.com>2013-09-14 12:57:34 -0700
commitedf483ecb66eff4cc378ea4c3ebba3410947ebe7 (patch)
treec79f8af774a156bda31955ee4f1aa582aff0f46c
parent215956353fa2b122f7b75a9e344138ab61d4b594 (diff)
downloadxrdp-proprietary-edf483ecb66eff4cc378ea4c3ebba3410947ebe7.tar.gz
xrdp-proprietary-edf483ecb66eff4cc378ea4c3ebba3410947ebe7.zip
chansrv: work on smartcard
-rw-r--r--sesman/chansrv/smartcard.c48
-rw-r--r--sesman/chansrv/smartcard_pcsc.c184
-rw-r--r--sesman/chansrv/smartcard_pcsc.h28
3 files changed, 225 insertions, 35 deletions
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index 78a47ba0..a0e15e6e 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -644,6 +644,9 @@ scard_send_GetStatusChange(IRP* irp, int wide, tui32 timeout,
int bytes;
int i;
int len;
+ int num_chars;
+ int index;
+ twchar w_reader_name[100];
if ((sc = smartcards[irp->scard_index]) == NULL)
{
@@ -672,26 +675,45 @@ scard_send_GetStatusChange(IRP* irp, int wide, tui32 timeout,
for (i = 0; i < num_readers; i++)
{
rs = &rsa[i];
-
xstream_wr_u32_le(s, 0); /* unused */
xstream_wr_u32_le(s, rs->current_state);
xstream_wr_u32_le(s, rs->event_state);
xstream_wr_u32_le(s, rs->atr_len);
- xstream_copyin(s, rs->atr, rs->atr_len);
- xstream_wr_u32_le(s, 0); /* unused */
+ xstream_copyin(s, rs->atr, 33);
+ out_uint8s(s, 3);
}
- /* insert card reader names */
- for (i = 0; i < num_readers; i++)
+ if (wide)
{
- rs = &rsa[i];
- len = strlen(rs->reader_name);
-
- xstream_wr_u32_le(s, 0); /* unused */
- xstream_wr_u32_le(s, 0); /* unused */
- xstream_wr_u32_le(s, len);
- xstream_copyin(s, rs->reader_name, len);
- xstream_wr_u32_le(s, 0); /* null terminate */
+ /* insert card reader names */
+ for (i = 0; i < num_readers; i++)
+ {
+ rs = &rsa[i];
+ num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
+ xstream_wr_u32_le(s, 0); /* unused */
+ xstream_wr_u32_le(s, 0); /* unused */
+ xstream_wr_u32_le(s, num_chars);
+ for (index = 0; index < num_chars; index++)
+ {
+ xstream_wr_u16_le(s, w_reader_name[index]);
+ }
+ }
+ }
+ else
+ {
+ /* insert card reader names */
+ for (i = 0; i < num_readers; i++)
+ {
+ rs = &rsa[i];
+ num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
+ xstream_wr_u32_le(s, 0); /* unused */
+ xstream_wr_u32_le(s, 0); /* unused */
+ xstream_wr_u32_le(s, num_chars);
+ for (index = 0; index < num_chars; index++)
+ {
+ xstream_wr_u8(s, w_reader_name[index]);
+ }
+ }
}
/* get stream len */
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index 5d1be106..7fe75956 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -31,6 +31,7 @@
#include "irp.h"
#include "devredir.h"
#include "trans.h"
+#include "chansrv.h"
#if PCSC_STANDIN
@@ -40,7 +41,7 @@
{ \
if (_level < LLOG_LEVEL) \
{ \
- g_write("chansrv:smartcard [%10.10u]: ", g_time3()); \
+ g_write("chansrv:smartcard_pcsc [%10.10u]: ", g_time3()); \
g_writeln _args ; \
} \
} \
@@ -95,8 +96,12 @@ struct pubReaderStatesList
#define PCSCLITE_MAX_READERS_CONTEXTS 16
+static int g_num_readers = 0;
+/* pcsc list */
static struct pubReaderStatesList
- g_reader_states[PCSCLITE_MAX_READERS_CONTEXTS];
+ g_pcsc_reader_states[PCSCLITE_MAX_READERS_CONTEXTS];
+/* rdp list */
+static READER_STATE g_xrdp_reader_states[PCSCLITE_MAX_READERS_CONTEXTS];
struct wait_reader_state_change
{
@@ -104,8 +109,11 @@ struct wait_reader_state_change
tui32 rv;
};
-#define XRDP_PCSC_STATE_NONE 0
-#define XRDP_PCSC_STATE_GOT_RSC 1
+#define XRDP_PCSC_STATE_NONE 0
+#define XRDP_PCSC_STATE_GOT_RSC (1 << 0) /* read state change */
+#define XRDP_PCSC_STATE_GOT_EC (1 << 1) /* establish context */
+#define XRDP_PCSC_STATE_GOT_LR (1 << 2) /* list readers */
+#define XRDP_PCSC_STATE_GOT_RC (1 << 3) /* release context */
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
@@ -166,6 +174,12 @@ scard_process_establish_context(struct trans *con, struct stream *in_s)
struct establish_struct in_es;
LLOGLN(0, ("scard_process_establish_context:"));
+ if (g_xrdp_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;
in_uint8a(in_s, &in_es, sizeof(in_es));
LLOGLN(0, ("scard_process_establish_context: dwScope 0x%8.8x",
in_es.dwScope));
@@ -183,6 +197,12 @@ scard_function_establish_context_return(struct trans *con, int context)
LLOGLN(0, ("scard_function_establish_context_return: context %d",
context));
+ if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0)
+ {
+ LLOGLN(0, ("scard_function_establish_context_return: opps"));
+ return 1;
+ }
+ g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC;
out_es.dwScope = 0;
out_es.hContext = context;
out_es.rv = SCARD_S_SUCCESS;
@@ -204,6 +224,9 @@ scard_process_release_context(struct stream *in_s)
LLOGLN(0, ("scard_process_release_context:"));
in_uint8a(in_s, &in_rs, sizeof(in_rs));
LLOGLN(0, ("scard_process_release_context: hContext %d", in_rs.hContext));
+
+ /* TODO: use XRDP_PCSC_STATE_GOT_RC */
+
out_rs.hContext = in_rs.hContext;
out_rs.rv = SCARD_S_SUCCESS;
out_s = trans_get_out_s(g_con, 8192);
@@ -238,10 +261,26 @@ scard_process_version(struct trans *con, struct stream *in_s)
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_process_get_readers_state(struct stream *in_s)
+scard_process_get_readers_state(struct trans *con, struct stream *in_s)
{
+ //struct stream *out_s;
+
LLOGLN(0, ("scard_process_get_readers_state:"));
- scard_send_irp_list_readers(g_con);
+
+ //out_s = trans_get_out_s(con, 8192);
+ //out_uint8a(out_s, g_pcsc_reader_states, sizeof(g_pcsc_reader_states));
+ //s_mark_end(out_s);
+ //return trans_force_write(con);
+
+ if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR)
+ {
+ LLOGLN(0, ("scard_process_get_readers_state: opps"));
+ return 1;
+ }
+ g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR;
+
+ scard_send_irp_list_readers(con);
+
return 0;
}
@@ -253,9 +292,55 @@ scard_function_list_readers_return(struct trans *con,
int len)
{
struct stream *out_s;
+ int chr;
+ int readers;
+ int rn_index;
+ char reader_name[100];
g_hexdump(in_s->p, len);
+ if ((g_xrdp_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;
+
+ in_uint8s(in_s, 28);
+ len -= 28;
+ in_uint32_le(in_s, len);
+ g_writeln("len %d", len);
+ rn_index = 0;
+ readers = 1;
+ while (len > 0)
+ {
+ in_uint16_le(in_s, chr);
+ len -= 2;
+ if (chr == 0)
+ {
+ if (reader_name[0] != 0)
+ {
+ g_writeln("1 %s", reader_name);
+ readers++;
+ }
+ reader_name[0] = 0;
+ rn_index = 0;
+ }
+ else
+ {
+ reader_name[rn_index] = chr;
+ rn_index++;
+ }
+ }
+ if (rn_index > 0)
+ {
+ if (reader_name[0] != 0)
+ {
+ g_writeln("2 %s", reader_name);
+ readers++;
+ }
+ }
+#if 0
g_strcpy(g_reader_states[0].readerName, "ACS AET65 00 00");
g_reader_states[0].readerState = 0x14;
g_reader_states[0].cardProtocol = 3;
@@ -278,6 +363,8 @@ scard_function_list_readers_return(struct trans *con,
out_uint8a(out_s, g_reader_states, sizeof(g_reader_states));
s_mark_end(out_s);
return trans_force_write(con);
+#endif
+ return 0;
}
/*****************************************************************************/
@@ -314,20 +401,44 @@ scard_process_read_state_change(struct trans *con, struct stream *in_s)
{
struct wait_reader_state_change in_rsc;
struct stream *out_s;
+ int index;
LLOGLN(0, ("scard_process_read_state_change:"));
in_uint8a(in_s, &in_rsc, sizeof(in_rsc));
+ if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RSC)
+ {
+ LLOGLN(0, ("scard_process_read_state_change: opps"));
+ return 0;
+ }
+
+#if 0
+ for (index = 0; index < 16; index++)
+ {
+ //g_memcpy(rd[index].reader_name, g_pcsc_reader_states[index].readerName, 99);
+ g_strncpy(rd[index].reader_name, "Gemalto PC Twin Reader 00 00", 99);
+ rd[index].current_state = g_pcsc_reader_states[index].readerState;
+ rd[index].event_state = g_pcsc_reader_states[index].eventCounter;
+ rd[index].atr_len = g_pcsc_reader_states[index].cardAtrLength;
+ g_memcpy(rd[index].atr, g_pcsc_reader_states[index].cardAtr, 33);
+ }
+#endif
+
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RSC;
+ scard_send_irp_get_status_change(con, 1, in_rsc.timeOut, g_num_readers,
+ g_xrdp_reader_states);
+
LLOGLN(0, ("scard_process_read_state_change: timeout %d rv %d",
in_rsc.timeOut, in_rsc.rv));
+
add_timeout(in_rsc.timeOut, scard_read_state_chage_timeout, con);
+
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_process_stop_read_state_change(struct stream *in_s)
+scard_process_stop_read_state_change(struct trans *con, struct stream *in_s)
{
struct wait_reader_state_change in_rsc;
struct wait_reader_state_change out_rsc;
@@ -339,13 +450,13 @@ scard_process_stop_read_state_change(struct stream *in_s)
in_rsc.timeOut, in_rsc.rv));
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RSC)
{
- out_s = trans_get_out_s(g_con, 8192);
+ out_s = trans_get_out_s(con, 8192);
out_rsc.timeOut = in_rsc.timeOut;
out_rsc.rv = SCARD_S_SUCCESS;
out_uint8a(out_s, &out_rsc, sizeof(out_rsc));
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_RSC;
s_mark_end(out_s);
- return trans_force_write(g_con);
+ return trans_force_write(con);
}
else
{
@@ -357,6 +468,54 @@ scard_process_stop_read_state_change(struct stream *in_s)
/*****************************************************************************/
/* returns error */
int APP_CC
+scard_function_get_status_change_return(struct trans *con,
+ struct stream *in_s,
+ int len)
+{
+ struct stream *out_s;
+ int num_readers;
+ int index;
+ int current_state;
+ int event_state;
+ int atr_len;
+ char atr[36];
+
+ LLOGLN(0, ("scard_function_get_status_change_return:"));
+
+ //g_hexdump(in_s->p, len);
+
+ in_uint8s(in_s, 28);
+ in_uint32_le(in_s, num_readers);
+ LLOGLN(0, (" num_reader %d", num_readers));
+
+ g_num_readers = num_readers;
+
+ for (index = 0; index < num_readers; index++)
+ {
+ in_uint32_le(in_s, current_state);
+ in_uint32_le(in_s, event_state);
+ in_uint32_le(in_s, atr_len);
+ in_uint8a(in_s, atr, 36);
+ LLOGLN(0, (" current_state 0x%8.8x event_state 0x%8.8x "
+ "atr_len 0x%8.8x", current_state, event_state, atr_len));
+ g_xrdp_reader_states[index].current_state = current_state;
+ g_xrdp_reader_states[index].event_state = event_state;
+ g_xrdp_reader_states[index].atr_len = atr_len;
+ g_memcpy(g_xrdp_reader_states[index].atr, atr, 36);
+
+ }
+ //out_s = trans_get_out_s(con, 8192);
+ //out_uint8a(out_s, g_reader_states, sizeof(g_reader_states));
+ //s_mark_end(out_s);
+ //return trans_force_write(con);
+
+ return 0;
+
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
scard_process_msg(struct trans *con, struct stream *in_s, int command)
{
int rv;
@@ -436,7 +595,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
break;
case 0x12: /* CMD_GET_READERS_STATE */
LLOGLN(0, ("scard_process_msg: CMD_GET_READERS_STATE"));
- rv = scard_process_get_readers_state(in_s);
+ rv = scard_process_get_readers_state(con, in_s);
break;
case 0x13: /* CMD_WAIT_READER_STATE_CHANGE */
LLOGLN(0, ("scard_process_msg: CMD_WAIT_READER_STATE_CHANGE"));
@@ -444,7 +603,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
break;
case 0x14: /* CMD_STOP_WAITING_READER_STATE_CHANGE */
LLOGLN(0, ("scard_process_msg: CMD_STOP_WAITING_READER_STATE_CHANGE"));
- rv = scard_process_stop_read_state_change(in_s);
+ rv = scard_process_stop_read_state_change(con, in_s);
break;
default:
LLOGLN(0, ("scard_process_msg: unknown mtype 0x%4.4x", command));
@@ -531,7 +690,8 @@ scard_pcsc_init(void)
int index;
LLOGLN(0, ("scard_pcsc_init:"));
- g_memset(g_reader_states, 0, sizeof(g_reader_states));
+ g_memset(g_pcsc_reader_states, 0, sizeof(g_pcsc_reader_states));
+ g_memset(g_xrdp_reader_states, 0, sizeof(g_xrdp_reader_states));
if (g_lis == 0)
{
g_lis = trans_create(2, 8192, 8192);
diff --git a/sesman/chansrv/smartcard_pcsc.h b/sesman/chansrv/smartcard_pcsc.h
index 1c8c6d7b..ef1ccd68 100644
--- a/sesman/chansrv/smartcard_pcsc.h
+++ b/sesman/chansrv/smartcard_pcsc.h
@@ -24,15 +24,23 @@
#ifndef _SMARTCARD_PCSC_H
#define _SMARTCARD_PCSC_H
-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 context);
-
-int APP_CC scard_function_list_readers_return(struct trans *con,
- struct stream *in_s,
- int len);
+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 context);
+int APP_CC
+scard_function_list_readers_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);
#endif /* end #ifndef _SMARTCARD_PCSC_H */