chansrv: smartcard, fix for SCardControl, SCardTransmit

ulab-next
Jay Sorg 11 years ago
parent 2aa92fd6a8
commit 9f8d369747

@ -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);

@ -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)

@ -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);

@ -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;
@ -1031,6 +1026,14 @@ scard_function_get_attrib_return(void *user_data,
return 0;
}
/*****************************************************************************/
struct pcsc_transmit
{
int uds_client_id;
struct xrdp_scard_io_request recv_ior;
int cbRecvLength;
};
/*****************************************************************************/
/* returns error */
int APP_CC
@ -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);

Loading…
Cancel
Save