summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2013-12-30 13:41:38 -0800
committerJay Sorg <jay.sorg@gmail.com>2013-12-30 13:41:38 -0800
commit9f8d3697472ce8dc6353172e9a471568d1aec45e (patch)
tree22bf5f7fb6bbb034761dcd55b264c7052333e80a
parent2aa92fd6a85a479343e6d2fb408bfc9a4e40fe18 (diff)
downloadxrdp-proprietary-9f8d3697472ce8dc6353172e9a471568d1aec45e.tar.gz
xrdp-proprietary-9f8d3697472ce8dc6353172e9a471568d1aec45e.zip
chansrv: smartcard, fix for SCardControl, SCardTransmit
-rw-r--r--sesman/chansrv/pcsc/xrdp_pcsc.c21
-rw-r--r--sesman/chansrv/smartcard.c25
-rw-r--r--sesman/chansrv/smartcard.h4
-rw-r--r--sesman/chansrv/smartcard_pcsc.c75
4 files changed, 75 insertions, 50 deletions
diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c
index 35c0b7b4..f4aaba14 100644
--- a/sesman/chansrv/pcsc/xrdp_pcsc.c
+++ b/sesman/chansrv/pcsc/xrdp_pcsc.c
@@ -461,9 +461,9 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
int offset;
LLOGLN(10, ("SCardConnect:"));
- LLOGLN(10, ("SCardConnect: hContext %p szReader %s dwShareMode %d "
+ LLOGLN(10, ("SCardConnect: hContext 0x%8.8x szReader %s dwShareMode %d "
"dwPreferredProtocols %d",
- (void*)hContext, szReader, dwShareMode, dwPreferredProtocols));
+ hContext, szReader, dwShareMode, dwPreferredProtocols));
if (g_sck == -1)
{
LLOGLN(0, ("SCardConnect: error, not connected"));
@@ -505,8 +505,9 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
*phCard = GET_UINT32(msg, 0);
*pdwActiveProtocol = GET_UINT32(msg, 4);
status = GET_UINT32(msg, 8);
- LLOGLN(10, ("SCardConnect: got status 0x%8.8x hCard %d",
- status, *phCard));
+ LLOGLN(10, ("SCardConnect: got status 0x%8.8x hCard 0x%8.8x "
+ "dwActiveProtocol %d",
+ status, *phCard, *pdwActiveProtocol));
return status;
}
@@ -534,7 +535,7 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
int bytes;
int status;
- LLOGLN(10, ("SCardDisconnect: hCard %d dwDisposition %d",
+ LLOGLN(10, ("SCardDisconnect: hCard 0x%8.8x dwDisposition %d",
hCard, dwDisposition));
if (g_sck == -1)
{
@@ -574,7 +575,7 @@ SCardBeginTransaction(SCARDHANDLE hCard)
int bytes;
int status;
- LLOGLN(10, ("SCardBeginTransaction: hCard %d", hCard));
+ LLOGLN(10, ("SCardBeginTransaction: hCard 0x%8.8x", hCard));
if (hCard == 0)
{
LLOGLN(0, ("SCardBeginTransaction: error, bad hCard"));
@@ -967,6 +968,7 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
int offset;
int status;
int extra_len;
+ int got_recv_pci;
LLOGLN(10, ("SCardTransmit:"));
if (g_sck == -1)
@@ -1002,8 +1004,10 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
offset += 4;
memcpy(msg + offset, pbSendBuffer, cbSendLength);
offset += cbSendLength;
- if ((pioRecvPci == 0) || (pioRecvPci->cbPciLength < 8))
+ // TODO figure out why recv pci does not work
+ if (1 || (pioRecvPci == 0) || (pioRecvPci->cbPciLength < 8))
{
+ got_recv_pci = 0;
SET_UINT32(msg, offset, 0); /* dwProtocol */
offset += 4;
SET_UINT32(msg, offset, 0); /* cbPciLength */
@@ -1013,6 +1017,7 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
}
else
{
+ got_recv_pci = 1;
SET_UINT32(msg, offset, pioRecvPci->dwProtocol);
offset += 4;
SET_UINT32(msg, offset, pioRecvPci->cbPciLength);
@@ -1046,7 +1051,7 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
return SCARD_F_INTERNAL_ERROR;
}
offset = 0;
- if (pioRecvPci == 0)
+ if (got_recv_pci == 0)
{
offset += 8;
extra_len = GET_UINT32(msg, offset);
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index 42a4ebd5..0d6d5405 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -207,7 +207,8 @@ static int APP_CC scard_send_Transmit(IRP *irp,
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, char *card, int card_bytes,
+static int APP_CC scard_send_Control(IRP* irp, char *context, int context_bytes,
+ char *card, int card_bytes,
char *send_data, int send_bytes,
int recv_bytes, int control_code);
static int APP_CC scard_send_Cancel(IRP *irp, char *context, int context_bytes);
@@ -737,7 +738,8 @@ scard_send_transmit(void *user_data, char *context, int context_bytes,
* Communicate directly with the smart card reader
*****************************************************************************/
int APP_CC
-scard_send_control(void *user_data, char *card, int card_bytes,
+scard_send_control(void *user_data, char* context, int context_bytes,
+ char *card, int card_bytes,
char *send_data, int send_bytes,
int recv_bytes, int control_code)
{
@@ -757,8 +759,10 @@ scard_send_control(void *user_data, char *card, int card_bytes,
irp->user_data = user_data;
/* send IRP to client */
- scard_send_Control(irp, card, card_bytes, send_data,
- send_bytes, recv_bytes, control_code);
+ scard_send_Control(irp, context, context_bytes,
+ card, card_bytes,
+ send_data, send_bytes,
+ recv_bytes, control_code);
return 0;
}
@@ -1981,7 +1985,7 @@ scard_send_Transmit(IRP *irp, char *context, int context_bytes,
{
/* map4 */
out_uint32_le(s, recv_ior->dwProtocol);
- out_uint32_le(s, recv_ior->cbPciLength);
+ out_uint32_le(s, recv_ior->cbPciLength - 8);
val = recv_ior->extra_bytes > 0 ? 1 : 0;
out_uint32_le(s, val); /* map6*/
if (val)
@@ -2022,7 +2026,8 @@ scard_send_Transmit(IRP *irp, char *context, int context_bytes,
* Communicate directly with the smart card reader
*****************************************************************************/
static int APP_CC
-scard_send_Control(IRP *irp, char *card, int card_bytes, char *send_data,
+scard_send_Control(IRP *irp, char *context, int context_bytes,
+ char *card, int card_bytes, char *send_data,
int send_bytes, int recv_bytes, int control_code)
{
/* see [MS-RDPESC] 2.2.2.19 */
@@ -2046,9 +2051,9 @@ scard_send_Control(IRP *irp, char *card, int card_bytes, char *send_data,
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
out_uint32_le(s, 0x00000000);
- out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, context_bytes);
out_uint32_le(s, 0x00020000); /* map0 */
- out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, card_bytes);
out_uint32_le(s, 0x00020004); /* map1 */
out_uint32_le(s, control_code);
out_uint32_le(s, send_bytes);
@@ -2056,8 +2061,8 @@ scard_send_Control(IRP *irp, char *card, int card_bytes, char *send_data,
out_uint32_le(s, val); /* map2 */
out_uint32_le(s, 0x00000000);
out_uint32_le(s, recv_bytes);
- out_uint32_le(s, 4);
- out_uint32_le(s, 0); /* context ? */
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
out_uint32_le(s, card_bytes);
out_uint8a(s, card, card_bytes);
if (send_bytes > 0)
diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h
index 5004f498..3ea503a8 100644
--- a/sesman/chansrv/smartcard.h
+++ b/sesman/chansrv/smartcard.h
@@ -156,7 +156,9 @@ int APP_CC scard_send_transmit(void *user_data,
struct xrdp_scard_io_request *send_ior,
struct xrdp_scard_io_request *recv_ior);
-int APP_CC scard_send_control(void *user_data, char *card, int card_bytes,
+int APP_CC scard_send_control(void *user_data,
+ char *context, int context_bytes,
+ char *card, int card_bytes,
char *send_data, int send_bytes,
int recv_bytes, int control_code);
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index a7bc14b2..1d1618dc 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -53,14 +53,12 @@
extern int g_display_num; /* in chansrv.c */
-static int g_uds_client_id = 0; /* auto incremented for each unix domain
- socket connection */
static int g_autoinc = 0; /* general purpose autoinc */
struct pcsc_card /* item for list of open cards in one context */
{
- tui32 app_card; /* application card, always 4 bytes */
- int card_bytes; /* client card bytes */
+ tui32 app_card; /* application card, always 4 bytes */
+ int card_bytes; /* client card bytes */
char card[16]; /* client card */
};
@@ -68,16 +66,16 @@ struct pcsc_context
{
tui32 app_context; /* application context, always 4 byte */
int context_bytes; /* client context bytes */
- char context[16]; /* client context */
+ char context[16]; /* client context */
struct list *cards; /* these need to be released on close */
};
/*****************************************************************************/
struct pcsc_uds_client
{
- int uds_client_id; /* from g_uds_client_id */
- struct trans *con;
- struct list *contexts; /* struct pcsc_context */
+ int uds_client_id; /* unique id represents each app */
+ struct trans *con; /* the connection to the app */
+ struct list *contexts; /* list of struct pcsc_context */
struct pcsc_context *connect_context;
};
@@ -104,8 +102,8 @@ create_uds_client(struct trans *con)
{
return 0;
}
- g_uds_client_id++;
- uds_client->uds_client_id = g_uds_client_id;
+ g_autoinc++;
+ uds_client->uds_client_id = g_autoinc;
uds_client->con = con;
con->callback_data = uds_client;
return uds_client;
@@ -283,7 +281,7 @@ uds_client_add_context(struct pcsc_uds_client *uds_client,
struct pcsc_context *pcscContext;
LLOGLN(10, ("uds_client_add_context:"));
- pcscContext = (struct pcsc_context * )
+ pcscContext = (struct pcsc_context *)
g_malloc(sizeof(struct pcsc_context), 1);
if (pcscContext == 0)
{
@@ -457,7 +455,7 @@ scard_function_establish_context_return(void *user_data,
int uds_client_id;
int context_bytes;
int app_context;
- char context[8];
+ char context[16];
struct stream *out_s;
struct pcsc_uds_client *uds_client;
struct trans *con;
@@ -477,12 +475,12 @@ scard_function_establish_context_return(void *user_data,
con = uds_client->con;
lcontext = 0;
app_context = 0;
- g_memset(context, 0, 8);
+ g_memset(context, 0, 16);
if (status == 0)
{
in_uint8s(in_s, 28);
in_uint32_le(in_s, context_bytes);
- if (context_bytes > 8)
+ if (context_bytes > 16)
{
LLOGLN(0, ("scard_function_establish_context_return: opps "
"context_bytes %d", context_bytes));
@@ -647,6 +645,8 @@ scard_function_list_readers_return(void *user_data,
return 1;
}
uds_client_id = pcscListReaders->uds_client_id;
+ cchReaders = pcscListReaders->cchReaders;
+ g_free(pcscListReaders);
uds_client = (struct pcsc_uds_client *)
get_uds_client_by_id(uds_client_id);
if (uds_client == 0)
@@ -654,14 +654,9 @@ scard_function_list_readers_return(void *user_data,
LLOGLN(0, ("scard_function_list_readers_return: "
"get_uds_client_by_id failed, could not find id %d",
uds_client_id));
- g_free(pcscListReaders);
return 1;
}
con = uds_client->con;
-
- cchReaders = pcscListReaders->cchReaders;
- g_free(pcscListReaders);
-
g_memset(reader_name, 0, sizeof(reader_name));
g_memset(lreader_name, 0, sizeof(lreader_name));
rn_index = 0;
@@ -1032,6 +1027,14 @@ scard_function_get_attrib_return(void *user_data,
}
/*****************************************************************************/
+struct pcsc_transmit
+{
+ int uds_client_id;
+ struct xrdp_scard_io_request recv_ior;
+ int cbRecvLength;
+};
+
+/*****************************************************************************/
/* returns error */
int APP_CC
scard_process_transmit(struct trans *con, struct stream *in_s)
@@ -1043,9 +1046,9 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
struct xrdp_scard_io_request send_ior;
struct xrdp_scard_io_request recv_ior;
struct pcsc_uds_client *uds_client;
- void *user_data;
struct pcsc_card *lcard;
struct pcsc_context *lcontext;
+ struct pcsc_transmit *pcscTransmit;
LLOGLN(10, ("scard_process_transmit:"));
uds_client = (struct pcsc_uds_client *) (con->callback_data);
@@ -1066,9 +1069,7 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
"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));
- user_data = (void *) (tintptr) (uds_client->uds_client_id);
lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
if ((lcard == 0) || (lcontext == 0))
{
@@ -1076,7 +1077,15 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
"get_pcsc_card_by_app_card failed"));
return 1;
}
- scard_send_transmit(user_data, lcontext->context, lcontext->context_bytes,
+
+ pcscTransmit = (struct pcsc_transmit *)
+ g_malloc(sizeof(struct pcsc_transmit), 1);
+ pcscTransmit->uds_client_id = uds_client->uds_client_id;
+ pcscTransmit->recv_ior = recv_ior;
+ pcscTransmit->cbRecvLength = recv_bytes;
+
+ scard_send_transmit(pcscTransmit,
+ lcontext->context, lcontext->context_bytes,
lcard->card, lcard->card_bytes,
send_data, send_bytes, recv_bytes,
&send_ior, &recv_ior);
@@ -1094,17 +1103,20 @@ scard_function_transmit_return(void *user_data,
int bytes;
int val;
int cbRecvLength;
- int uds_client_id;
- struct xrdp_scard_io_request recv_ior;
char *recvBuf;
+ struct xrdp_scard_io_request recv_ior;
struct pcsc_uds_client *uds_client;
struct trans *con;
+ struct pcsc_transmit *pcscTransmit;
LLOGLN(10, ("scard_function_transmit_return:"));
LLOGLN(10, (" status 0x%8.8x", status));
- uds_client_id = (int) (tintptr) user_data;
+ pcscTransmit = (struct pcsc_transmit *) user_data;
+ recv_ior = pcscTransmit->recv_ior;
uds_client = (struct pcsc_uds_client *)
- get_uds_client_by_id(uds_client_id);
+ get_uds_client_by_id(pcscTransmit->uds_client_id);
+ g_free(pcscTransmit);
+
if (uds_client == 0)
{
LLOGLN(0, ("scard_function_transmit_return: "
@@ -1112,7 +1124,6 @@ scard_function_transmit_return(void *user_data,
return 1;
}
con = uds_client->con;
- g_memset(&recv_ior, 0, sizeof(recv_ior));
cbRecvLength = 0;
recvBuf = 0;
if (status == 0)
@@ -1172,6 +1183,7 @@ scard_process_control(struct trans *con, struct stream *in_s)
char *send_data;
struct pcsc_uds_client *uds_client;
void *user_data;
+ struct pcsc_context *lcontext;
struct pcsc_card *lcard;
LLOGLN(10, ("scard_process_control:"));
@@ -1185,14 +1197,15 @@ scard_process_control(struct trans *con, struct stream *in_s)
in_uint32_le(in_s, recv_bytes);
user_data = (void *) (tintptr) (uds_client->uds_client_id);
- lcard = get_pcsc_card_by_app_card(uds_client, hCard, 0);
- if (lcard == 0)
+ lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
+ if ((lcard == 0) || (lcontext == 0))
{
LLOGLN(0, ("scard_process_control: "
"get_pcsc_card_by_app_card failed"));
return 1;
}
- scard_send_control(user_data, lcard->card, lcard->card_bytes,
+ scard_send_control(user_data, lcontext->context, lcontext->context_bytes,
+ lcard->card, lcard->card_bytes,
send_data, send_bytes, recv_bytes,
control_code);