chansrv: work on smartcard
This commit is contained in:
parent
d926a5becd
commit
9263b22cb2
@ -55,6 +55,7 @@ typedef struct _SCARD_IO_REQUEST
|
||||
#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_S_SUCCESS 0x00000000
|
||||
@ -79,6 +80,9 @@ static int g_sck = -1; /* unix domain socket */
|
||||
|
||||
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* for pcsc_stringify_error */
|
||||
static char g_error_str[512];
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
get_display_num_from_display(const char *display_text)
|
||||
@ -152,6 +156,11 @@ connect_to_chansrv(void)
|
||||
struct sockaddr_un saddr;
|
||||
struct sockaddr *psaddr;
|
||||
|
||||
if (g_sck != -1)
|
||||
{
|
||||
/* already connected */
|
||||
return 0;
|
||||
}
|
||||
xrdp_session = getenv("XRDP_SESSION");
|
||||
if (xrdp_session == NULL)
|
||||
{
|
||||
@ -180,34 +189,31 @@ connect_to_chansrv(void)
|
||||
LLOGLN(0, ("connect_to_chansrv: error, display not > 9 %d", dis));
|
||||
return 1;
|
||||
}
|
||||
g_sck = socket(PF_LOCAL, SOCK_STREAM, 0);
|
||||
if (g_sck == -1)
|
||||
{
|
||||
g_sck = socket(PF_LOCAL, SOCK_STREAM, 0);
|
||||
if (g_sck == -1)
|
||||
{
|
||||
LLOGLN(0, ("connect_to_chansrv: error, socket failed"));
|
||||
return 1;
|
||||
}
|
||||
memset(&saddr, 0, sizeof(struct sockaddr_un));
|
||||
saddr.sun_family = AF_UNIX;
|
||||
bytes = sizeof(saddr.sun_path);
|
||||
snprintf(saddr.sun_path, bytes, "%s/.pcsc%d/pcscd.comm", home_str, dis);
|
||||
saddr.sun_path[bytes - 1] = 0;
|
||||
LLOGLN(0, ("connect_to_chansrv: connecting to %s", saddr.sun_path));
|
||||
psaddr = (struct sockaddr *) &saddr;
|
||||
bytes = sizeof(struct sockaddr_un);
|
||||
error = connect(g_sck, psaddr, bytes);
|
||||
if (error == 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("connect_to_chansrv");
|
||||
close(g_sck);
|
||||
g_sck = -1;
|
||||
LLOGLN(0, ("connect_to_chansrv: error, open %s", saddr.sun_path));
|
||||
return 1;
|
||||
}
|
||||
LLOGLN(0, ("connect_to_chansrv: error, socket failed"));
|
||||
return 1;
|
||||
}
|
||||
memset(&saddr, 0, sizeof(struct sockaddr_un));
|
||||
saddr.sun_family = AF_UNIX;
|
||||
bytes = sizeof(saddr.sun_path);
|
||||
snprintf(saddr.sun_path, bytes, "%s/.pcsc%d/pcscd.comm", home_str, dis);
|
||||
saddr.sun_path[bytes - 1] = 0;
|
||||
LLOGLN(0, ("connect_to_chansrv: connecting to %s", saddr.sun_path));
|
||||
psaddr = (struct sockaddr *) &saddr;
|
||||
bytes = sizeof(struct sockaddr_un);
|
||||
error = connect(g_sck, psaddr, bytes);
|
||||
if (error == 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("connect_to_chansrv");
|
||||
close(g_sck);
|
||||
g_sck = -1;
|
||||
LLOGLN(0, ("connect_to_chansrv: error, open %s", saddr.sun_path));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -369,6 +375,12 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
||||
DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
|
||||
LPDWORD pdwActiveProtocol)
|
||||
{
|
||||
char msg[256];
|
||||
int code;
|
||||
int bytes;
|
||||
int status;
|
||||
int offset;
|
||||
|
||||
LLOGLN(0, ("SCardConnect:"));
|
||||
if (g_sck == -1)
|
||||
{
|
||||
@ -376,8 +388,47 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
pthread_mutex_lock(&g_mutex);
|
||||
offset = 0;
|
||||
SET_UINT32(msg, offset, hContext);
|
||||
offset += 4;
|
||||
bytes = strlen(szReader);
|
||||
if (bytes > 99)
|
||||
{
|
||||
LLOGLN(0, ("SCardConnect: error, name too long"));
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
memcpy(msg + offset, szReader, bytes);
|
||||
memset(msg + bytes, 0, 100 - bytes);
|
||||
offset += 100;
|
||||
SET_UINT32(msg, offset, dwShareMode);
|
||||
offset += 4;
|
||||
SET_UINT32(msg, offset, dwPreferredProtocols);
|
||||
offset += 4;
|
||||
if (send_message(SCARD_CONNECT, msg, offset) != 0)
|
||||
{
|
||||
LLOGLN(0, ("SCardConnect: error, send_message"));
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
bytes = 256;
|
||||
if (get_message(&code, msg, &bytes) != 0)
|
||||
{
|
||||
LLOGLN(0, ("SCardConnect: error, get_message"));
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
if (code != SCARD_RELEASE_CONTEXT)
|
||||
{
|
||||
LLOGLN(0, ("SCardConnect: error, bad code"));
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_S_SUCCESS;
|
||||
*phCard = GET_UINT32(msg, 0);
|
||||
*pdwActiveProtocol = GET_UINT32(msg, 4);
|
||||
status = GET_UINT32(msg, 8);
|
||||
LLOGLN(10, ("SCardReleaseContext: got status 0x%8.8x", status));
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -746,8 +797,6 @@ SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
static char g_error_str[512];
|
||||
|
||||
/*****************************************************************************/
|
||||
char *
|
||||
pcsc_stringify_error(const long code)
|
||||
|
@ -285,7 +285,7 @@ scard_deinit(void)
|
||||
*
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_irp_establish_context(struct trans *con, int scope)
|
||||
scard_send_establish_context(struct trans *con, int scope)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -312,7 +312,7 @@ scard_send_irp_establish_context(struct trans *con, int scope)
|
||||
* Release a previously established Smart Card context
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_irp_release_context(struct trans *con, tui32 context)
|
||||
scard_send_release_context(struct trans *con, tui32 context)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -339,7 +339,7 @@ scard_send_irp_release_context(struct trans *con, tui32 context)
|
||||
*
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_irp_list_readers(struct trans *con, tui32 context, int wide)
|
||||
scard_send_list_readers(struct trans *con, tui32 context, int wide)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -371,9 +371,9 @@ scard_send_irp_list_readers(struct trans *con, tui32 context, int wide)
|
||||
* @param rsa array of READER_STATEs
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_irp_get_status_change(struct trans *con, tui32 context, int wide,
|
||||
tui32 timeout, tui32 num_readers,
|
||||
READER_STATE* rsa)
|
||||
scard_send_get_status_change(struct trans *con, tui32 context, int wide,
|
||||
tui32 timeout, tui32 num_readers,
|
||||
READER_STATE* rsa)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -403,8 +403,8 @@ scard_send_irp_get_status_change(struct trans *con, tui32 context, int wide,
|
||||
* @param wide TRUE if unicode string
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_irp_connect(struct trans *con, tui32 context, int wide,
|
||||
READER_STATE* rs)
|
||||
scard_send_connect(struct trans *con, tui32 context, int wide,
|
||||
READER_STATE* rs)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
|
@ -73,17 +73,14 @@ 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);
|
||||
int APP_CC scard_send_irp_establish_context(struct trans *con, int scope);
|
||||
int APP_CC scard_send_irp_release_context(struct trans *con, tui32 context);
|
||||
int APP_CC scard_send_irp_list_readers(struct trans *con, tui32 context, int wide);
|
||||
|
||||
int APP_CC scard_send_irp_get_status_change(struct trans *con, tui32 context,
|
||||
int wide, tui32 timeout,
|
||||
tui32 num_readers, READER_STATE* rsa);
|
||||
|
||||
int APP_CC scard_send_irp_connect(struct trans *con, tui32 context, int wide,
|
||||
READER_STATE* rs);
|
||||
|
||||
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_list_readers(struct trans *con, tui32 context, int wide);
|
||||
int APP_CC scard_send_get_status_change(struct trans *con, tui32 context,
|
||||
int wide, tui32 timeout,
|
||||
tui32 num_readers, READER_STATE* rsa);
|
||||
int APP_CC scard_send_connect(struct trans *con, tui32 context, int wide,
|
||||
READER_STATE* rs);
|
||||
int APP_CC scard_send_begin_transaction(struct trans *con, tui32 sc_handle);
|
||||
int APP_CC scard_send_end_transaction(struct trans *con, tui32 sc_handle);
|
||||
int APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle);
|
||||
|
@ -55,6 +55,7 @@
|
||||
#define XRDP_PCSC_STATE_GOT_LR (1 << 1) /* list readers */
|
||||
#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 */
|
||||
|
||||
/* TODO: put this in con */
|
||||
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
|
||||
@ -123,7 +124,7 @@ scard_process_establish_context(struct trans *con, struct stream *in_s)
|
||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_EC;
|
||||
in_uint32_le(in_s, dwScope);
|
||||
LLOGLN(0, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope));
|
||||
scard_send_irp_establish_context(con, dwScope);
|
||||
scard_send_establish_context(con, dwScope);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -183,7 +184,7 @@ scard_process_release_context(struct trans *con, struct stream *in_s)
|
||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RC;
|
||||
in_uint32_le(in_s, hContext);
|
||||
LLOGLN(0, ("scard_process_release_context: hContext 0x%8.8x", hContext));
|
||||
scard_send_irp_release_context(con, hContext);
|
||||
scard_send_release_context(con, hContext);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -232,7 +233,7 @@ 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(0, ("scard_process_list_readers: dwScope 0x%8.8x", hContext));
|
||||
scard_send_irp_list_readers(con, hContext, 1);
|
||||
scard_send_list_readers(con, hContext, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -318,6 +319,34 @@ scard_function_list_readers_return(struct trans *con,
|
||||
return trans_force_write(con);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
scard_process_connect(struct trans *con, struct stream *in_s)
|
||||
{
|
||||
int hContext;
|
||||
char szReader[100];
|
||||
READER_STATE rs;
|
||||
|
||||
LLOGLN(0, ("scard_process_connect:"));
|
||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_connect: opps"));
|
||||
return 1;
|
||||
}
|
||||
g_memset(&rs, 0, sizeof(rs));
|
||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_C;
|
||||
in_uint32_le(in_s, hContext);
|
||||
in_uint8a(in_s, szReader, 100);
|
||||
in_uint32_le(in_s, rs.shared_mode_flag);
|
||||
in_uint32_le(in_s, rs.preferred_protocol);
|
||||
LLOGLN(0, ("scard_process_connect: dwShareMode 0x%8.8x "
|
||||
"dwPreferredProtocols 0x%8.8x", rs.shared_mode_flag,
|
||||
rs.preferred_protocol));
|
||||
scard_send_connect(con, hContext, 1, &rs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
@ -367,7 +396,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
|
||||
|
||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_GSC;
|
||||
|
||||
scard_send_irp_get_status_change(con, hContext, 1, dwTimeout, cReaders, rsa);
|
||||
scard_send_get_status_change(con, hContext, 1, dwTimeout, cReaders, rsa);
|
||||
|
||||
g_free(rsa);
|
||||
|
||||
@ -453,6 +482,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
|
||||
|
||||
case 0x04: /* SCARD_CONNECT */
|
||||
LLOGLN(0, ("scard_process_msg: SCARD_CONNECT"));
|
||||
rv = scard_process_connect(con, in_s);
|
||||
break;
|
||||
|
||||
case 0x05: /* SCARD_RECONNECT */
|
||||
|
Loading…
Reference in New Issue
Block a user