chansrv: work on smartcard

This commit is contained in:
Jay Sorg 2013-09-19 01:03:20 -07:00
parent d926a5becd
commit 9263b22cb2
4 changed files with 128 additions and 52 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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 */