summaryrefslogtreecommitdiffstats
path: root/sesman/chansrv
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2013-12-04 15:40:55 -0800
committerJay Sorg <jay.sorg@gmail.com>2013-12-04 15:40:55 -0800
commitf265c14499f258cab934ee114a4c99877a751d23 (patch)
treed291d70ffa085091245b6da297fd556540d9103b /sesman/chansrv
parent50962fadcd7c36fac7c8d22dd3ff0e7247a844fe (diff)
downloadxrdp-proprietary-f265c14499f258cab934ee114a4c99877a751d23.tar.gz
xrdp-proprietary-f265c14499f258cab934ee114a4c99877a751d23.zip
chansrv: smartcard, work on getting MSTSC working
Diffstat (limited to 'sesman/chansrv')
-rw-r--r--sesman/chansrv/smartcard.c746
-rw-r--r--sesman/chansrv/smartcard_pcsc.c204
-rw-r--r--sesman/chansrv/smartcard_pcsc.h26
3 files changed, 524 insertions, 452 deletions
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index 4b2104a6..c6a36811 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -2,6 +2,7 @@
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Laxmikant Rashinkar 2013 LK.Rashinkar@gmail.com
+ * Copyright (C) Jay Sorg 2013 jay.sorg@gmail.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -163,25 +164,25 @@ static int APP_CC scard_get_free_slot(void);
#if 0
static void APP_CC scard_release_resources(void);
#endif
-static void APP_CC scard_send_EstablishContext(IRP* irp, int scope);
-static void APP_CC scard_send_ReleaseContext(IRP* irp, tui32 context);
+static void APP_CC scard_send_EstablishContext(IRP *irp, int scope);
+static void APP_CC scard_send_ReleaseContext(IRP *irp, tui32 context);
static void APP_CC scard_send_IsContextValid(IRP* irp, tui32 context);
-static void APP_CC scard_send_ListReaders(IRP* irp, tui32 context, int wide);
-static void APP_CC scard_send_GetStatusChange(IRP* irp, tui32 context, int wide,
+static void APP_CC scard_send_ListReaders(IRP *irp, tui32 context, int wide);
+static void APP_CC scard_send_GetStatusChange(IRP *irp, tui32 context, int wide,
tui32 timeout, tui32 num_readers,
- READER_STATE* rsa);
-static void APP_CC scard_send_Connect(IRP* irp, tui32 context, int wide,
- READER_STATE* rs);
-static void APP_CC scard_send_Reconnect(IRP* irp, tui32 context,
- tui32 sc_handle, READER_STATE* rs);
-static void APP_CC scard_send_BeginTransaction(IRP* irp, tui32 sc_handle);
-static void APP_CC scard_send_EndTransaction(IRP* irp, tui32 sc_handle,
+ READER_STATE *rsa);
+static void APP_CC scard_send_Connect(IRP *irp, tui32 context, int wide,
+ READER_STATE *rs);
+static void APP_CC scard_send_Reconnect(IRP *irp, tui32 context,
+ tui32 sc_handle, READER_STATE *rs);
+static void APP_CC scard_send_BeginTransaction(IRP *irp, tui32 sc_handle);
+static void APP_CC scard_send_EndTransaction(IRP *irp, tui32 sc_handle,
tui32 dwDisposition);
-static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle,
+static void APP_CC scard_send_Status(IRP *irp, int wide, tui32 sc_handle,
int cchReaderLen, int cbAtrLen);
-static void APP_CC scard_send_Disconnect(IRP* irp, tui32 context,
+static void APP_CC scard_send_Disconnect(IRP *irp, tui32 context,
tui32 sc_handle, int dwDisposition);
-static int APP_CC scard_send_Transmit(IRP* irp, tui32 sc_handle,
+static int APP_CC scard_send_Transmit(IRP *irp, tui32 sc_handle,
char *send_data, int send_bytes,
int recv_bytes,
struct xrdp_scard_io_request *send_ior,
@@ -189,9 +190,9 @@ static int APP_CC scard_send_Transmit(IRP* irp, tui32 sc_handle,
static int APP_CC scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle,
char *send_data, int send_bytes,
int recv_bytes, int control_code);
-static int APP_CC scard_send_Cancel(IRP* irp, tui32 context);
-static int APP_CC scard_send_GetAttrib(IRP* irp, tui32 sc_handle,
- READER_STATE* rs);
+static int APP_CC scard_send_Cancel(IRP *irp, tui32 context);
+static int APP_CC scard_send_GetAttrib(IRP *irp, tui32 sc_handle,
+ READER_STATE *rs);
/******************************************************************************
** local callbacks into this module **
@@ -937,14 +938,19 @@ scard_send_EstablishContext(IRP *irp, int scope)
xstream_wr_u32_le(s, scope); /* Ioctl specific data */
xstream_wr_u32_le(s, 0); /* don't know what this is, */
/* but Win7 is sending it */
- /* get stream len */
- bytes = xstream_len(s);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_mark_end(s);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
}
@@ -952,12 +958,12 @@ scard_send_EstablishContext(IRP *irp, int scope)
* Release a previously established Smart Card context
*****************************************************************************/
static void APP_CC
-scard_send_ReleaseContext(IRP* irp, tui32 context)
+scard_send_ReleaseContext(IRP *irp, tui32 context)
{
/* see [MS-RDPESC] 3.1.4.2 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -992,14 +998,18 @@ scard_send_ReleaseContext(IRP* irp, tui32 context)
xstream_wr_u32_le(s, 4);
xstream_wr_u32_le(s, context);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
}
@@ -1007,12 +1017,12 @@ scard_send_ReleaseContext(IRP* irp, tui32 context)
* Checks if a previously established context is still valid
*****************************************************************************/
static void APP_CC
-scard_send_IsContextValid(IRP* irp, tui32 context)
+scard_send_IsContextValid(IRP *irp, tui32 context)
{
/* see [MS-RDPESC] 3.1.4.3 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -1045,14 +1055,18 @@ scard_send_IsContextValid(IRP* irp, tui32 context)
xstream_wr_u32_le(s, 4);
xstream_wr_u32_le(s, context);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
}
@@ -1118,17 +1132,22 @@ scard_send_ListReaders(IRP *irp, tui32 context, int wide)
xstream_wr_u32_le(s, 0x00);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- //g_writeln("scard_send_ListReaders:");
- //g_hexdump(s->data, bytes);
+#if 0
+ g_writeln("scard_send_ListReaders:");
+ g_hexdump(s->data, bytes);
+#endif
xstream_free(s);
@@ -1215,7 +1234,7 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
return;
}
- s_push_layer(s, mcs_hdr, 4); /* set later */
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
out_uint32_le(s, 0x00000000);
out_uint32_le(s, 0x00000004);
out_uint32_le(s, 0x00020000);
@@ -1342,58 +1361,54 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
return;
}
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 20 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes dwShareMode
- * u32 4 bytes dwPreferredProtocols
- * xx bytes reader name
- * u32 4 bytes context length (len)
- * len bytes context
- */
-
- xstream_seek(s, 20);
- xstream_wr_u32_le(s, rs->dwShareMode);
- xstream_wr_u32_le(s, rs->dwPreferredProtocols);
-
- /* insert reader name */
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, rs->dwShareMode);
+ out_uint32_le(s, rs->dwPreferredProtocols);
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);
+ out_uint32_le(s, num_chars + 2);
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, num_chars + 2);
if (wide)
{
for (index = 0; index < num_chars; index++)
{
- xstream_wr_u16_le(s, w_reader_name[index]);
+ out_uint16_le(s, w_reader_name[index]);
}
+ out_uint16_le(s, 0);
+ out_uint16_le(s, 0);
}
else
{
for (index = 0; index < num_chars; index++)
{
- xstream_wr_u8(s, w_reader_name[index]);
+ out_uint8(s, w_reader_name[index]);
}
+ out_uint8(s, 0);
+ out_uint8(s, 0);
}
align_s(s, 4);
/* insert context */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
+ out_uint32_le(s, 4);
+ out_uint32_le(s, context);
+ out_uint32_le(s, 0);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
}
@@ -1409,13 +1424,13 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
* rs.init_type
*****************************************************************************/
static void APP_CC
-scard_send_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
+scard_send_Reconnect(IRP *irp, tui32 context, tui32 sc_handle, READER_STATE *rs)
{
/* see [MS-RDPESC] 2.2.2.15 */
/* see [MS-RDPESC] 3.1.4.36 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -1456,14 +1471,18 @@ scard_send_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
xstream_wr_u32_le(s, 4);
xstream_wr_u32_le(s, sc_handle);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
}
@@ -1494,32 +1513,38 @@ scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
return;
}
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 36 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes len of sc_handle
- * 4 bytes sc_handle
- */
-
- xstream_seek(s, 36);
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00000002);
/* insert handle */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ out_uint32_le(s, 4);
+ out_uint32_le(s, sc_handle);
+ out_uint32_le(s, 0x00000000);
+
+ s_mark_end(s);
+
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
}
@@ -1551,36 +1576,38 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition)
return;
}
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 24 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes disposition
- * 8 unused
- * u32 4 bytes length of sc_handle
- * 4 bytes sc_handle
- */
-
- xstream_seek(s, 24);
- xstream_wr_u32_le(s, dwDisposition);
- xstream_seek(s, 8);
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, dwDisposition);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00000009);
/* insert handle */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ out_uint32_le(s, 4);
+ out_uint32_le(s, sc_handle);
+ out_uint32_le(s, 0);
+
+ s_mark_end(s);
+
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
}
@@ -1613,42 +1640,55 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle,
log_error("scard_make_new_ioctl");
return;
}
-
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 28 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes reader len
- * u32 4 bytes ATR len
- * 8 bytes unused
- * u32 4 bytes len of sc_handle
- * 4 bytes sc_handle
- * 4 bytes unused
- */
-
- xstream_seek(s, 28);
- xstream_wr_u32_le(s, cchReaderLen); /* readerLen, see [MS-RDPESC] 4.11 */
- xstream_wr_u32_le(s, cbAtrLen); /* atrLen, see [MS-RDPESC] 4.11 */
- xstream_seek(s, 8);
-
+/*
+ 30 00 00 00
+ 00 00 00 00
+ 04 00 00 00
+ 00 00 02 00
+ 04 00 00 00
+ 04 00 02 00
+ 01 00 00 00 dwReaderLen
+ 00 00 00 00 dwAtrLen
+ 40 00 00 00
+ 04 00 00 00
+ 07 00 00 00
+ 04 00 00 00
+ 09 00 00 00 hCard
+ 00 00 00 00
+*/
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, cchReaderLen); /* readerLen, see [MS-RDPESC] 4.11 */
+ out_uint32_le(s, cbAtrLen); /* atrLen, see [MS-RDPESC] 4.11 */
+ out_uint32_le(s, 0x00000040);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00000007);
/* insert sc_handle */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ out_uint32_le(s, 4);
+ out_uint32_le(s, sc_handle);
+ out_uint32_le(s, 0);
- xstream_wr_u32_le(s, 0);
+ s_mark_end(s);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
}
@@ -1680,40 +1720,41 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
return;
}
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 24 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes disposition
- * u32 4 bytes context len
- * 4 bytes context
- * u32 4 bytes length of sc_handle
- * 4 bytes sc_handle
- */
-
- xstream_seek(s, 24);
- xstream_wr_u32_le(s, dwDisposition);
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, dwDisposition);
/* insert context */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
+ out_uint32_le(s, 4);
+ out_uint32_le(s, context);
/* insert handle */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ out_uint32_le(s, 4);
+ out_uint32_le(s, sc_handle);
+
+ out_uint32_le(s, 0x00000000);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
}
@@ -1722,15 +1763,15 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
* associated with a valid context.
*****************************************************************************/
static int APP_CC
-scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data,
+scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data,
int send_bytes, int recv_bytes,
struct xrdp_scard_io_request *send_ior,
struct xrdp_scard_io_request *recv_ior)
{
/* see [MS-RDPESC] 2.2.2.19 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
int val;
@@ -1776,21 +1817,84 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data,
* u32 4 bytes sc_handle
*/
- xstream_seek(s, 12);
- xstream_wr_u32_le(s, 0); // map0
- xstream_seek(s, 4);
- xstream_wr_u32_le(s, 0); // map1
+ g_writeln("send_bytes %d", send_bytes);
+ g_writeln("recv_bytes %d", recv_bytes);
+
+#if 1
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ //out_uint32_be(s, 0x58000000);
+ out_uint32_be(s, 0x00000000);
+ out_uint32_be(s, 0x04000000);
+ out_uint32_be(s, 0x00000200);
+ out_uint32_be(s, 0x04000000);
+ out_uint32_be(s, 0x04000200);
+ out_uint32_be(s, 0x01000000);
+ out_uint32_be(s, 0x00000000);
+ out_uint32_be(s, 0x00000000);
+
+ //out_uint32_be(s, 0x05000000);
+ out_uint32_le(s, send_bytes);
+
+ out_uint32_be(s, 0x08000200);
+ out_uint32_be(s, 0x0c000200);
+ out_uint32_be(s, 0x00000000);
+
+ //out_uint32_be(s, 0x02010000);
+ out_uint32_le(s, recv_bytes);
+
+ out_uint32_be(s, 0x04000000);
+ out_uint32_be(s, 0x05000000);
+ out_uint32_be(s, 0x04000000);
+ out_uint32_be(s, 0x0b000000);
+
+ //out_uint32_be(s, 0x05000000);
+ //out_uint32_be(s, 0x00b00704);
+ //out_uint32_be(s, 0x10000000);
+ out_uint32_le(s, send_bytes);
+ out_uint8p(s, send_data, send_bytes);
+ align_s(s, 4);
+
+ out_uint32_be(s, 0x01000000);
+ out_uint32_be(s, 0x00000000);
+ out_uint32_be(s, 0x00000000);
+#else
+
+ g_printf("send cbPciLength %d\n", send_ior->cbPciLength);
+ g_printf("send extra_bytes %d\n", send_ior->extra_bytes);
+ g_printf("recv cbPciLength %d\n", recv_ior->cbPciLength);
+ g_printf("recv extra_bytes %d\n", recv_ior->extra_bytes);
+
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+
+ out_uint32_le(s, 4);
+ xstream_wr_u32_le(s, 0x00020000); /* map0 */
+
+ out_uint32_le(s, 4);
+ xstream_wr_u32_le(s, 0x00020004); /* map1 */
+
xstream_wr_u32_le(s, send_ior->dwProtocol);
- xstream_wr_u32_le(s, send_ior->cbPciLength);
+ xstream_wr_u32_le(s, send_ior->cbPciLength - 8);
+
val = send_ior->extra_bytes > 0 ? 1 : 0;
- xstream_wr_u32_le(s, val); // map2
+ xstream_wr_u32_le(s, val); /* map2 */
+
xstream_wr_u32_le(s, send_bytes);
- val = send_bytes > 0 ? 1 : 0;
- xstream_wr_u32_le(s, val); // map3
- val = recv_ior->cbPciLength > 0 ? 1 : 0;
- xstream_wr_u32_le(s, val); // map 4
+
+ val = send_bytes > 0 ? 0x00020008 : 0;
+ xstream_wr_u32_le(s, val); /* map3 */
+
+ val = recv_ior->cbPciLength > 0 ? 0x0002000c : 0;
+ xstream_wr_u32_le(s, val); /* map 4 */
+
xstream_wr_u32_le(s, 0); // map5
xstream_wr_u32_le(s, recv_bytes);
+
+ /* map0 */
+ out_uint32_le(s, 4);
+ out_uint32_le(s, 5);
+
+ /* map1 */
xstream_wr_u32_le(s, 4);
xstream_wr_u32_le(s, sc_handle);
@@ -1804,29 +1908,46 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data,
{
xstream_wr_u32_le(s, send_bytes);
out_uint8a(s, send_data, send_bytes);
+ align_s(s, 4);
}
if (recv_ior->cbPciLength > 0)
{
+ /* map4 */
xstream_wr_u32_le(s, recv_ior->dwProtocol);
xstream_wr_u32_le(s, recv_ior->cbPciLength);
val = recv_ior->extra_bytes > 0 ? 1 : 0;
- xstream_wr_u32_le(s, val);
+ xstream_wr_u32_le(s, val); /* map6*/
if (val)
{
xstream_wr_u32_le(s, recv_ior->extra_bytes);
out_uint8a(s, recv_ior->extra_data, recv_ior->extra_bytes);
}
}
+#endif
+
+ s_mark_end(s);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
+#if 1
+ g_writeln("scard_send_Transmit:");
+ g_hexdump(s->data, bytes);
+#endif
+
xstream_free(s);
return 0;
}
@@ -1835,13 +1956,13 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data,
* Communicate directly with the smart card reader
*****************************************************************************/
static int APP_CC
-scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data,
+scard_send_Control(IRP *irp, tui32 context, tui32 sc_handle, char *send_data,
int send_bytes, int recv_bytes, int control_code)
{
/* see [MS-RDPESC] 2.2.2.19 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
int val;
@@ -1857,61 +1978,49 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data,
return 1;
}
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 12 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes map0
- * 4 bytes unused
- * u32 4 bytes map1
- * u32 4 bytes dwControlCode
- * u32 4 bytes cbRecvLength
- * u32 4 bytes map2
- * 4 bytes unused
- * u32 4 bytes cbOutBufferSize
- * u32 4 bytes context len
- * u32 4 bytes context
- * u32 4 bytes handle len
- * u32 4 bytes handle
- */
-
- xstream_seek(s, 12);
- xstream_wr_u32_le(s, 0); // map0
- xstream_seek(s, 4);
- xstream_wr_u32_le(s, 0); // map1
-
- xstream_wr_u32_le(s, control_code);
-
- xstream_wr_u32_le(s, send_bytes);
-
- val = send_bytes > 0 ? 1 : 0;
- xstream_wr_u32_le(s, val); // map2
-
- xstream_wr_u32_le(s, 0);
- xstream_wr_u32_le(s, recv_bytes);
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
-
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020000); /* map0 */
+ out_uint32_le(s, 0x00000004);
+ out_uint32_le(s, 0x00020004); /* map1 */
+ out_uint32_le(s, control_code);
+ out_uint32_le(s, send_bytes);
+ val = send_bytes > 0 ? 0x00020008 : 0;
+ 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, context);
+ out_uint32_le(s, 4);
+ out_uint32_le(s, sc_handle);
if (send_bytes > 0)
{
- xstream_wr_u32_le(s, send_bytes);
+ out_uint32_le(s, send_bytes);
out_uint8a(s, send_data, send_bytes);
}
+ else
+ {
+ out_uint32_le(s, 0x00000000);
+ }
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
return 0;
}
@@ -1920,12 +2029,12 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data,
* Cancel any outstanding calls
*****************************************************************************/
static int APP_CC
-scard_send_Cancel(IRP* irp, tui32 context)
+scard_send_Cancel(IRP *irp, tui32 context)
{
/* see [MS-RDPESC] 3.1.4.27 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -1956,14 +2065,18 @@ scard_send_Cancel(IRP* irp, tui32 context)
xstream_wr_u32_le(s, 4);
xstream_wr_u32_le(s, context);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
return 0;
}
@@ -1972,12 +2085,12 @@ scard_send_Cancel(IRP* irp, tui32 context)
* Get reader attributes
*****************************************************************************/
static int APP_CC
-scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs)
+scard_send_GetAttrib(IRP *irp, tui32 sc_handle, READER_STATE *rs)
{
/* see [MS-RDPESC] 2.2.2.21 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -2016,14 +2129,18 @@ scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs)
xstream_wr_u32_le(s, 4);
xstream_wr_u32_le(s, sc_handle);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+
xstream_free(s);
return 0;
}
@@ -2052,16 +2169,10 @@ scard_handle_EstablishContext_Return(struct stream *s, IRP *irp,
log_error("DeviceId/CompletionId do not match those in IRP");
return;
}
- if (IoStatus != 0)
- {
- log_error("failed to establish context - device not usable");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_establish_context_return(con, s, len);
+ scard_function_establish_context_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2084,16 +2195,10 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp,
log_error("DeviceId/CompletionId do not match those in IRP");
return;
}
- if (IoStatus != 0)
- {
- log_error("ReleaseContext failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_release_context_return(con, s, len);
+ scard_function_release_context_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2118,17 +2223,10 @@ APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("Error checking context validity");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_is_context_valid_return(con, s, len);
+ scard_function_is_context_valid_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2205,18 +2303,11 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("failed to connect");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_connect_return(con, s, len);
+ scard_function_connect_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
@@ -2242,17 +2333,10 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("failed to reconnect");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_reconnect_return(con, s, len);
+ scard_function_reconnect_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2277,17 +2361,10 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("BeginTransaction failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_begin_transaction_return(con, s, len);
+ scard_function_begin_transaction_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2312,17 +2389,10 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("EndTransaction failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_end_transaction_return(con, s, len);
+ scard_function_end_transaction_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2347,17 +2417,10 @@ scard_handle_Status_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("StatusCall failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_status_return(con, s, len);
+ scard_function_status_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2382,17 +2445,10 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("Disconnect failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_disconnect_return(con, s, len);
+ scard_function_disconnect_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2416,17 +2472,10 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId,
return;
}
- if (IoStatus != 0)
- {
- log_error("Transmit failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_transmit_return(con, s, len);
+ scard_function_transmit_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2450,17 +2499,10 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId,
return;
}
- if (IoStatus != 0)
- {
- log_error("Control failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_control_return(con, s, len);
+ scard_function_control_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2484,17 +2526,10 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId,
return;
}
- if (IoStatus != 0)
- {
- log_error("Cancel_call failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_cancel_return(con, s, len);
+ scard_function_cancel_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2518,17 +2553,10 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId,
return;
}
- if (IoStatus != 0)
- {
- log_error("GetAttrib_call failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
- scard_function_get_attrib_return(con, s, len);
+ scard_function_get_attrib_return(con, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index 731b4718..a98ff194 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -140,8 +140,8 @@ scard_process_establish_context(struct trans *con, struct stream *in_s)
/* returns error */
int APP_CC
scard_function_establish_context_return(struct trans *con,
- struct stream *in_s,
- int len)
+ struct stream *in_s,
+ int len, int status)
{
int bytes;
tui32 context;
@@ -149,28 +149,32 @@ scard_function_establish_context_return(struct trans *con,
struct stream *out_s;
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)
{
LLOGLN(0, ("scard_function_establish_context_return: opps"));
return 1;
}
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC;
-
- //g_hexdump(in_s->p, len);
-
- in_uint8s(in_s, 28);
- in_uint32_le(in_s, context_len);
- if (context_len != 4)
+ context = 0;
+ if (status == 0)
{
- LLOGLN(0, ("scard_function_establish_context_return: opps"));
- return 1;
+ in_uint8s(in_s, 28);
+ in_uint32_le(in_s, context_len);
+ if (context_len != 4)
+ {
+ LLOGLN(0, ("scard_function_establish_context_return: opps"));
+ return 1;
+ }
+ in_uint32_le(in_s, context);
+ LLOGLN(10, ("scard_function_establish_context_return: context 0x%8.8x",
+ context));
}
- in_uint32_le(in_s, 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);
out_uint32_le(out_s, context);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -204,12 +208,13 @@ scard_process_release_context(struct trans *con, struct stream *in_s)
int APP_CC
scard_function_release_context_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
int bytes;
struct stream *out_s;
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)
{
LLOGLN(0, ("scard_function_release_context_return: opps"));
@@ -218,7 +223,7 @@ scard_function_release_context_return(struct trans *con,
g_xrdp_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, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -263,6 +268,7 @@ scard_function_list_readers_return(struct trans *con,
char lreader_name[16][100];
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)
{
@@ -273,13 +279,12 @@ scard_function_list_readers_return(struct trans *con,
g_memset(reader_name, 0, sizeof(reader_name));
g_memset(lreader_name, 0, sizeof(lreader_name));
- in_uint8s(in_s, 28);
- len -= 28;
- in_uint32_le(in_s, len);
rn_index = 0;
readers = 0;
if (status == 0)
{
+ in_uint8s(in_s, 28);
+ in_uint32_le(in_s, len);
while (len > 0)
{
in_uint16_le(in_s, chr);
@@ -359,13 +364,15 @@ scard_process_connect(struct trans *con, struct stream *in_s)
int APP_CC
scard_function_connect_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
int dwActiveProtocol;
int hCard;
int bytes;
struct stream *out_s;
+ 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)
{
@@ -373,16 +380,21 @@ scard_function_connect_return(struct trans *con,
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, 4);
- in_uint32_le(in_s, hCard);
- LLOGLN(10, ("scard_function_connect_return: hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol));
+ dwActiveProtocol = 0;
+ hCard = 0;
+ if (status == 0)
+ {
+ in_uint8s(in_s, 36);
+ in_uint32_le(in_s, dwActiveProtocol);
+ in_uint8s(in_s, 4);
+ in_uint32_le(in_s, hCard);
+ LLOGLN(10, (" hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol));
+ }
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 */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -421,13 +433,15 @@ scard_process_disconnect(struct trans *con, struct stream *in_s)
int APP_CC
scard_function_disconnect_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
int dwActiveProtocol;
int hCard;
int bytes;
struct stream *out_s;
+ 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)
{
@@ -435,14 +449,19 @@ scard_function_disconnect_return(struct trans *con,
return 1;
}
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_D;
- in_uint8s(in_s, 36);
- in_uint32_le(in_s, dwActiveProtocol);
- in_uint8s(in_s, 4);
- in_uint32_le(in_s, hCard);
- LLOGLN(10, ("scard_function_connect_return: hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol));
+ dwActiveProtocol = 0;
+ hCard = 0;
+ if (status == 0)
+ {
+ in_uint8s(in_s, 36);
+ in_uint32_le(in_s, dwActiveProtocol);
+ in_uint8s(in_s, 4);
+ in_uint32_le(in_s, hCard);
+ LLOGLN(10, ("scard_function_connect_return: hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol));
+ }
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -476,11 +495,13 @@ scard_process_begin_transaction(struct trans *con, struct stream *in_s)
int APP_CC
scard_function_begin_transaction_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int bytes;
+ 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)
{
@@ -488,10 +509,9 @@ scard_function_begin_transaction_return(struct trans *con,
return 1;
}
g_xrdp_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, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -527,11 +547,13 @@ scard_process_end_transaction(struct trans *con, struct stream *in_s)
int APP_CC
scard_function_end_transaction_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int bytes;
+ 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)
{
@@ -542,7 +564,7 @@ scard_function_end_transaction_return(struct trans *con,
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -556,7 +578,7 @@ scard_function_end_transaction_return(struct trans *con,
int APP_CC
scard_function_cancel_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
return 0;
}
@@ -566,7 +588,7 @@ scard_function_cancel_return(struct trans *con,
int APP_CC
scard_function_get_attrib_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
return 0;
}
@@ -619,7 +641,7 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
int APP_CC
scard_function_transmit_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int bytes;
@@ -629,6 +651,7 @@ scard_function_transmit_return(struct trans *con,
char *recvBuf;
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)
{
@@ -637,22 +660,28 @@ scard_function_transmit_return(struct trans *con,
}
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_TR;
- in_uint8s(in_s, 20);
- in_uint32_le(in_s, val);
g_memset(&recv_ior, 0, sizeof(recv_ior));
- if (val != 0)
- {
- /* pioRecvPci */
- LLOGLN(0, ("scard_function_transmit_return: pioRecvPci not zero!"));
- }
- in_uint8s(in_s, 4);
- in_uint32_le(in_s, val);
cbRecvLength = 0;
- recvBuf = 0;
- if (val != 0)
+
+ if (status == 0)
{
- in_uint32_le(in_s, cbRecvLength);
- in_uint8p(in_s, recvBuf, cbRecvLength);
+ in_uint8s(in_s, 20);
+ in_uint32_le(in_s, val);
+ g_memset(&recv_ior, 0, sizeof(recv_ior));
+ if (val != 0)
+ {
+ /* pioRecvPci */
+ LLOGLN(0, ("scard_function_transmit_return: pioRecvPci not zero!"));
+ }
+ in_uint8s(in_s, 4);
+ in_uint32_le(in_s, val);
+ cbRecvLength = 0;
+ recvBuf = 0;
+ if (val != 0)
+ {
+ in_uint32_le(in_s, cbRecvLength);
+ in_uint8p(in_s, recvBuf, cbRecvLength);
+ }
}
LLOGLN(10, ("scard_function_transmit_return: cbRecvLength %d", cbRecvLength));
out_s = trans_get_out_s(con, 8192);
@@ -663,7 +692,7 @@ scard_function_transmit_return(struct trans *con,
out_uint8a(out_s, recv_ior.extra_data, recv_ior.extra_bytes);
out_uint32_le(out_s, cbRecvLength);
out_uint8a(out_s, recvBuf, cbRecvLength);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -712,13 +741,15 @@ scard_process_control(struct trans *con, struct stream *in_s)
int APP_CC
scard_function_control_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int bytes;
int cbRecvLength;
char *recvBuf;
+ 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)
{
@@ -726,17 +757,20 @@ scard_function_control_return(struct trans *con,
return 1;
}
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_CO;
-
- in_uint8s(in_s, 28);
- in_uint32_le(in_s, cbRecvLength);
- in_uint8p(in_s, recvBuf, cbRecvLength);
-
+ cbRecvLength = 0;
+ recvBuf = 0;
+ if (status == 0)
+ {
+ in_uint8s(in_s, 28);
+ in_uint32_le(in_s, cbRecvLength);
+ in_uint8p(in_s, recvBuf, cbRecvLength);
+ }
LLOGLN(10, ("scard_function_control_return: cbRecvLength %d", cbRecvLength));
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
out_uint32_le(out_s, cbRecvLength);
out_uint8a(out_s, recvBuf, cbRecvLength);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -797,7 +831,7 @@ static int g_ms2pc[] = { PC_SCARD_UNKNOWN, PC_SCARD_ABSENT,
int APP_CC
scard_function_status_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int index;
@@ -810,6 +844,8 @@ scard_function_status_return(struct trans *con,
twchar reader_name[100];
char lreader_name[100];
+ 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)
{
@@ -817,23 +853,31 @@ scard_function_status_return(struct trans *con,
return 1;
}
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_ST;
- in_uint8s(in_s, 20);
- in_uint32_le(in_s, dwReaderLen);
- in_uint8s(in_s, 4);
- in_uint32_le(in_s, dwState);
- dwState = g_ms2pc[dwState % 6];
- in_uint32_le(in_s, dwProtocol);
- in_uint8a(in_s, attr, 32);
- in_uint32_le(in_s, dwAtrLen);
- in_uint32_le(in_s, dwReaderLen);
- dwReaderLen /= 2;
- g_memset(reader_name, 0, sizeof(reader_name));
- g_memset(lreader_name, 0, sizeof(lreader_name));
- for (index = 0; index < dwReaderLen; index++)
+ dwReaderLen = 0;
+ dwState = 0;
+ dwProtocol = 0;
+ dwAtrLen = 0;
+ lreader_name[0] = 0;
+ if (status == 0)
{
- in_uint16_le(in_s, reader_name[index]);
+ in_uint8s(in_s, 20);
+ in_uint32_le(in_s, dwReaderLen);
+ in_uint8s(in_s, 4);
+ in_uint32_le(in_s, dwState);
+ dwState = g_ms2pc[dwState % 6];
+ in_uint32_le(in_s, dwProtocol);
+ in_uint8a(in_s, attr, 32);
+ in_uint32_le(in_s, dwAtrLen);
+ in_uint32_le(in_s, dwReaderLen);
+ dwReaderLen /= 2;
+ g_memset(reader_name, 0, sizeof(reader_name));
+ g_memset(lreader_name, 0, sizeof(lreader_name));
+ for (index = 0; index < dwReaderLen; index++)
+ {
+ in_uint16_le(in_s, reader_name[index]);
+ }
+ g_wcstombs(lreader_name, reader_name, 99);
}
- g_wcstombs(lreader_name, reader_name, 99);
LLOGLN(10, ("scard_function_status_return: dwAtrLen %d dwReaderLen %d "
"dwProtocol %d dwState %d name %s",
dwAtrLen, dwReaderLen, dwProtocol, dwState, lreader_name));
@@ -846,7 +890,7 @@ scard_function_status_return(struct trans *con,
out_uint32_le(out_s, dwProtocol);
out_uint32_le(out_s, dwAtrLen);
out_uint8a(out_s, attr, dwAtrLen);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -979,7 +1023,7 @@ scard_function_get_status_change_return(struct trans *con,
int APP_CC
scard_function_is_context_valid_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
return 0;
}
@@ -988,7 +1032,7 @@ scard_function_is_context_valid_return(struct trans *con,
/* returns error */
int APP_CC scard_function_reconnect_return(struct trans *con,
struct stream *in_s,
- int len)
+ int len, int status)
{
return 0;
}
diff --git a/sesman/chansrv/smartcard_pcsc.h b/sesman/chansrv/smartcard_pcsc.h
index 456d0701..34c74063 100644
--- a/sesman/chansrv/smartcard_pcsc.h
+++ b/sesman/chansrv/smartcard_pcsc.h
@@ -30,21 +30,21 @@ 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,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_release_context_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_list_readers_return(struct trans *con,
struct stream *in_s,
int len, int status);
int APP_CC scard_function_transmit_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_control_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_get_status_change_return(struct trans *con,
struct stream *in_s,
@@ -52,38 +52,38 @@ int APP_CC scard_function_get_status_change_return(struct trans *con,
int APP_CC scard_function_connect_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_status_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_begin_transaction_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_end_transaction_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_is_context_valid_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_reconnect_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_disconnect_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_cancel_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
int APP_CC scard_function_get_attrib_return(struct trans *con,
struct stream *in_s,
- int len);
+ int len, int status);
#endif /* end #ifndef _SMARTCARD_PCSC_H */