summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2013-09-24 11:17:50 -0700
committerJay Sorg <jay.sorg@gmail.com>2013-09-24 11:17:50 -0700
commit675e1b86c44d6b75032ec4cb40f4ccfb8cd06358 (patch)
tree74076c1a8a96e2fa3cb9001e778f2dbb81d2cabe
parentfc31ae1f48bc2162c49daee8b79f66c67c9cf428 (diff)
downloadxrdp-proprietary-675e1b86c44d6b75032ec4cb40f4ccfb8cd06358.tar.gz
xrdp-proprietary-675e1b86c44d6b75032ec4cb40f4ccfb8cd06358.zip
chansrv: work on smartcard
-rw-r--r--sesman/chansrv/pcsc/xrdp_pcsc.c52
-rw-r--r--sesman/chansrv/smartcard.c8
-rw-r--r--sesman/chansrv/smartcard_pcsc.c57
-rw-r--r--sesman/chansrv/smartcard_pcsc.h3
4 files changed, 112 insertions, 8 deletions
diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c
index 520c9971..b93dba12 100644
--- a/sesman/chansrv/pcsc/xrdp_pcsc.c
+++ b/sesman/chansrv/pcsc/xrdp_pcsc.c
@@ -52,11 +52,22 @@ typedef struct _SCARD_IO_REQUEST
#define LLOGLN(_level, _args) \
do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
-#define SCARD_ESTABLISH_CONTEXT 0x01
-#define SCARD_RELEASE_CONTEXT 0x02
-#define SCARD_LIST_READERS 0x03
-#define SCARD_CONNECT 0x04
-#define SCARD_GET_STATUS_CHANGE 0x0C
+#define SCARD_ESTABLISH_CONTEXT 0x01
+#define SCARD_RELEASE_CONTEXT 0x02
+#define SCARD_LIST_READERS 0x03
+#define SCARD_CONNECT 0x04
+#define SCARD_RECONNECT 0x05
+#define SCARD_DISCONNECT 0x06
+#define SCARD_BEGIN_TRANSACTION 0x07
+#define SCARD_END_TRANSACTION 0x08
+#define SCARD_TRANSMIT 0x09
+#define SCARD_CONTROL 0x0A
+#define SCARD_STATUS 0x0B
+#define SCARD_GET_STATUS_CHANGE 0x0C
+#define SCARD_CANCEL 0x0D
+#define SCARD_CANCEL_TRANSACTION 0x0E
+#define SCARD_GET_ATTRIB 0x0F
+#define SCARD_SET_ATTRIB 0x10
#define SCARD_S_SUCCESS 0x00000000
#define SCARD_F_INTERNAL_ERROR ((LONG)0x80100001)
@@ -417,7 +428,7 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
- if (code != SCARD_RELEASE_CONTEXT)
+ if (code != SCARD_CONNECT)
{
LLOGLN(0, ("SCardConnect: error, bad code"));
pthread_mutex_unlock(&g_mutex);
@@ -467,6 +478,11 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
PCSC_API LONG
SCardBeginTransaction(SCARDHANDLE hCard)
{
+ char msg[256];
+ int code;
+ int bytes;
+ int status;
+
LLOGLN(0, ("SCardBeginTransaction:"));
if (g_sck == -1)
{
@@ -474,8 +490,30 @@ SCardBeginTransaction(SCARDHANDLE hCard)
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
+ SET_UINT32(msg, 0, hCard);
+ if (send_message(SCARD_BEGIN_TRANSACTION, msg, 4) != 0)
+ {
+ LLOGLN(0, ("SCardBeginTransaction: error, send_message"));
+ pthread_mutex_unlock(&g_mutex);
+ return SCARD_F_INTERNAL_ERROR;
+ }
+ bytes = 256;
+ if (get_message(&code, msg, &bytes) != 0)
+ {
+ LLOGLN(0, ("SCardBeginTransaction: error, get_message"));
+ pthread_mutex_unlock(&g_mutex);
+ return SCARD_F_INTERNAL_ERROR;
+ }
+ if ((code != SCARD_BEGIN_TRANSACTION) || (bytes != 4))
+ {
+ LLOGLN(0, ("SCardBeginTransaction: error, bad code"));
+ pthread_mutex_unlock(&g_mutex);
+ return SCARD_F_INTERNAL_ERROR;
+ }
pthread_mutex_unlock(&g_mutex);
- return SCARD_S_SUCCESS;
+ status = GET_UINT32(msg, 0);
+ LLOGLN(10, ("SCardBeginTransaction: got status 0x%8.8x", status));
+ return status;
}
/*****************************************************************************/
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index 1a81efea..e4d144bd 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -1163,6 +1163,8 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
/* insert reader name */
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);
if (wide)
{
@@ -1178,6 +1180,7 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
xstream_wr_u8(s, w_reader_name[index]);
}
}
+ align_s(s, 4);
/* insert context */
xstream_wr_u32_le(s, 4);
@@ -1670,6 +1673,7 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
+ struct trans *con;
log_debug("entered");
@@ -1689,7 +1693,9 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
-
+ con = (struct trans *) (irp->user_data);
+ scard_function_connect_return(con, s, len);
+ devredir_irp_delete(irp);
log_debug("leaving");
}
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index 7af1871c..4d496c97 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -56,6 +56,7 @@
#define XRDP_PCSC_STATE_GOT_RC (1 << 2) /* release context */
#define XRDP_PCSC_STATE_GOT_GSC (1 << 3) /* get status change */
#define XRDP_PCSC_STATE_GOT_C (1 << 4) /* connect */
+#define XRDP_PCSC_STATE_GOT_BT (1 << 5) /* begin transaction */
/* TODO: put this in con */
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
@@ -348,6 +349,61 @@ 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 dwActiveProtocol;
+ int hCard;
+ int bytes;
+ struct stream *out_s;
+
+ g_hexdump(in_s->p, len);
+ if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C) == 0)
+ {
+ LLOGLN(0, ("scard_function_connect_return: opps"));
+ return 1;
+ }
+ g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_C;
+ in_uint8s(in_s, 36);
+ in_uint32_le(in_s, dwActiveProtocol);
+ in_uint8s(in_s, 36);
+ in_uint32_le(in_s, hCard);
+ 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 */
+ s_mark_end(out_s);
+ bytes = (int) (out_s->end - out_s->data);
+ s_pop_layer(out_s, iso_hdr);
+ out_uint32_le(out_s, bytes - 8);
+ out_uint32_le(out_s, 0x04); /* SCARD_CONNECT 0x04 */
+ return trans_force_write(con);
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+scard_process_begin_transaction(struct trans *con, struct stream *in_s)
+{
+ int hCard;
+
+ LLOGLN(0, ("scard_process_begin_transaction:"));
+ if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT)
+ {
+ LLOGLN(0, ("scard_process_begin_transaction: opps"));
+ return 1;
+ }
+ g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_BT;
+ in_uint32_le(in_s, hCard);
+ LLOGLN(0, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard));
+ scard_send_begin_transaction(con, hCard);
+ return 0;
+}
+
+/*****************************************************************************/
/* returns error */
int APP_CC
scard_process_get_status_change(struct trans *con, struct stream *in_s)
@@ -495,6 +551,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
case 0x07: /* SCARD_BEGIN_TRANSACTION */
LLOGLN(0, ("scard_process_msg: SCARD_BEGIN_TRANSACTION"));
+ rv = scard_process_begin_transaction(con, in_s);
break;
case 0x08: /* SCARD_END_TRANSACTION */
diff --git a/sesman/chansrv/smartcard_pcsc.h b/sesman/chansrv/smartcard_pcsc.h
index 81bf5046..94effea9 100644
--- a/sesman/chansrv/smartcard_pcsc.h
+++ b/sesman/chansrv/smartcard_pcsc.h
@@ -41,5 +41,8 @@ int APP_CC scard_function_list_readers_return(struct trans *con,
int APP_CC scard_function_get_status_change_return(struct trans *con,
struct stream *in_s,
int len);
+int APP_CC scard_function_connect_return(struct trans *con,
+ struct stream *in_s,
+ int len);
#endif /* end #ifndef _SMARTCARD_PCSC_H */