summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2013-12-05 02:22:41 -0800
committerJay Sorg <jay.sorg@gmail.com>2013-12-05 02:22:41 -0800
commitde9fa3d5fac378ba63cc9e46f8ff08a425953eaf (patch)
treeb8daf56ac4883d402395b0748f9f66cb445edde4
parentf265c14499f258cab934ee114a4c99877a751d23 (diff)
downloadxrdp-proprietary-de9fa3d5fac378ba63cc9e46f8ff08a425953eaf.tar.gz
xrdp-proprietary-de9fa3d5fac378ba63cc9e46f8ff08a425953eaf.zip
chansrv: smartcard, more work on support for MSTSC
-rw-r--r--sesman/chansrv/pcsc/xrdp_pcsc.c29
-rw-r--r--sesman/chansrv/smartcard.c209
-rw-r--r--sesman/chansrv/smartcard.h3
-rw-r--r--sesman/chansrv/smartcard_pcsc.c55
4 files changed, 175 insertions, 121 deletions
diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c
index b28df62c..e4bb0bfc 100644
--- a/sesman/chansrv/pcsc/xrdp_pcsc.c
+++ b/sesman/chansrv/pcsc/xrdp_pcsc.c
@@ -1004,9 +1004,14 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
int status;
int offset;
int index;
+ int bytes_groups;
+ int val;
+ int llen;
char reader[100];
LLOGLN(10, ("SCardListReaders:"));
+ LLOGLN(10, ("SCardListReaders: mszGroups %s", mszGroups));
+ LLOGLN(10, ("SCardListReaders: *pcchReaders %d", *pcchReaders));
if (g_sck == -1)
{
LLOGLN(0, ("SCardListReaders: error, not connected"));
@@ -1014,8 +1019,22 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
}
msg = (char *) malloc(8192);
pthread_mutex_lock(&g_mutex);
- SET_UINT32(msg, 0, hContext);
- if (send_message(SCARD_LIST_READERS, msg, 4) != 0)
+ offset = 0;
+ SET_UINT32(msg, offset, hContext);
+ offset += 4;
+ bytes_groups = 0;
+ if (mszGroups != 0)
+ {
+ bytes_groups = strlen(mszGroups);
+ }
+ SET_UINT32(msg, offset, bytes_groups);
+ offset += 4;
+ memcpy(msg + offset, mszGroups, bytes_groups);
+ offset += bytes_groups;
+ val = *pcchReaders;
+ SET_UINT32(msg, offset, val);
+ offset += 4;
+ if (send_message(SCARD_LIST_READERS, msg, offset) != 0)
{
LLOGLN(0, ("SCardListReaders: error, send_message"));
free(msg);
@@ -1039,6 +1058,8 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
}
pthread_mutex_unlock(&g_mutex);
offset = 0;
+ llen = GET_UINT32(msg, offset);
+ offset += 4;
num_readers = GET_UINT32(msg, offset);
offset += 4;
LLOGLN(10, ("SCardListReaders: mszReaders %p pcchReaders %p num_readers %d",
@@ -1060,6 +1081,10 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
reader_names_index++;
status = GET_UINT32(msg, offset);
offset += 4;
+ if (mszReaders == 0)
+ {
+ reader_names_index = llen;
+ }
if (pcchReaders != 0)
{
*pcchReaders = reader_names_index;
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index c6a36811..7f533a0e 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -167,7 +167,9 @@ static void APP_CC scard_release_resources(void);
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_ListReaders(IRP *irp, tui32 context,
+ char *groups, int cchReaders,
+ int wide);
static void APP_CC scard_send_GetStatusChange(IRP *irp, tui32 context, int wide,
tui32 timeout, tui32 num_readers,
READER_STATE *rsa);
@@ -415,7 +417,8 @@ scard_send_is_valid_context(struct trans *con, tui32 context)
*
*****************************************************************************/
int APP_CC
-scard_send_list_readers(struct trans *con, tui32 context, int wide)
+scard_send_list_readers(struct trans *con, tui32 context, char *groups,
+ int cchReaders, int wide)
{
IRP *irp;
@@ -432,7 +435,7 @@ scard_send_list_readers(struct trans *con, tui32 context, int wide)
irp->user_data = con;
/* send IRP to client */
- scard_send_ListReaders(irp, context, wide);
+ scard_send_ListReaders(irp, context, groups, cchReaders, wide);
return 0;
}
@@ -933,14 +936,18 @@ scard_send_EstablishContext(IRP *irp, int scope)
return;
}
- xstream_wr_u32_le(s, 0x08); /* len */
- xstream_wr_u32_le(s, 0); /* unused */
- 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 */
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, scope);
+ 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);
+
s_pop_layer(s, iso_hdr);
bytes = (int) (s->end - s->p);
bytes -= 28;
@@ -951,7 +958,7 @@ scard_send_EstablishContext(IRP *irp, int scope)
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
}
/**
@@ -978,28 +985,20 @@ scard_send_ReleaseContext(IRP *irp, tui32 context)
return;
}
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 4 bytes len - don't know what this is, zero for now
- * 12 bytes unused
- * u32 4 bytes context len
- * 4 bytes context
- */
-
- xstream_wr_u32_le(s, 0);
- xstream_seek(s, 12);
-
- /* insert context */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
+ 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, context);
s_mark_end(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;
@@ -1010,7 +1009,7 @@ scard_send_ReleaseContext(IRP *irp, tui32 context)
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
}
/**
@@ -1067,21 +1066,28 @@ scard_send_IsContextValid(IRP *irp, tui32 context)
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
}
/**
*
*****************************************************************************/
static void APP_CC
-scard_send_ListReaders(IRP *irp, tui32 context, int wide)
+scard_send_ListReaders(IRP *irp, tui32 context, char *groups,
+ int cchReaders, int wide)
{
/* see [MS-RDPESC] 2.2.2.4 */
SMARTCARD *sc;
struct stream *s;
int bytes;
+ int bytes_groups;
+ int val;
+ int index;
+ int num_chars;
tui32 ioctl;
+ twchar w_groups[100];
+
if ((sc = smartcards[irp->scard_index]) == NULL)
{
@@ -1098,42 +1104,64 @@ scard_send_ListReaders(IRP *irp, tui32 context, int wide)
return;
}
- xstream_wr_u32_le(s, 72); /* number of bytes to follow */
+ num_chars = 0;
+ bytes_groups = 0;
+ w_groups[0] = 0;
+ val = 0;
+ if (groups != 0)
+ {
+ if (groups[0] != 0)
+ {
+ num_chars = g_mbstowcs(w_groups, groups, 99);
+ bytes_groups = wide ? (num_chars + 2) * 2 : num_chars + 2;
+ val = 0x00020004;
+ }
+ }
+ 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, 0x00000024);
- out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, bytes_groups);
+ out_uint32_le(s, val);
out_uint32_le(s, 0x00000000);
- out_uint32_le(s, 0xFFFFFFFF);
+ out_uint32_le(s, cchReaders);
/* insert context */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
+ out_uint32_le(s, 4);
+ out_uint32_le(s, context);
- xstream_wr_u32_le(s, 36); /* length of mszGroups */
- xstream_wr_u16_le(s, 0x0053);
- xstream_wr_u16_le(s, 0x0043);
- xstream_wr_u16_le(s, 0x0061);
- xstream_wr_u16_le(s, 0x0072);
- xstream_wr_u16_le(s, 0x0064);
- xstream_wr_u16_le(s, 0x0024);
- xstream_wr_u16_le(s, 0x0041);
- xstream_wr_u16_le(s, 0x006c);
- xstream_wr_u16_le(s, 0x006c);
- xstream_wr_u16_le(s, 0x0052);
- xstream_wr_u16_le(s, 0x0065);
- xstream_wr_u16_le(s, 0x0061);
- xstream_wr_u16_le(s, 0x0064);
- xstream_wr_u16_le(s, 0x0065);
- xstream_wr_u16_le(s, 0x0072);
- xstream_wr_u16_le(s, 0x0073);
-
- xstream_wr_u32_le(s, 0x00);
+ if (bytes_groups > 0)
+ {
+ if (wide)
+ {
+ out_uint32_le(s, bytes_groups);
+ for (index = 0; index < num_chars; index++)
+ {
+ out_uint16_le(s, w_groups[index]);
+ }
+ out_uint16_le(s, 0);
+ out_uint16_le(s, 0);
+ }
+ else
+ {
+ out_uint32_le(s, bytes_groups);
+ for (index = 0; index < num_chars; index++)
+ {
+ out_uint8(s, w_groups[index]);
+ }
+ out_uint16_le(s, 0);
+ out_uint16_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);
+
s_pop_layer(s, iso_hdr);
bytes = (int) (s->end - s->p);
bytes -= 28;
@@ -1149,33 +1177,7 @@ scard_send_ListReaders(IRP *irp, tui32 context, int wide)
g_hexdump(s->data, bytes);
#endif
- xstream_free(s);
-
- /*
- scard_device_control: dumping 120 bytes of data
- 0000 00 08 00 00 58 00 00 00 2c 00 09 00 00 00 00 00 ....X...,.......
- 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 0020 01 10 08 00 cc cc cc cc 48 00 00 00 00 00 00 00 ........H.......
- 0030 04 00 00 00 00 00 02 00 24 00 00 00 04 00 02 00 ........$.......
- 0040 00 00 00 00 ff ff ff ff 04 00 00 00 84 db 03 01 ................
- 0050 24 00 00 00 53 00 43 00 61 00 72 00 64 00 24 00 $...S.C.a.r.d.$.
- 0060 41 00 6c 00 6c 00 52 00 65 00 61 00 64 00 65 00 A.l.l.R.e.a.d.e.
- 0070 72 00 73 00 00 00 00 00 r.s.....
- scard_device_control: output_len=2048 input_len=88 ioctl_code=0x9002c
- */
-
- /*
- scard_device_control: dumping 120 bytes of data
- 0000 00 08 00 00 80 00 00 00 14 00 09 00 00 00 00 00 ................
- 0010 2e 2e 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
- 0020 01 10 08 00 cc cc cc cc 48 00 00 00 00 00 00 00 ........H.......
- 0030 02 00 00 00 00 00 00 00 72 64 00 00 00 00 00 00 ........rd......
- 0040 81 27 00 00 00 00 00 00 04 00 00 00 84 b3 03 01 .'..............
- 0050 24 00 00 00 53 00 43 00 61 00 72 00 64 00 24 00 $...S.C.a.r.d.$.
- 0060 41 00 6c 00 6c 00 52 00 65 00 61 00 64 00 65 00 A.l.l.R.e.a.d.e.
- 0070 72 00 73 00 00 00 00 00 r.s.....
- scard_device_control: output_len=2048 input_len=128 ioctl_code=0x90014
- */
+ free_stream(s);
}
/*****************************************************************************/
@@ -1399,6 +1401,11 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
s_mark_end(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;
@@ -1409,7 +1416,7 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
}
/**
@@ -1483,7 +1490,7 @@ scard_send_Reconnect(IRP *irp, tui32 context, tui32 sc_handle, READER_STATE *rs)
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
}
/**
@@ -1545,7 +1552,7 @@ scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
}
/**
@@ -1608,7 +1615,7 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition)
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
}
/**
@@ -1689,7 +1696,7 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle,
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
}
/**
@@ -1755,7 +1762,7 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
}
/**
@@ -1817,10 +1824,10 @@ scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data,
* u32 4 bytes sc_handle
*/
- g_writeln("send_bytes %d", send_bytes);
- g_writeln("recv_bytes %d", recv_bytes);
+ //g_writeln("send_bytes %d", send_bytes);
+ //g_writeln("recv_bytes %d", recv_bytes);
-#if 1
+#if 0
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
//out_uint32_be(s, 0x58000000);
out_uint32_be(s, 0x00000000);
@@ -1859,10 +1866,10 @@ scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data,
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);
+ //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);
@@ -1943,12 +1950,12 @@ scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data,
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
-#if 1
+#if 0
g_writeln("scard_send_Transmit:");
g_hexdump(s->data, bytes);
#endif
- xstream_free(s);
+ free_stream(s);
return 0;
}
@@ -2021,7 +2028,7 @@ scard_send_Control(IRP *irp, tui32 context, tui32 sc_handle, char *send_data,
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
return 0;
}
@@ -2077,7 +2084,7 @@ scard_send_Cancel(IRP *irp, tui32 context)
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
return 0;
}
@@ -2141,7 +2148,7 @@ scard_send_GetAttrib(IRP *irp, tui32 sc_handle, READER_STATE *rs)
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+ free_stream(s);
return 0;
}
diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h
index 88f4cdf6..24ba2123 100644
--- a/sesman/chansrv/smartcard.h
+++ b/sesman/chansrv/smartcard.h
@@ -113,7 +113,8 @@ int APP_CC scard_deinit(void);
int APP_CC scard_send_establish_context(struct trans *con, int scope);
int APP_CC scard_send_release_context(struct trans *con, tui32 context);
int APP_CC scard_send_is_valid_context(struct trans *con, tui32 context);
-int APP_CC scard_send_list_readers(struct trans *con, tui32 context, int wide);
+int APP_CC scard_send_list_readers(struct trans *con, tui32 context,
+ char *groups, int cchReaders, int wide);
int APP_CC scard_send_get_status_change(struct trans *con, tui32 context,
int wide, tui32 timeout,
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index a98ff194..c6114c2c 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -65,6 +65,7 @@
/* TODO: put this in con */
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
+static int g_xrdp_pcsc_extra1;
extern int g_display_num; /* in chansrv.c */
@@ -238,6 +239,9 @@ int APP_CC
scard_process_list_readers(struct trans *con, struct stream *in_s)
{
int hContext;
+ int bytes_groups;
+ int cchReaders;
+ char *groups;
LLOGLN(10, ("scard_process_list_readers:"));
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR)
@@ -247,8 +251,15 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
}
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR;
in_uint32_le(in_s, hContext);
- LLOGLN(10, ("scard_process_list_readers: dwScope 0x%8.8x", hContext));
- scard_send_list_readers(con, hContext, 1);
+ 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 = g_xrdp_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);
+ g_free(groups);
return 0;
}
@@ -264,6 +275,8 @@ scard_function_list_readers_return(struct trans *con,
int rn_index;
int index;
int bytes;
+ int cchReaders;
+ int llen;
twchar reader_name[100];
char lreader_name[16][100];
@@ -277,33 +290,40 @@ scard_function_list_readers_return(struct trans *con,
}
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR;
+ cchReaders = g_xrdp_pcsc_extra1;
+
g_memset(reader_name, 0, sizeof(reader_name));
g_memset(lreader_name, 0, sizeof(lreader_name));
rn_index = 0;
readers = 0;
+ llen = 0;
if (status == 0)
{
in_uint8s(in_s, 28);
in_uint32_le(in_s, len);
- while (len > 0)
+ llen = len;
+ if (cchReaders > 0)
{
- in_uint16_le(in_s, chr);
- len -= 2;
- if (chr == 0)
+ while (len > 0)
{
- if (reader_name[0] != 0)
+ in_uint16_le(in_s, chr);
+ len -= 2;
+ if (chr == 0)
{
- g_wcstombs(lreader_name[readers], reader_name, 99);
- g_memset(reader_name, 0, sizeof(reader_name));
- readers++;
+ if (reader_name[0] != 0)
+ {
+ g_wcstombs(lreader_name[readers], reader_name, 99);
+ g_memset(reader_name, 0, sizeof(reader_name));
+ readers++;
+ }
+ reader_name[0] = 0;
+ rn_index = 0;
+ }
+ else
+ {
+ reader_name[rn_index] = chr;
+ rn_index++;
}
- reader_name[0] = 0;
- rn_index = 0;
- }
- else
- {
- reader_name[rn_index] = chr;
- rn_index++;
}
}
if (rn_index > 0)
@@ -319,6 +339,7 @@ scard_function_list_readers_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, llen);
out_uint32_le(out_s, readers);
for (index = 0; index < readers; index++)
{