summaryrefslogtreecommitdiffstats
path: root/sesman/chansrv/smartcard_pcsc.c
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2013-12-21 19:16:08 -0800
committerJay Sorg <jay.sorg@gmail.com>2013-12-21 19:16:08 -0800
commit1483c7591121036b29ad5243fc2e2419992331ac (patch)
tree7102a5c5dddda2cd0e5d7ffe1c4dd80f8edeb8c4 /sesman/chansrv/smartcard_pcsc.c
parent6eab2ed11b634342b48dd75bd3866f35d6479a0f (diff)
downloadxrdp-proprietary-1483c7591121036b29ad5243fc2e2419992331ac.tar.gz
xrdp-proprietary-1483c7591121036b29ad5243fc2e2419992331ac.zip
chansrv: work on smartcard stability, handle multi threaded calls, app crashes, etc
Diffstat (limited to 'sesman/chansrv/smartcard_pcsc.c')
-rw-r--r--sesman/chansrv/smartcard_pcsc.c632
1 files changed, 525 insertions, 107 deletions
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index ebf52c82..95c01a04 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -35,6 +35,7 @@
#include "devredir.h"
#include "trans.h"
#include "chansrv.h"
+#include "list.h"
#if PCSC_STANDIN
@@ -63,42 +64,242 @@
#define XRDP_PCSC_STATE_GOT_D (1 << 9) /* disconnect */
#define XRDP_PCSC_STATE_GOT_ST (1 << 10) /* get status */
+#if 0
/* TODO: put this in con */
-static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
+static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE; /* 0 */
static int g_xrdp_pcsc_extra1;
+#endif
extern int g_display_num; /* in chansrv.c */
+static int g_uds_client_id = 0; /* auto incremented for each unix domain
+ socket connection */
+
+struct pcsc_card /* item for list of open cards in one context */
+{
+ tui32 card;
+};
+
+struct pcsc_context
+{
+ tui32 context;
+ struct list *cards; /* these need to be released on close */
+};
+
/*****************************************************************************/
-struct pcsc_client
+struct pcsc_uds_client
{
+ int uds_client_id; /* from g_uds_client_id */
struct trans *con;
+ struct list *contexts; /* struct pcsc_context */
+ int pcsc_state;
+ int pcsc_extra1;
};
-#if 0
-static struct pcsc_client *g_head = 0;
-static struct pcsc_client *g_tail = 0;
-#endif
+static struct list *g_uds_clients = 0; /* struct pcsc_uds_client */
static struct trans *g_lis = 0;
+#if 0
static struct trans *g_con = 0; /* todo, remove this */
+#endif
static char g_pcsclite_ipc_dir[256] = "";
static char g_pcsclite_ipc_file[256] = "";
-static int g_pub_file_fd = 0;
+
+/*****************************************************************************/
+/* got a new unix domain socket connection */
+static struct pcsc_uds_client *
+create_uds_client(struct trans *con)
+{
+ struct pcsc_uds_client *uds_client;
+
+ LLOGLN(10, ("create_uds_client:"));
+ if (con == 0)
+ {
+ return 0;
+ }
+ uds_client = g_malloc(sizeof(struct pcsc_uds_client), 1);
+ if (uds_client == 0)
+ {
+ return 0;
+ }
+ g_uds_client_id++;
+ uds_client->uds_client_id = g_uds_client_id;
+ uds_client->con = con;
+ con->callback_data = uds_client;
+ return uds_client;
+}
+
+/*****************************************************************************/
+static struct pcsc_uds_client *
+get_uds_client_by_id(int uds_client_id)
+{
+ struct pcsc_uds_client *uds_client;
+ int index;
+
+ LLOGLN(10, ("get_uds_client_by_id:"));
+ if (uds_client_id == 0)
+ {
+ LLOGLN(10, ("get_uds_client_by_id: uds_client_id zero"));
+ return 0;
+ }
+ if (g_uds_clients == 0)
+ {
+ LLOGLN(10, ("get_uds_client_by_id: g_uds_clients is nil"));
+ return 0;
+ }
+ LLOGLN(10, (" count %d", g_uds_clients->count));
+ for (index = 0; index < g_uds_clients->count; index++)
+ {
+ uds_client = (struct pcsc_uds_client *)
+ list_get_item(g_uds_clients, index);
+ if (uds_client->uds_client_id == uds_client_id)
+ {
+ return uds_client;
+ }
+ }
+ LLOGLN(10, ("get_uds_client_by_id: can't find uds_client_id %d",
+ uds_client_id));
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+free_uds_client(struct pcsc_uds_client *uds_client)
+{
+ int i;
+ int j;
+ struct pcsc_context *context;
+ struct pcsc_card *card;
+
+ LLOGLN(10, ("free_uds_client:"));
+ if (uds_client == 0)
+ {
+ return 0;
+ }
+ if (uds_client->contexts != 0)
+ {
+ for (i = 0; i < uds_client->contexts->count; i++)
+ {
+ context = (struct pcsc_context *)
+ list_get_item(uds_client->contexts, i);
+ if (context != 0)
+ {
+ if (context->cards != 0)
+ {
+ for (j = 0; j < context->cards->count; j++)
+ {
+ card = (struct pcsc_card *)
+ list_get_item(context->cards, j);
+ if (card != 0)
+ {
+ /* TODO: send free card to client */
+ g_free(card);
+ }
+ }
+ list_delete(context->cards);
+ }
+ LLOGLN(10, (" left over context 0x%8.8x", context->context));
+ scard_send_cancel(0, context->context);
+ scard_send_release_context(0, context->context);
+ g_free(context);
+ }
+ }
+ list_delete(uds_client->contexts);
+ }
+ trans_delete(uds_client->con);
+ g_free(uds_client);
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+uds_client_add_context(struct pcsc_uds_client *uds_client, tui32 context)
+{
+ struct pcsc_context *pcscContext;
+
+ LLOGLN(10, ("uds_client_add_context:"));
+ pcscContext = (struct pcsc_context * )
+ g_malloc(sizeof(struct pcsc_context), 1);
+ if (pcscContext == 0)
+ {
+ LLOGLN(0, ("uds_client_add_context: error"));
+ return 1;
+ }
+ pcscContext->context = context;
+ if (uds_client->contexts == 0)
+ {
+ uds_client->contexts = list_create();
+ if (uds_client->contexts == 0)
+ {
+ LLOGLN(0, ("uds_client_add_context: error"));
+ return 1;
+ }
+ }
+ list_add_item(uds_client->contexts, (tintptr) pcscContext);
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+uds_client_remove_context(struct pcsc_uds_client *uds_client, tui32 context)
+{
+ int index;
+ struct pcsc_context *pcscContext;
+
+ LLOGLN(10, ("uds_client_remove_context:"));
+ if (uds_client->contexts == 0)
+ {
+ LLOGLN(0, ("uds_client_remove_context: error"));
+ return 1;
+ }
+ for (index = 0; index < uds_client->contexts->count; index++)
+ {
+ pcscContext = (struct pcsc_context *)
+ list_get_item(uds_client->contexts, index);
+ if (pcscContext != 0)
+ {
+ if (pcscContext->context == context)
+ {
+ list_remove_item(uds_client->contexts, index);
+ g_free(pcscContext);
+ return 0;
+ }
+ }
+ }
+ LLOGLN(10, ("uds_client_remove_context: not found"));
+ return 1;
+}
/*****************************************************************************/
int APP_CC
scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout)
{
- LLOGLN(10, ("scard_pcsc_get_wait_objs"));
+ struct pcsc_uds_client *uds_client;
+ int index;
+
+ LLOGLN(10, ("scard_pcsc_get_wait_objs:"));
if (g_lis != 0)
{
trans_get_wait_objs(g_lis, objs, count);
}
+#if 0
if (g_con != 0)
{
trans_get_wait_objs(g_con, objs, count);
}
+#endif
+ if (g_uds_clients != 0)
+ {
+ for (index = 0; index < g_uds_clients->count; index++)
+ {
+ uds_client = (struct pcsc_uds_client *)
+ list_get_item(g_uds_clients, index);
+ if (uds_client != 0)
+ {
+ trans_get_wait_objs(uds_client->con, objs, count);
+ }
+ }
+ }
return 0;
}
@@ -106,6 +307,9 @@ scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout)
int APP_CC
scard_pcsc_check_wait_objs(void)
{
+ struct pcsc_uds_client *uds_client;
+ int index;
+
LLOGLN(10, ("scard_pcsc_check_wait_objs:"));
if (g_lis != 0)
{
@@ -114,6 +318,7 @@ scard_pcsc_check_wait_objs(void)
LLOGLN(0, ("scard_pcsc_check_wait_objs: g_lis trans_check_wait_objs error"));
}
}
+#if 0
if (g_con != 0)
{
if (trans_check_wait_objs(g_con) != 0)
@@ -125,6 +330,26 @@ scard_pcsc_check_wait_objs(void)
g_xrdp_pcsc_state = 0;
}
}
+#endif
+ if (g_uds_clients != 0)
+ {
+ index = 0;
+ while (index < g_uds_clients->count)
+ {
+ uds_client = (struct pcsc_uds_client *)
+ list_get_item(g_uds_clients, index);
+ if (uds_client != 0)
+ {
+ if (trans_check_wait_objs(uds_client->con) != 0)
+ {
+ free_uds_client(uds_client);
+ list_remove_item(g_uds_clients, index);
+ continue;
+ }
+ }
+ index++;
+ }
+ }
return 0;
}
@@ -134,42 +359,58 @@ int APP_CC
scard_process_establish_context(struct trans *con, struct stream *in_s)
{
int dwScope;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_establish_context:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_EC)
{
LLOGLN(0, ("scard_process_establish_context: opps"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_EC;
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_EC;
in_uint32_le(in_s, dwScope);
LLOGLN(10, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope));
- scard_send_establish_context(con, dwScope);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_establish_context(user_data, dwScope);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_establish_context_return(struct trans *con,
+scard_function_establish_context_return(void *user_data,
struct stream *in_s,
int len, int status)
{
int bytes;
+ int uds_client_id;
tui32 context;
tui32 context_len;
struct stream *out_s;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_establish_context_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_establish_context_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0)
{
LLOGLN(0, ("scard_function_establish_context_return: opps "
- "g_xrdp_pcsc_state 0x%8.8x, g_xrdp_pcsc_state"));
+ "uds_client->pcsc_state 0x%8.8x", uds_client->pcsc_state));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC;
context = 0;
if (status == 0)
{
@@ -182,8 +423,9 @@ scard_function_establish_context_return(struct trans *con,
return 1;
}
in_uint32_le(in_s, context);
- LLOGLN(10, ("scard_function_establish_context_return: context 0x%8.8x",
- context));
+ uds_client_add_context(uds_client, context);
+ LLOGLN(10, ("scard_function_establish_context_return: "
+ "context 0x%8.8x", context));
}
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
@@ -203,38 +445,56 @@ int APP_CC
scard_process_release_context(struct trans *con, struct stream *in_s)
{
int hContext;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_release_context:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_RC)
{
LLOGLN(0, ("scard_process_establish_context: opps"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RC;
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_RC;
in_uint32_le(in_s, hContext);
LLOGLN(10, ("scard_process_release_context: hContext 0x%8.8x", hContext));
- scard_send_release_context(con, hContext);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_release_context(user_data, hContext);
+ uds_client_remove_context(uds_client, hContext);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_release_context_return(struct trans *con,
+scard_function_release_context_return(void *user_data,
struct stream *in_s,
int len, int status)
{
int bytes;
+ int uds_client_id;
struct stream *out_s;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_release_context_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_release_context_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0)
{
LLOGLN(0, ("scard_function_release_context_return: opps"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_RC;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_RC;
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
@@ -255,30 +515,34 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
int bytes_groups;
int cchReaders;
char *groups;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_list_readers:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_LR)
{
LLOGLN(0, ("scard_process_list_readers: opps"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR;
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_LR;
in_uint32_le(in_s, hContext);
in_uint32_le(in_s, bytes_groups);
groups = (char *) g_malloc(bytes_groups + 1, 1);
in_uint8a(in_s, groups, bytes_groups);
in_uint32_le(in_s, cchReaders);
- g_xrdp_pcsc_extra1 = cchReaders;
+ uds_client->pcsc_extra1 = cchReaders;
LLOGLN(10, ("scard_process_list_readers: hContext 0x%8.8x cchReaders %d",
hContext, cchReaders));
- scard_send_list_readers(con, hContext, groups, cchReaders, 1);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_list_readers(user_data, hContext, groups, cchReaders, 1);
g_free(groups);
return 0;
}
/*****************************************************************************/
int APP_CC
-scard_function_list_readers_return(struct trans *con,
+scard_function_list_readers_return(void *user_data,
struct stream *in_s,
int len, int status)
{
@@ -290,20 +554,33 @@ scard_function_list_readers_return(struct trans *con,
int bytes;
int cchReaders;
int llen;
+ int uds_client_id;
twchar reader_name[100];
char lreader_name[16][100];
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_list_readers_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_list_readers_return: "
+ "get_uds_client_by_id failed, could not find id %d",
+ uds_client_id));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0)
{
LLOGLN(0, ("scard_function_list_readers_return: opps"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR;
- cchReaders = g_xrdp_pcsc_extra1;
+ cchReaders = uds_client->pcsc_extra1;
g_memset(reader_name, 0, sizeof(reader_name));
g_memset(lreader_name, 0, sizeof(lreader_name));
@@ -358,6 +635,10 @@ scard_function_list_readers_return(struct trans *con,
{
out_uint8a(out_s, lreader_name[index], 100);
}
+ //if (readers == 0)
+ //{
+ // status = 0x8010002E; /* SCARD_E_NO_READERS_AVAILABLE */
+ //}
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
@@ -374,15 +655,18 @@ scard_process_connect(struct trans *con, struct stream *in_s)
{
int hContext;
READER_STATE rs;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_connect:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_C)
{
LLOGLN(0, ("scard_process_connect: opps"));
return 1;
}
g_memset(&rs, 0, sizeof(rs));
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_C;
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_C;
in_uint32_le(in_s, hContext);
in_uint8a(in_s, rs.reader_name, 100);
in_uint32_le(in_s, rs.dwShareMode);
@@ -390,30 +674,43 @@ scard_process_connect(struct trans *con, struct stream *in_s)
LLOGLN(10, ("scard_process_connect: rs.reader_name %s dwShareMode 0x%8.8x "
"dwPreferredProtocols 0x%8.8x", rs.reader_name, rs.dwShareMode,
rs.dwPreferredProtocols));
- scard_send_connect(con, hContext, 1, &rs);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_connect(user_data, hContext, 1, &rs);
return 0;
}
/*****************************************************************************/
int APP_CC
-scard_function_connect_return(struct trans *con,
+scard_function_connect_return(void *user_data,
struct stream *in_s,
int len, int status)
{
int dwActiveProtocol;
int hCard;
int bytes;
+ int uds_client_id;
struct stream *out_s;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_connect_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_connect_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_C) == 0)
{
LLOGLN(0, ("scard_function_connect_return: opps"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_C;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_C;
dwActiveProtocol = 0;
hCard = 0;
if (status == 0)
@@ -445,44 +742,59 @@ scard_process_disconnect(struct trans *con, struct stream *in_s)
int hContext;
int hCard;
int dwDisposition;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_disconnect:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_D)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_D)
{
LLOGLN(0, ("scard_process_disconnect: opps"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_D;
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_D;
in_uint32_le(in_s, hCard);
in_uint32_le(in_s, dwDisposition);
hContext = 1;
-
- scard_send_disconnect(con, hContext, hCard, dwDisposition);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_disconnect(user_data, hContext, hCard, dwDisposition);
return 0;
}
/*****************************************************************************/
int APP_CC
-scard_function_disconnect_return(struct trans *con,
+scard_function_disconnect_return(void *user_data,
struct stream *in_s,
int len, int status)
{
int dwActiveProtocol;
int hCard;
int bytes;
+ int uds_client_id;
struct stream *out_s;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_disconnect_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_D) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_disconnect_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_D) == 0)
{
LLOGLN(0, ("scard_function_connect_return: opps"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_D;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_D;
dwActiveProtocol = 0;
hCard = 0;
if (status == 0)
@@ -511,39 +823,55 @@ int APP_CC
scard_process_begin_transaction(struct trans *con, struct stream *in_s)
{
int hCard;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_begin_transaction:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_BT)
{
LLOGLN(0, ("scard_process_begin_transaction: opps"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_BT;
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_BT;
in_uint32_le(in_s, hCard);
LLOGLN(10, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard));
- scard_send_begin_transaction(con, hCard);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_begin_transaction(user_data, hCard);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_begin_transaction_return(struct trans *con,
+scard_function_begin_transaction_return(void *user_data,
struct stream *in_s,
int len, int status)
{
struct stream *out_s;
int bytes;
+ int uds_client_id;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_begin_transaction_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_begin_transaction_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_BT) == 0)
{
LLOGLN(0, ("scard_function_begin_transaction_return: opps"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_BT;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_BT;
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
@@ -562,40 +890,56 @@ scard_process_end_transaction(struct trans *con, struct stream *in_s)
{
int hCard;
int dwDisposition;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_end_transaction:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ET)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_ET)
{
LLOGLN(0, ("scard_process_end_transaction: opps"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_ET;
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_ET;
in_uint32_le(in_s, hCard);
in_uint32_le(in_s, dwDisposition);
LLOGLN(10, ("scard_process_end_transaction: hCard 0x%8.8x", hCard));
- scard_send_end_transaction(con, hCard, dwDisposition);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_end_transaction(user_data, hCard, dwDisposition);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_end_transaction_return(struct trans *con,
+scard_function_end_transaction_return(void *user_data,
struct stream *in_s,
int len, int status)
{
struct stream *out_s;
int bytes;
+ int uds_client_id;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_end_transaction_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ET) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_end_transaction_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_ET) == 0)
{
LLOGLN(0, ("scard_function_end_transaction_return: opps"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_ET;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_ET;
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
@@ -611,17 +955,19 @@ scard_function_end_transaction_return(struct trans *con,
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_cancel_return(struct trans *con,
+scard_function_cancel_return(void *user_data,
struct stream *in_s,
int len, int status)
{
+ LLOGLN(10, ("scard_function_cancel_return:"));
+ //g_hexdump(in_s->p, len);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_get_attrib_return(struct trans *con,
+scard_function_get_attrib_return(void *user_data,
struct stream *in_s,
int len, int status)
{
@@ -639,14 +985,17 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
char *send_data;
struct xrdp_scard_io_request send_ior;
struct xrdp_scard_io_request recv_ior;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_transmit:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_TR)
{
LLOGLN(0, ("scard_process_transmit: opps"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_TR;
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_TR;
LLOGLN(10, ("scard_process_transmit:"));
in_uint32_le(in_s, hCard);
in_uint32_le(in_s, send_ior.dwProtocol);
@@ -666,7 +1015,8 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
recv_ior.cbPciLength, send_bytes));
//g_hexdump(in_s->p, send_bytes);
LLOGLN(10, ("scard_process_transmit: recv_bytes %d", recv_bytes));
- scard_send_transmit(con, hCard, send_data, send_bytes, recv_bytes,
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_transmit(user_data, hCard, send_data, send_bytes, recv_bytes,
&send_ior, &recv_ior);
return 0;
}
@@ -674,7 +1024,7 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_transmit_return(struct trans *con,
+scard_function_transmit_return(void *user_data,
struct stream *in_s,
int len, int status)
{
@@ -682,18 +1032,30 @@ scard_function_transmit_return(struct trans *con,
int bytes;
int val;
int cbRecvLength;
+ int uds_client_id;
struct xrdp_scard_io_request recv_ior;
char *recvBuf;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_transmit_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_transmit_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_TR) == 0)
{
LLOGLN(0, ("scard_function_transmit_return: opps"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_TR;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_TR;
g_memset(&recv_ior, 0, sizeof(recv_ior));
cbRecvLength = 0;
recvBuf = 0;
@@ -752,14 +1114,17 @@ scard_process_control(struct trans *con, struct stream *in_s)
int recv_bytes;
int control_code;
char *send_data;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_control:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_CO)
{
LLOGLN(0, ("scard_process_control: opps"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_CO;
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_CO;
LLOGLN(10, ("scard_process_control:"));
in_uint32_le(in_s, hCard);
@@ -768,7 +1133,8 @@ scard_process_control(struct trans *con, struct stream *in_s)
in_uint8p(in_s, send_data, send_bytes);
in_uint32_le(in_s, recv_bytes);
- scard_send_control(con, hCard, send_data, send_bytes, recv_bytes,
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_control(user_data, hCard, send_data, send_bytes, recv_bytes,
control_code);
return 0;
@@ -777,7 +1143,7 @@ scard_process_control(struct trans *con, struct stream *in_s)
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_control_return(struct trans *con,
+scard_function_control_return(void *user_data,
struct stream *in_s,
int len, int status)
{
@@ -785,16 +1151,28 @@ scard_function_control_return(struct trans *con,
int bytes;
int cbRecvLength;
char *recvBuf;
+ int uds_client_id;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_control_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_control_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_CO) == 0)
{
LLOGLN(0, ("scard_function_control_return: opps"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_CO;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_CO;
cbRecvLength = 0;
recvBuf = 0;
if (status == 0)
@@ -825,20 +1203,24 @@ scard_process_status(struct trans *con, struct stream *in_s)
int hCard;
int cchReaderLen;
int cbAtrLen;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_status:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_ST)
{
LLOGLN(0, ("scard_process_status: opps"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_ST;
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_ST;
in_uint32_le(in_s, hCard);
in_uint32_le(in_s, cchReaderLen);
in_uint32_le(in_s, cbAtrLen);
- scard_send_status(con, 1, hCard, cchReaderLen, cbAtrLen);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_status(user_data, 1, hCard, cchReaderLen, cbAtrLen);
return 0;
}
@@ -867,7 +1249,7 @@ static int g_ms2pc[] = { PC_SCARD_UNKNOWN, PC_SCARD_ABSENT,
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_status_return(struct trans *con,
+scard_function_status_return(void *user_data,
struct stream *in_s,
int len, int status)
{
@@ -881,16 +1263,28 @@ scard_function_status_return(struct trans *con,
char attr[32];
twchar reader_name[100];
char lreader_name[100];
+ int uds_client_id;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_status_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_status_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_ST) == 0)
{
LLOGLN(0, ("scard_function_status_return: opps"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_ST;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_ST;
dwReaderLen = 0;
dwState = 0;
dwProtocol = 0;
@@ -947,13 +1341,17 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
int dwTimeout;
int cReaders;
READER_STATE *rsa;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_get_status_change:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_GSC)
{
LLOGLN(0, ("scard_process_get_status_change: opps"));
return 1;
}
+ uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_GSC;
in_uint32_le(in_s, hContext);
in_uint32_le(in_s, dwTimeout);
in_uint32_le(in_s, cReaders);
@@ -984,9 +1382,8 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
LLOGLN(10, ("scard_process_get_status_change: hContext 0x%8.8x dwTimeout "
"%d cReaders %d", hContext, dwTimeout, cReaders));
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_GSC;
-
- scard_send_get_status_change(con, hContext, 1, dwTimeout, cReaders, rsa);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_get_status_change(user_data, hContext, 1, dwTimeout, cReaders, rsa);
g_free(rsa);
@@ -995,7 +1392,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
/*****************************************************************************/
int APP_CC
-scard_function_get_status_change_return(struct trans *con,
+scard_function_get_status_change_return(void *user_data,
struct stream *in_s,
int len, int status)
{
@@ -1007,17 +1404,29 @@ scard_function_get_status_change_return(struct trans *con,
tui32 atr_len; /* number of bytes in atr[] */
tui8 atr[36];
struct stream *out_s;
+ int uds_client_id;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_get_status_change_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC) == 0)
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_get_status_change_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_GSC) == 0)
{
LLOGLN(0, ("scard_function_get_status_change_return: opps "
- "g_xrdp_pcsc_state 0x%8.8x", g_xrdp_pcsc_state));
+ "g_xrdp_pcsc_state 0x%8.8x", uds_client->pcsc_state));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_GSC;
+ uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_GSC;
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
@@ -1060,7 +1469,7 @@ scard_function_get_status_change_return(struct trans *con,
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_is_context_valid_return(struct trans *con,
+scard_function_is_context_valid_return(void *user_data,
struct stream *in_s,
int len, int status)
{
@@ -1069,7 +1478,7 @@ scard_function_is_context_valid_return(struct trans *con,
/*****************************************************************************/
/* returns error */
-int APP_CC scard_function_reconnect_return(struct trans *con,
+int APP_CC scard_function_reconnect_return(void *user_data,
struct stream *in_s,
int len, int status)
{
@@ -1184,10 +1593,6 @@ my_pcsc_trans_data_in(struct trans *trans)
{
return 0;
}
- if (trans != g_con)
- {
- return 1;
- }
s = trans_get_in_s(trans);
in_uint32_le(s, size);
in_uint32_le(s, command);
@@ -1195,7 +1600,7 @@ my_pcsc_trans_data_in(struct trans *trans)
error = trans_force_read(trans, size);
if (error == 0)
{
- error = scard_process_msg(g_con, s, command);
+ error = scard_process_msg(trans, s, command);
}
return error;
}
@@ -1205,6 +1610,8 @@ my_pcsc_trans_data_in(struct trans *trans)
int DEFAULT_CC
my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans)
{
+ struct pcsc_uds_client *uds_client;
+
LLOGLN(10, ("my_pcsc_trans_conn_in:"));
if (trans == 0)
@@ -1222,9 +1629,26 @@ my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans)
return 1;
}
+ uds_client = create_uds_client(new_trans);
+ if (uds_client == 0)
+ {
+ return 1;
+ }
+ uds_client->con->trans_data_in = my_pcsc_trans_data_in;
+ uds_client->con->header_size = 8;
+
+ if (g_uds_clients == 0)
+ {
+ g_uds_clients = list_create();
+ }
+ list_add_item(g_uds_clients, (tbus)uds_client);
+
+#if 0
g_con = new_trans;
g_con->trans_data_in = my_pcsc_trans_data_in;
g_con->header_size = 8;
+#endif
+
return 0;
}
@@ -1287,12 +1711,6 @@ scard_pcsc_deinit(void)
g_lis = 0;
}
- if (g_pub_file_fd != 0)
- {
- g_file_close(g_pub_file_fd);
- g_pub_file_fd = 0;
- }
-
if (g_pcsclite_ipc_dir[0] != 0)
{
g_file_delete(g_pcsclite_ipc_file);