summaryrefslogtreecommitdiffstats
path: root/sesman
diff options
context:
space:
mode:
authorLaxmikant Rashinkar <LK.Rashinkar@gmail.com>2013-08-09 19:44:05 -0700
committerLaxmikant Rashinkar <LK.Rashinkar@gmail.com>2013-08-09 19:44:05 -0700
commitd2de1b703be307ffd36e618cef68b3976ddf548d (patch)
tree26fd69308d9f66a213c817ac3d47061af4772b2b /sesman
parent23433c9c7e10af845c80a6b58324f24b1f3cf189 (diff)
parent8b48e2274e4ecbce56893b6915d13781474d19d6 (diff)
downloadxrdp-proprietary-d2de1b703be307ffd36e618cef68b3976ddf548d.tar.gz
xrdp-proprietary-d2de1b703be307ffd36e618cef68b3976ddf548d.zip
Merge branch 'master' of github.com:neutrinolabs/xrdp
Diffstat (limited to 'sesman')
-rw-r--r--sesman/chansrv/Makefile.am1
-rw-r--r--sesman/chansrv/devredir.c16
-rw-r--r--sesman/chansrv/smartcard.c35
-rw-r--r--sesman/chansrv/smartcard.h9
-rw-r--r--sesman/chansrv/smartcard_pcsc.c294
-rw-r--r--sesman/chansrv/smartcard_pcsc.h36
6 files changed, 389 insertions, 2 deletions
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am
index 89753430..7cecdb1e 100644
--- a/sesman/chansrv/Makefile.am
+++ b/sesman/chansrv/Makefile.am
@@ -46,6 +46,7 @@ xrdp_chansrv_SOURCES = \
clipboard_file.c \
devredir.c \
smartcard.c \
+ smartcard_pcsc.c \
rail.c \
xcommon.c \
drdynvc.c \
diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c
index f254fa89..57d877df 100644
--- a/sesman/chansrv/devredir.c
+++ b/sesman/chansrv/devredir.c
@@ -120,13 +120,15 @@ dev_redir_init(void)
/* get a random number that will act as a unique clientID */
if ((fd = open("/dev/urandom", O_RDONLY)))
{
- read(fd, u.buf, 4);
+ if (read(fd, u.buf, 4) != 4)
+ {
+ }
close(fd);
}
else
{
/* /dev/urandom did not work - use address of struct s */
- tui64 u64 = (tui64) &s;
+ tui64 u64 = (tui64) (tintptr) &s;
u.clientID = (tui32) u64;
}
@@ -152,6 +154,7 @@ dev_redir_init(void)
int APP_CC
dev_redir_deinit(void)
{
+ scard_deinit();
return 0;
}
@@ -282,6 +285,10 @@ done:
int APP_CC
dev_redir_get_wait_objs(tbus *objs, int *count, int *timeout)
{
+ if (g_is_smartcard_redir_supported)
+ {
+ return scard_get_wait_objs(objs, count, timeout);
+ }
return 0;
}
@@ -289,6 +296,10 @@ dev_redir_get_wait_objs(tbus *objs, int *count, int *timeout)
int APP_CC
dev_redir_check_wait_objs(void)
{
+ if (g_is_smartcard_redir_supported)
+ {
+ return scard_check_wait_objs();
+ }
return 0;
}
@@ -619,6 +630,7 @@ void dev_redir_proc_client_core_cap_resp(struct stream *s)
case CAP_SMARTCARD_TYPE:
log_debug("got CAP_SMARTCARD_TYPE");
g_is_smartcard_redir_supported = 1;
+ scard_init();
xstream_seek(s, cap_len);
break;
}
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index d1052b9c..c370479e 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -26,6 +26,7 @@
#include "log.h"
#include "irp.h"
#include "devredir.h"
+#include "smartcard_pcsc.h"
/*
* TODO
@@ -536,3 +537,37 @@ scard_release_resources(void)
/**
*
*****************************************************************************/
+int APP_CC
+scard_get_wait_objs(tbus *objs, int *count, int *timeout)
+{
+ return scard_pcsc_get_wait_objs(objs, count, timeout);
+}
+
+/**
+ *
+ *****************************************************************************/
+int APP_CC
+scard_check_wait_objs(void)
+{
+ return scard_pcsc_check_wait_objs();
+}
+
+/**
+ *
+ *****************************************************************************/
+int APP_CC
+scard_init(void)
+{
+ log_debug("init")
+ return scard_pcsc_init();
+}
+
+/**
+ *
+ *****************************************************************************/
+int APP_CC
+scard_deinit(void)
+{
+ log_debug("deinit")
+ return scard_pcsc_deinit();
+}
diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h
index 88f31369..a85b9f5f 100644
--- a/sesman/chansrv/smartcard.h
+++ b/sesman/chansrv/smartcard.h
@@ -39,4 +39,13 @@ void scard_handle_ListReaders_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus);
+int APP_CC
+scard_get_wait_objs(tbus *objs, int *count, int *timeout);
+int APP_CC
+scard_check_wait_objs(void);
+int APP_CC
+scard_init(void);
+int APP_CC
+scard_deinit(void);
+
#endif /* end #ifndef _SMARTCARD_C */
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
new file mode 100644
index 00000000..5312ec5f
--- /dev/null
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -0,0 +1,294 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * smartcard redirection support, PCSC daemon standin
+ * this will act like pcsc daemon
+ */
+
+#define PCSC_STANDIN 1
+
+#include "os_calls.h"
+#include "smartcard.h"
+#include "log.h"
+#include "irp.h"
+#include "devredir.h"
+#include "trans.h"
+
+#if PCSC_STANDIN
+
+#define LLOG_LEVEL 11
+#define LLOGLN(_level, _args) \
+ do \
+ { \
+ if (_level < LLOG_LEVEL) \
+ { \
+ g_write("chansrv:smartcard [%10.10u]: ", g_time3()); \
+ g_writeln _args ; \
+ } \
+ } \
+ while (0)
+
+#define PCSCLITE_MSG_KEY_LEN 16
+#define PCSCLITE_MAX_MESSAGE_SIZE 2048
+
+struct version_struct
+{
+ tsi32 major; /**< IPC major \ref PROTOCOL_VERSION_MAJOR */
+ tsi32 minor; /**< IPC minor \ref PROTOCOL_VERSION_MINOR */
+ tui32 rv;
+};
+typedef struct version_struct version_struct;
+
+struct rxSharedSegment
+{
+ tui32 mtype; /** one of the \c pcsc_adm_commands */
+ tui32 user_id;
+ tui32 group_id;
+ tui32 command; /** one of the \c pcsc_msg_commands */
+ tui64 date;
+ tui8 key[PCSCLITE_MSG_KEY_LEN]; /* 16 bytes */
+ union _u
+ {
+ tui8 data[PCSCLITE_MAX_MESSAGE_SIZE];
+ struct version_struct veStr;
+ } u;
+};
+typedef struct rxSharedSegment sharedSegmentMsg, *psharedSegmentMsg;
+
+#define RXSHAREDSEGMENT_BYTES 2088
+
+extern int g_display_num; /* in chansrv.c */
+
+/*****************************************************************************/
+struct pcsc_client
+{
+ struct trans *con;
+};
+
+static struct pcsc_client *g_head = 0;
+static struct pcsc_client *g_tail = 0;
+
+static struct trans *g_lis = 0;
+static struct trans *g_con = 0; /* todo, remove this */
+
+static char g_pcsc_directory[256] = "";
+
+/*****************************************************************************/
+int APP_CC
+scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout)
+{
+ LLOGLN(0, ("scard_pcsc_get_wait_objs"));
+ if (g_lis != 0)
+ {
+ trans_get_wait_objs(g_lis, objs, count);
+ }
+ if (g_con != 0)
+ {
+ trans_get_wait_objs(g_con, objs, count);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+scard_pcsc_check_wait_objs(void)
+{
+ LLOGLN(0, ("scard_pcsc_check_wait_objs"));
+ if (g_lis != 0)
+ {
+ trans_check_wait_objs(g_lis);
+ }
+ if (g_con != 0)
+ {
+ trans_check_wait_objs(g_con);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+scard_process_version(psharedSegmentMsg msg)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+scard_process_msg(struct stream *s)
+{
+ sharedSegmentMsg msg;
+ int rv;
+
+ g_memset(&msg, 0, sizeof(msg));
+ in_uint32_le(s, msg.mtype);
+ in_uint32_le(s, msg.user_id);
+ in_uint32_le(s, msg.group_id);
+ in_uint32_le(s, msg.command);
+ in_uint64_le(s, msg.date);
+ LLOGLN(0, ("scard_process_msg: mtype 0x%2.2x command 0x%2.2x",
+ msg.mtype, msg.command));
+ rv = 0;
+ switch (msg.mtype)
+ {
+ case 0xF8: /* CMD_VERSION */
+ rv = scard_process_version(&msg);
+ break;
+ }
+ return rv;
+}
+
+/*****************************************************************************/
+/* returns error */
+int DEFAULT_CC
+my_pcsc_trans_data_in(struct trans *trans)
+{
+ struct stream *s;
+ int id;
+ int size;
+ int error;
+
+ LLOGLN(0, ("my_pcsc_trans_data_in:"));
+ if (trans == 0)
+ {
+ return 0;
+ }
+
+ if (trans != g_con)
+ {
+ return 1;
+ }
+ s = trans_get_in_s(trans);
+ g_hexdump(s->p, 64);
+ error = scard_process_msg(s);
+ return error;
+}
+
+/*****************************************************************************/
+/* got a new connection from libpcsclite */
+int DEFAULT_CC
+my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans)
+{
+ LLOGLN(0, ("my_pcsc_trans_conn_in:"));
+
+ if (trans == 0)
+ {
+ return 1;
+ }
+
+ if (trans != g_lis)
+ {
+ return 1;
+ }
+
+ if (new_trans == 0)
+ {
+ return 1;
+ }
+
+ g_con = new_trans;
+ g_con->trans_data_in = my_pcsc_trans_data_in;
+ g_con->header_size = RXSHAREDSEGMENT_BYTES;
+ LLOGLN(0, ("my_pcsc_trans_conn_in: sizeof sharedSegmentMsg is %d",
+ sizeof(sharedSegmentMsg)));
+
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+scard_pcsc_init(void)
+{
+ char port[256];
+ int error;
+
+ LLOGLN(0, ("scard_pcsc_init:"));
+ if (g_lis == 0)
+ {
+ g_lis = trans_create(2, 8192, 8192);
+ g_snprintf(g_pcsc_directory, 255, "/tmp/.xrdp/pcsc%d", g_display_num);
+ if (g_directory_exist(g_pcsc_directory))
+ {
+ if (g_remove_dir(g_pcsc_directory) != 0)
+ {
+ LLOGLN(0, ("scard_pcsc_init: g_remove_dir failed"));
+ }
+ }
+ if (g_create_dir(g_pcsc_directory) != 0)
+ {
+ LLOGLN(0, ("scard_pcsc_init: g_create_dir failed"));
+ }
+ g_chmod_hex(g_pcsc_directory, 0x1777);
+ g_snprintf(port, 255, "%s/pcscd.comm", g_pcsc_directory);
+ g_lis->trans_conn_in = my_pcsc_trans_conn_in;
+ error = trans_listen(g_lis, port);
+ if (error != 0)
+ {
+ LLOGLN(0, ("scard_pcsc_init: trans_listen failed for port %s",
+ port));
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+scard_pcsc_deinit(void)
+{
+ LLOGLN(0, ("scard_pcsc_deinit:"));
+ if (g_lis != 0)
+ {
+ trans_delete(g_lis);
+ g_lis = 0;
+ if (g_remove_dir(g_pcsc_directory) != 0)
+ {
+ LLOGLN(0, ("scard_pcsc_deinit: g_remove_dir failed"));
+ }
+ g_pcsc_directory[0] = 0;
+ }
+ return 0;
+}
+
+#else
+
+int APP_CC
+scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout)
+{
+ return 0;
+}
+int APP_CC
+scard_pcsc_check_wait_objs(void)
+{
+ return 0;
+}
+int APP_CC
+scard_pcsc_init(void)
+{
+ return 0;
+}
+int APP_CC
+scard_pcsc_deinit(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/sesman/chansrv/smartcard_pcsc.h b/sesman/chansrv/smartcard_pcsc.h
new file mode 100644
index 00000000..a97a70d3
--- /dev/null
+++ b/sesman/chansrv/smartcard_pcsc.h
@@ -0,0 +1,36 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * smartcard redirection support, PCSC daemon standin
+ */
+
+#ifndef _SMARTCARD_PCSC_H
+#define _SMARTCARD_PCSC_H
+
+int APP_CC
+scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout);
+int APP_CC
+scard_pcsc_check_wait_objs(void);
+int APP_CC
+scard_pcsc_init(void);
+int APP_CC
+scard_pcsc_deinit(void);
+
+#endif /* end #ifndef _SMARTCARD_PCSC_H */