chansrv: work on smartcard redir
This commit is contained in:
parent
474d17d556
commit
e427113fa8
@ -46,6 +46,7 @@ xrdp_chansrv_SOURCES = \
|
|||||||
clipboard_file.c \
|
clipboard_file.c \
|
||||||
devredir.c \
|
devredir.c \
|
||||||
smartcard.c \
|
smartcard.c \
|
||||||
|
smartcard_pcsc.c \
|
||||||
rail.c \
|
rail.c \
|
||||||
xcommon.c \
|
xcommon.c \
|
||||||
drdynvc.c \
|
drdynvc.c \
|
||||||
|
@ -120,13 +120,15 @@ dev_redir_init(void)
|
|||||||
/* get a random number that will act as a unique clientID */
|
/* get a random number that will act as a unique clientID */
|
||||||
if ((fd = open("/dev/urandom", O_RDONLY)))
|
if ((fd = open("/dev/urandom", O_RDONLY)))
|
||||||
{
|
{
|
||||||
read(fd, u.buf, 4);
|
if (read(fd, u.buf, 4) != 4)
|
||||||
|
{
|
||||||
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* /dev/urandom did not work - use address of struct s */
|
/* /dev/urandom did not work - use address of struct s */
|
||||||
tui64 u64 = (tui64) &s;
|
tui64 u64 = (tui64) (tintptr) &s;
|
||||||
u.clientID = (tui32) u64;
|
u.clientID = (tui32) u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +154,7 @@ dev_redir_init(void)
|
|||||||
int APP_CC
|
int APP_CC
|
||||||
dev_redir_deinit(void)
|
dev_redir_deinit(void)
|
||||||
{
|
{
|
||||||
|
scard_deinit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +285,10 @@ done:
|
|||||||
int APP_CC
|
int APP_CC
|
||||||
dev_redir_get_wait_objs(tbus *objs, int *count, int *timeout)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,6 +296,10 @@ dev_redir_get_wait_objs(tbus *objs, int *count, int *timeout)
|
|||||||
int APP_CC
|
int APP_CC
|
||||||
dev_redir_check_wait_objs(void)
|
dev_redir_check_wait_objs(void)
|
||||||
{
|
{
|
||||||
|
if (g_is_smartcard_redir_supported)
|
||||||
|
{
|
||||||
|
return scard_check_wait_objs();
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,6 +630,7 @@ void dev_redir_proc_client_core_cap_resp(struct stream *s)
|
|||||||
case CAP_SMARTCARD_TYPE:
|
case CAP_SMARTCARD_TYPE:
|
||||||
log_debug("got CAP_SMARTCARD_TYPE");
|
log_debug("got CAP_SMARTCARD_TYPE");
|
||||||
g_is_smartcard_redir_supported = 1;
|
g_is_smartcard_redir_supported = 1;
|
||||||
|
scard_init();
|
||||||
xstream_seek(s, cap_len);
|
xstream_seek(s, cap_len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "irp.h"
|
#include "irp.h"
|
||||||
#include "devredir.h"
|
#include "devredir.h"
|
||||||
|
#include "smartcard_pcsc.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO
|
* 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();
|
||||||
|
}
|
||||||
|
@ -39,4 +39,13 @@ void scard_handle_ListReaders_Return(struct stream *s, IRP *irp,
|
|||||||
tui32 DeviceId, tui32 CompletionId,
|
tui32 DeviceId, tui32 CompletionId,
|
||||||
tui32 IoStatus);
|
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 */
|
#endif /* end #ifndef _SMARTCARD_C */
|
||||||
|
275
sesman/chansrv/smartcard_pcsc.c
Normal file
275
sesman/chansrv/smartcard_pcsc.c
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/**
|
||||||
|
* 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 0
|
||||||
|
|
||||||
|
#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;
|
||||||
|
|
||||||
|
typedef 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;
|
||||||
|
unsigned char key[PCSCLITE_MSG_KEY_LEN]; /* 16 bytes */
|
||||||
|
union _u
|
||||||
|
{
|
||||||
|
unsigned char data[PCSCLITE_MAX_MESSAGE_SIZE];
|
||||||
|
struct version_struct veStr;
|
||||||
|
} u;
|
||||||
|
} sharedSegmentMsg, *psharedSegmentMsg;
|
||||||
|
|
||||||
|
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_msg(struct stream *s)
|
||||||
|
{
|
||||||
|
psharedSegmentMsg msg;
|
||||||
|
|
||||||
|
LLOGLN(0, ("scard_process_msg: mtype 0x%2.2x command 0x%2.2x",
|
||||||
|
msg->mtype, msg->command));
|
||||||
|
msg = (psharedSegmentMsg)(s->p);
|
||||||
|
switch (msg->mtype)
|
||||||
|
{
|
||||||
|
case 0xF8: /* CMD_VERSION */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* 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 = sizeof(sharedSegmentMsg);
|
||||||
|
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
|
36
sesman/chansrv/smartcard_pcsc.h
Normal file
36
sesman/chansrv/smartcard_pcsc.h
Normal file
@ -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 */
|
Loading…
Reference in New Issue
Block a user