chansrv: work on smartcard
This commit is contained in:
parent
9d8d31d02a
commit
b69c144c7d
@ -393,12 +393,13 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
|||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
LLOGLN(0, ("SCardConnect:"));
|
LLOGLN(0, ("SCardConnect:"));
|
||||||
|
LLOGLN(0, ("SCardConnect: hContext %p szReader %s dwShareMode %d dwPreferredProtocols %d",
|
||||||
|
hContext, szReader, dwShareMode, dwPreferredProtocols));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardConnect: error, not connected"));
|
LLOGLN(0, ("SCardConnect: error, not connected"));
|
||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&g_mutex);
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
SET_UINT32(msg, offset, hContext);
|
SET_UINT32(msg, offset, hContext);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
@ -409,12 +410,13 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
|||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
memcpy(msg + offset, szReader, bytes);
|
memcpy(msg + offset, szReader, bytes);
|
||||||
memset(msg + bytes, 0, 100 - bytes);
|
memset(msg + offset + bytes, 0, 100 - bytes);
|
||||||
offset += 100;
|
offset += 100;
|
||||||
SET_UINT32(msg, offset, dwShareMode);
|
SET_UINT32(msg, offset, dwShareMode);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
SET_UINT32(msg, offset, dwPreferredProtocols);
|
SET_UINT32(msg, offset, dwPreferredProtocols);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
pthread_mutex_lock(&g_mutex);
|
||||||
if (send_message(SCARD_CONNECT, msg, offset) != 0)
|
if (send_message(SCARD_CONNECT, msg, offset) != 0)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardConnect: error, send_message"));
|
LLOGLN(0, ("SCardConnect: error, send_message"));
|
||||||
@ -463,6 +465,11 @@ SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
|
|||||||
PCSC_API LONG
|
PCSC_API LONG
|
||||||
SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
||||||
{
|
{
|
||||||
|
char msg[256];
|
||||||
|
int code;
|
||||||
|
int bytes;
|
||||||
|
int status;
|
||||||
|
|
||||||
LLOGLN(0, ("SCardDisconnect:"));
|
LLOGLN(0, ("SCardDisconnect:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
@ -470,8 +477,31 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
|||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&g_mutex);
|
pthread_mutex_lock(&g_mutex);
|
||||||
|
SET_UINT32(msg, 0, hCard);
|
||||||
|
SET_UINT32(msg, 4, dwDisposition);
|
||||||
|
if (send_message(SCARD_DISCONNECT, msg, 8) != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardDisconnect: error, send_message"));
|
||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
return SCARD_S_SUCCESS;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
bytes = 256;
|
||||||
|
if (get_message(&code, msg, &bytes) != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardDisconnect: error, get_message"));
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
if ((code != SCARD_DISCONNECT) || (bytes != 4))
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardDisconnect: error, bad code"));
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
status = GET_UINT32(msg, 0);
|
||||||
|
LLOGLN(10, ("SCardDisconnect: got status 0x%8.8x", status));
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -534,7 +564,7 @@ SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
|
|||||||
pthread_mutex_lock(&g_mutex);
|
pthread_mutex_lock(&g_mutex);
|
||||||
SET_UINT32(msg, 0, hCard);
|
SET_UINT32(msg, 0, hCard);
|
||||||
SET_UINT32(msg, 4, dwDisposition);
|
SET_UINT32(msg, 4, dwDisposition);
|
||||||
if (send_message(SCARD_BEGIN_TRANSACTION, msg, 8) != 0)
|
if (send_message(SCARD_END_TRANSACTION, msg, 8) != 0)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardEndTransaction: error, send_message"));
|
LLOGLN(0, ("SCardEndTransaction: error, send_message"));
|
||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
@ -547,7 +577,7 @@ SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
|
|||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
if ((code != SCARD_BEGIN_TRANSACTION) || (bytes != 4))
|
if ((code != SCARD_END_TRANSACTION) || (bytes != 4))
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardEndTransaction: error, bad code"));
|
LLOGLN(0, ("SCardEndTransaction: error, bad code"));
|
||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
@ -674,6 +704,12 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
|
|||||||
DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
|
DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
|
||||||
LPDWORD lpBytesReturned)
|
LPDWORD lpBytesReturned)
|
||||||
{
|
{
|
||||||
|
char *msg;
|
||||||
|
int bytes;
|
||||||
|
int code;
|
||||||
|
int offset;
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
LLOGLN(0, ("SCardControl:"));
|
LLOGLN(0, ("SCardControl:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
@ -683,9 +719,50 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
|
|||||||
LLOGLN(0, ("SCardControl: dwControlCode %d", dwControlCode));
|
LLOGLN(0, ("SCardControl: dwControlCode %d", dwControlCode));
|
||||||
LLOGLN(0, ("SCardControl: cbSendLength %d", cbSendLength));
|
LLOGLN(0, ("SCardControl: cbSendLength %d", cbSendLength));
|
||||||
LLOGLN(0, ("SCardControl: cbRecvLength %d", cbRecvLength));
|
LLOGLN(0, ("SCardControl: cbRecvLength %d", cbRecvLength));
|
||||||
|
msg = (char *) malloc(8192);
|
||||||
|
offset = 0;
|
||||||
|
SET_UINT32(msg, offset, hCard);
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, dwControlCode);
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, cbSendLength);
|
||||||
|
offset += 4;
|
||||||
|
memcpy(msg + offset, pbSendBuffer, cbSendLength);
|
||||||
|
offset += cbSendLength;
|
||||||
|
SET_UINT32(msg, offset, cbRecvLength);
|
||||||
|
offset += 4;
|
||||||
pthread_mutex_lock(&g_mutex);
|
pthread_mutex_lock(&g_mutex);
|
||||||
|
if (send_message(SCARD_CONTROL, msg, offset) != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardControl: error, send_message"));
|
||||||
|
free(msg);
|
||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
return SCARD_S_SUCCESS;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
bytes = 8192;
|
||||||
|
if (get_message(&code, msg, &bytes) != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardControl: error, get_message"));
|
||||||
|
free(msg);
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
if (code != SCARD_CONTROL)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardControl: error, bad code"));
|
||||||
|
free(msg);
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
offset = 0;
|
||||||
|
*lpBytesReturned = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
memcpy(pbRecvBuffer, msg + offset, *lpBytesReturned);
|
||||||
|
offset += *lpBytesReturned;
|
||||||
|
status = GET_UINT32(msg, offset);
|
||||||
|
free(msg);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -700,6 +777,7 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
|
|||||||
int code;
|
int code;
|
||||||
int offset;
|
int offset;
|
||||||
int status;
|
int status;
|
||||||
|
int extra_len;
|
||||||
|
|
||||||
LLOGLN(0, ("SCardTransmit:"));
|
LLOGLN(0, ("SCardTransmit:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
@ -708,19 +786,55 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
|
|||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
LLOGLN(0, ("SCardTransmit: cbSendLength %d", cbSendLength));
|
LLOGLN(0, ("SCardTransmit: cbSendLength %d", cbSendLength));
|
||||||
|
LLOGLN(0, ("SCardTransmit: pioRecvPci %p", pioRecvPci));
|
||||||
|
if (pioRecvPci != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardTransmit: pioRecvPci->dwProtocol %d",
|
||||||
|
(int)pioRecvPci->dwProtocol));
|
||||||
|
LLOGLN(0, ("SCardTransmit: pioRecvPci->cbPciLength %d",
|
||||||
|
(int)pioRecvPci->cbPciLength));
|
||||||
|
}
|
||||||
msg = (char *) malloc(8192);
|
msg = (char *) malloc(8192);
|
||||||
SET_UINT32(msg, 0, hCard);
|
offset = 0;
|
||||||
SET_UINT32(msg, 4, pioSendPci->dwProtocol);
|
SET_UINT32(msg, offset, hCard);
|
||||||
SET_UINT32(msg, 8, pioSendPci->cbPciLength);
|
offset += 4;
|
||||||
SET_UINT32(msg, 12, cbSendLength);
|
SET_UINT32(msg, offset, pioSendPci->dwProtocol);
|
||||||
offset = 16;
|
offset += 4;
|
||||||
memcpy(msg + 16, pbSendBuffer, cbSendLength);
|
SET_UINT32(msg, offset, pioSendPci->cbPciLength);
|
||||||
|
offset += 4;
|
||||||
|
extra_len = pioSendPci->cbPciLength - 8;
|
||||||
|
SET_UINT32(msg, offset, extra_len);
|
||||||
|
offset += 4;
|
||||||
|
memcpy(msg + offset, pioSendPci + 1, extra_len);
|
||||||
|
offset += extra_len;
|
||||||
|
SET_UINT32(msg, offset, cbSendLength);
|
||||||
|
offset += 4;
|
||||||
|
memcpy(msg + offset, pbSendBuffer, cbSendLength);
|
||||||
offset += cbSendLength;
|
offset += cbSendLength;
|
||||||
|
if ((pioRecvPci == 0) || (pioRecvPci->cbPciLength < 8))
|
||||||
|
{
|
||||||
|
SET_UINT32(msg, offset, 0); /* dwProtocol */
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, 0); /* cbPciLength */
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, 0); /* extra_len */
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SET_UINT32(msg, offset, pioRecvPci->dwProtocol);
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, pioRecvPci->cbPciLength);
|
||||||
|
offset += 4;
|
||||||
|
extra_len = pioRecvPci->cbPciLength - 8;
|
||||||
|
SET_UINT32(msg, offset, extra_len);
|
||||||
|
offset += 4;
|
||||||
|
memcpy(msg + offset, pioRecvPci + 1, extra_len);
|
||||||
|
offset += extra_len;
|
||||||
|
}
|
||||||
SET_UINT32(msg, offset, *pcbRecvLength);
|
SET_UINT32(msg, offset, *pcbRecvLength);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
pthread_mutex_lock(&g_mutex);
|
pthread_mutex_lock(&g_mutex);
|
||||||
|
|
||||||
if (send_message(SCARD_TRANSMIT, msg, offset) != 0)
|
if (send_message(SCARD_TRANSMIT, msg, offset) != 0)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardTransmit: error, send_message"));
|
LLOGLN(0, ("SCardTransmit: error, send_message"));
|
||||||
@ -743,9 +857,33 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
|
|||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
return SCARD_S_SUCCESS;
|
offset = 0;
|
||||||
|
if (pioRecvPci == 0)
|
||||||
|
{
|
||||||
|
offset += 8;
|
||||||
|
extra_len = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
offset += extra_len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pioRecvPci->dwProtocol = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
pioRecvPci->cbPciLength = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
extra_len = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
offset += extra_len;
|
||||||
|
}
|
||||||
|
*pcbRecvLength = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
LLOGLN(0, ("SCardTransmit: cbRecvLength %d", *pcbRecvLength));
|
||||||
|
memcpy(pbRecvBuffer, msg + offset, *pcbRecvLength);
|
||||||
|
offset += *pcbRecvLength;
|
||||||
|
status = GET_UINT32(msg, offset);
|
||||||
|
free(msg);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -182,13 +182,17 @@ static void APP_CC scard_send_EndTransaction(IRP* irp, tui32 sc_handle,
|
|||||||
static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle);
|
static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle);
|
||||||
|
|
||||||
static void APP_CC scard_send_Disconnect(IRP* irp, tui32 context,
|
static void APP_CC scard_send_Disconnect(IRP* irp, tui32 context,
|
||||||
tui32 sc_handle);
|
tui32 sc_handle, int dwDisposition);
|
||||||
|
|
||||||
static int APP_CC scard_send_Transmit(IRP* irp, tui32 sc_handle,
|
static int APP_CC scard_send_Transmit(IRP* irp, tui32 sc_handle,
|
||||||
READER_STATE* rs);
|
char *send_data, int send_bytes,
|
||||||
|
int recv_bytes,
|
||||||
|
struct xrdp_scard_io_request *send_ior,
|
||||||
|
struct xrdp_scard_io_request *recv_ior);
|
||||||
|
|
||||||
static int APP_CC scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle,
|
static int APP_CC scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle,
|
||||||
READER_STATE* rs);
|
char *send_data, int send_bytes,
|
||||||
|
int recv_bytes, int control_code);
|
||||||
|
|
||||||
static int APP_CC scard_send_Cancel(IRP* irp, tui32 context);
|
static int APP_CC scard_send_Cancel(IRP* irp, tui32 context);
|
||||||
|
|
||||||
@ -639,7 +643,8 @@ scard_send_status(struct trans *con, int wide, tui32 sc_handle)
|
|||||||
* @param sc_handle handle to smartcard
|
* @param sc_handle handle to smartcard
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int APP_CC
|
int APP_CC
|
||||||
scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle)
|
scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle,
|
||||||
|
int dwDisposition)
|
||||||
{
|
{
|
||||||
IRP *irp;
|
IRP *irp;
|
||||||
|
|
||||||
@ -657,7 +662,7 @@ scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle)
|
|||||||
irp->user_data = con;
|
irp->user_data = con;
|
||||||
|
|
||||||
/* send IRP to client */
|
/* send IRP to client */
|
||||||
scard_send_Disconnect(irp, context, sc_handle);
|
scard_send_Disconnect(irp, context, sc_handle, dwDisposition);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -667,7 +672,10 @@ scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle)
|
|||||||
* associated with a valid context.
|
* associated with a valid context.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int APP_CC
|
int APP_CC
|
||||||
scard_send_transmit(struct trans *con, tui32 sc_handle, READER_STATE* rs)
|
scard_send_transmit(struct trans *con, tui32 sc_handle,
|
||||||
|
char *send_data, int send_bytes, int recv_bytes,
|
||||||
|
struct xrdp_scard_io_request *send_ior,
|
||||||
|
struct xrdp_scard_io_request *recv_ior)
|
||||||
{
|
{
|
||||||
IRP *irp;
|
IRP *irp;
|
||||||
|
|
||||||
@ -685,7 +693,8 @@ scard_send_transmit(struct trans *con, tui32 sc_handle, READER_STATE* rs)
|
|||||||
irp->user_data = con;
|
irp->user_data = con;
|
||||||
|
|
||||||
/* send IRP to client */
|
/* send IRP to client */
|
||||||
scard_send_Transmit(irp, sc_handle, rs);
|
scard_send_Transmit(irp, sc_handle, send_data, send_bytes, recv_bytes,
|
||||||
|
send_ior, recv_ior);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -695,7 +704,8 @@ scard_send_transmit(struct trans *con, tui32 sc_handle, READER_STATE* rs)
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int APP_CC
|
int APP_CC
|
||||||
scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
|
scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
|
||||||
READER_STATE* rs)
|
char *send_data, int send_bytes,
|
||||||
|
int recv_bytes, int control_code)
|
||||||
{
|
{
|
||||||
IRP *irp;
|
IRP *irp;
|
||||||
|
|
||||||
@ -713,7 +723,8 @@ scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
|
|||||||
irp->user_data = con;
|
irp->user_data = con;
|
||||||
|
|
||||||
/* send IRP to client */
|
/* send IRP to client */
|
||||||
scard_send_Control(irp, context, sc_handle, rs);
|
scard_send_Control(irp, context, sc_handle, send_data,
|
||||||
|
send_bytes, recv_bytes, control_code);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1594,7 +1605,8 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle)
|
|||||||
* @param sc_handle handle to smartcard
|
* @param sc_handle handle to smartcard
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void APP_CC
|
static void APP_CC
|
||||||
scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle)
|
scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
|
||||||
|
int dwDisposition)
|
||||||
{
|
{
|
||||||
/* see [MS-RDPESC] 3.1.4.30 */
|
/* see [MS-RDPESC] 3.1.4.30 */
|
||||||
|
|
||||||
@ -1627,7 +1639,7 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
xstream_seek(s, 24);
|
xstream_seek(s, 24);
|
||||||
xstream_wr_u32_le(s, SCARD_RESET_CARD);
|
xstream_wr_u32_le(s, dwDisposition);
|
||||||
|
|
||||||
/* insert context */
|
/* insert context */
|
||||||
xstream_wr_u32_le(s, 4);
|
xstream_wr_u32_le(s, 4);
|
||||||
@ -1653,13 +1665,17 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle)
|
|||||||
* associated with a valid context.
|
* associated with a valid context.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static int APP_CC
|
static int APP_CC
|
||||||
scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data,
|
||||||
|
int send_bytes, int recv_bytes,
|
||||||
|
struct xrdp_scard_io_request *send_ior,
|
||||||
|
struct xrdp_scard_io_request *recv_ior)
|
||||||
{
|
{
|
||||||
/* see [MS-RDPESC] 2.2.2.19 */
|
/* see [MS-RDPESC] 2.2.2.19 */
|
||||||
|
|
||||||
SMARTCARD* sc;
|
SMARTCARD* sc;
|
||||||
struct stream* s;
|
struct stream* s;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
int val;
|
||||||
|
|
||||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||||
{
|
{
|
||||||
@ -1670,6 +1686,12 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
|||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_TRANSMIT)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_TRANSMIT)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
log_debug("send_bytes %d recv_bytes %d send dwProtocol %d cbPciLength %d "
|
||||||
|
"extra_bytes %d recv dwProtocol %d cbPciLength %d", send_bytes,
|
||||||
|
recv_bytes, send_ior->dwProtocol, send_ior->cbPciLength,
|
||||||
|
send_ior->extra_bytes, recv_ior->dwProtocol, recv_ior->cbPciLength,
|
||||||
|
recv_ior->extra_bytes);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
*
|
*
|
||||||
@ -1695,21 +1717,48 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
xstream_seek(s, 12);
|
xstream_seek(s, 12);
|
||||||
xstream_wr_u32_le(s, rs->map0);
|
xstream_wr_u32_le(s, 0); // map0
|
||||||
xstream_seek(s, 4);
|
xstream_seek(s, 4);
|
||||||
xstream_wr_u32_le(s, rs->map1);
|
xstream_wr_u32_le(s, 0); // map1
|
||||||
xstream_wr_u32_le(s, rs->dwProtocol);
|
xstream_wr_u32_le(s, send_ior->dwProtocol);
|
||||||
xstream_wr_u32_le(s, rs->cbPciLength);
|
xstream_wr_u32_le(s, send_ior->cbPciLength);
|
||||||
xstream_wr_u32_le(s, rs->map2);
|
val = send_ior->extra_bytes > 0 ? 1 : 0;
|
||||||
xstream_wr_u32_le(s, rs->cbSendLength);
|
xstream_wr_u32_le(s, val); // map2
|
||||||
xstream_wr_u32_le(s, rs->map3);
|
xstream_wr_u32_le(s, send_bytes);
|
||||||
xstream_wr_u32_le(s, rs->map4);
|
val = send_bytes > 0 ? 1 : 0;
|
||||||
xstream_wr_u32_le(s, rs->map5);
|
xstream_wr_u32_le(s, val); // map3
|
||||||
xstream_wr_u32_le(s, rs->map6);
|
val = recv_ior->cbPciLength > 0 ? 1 : 0;
|
||||||
xstream_wr_u32_le(s, rs->cbRecvLength);
|
xstream_wr_u32_le(s, val); // map 4
|
||||||
|
xstream_wr_u32_le(s, 0); // map5
|
||||||
|
xstream_wr_u32_le(s, recv_bytes);
|
||||||
xstream_wr_u32_le(s, 4);
|
xstream_wr_u32_le(s, 4);
|
||||||
xstream_wr_u32_le(s, sc_handle);
|
xstream_wr_u32_le(s, sc_handle);
|
||||||
|
|
||||||
|
if (send_ior->extra_bytes > 0)
|
||||||
|
{
|
||||||
|
xstream_wr_u32_le(s, send_ior->extra_bytes);
|
||||||
|
out_uint8a(s, send_ior->extra_data, send_ior->extra_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (send_bytes > 0)
|
||||||
|
{
|
||||||
|
xstream_wr_u32_le(s, send_bytes);
|
||||||
|
out_uint8a(s, send_data, send_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recv_ior->cbPciLength > 0)
|
||||||
|
{
|
||||||
|
xstream_wr_u32_le(s, recv_ior->dwProtocol);
|
||||||
|
xstream_wr_u32_le(s, recv_ior->cbPciLength);
|
||||||
|
val = recv_ior->extra_bytes > 0 ? 1 : 0;
|
||||||
|
xstream_wr_u32_le(s, val);
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
xstream_wr_u32_le(s, recv_ior->extra_bytes);
|
||||||
|
out_uint8a(s, recv_ior->extra_data, recv_ior->extra_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* get stream len */
|
/* get stream len */
|
||||||
bytes = xstream_len(s);
|
bytes = xstream_len(s);
|
||||||
|
|
||||||
@ -1725,13 +1774,15 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
|||||||
* Communicate directly with the smart card reader
|
* Communicate directly with the smart card reader
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static int APP_CC
|
static int APP_CC
|
||||||
scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
|
scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data,
|
||||||
|
int send_bytes, int recv_bytes, int control_code)
|
||||||
{
|
{
|
||||||
/* see [MS-RDPESC] 2.2.2.19 */
|
/* see [MS-RDPESC] 2.2.2.19 */
|
||||||
|
|
||||||
SMARTCARD* sc;
|
SMARTCARD* sc;
|
||||||
struct stream* s;
|
struct stream* s;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
int val;
|
||||||
|
|
||||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||||
{
|
{
|
||||||
@ -1765,19 +1816,30 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
xstream_seek(s, 12);
|
xstream_seek(s, 12);
|
||||||
xstream_wr_u32_le(s, rs->map0);
|
xstream_wr_u32_le(s, 0); // map0
|
||||||
|
xstream_seek(s, 4);
|
||||||
|
xstream_wr_u32_le(s, 0); // map1
|
||||||
|
|
||||||
|
xstream_wr_u32_le(s, control_code);
|
||||||
|
|
||||||
|
xstream_wr_u32_le(s, send_bytes);
|
||||||
|
|
||||||
|
val = send_bytes > 0 ? 1 : 0;
|
||||||
|
xstream_wr_u32_le(s, val); // map2
|
||||||
|
|
||||||
xstream_wr_u32_le(s, 0);
|
xstream_wr_u32_le(s, 0);
|
||||||
xstream_wr_u32_le(s, rs->map1);
|
xstream_wr_u32_le(s, recv_bytes);
|
||||||
xstream_wr_u32_le(s, rs->dwControlCode);
|
|
||||||
xstream_wr_u32_le(s, rs->cbRecvLength);
|
|
||||||
xstream_wr_u32_le(s, rs->map2);
|
|
||||||
xstream_wr_u32_le(s, 0);
|
|
||||||
xstream_wr_u32_le(s, rs->cbOutBufferSize);
|
|
||||||
xstream_wr_u32_le(s, 4);
|
xstream_wr_u32_le(s, 4);
|
||||||
xstream_wr_u32_le(s, context);
|
xstream_wr_u32_le(s, context);
|
||||||
xstream_wr_u32_le(s, 4);
|
xstream_wr_u32_le(s, 4);
|
||||||
xstream_wr_u32_le(s, sc_handle);
|
xstream_wr_u32_le(s, sc_handle);
|
||||||
|
|
||||||
|
if (send_bytes > 0)
|
||||||
|
{
|
||||||
|
xstream_wr_u32_le(s, send_bytes);
|
||||||
|
out_uint8a(s, send_data, send_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
/* get stream len */
|
/* get stream len */
|
||||||
bytes = xstream_len(s);
|
bytes = xstream_len(s);
|
||||||
|
|
||||||
@ -2170,6 +2232,7 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
|
|||||||
tui32 IoStatus)
|
tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2190,6 +2253,10 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
|
|||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
xstream_rd_u32_le(s, len);
|
||||||
|
|
||||||
|
con = (struct trans *) (irp->user_data);
|
||||||
|
scard_function_end_transaction_return(con, s, len);
|
||||||
|
devredir_irp_delete(irp);
|
||||||
|
|
||||||
log_debug("leaving");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2234,6 +2301,7 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
|
|||||||
tui32 IoStatus)
|
tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2254,6 +2322,10 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
|
|||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
xstream_rd_u32_le(s, len);
|
||||||
|
|
||||||
|
con = (struct trans *) (irp->user_data);
|
||||||
|
scard_function_disconnect_return(con, s, len);
|
||||||
|
devredir_irp_delete(irp);
|
||||||
|
|
||||||
log_debug("leaving");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2265,6 +2337,7 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
tui32 CompletionId, tui32 IoStatus)
|
tui32 CompletionId, tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2285,6 +2358,10 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
xstream_rd_u32_le(s, len);
|
||||||
|
|
||||||
|
con = (struct trans *) (irp->user_data);
|
||||||
|
scard_function_transmit_return(con, s, len);
|
||||||
|
devredir_irp_delete(irp);
|
||||||
|
|
||||||
log_debug("leaving");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2296,6 +2373,7 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
tui32 CompletionId,tui32 IoStatus)
|
tui32 CompletionId,tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2316,6 +2394,10 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
xstream_rd_u32_le(s, len);
|
||||||
|
|
||||||
|
con = (struct trans *) (irp->user_data);
|
||||||
|
scard_function_control_return(con, s, len);
|
||||||
|
devredir_irp_delete(irp);
|
||||||
|
|
||||||
log_debug("leaving");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,14 @@
|
|||||||
#define SCARD_RESET_CARD 0x00000001 /* reset smart card */
|
#define SCARD_RESET_CARD 0x00000001 /* reset smart card */
|
||||||
#define SCARD_UNPOWER_CARD 0x00000002 /* turn off and reset card */
|
#define SCARD_UNPOWER_CARD 0x00000002 /* turn off and reset card */
|
||||||
|
|
||||||
|
struct xrdp_scard_io_request
|
||||||
|
{
|
||||||
|
tui32 dwProtocol;
|
||||||
|
tui32 cbPciLength;
|
||||||
|
int extra_bytes;
|
||||||
|
char *extra_data;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct reader_state
|
typedef struct reader_state
|
||||||
{
|
{
|
||||||
char reader_name[128];
|
char reader_name[128];
|
||||||
@ -121,13 +129,17 @@ 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_end_transaction(struct trans *con, tui32 sc_handle,
|
||||||
tui32 dwDisposition);
|
tui32 dwDisposition);
|
||||||
int APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle);
|
int APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle);
|
||||||
int APP_CC scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle);
|
int APP_CC scard_send_disconnect(struct trans *con, tui32 context,
|
||||||
|
tui32 sc_handle, int dwDisposition);
|
||||||
|
|
||||||
int APP_CC scard_send_transmit(struct trans *con, tui32 sc_handle,
|
int APP_CC scard_send_transmit(struct trans *con, tui32 sc_handle,
|
||||||
READER_STATE* rs);
|
char *send_data, int send_bytes, int recv_bytes,
|
||||||
|
struct xrdp_scard_io_request *send_ior,
|
||||||
|
struct xrdp_scard_io_request *recv_ior);
|
||||||
|
|
||||||
int APP_CC scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
|
int APP_CC scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
|
||||||
READER_STATE* rs);
|
char *send_data, int send_bytes,
|
||||||
|
int recv_bytes, int control_code);
|
||||||
|
|
||||||
int APP_CC scard_send_cancel(struct trans *con, tui32 context);
|
int APP_CC scard_send_cancel(struct trans *con, tui32 context);
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
#define XRDP_PCSC_STATE_GOT_ET (1 << 6) /* end transaction */
|
#define XRDP_PCSC_STATE_GOT_ET (1 << 6) /* end transaction */
|
||||||
#define XRDP_PCSC_STATE_GOT_TR (1 << 7) /* transmit */
|
#define XRDP_PCSC_STATE_GOT_TR (1 << 7) /* transmit */
|
||||||
#define XRDP_PCSC_STATE_GOT_CO (1 << 8) /* control */
|
#define XRDP_PCSC_STATE_GOT_CO (1 << 8) /* control */
|
||||||
|
#define XRDP_PCSC_STATE_GOT_D (1 << 9) /* disconnect */
|
||||||
|
|
||||||
/* TODO: put this in con */
|
/* TODO: put this in con */
|
||||||
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
|
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
|
||||||
@ -329,7 +330,6 @@ int APP_CC
|
|||||||
scard_process_connect(struct trans *con, struct stream *in_s)
|
scard_process_connect(struct trans *con, struct stream *in_s)
|
||||||
{
|
{
|
||||||
int hContext;
|
int hContext;
|
||||||
char szReader[100];
|
|
||||||
READER_STATE rs;
|
READER_STATE rs;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_connect:"));
|
LLOGLN(0, ("scard_process_connect:"));
|
||||||
@ -341,11 +341,11 @@ scard_process_connect(struct trans *con, struct stream *in_s)
|
|||||||
g_memset(&rs, 0, sizeof(rs));
|
g_memset(&rs, 0, sizeof(rs));
|
||||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_C;
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_C;
|
||||||
in_uint32_le(in_s, hContext);
|
in_uint32_le(in_s, hContext);
|
||||||
in_uint8a(in_s, szReader, 100);
|
in_uint8a(in_s, rs.reader_name, 100);
|
||||||
in_uint32_le(in_s, rs.dwShareMode);
|
in_uint32_le(in_s, rs.dwShareMode);
|
||||||
in_uint32_le(in_s, rs.dwPreferredProtocols);
|
in_uint32_le(in_s, rs.dwPreferredProtocols);
|
||||||
LLOGLN(0, ("scard_process_connect: dwShareMode 0x%8.8x "
|
LLOGLN(0, ("scard_process_connect: rs.reader_name %s dwShareMode 0x%8.8x "
|
||||||
"dwPreferredProtocols 0x%8.8x", rs.dwShareMode,
|
"dwPreferredProtocols 0x%8.8x", rs.reader_name, rs.dwShareMode,
|
||||||
rs.dwPreferredProtocols));
|
rs.dwPreferredProtocols));
|
||||||
scard_send_connect(con, hContext, 1, &rs);
|
scard_send_connect(con, hContext, 1, &rs);
|
||||||
return 0;
|
return 0;
|
||||||
@ -371,8 +371,9 @@ scard_function_connect_return(struct trans *con,
|
|||||||
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_C;
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_C;
|
||||||
in_uint8s(in_s, 36);
|
in_uint8s(in_s, 36);
|
||||||
in_uint32_le(in_s, dwActiveProtocol);
|
in_uint32_le(in_s, dwActiveProtocol);
|
||||||
in_uint8s(in_s, 36);
|
in_uint8s(in_s, 4);
|
||||||
in_uint32_le(in_s, hCard);
|
in_uint32_le(in_s, hCard);
|
||||||
|
LLOGLN(0, ("scard_function_connect_return: hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol));
|
||||||
out_s = trans_get_out_s(con, 8192);
|
out_s = trans_get_out_s(con, 8192);
|
||||||
s_push_layer(out_s, iso_hdr, 8);
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
out_uint32_le(out_s, hCard);
|
out_uint32_le(out_s, hCard);
|
||||||
@ -386,6 +387,66 @@ scard_function_connect_return(struct trans *con,
|
|||||||
return trans_force_write(con);
|
return trans_force_write(con);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* returns error */
|
||||||
|
int APP_CC
|
||||||
|
scard_process_disconnect(struct trans *con, struct stream *in_s)
|
||||||
|
{
|
||||||
|
int hContext;
|
||||||
|
int hCard;
|
||||||
|
int dwDisposition;
|
||||||
|
|
||||||
|
LLOGLN(0, ("scard_process_disconnect:"));
|
||||||
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_D)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_process_disconnect: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_D;
|
||||||
|
in_uint32_le(in_s, hCard);
|
||||||
|
in_uint32_le(in_s, dwDisposition);
|
||||||
|
|
||||||
|
hContext = 1;
|
||||||
|
|
||||||
|
scard_send_disconnect(con, hContext, hCard, dwDisposition);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
int APP_CC
|
||||||
|
scard_function_disconnect_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_D) == 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_function_connect_return: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_D;
|
||||||
|
in_uint8s(in_s, 36);
|
||||||
|
in_uint32_le(in_s, dwActiveProtocol);
|
||||||
|
in_uint8s(in_s, 4);
|
||||||
|
in_uint32_le(in_s, hCard);
|
||||||
|
LLOGLN(0, ("scard_function_connect_return: hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol));
|
||||||
|
out_s = trans_get_out_s(con, 8192);
|
||||||
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
|
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, 0x06); /* SCARD_DISCONNECT 0x06 */
|
||||||
|
return trans_force_write(con);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* returns error */
|
/* returns error */
|
||||||
int APP_CC
|
int APP_CC
|
||||||
@ -492,7 +553,11 @@ int APP_CC
|
|||||||
scard_process_transmit(struct trans *con, struct stream *in_s)
|
scard_process_transmit(struct trans *con, struct stream *in_s)
|
||||||
{
|
{
|
||||||
int hCard;
|
int hCard;
|
||||||
READER_STATE rs;
|
int recv_bytes;
|
||||||
|
int send_bytes;
|
||||||
|
char *send_data;
|
||||||
|
struct xrdp_scard_io_request send_ior;
|
||||||
|
struct xrdp_scard_io_request recv_ior;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_transmit:"));
|
LLOGLN(0, ("scard_process_transmit:"));
|
||||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR)
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR)
|
||||||
@ -502,21 +567,26 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
|
|||||||
}
|
}
|
||||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_TR;
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_TR;
|
||||||
LLOGLN(0, ("scard_process_transmit:"));
|
LLOGLN(0, ("scard_process_transmit:"));
|
||||||
|
|
||||||
// todo
|
|
||||||
g_memset(&rs, 0, sizeof(rs));
|
|
||||||
|
|
||||||
in_uint32_le(in_s, hCard);
|
in_uint32_le(in_s, hCard);
|
||||||
in_uint32_le(in_s, rs.dwProtocol);
|
in_uint32_le(in_s, send_ior.dwProtocol);
|
||||||
in_uint32_le(in_s, rs.cbPciLength);
|
in_uint32_le(in_s, send_ior.cbPciLength);
|
||||||
in_uint32_le(in_s, rs.cbSendLength);
|
in_uint32_le(in_s, send_ior.extra_bytes);
|
||||||
LLOGLN(0, ("scard_process_transmit: dwProtocol %d cbPciLength %d "
|
in_uint8p(in_s, send_ior.extra_data, send_ior.extra_bytes);
|
||||||
"cbSendLength %d", rs.dwProtocol, rs.cbPciLength, rs.cbSendLength));
|
in_uint32_le(in_s, send_bytes);
|
||||||
g_hexdump(in_s->p, rs.cbSendLength);
|
in_uint8p(in_s, send_data, send_bytes);
|
||||||
in_uint8s(in_s, rs.cbSendLength);
|
in_uint32_le(in_s, recv_ior.dwProtocol);
|
||||||
in_uint32_le(in_s, rs.cbRecvLength);
|
in_uint32_le(in_s, recv_ior.cbPciLength);
|
||||||
LLOGLN(0, ("scard_process_transmit: cbRecvLength %d", rs.cbRecvLength));
|
in_uint32_le(in_s, recv_ior.extra_bytes);
|
||||||
|
in_uint8p(in_s, recv_ior.extra_data, recv_ior.extra_bytes);
|
||||||
|
in_uint32_le(in_s, recv_bytes);
|
||||||
|
LLOGLN(0, ("scard_process_transmit: send dwProtocol %d cbPciLength %d "
|
||||||
|
"recv dwProtocol %d cbPciLength %d send_bytes %d ",
|
||||||
|
send_ior.dwProtocol, send_ior.cbPciLength, recv_ior.dwProtocol,
|
||||||
|
recv_ior.cbPciLength, send_bytes));
|
||||||
|
g_hexdump(in_s->p, send_bytes);
|
||||||
|
LLOGLN(0, ("scard_process_transmit: recv_bytes %d", recv_bytes));
|
||||||
|
scard_send_transmit(con, hCard, send_data, send_bytes, recv_bytes,
|
||||||
|
&send_ior, &recv_ior);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,7 +599,13 @@ scard_function_transmit_return(struct trans *con,
|
|||||||
{
|
{
|
||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
int val;
|
||||||
|
int got_recv_pci;
|
||||||
|
int cbRecvLength;
|
||||||
|
struct xrdp_scard_io_request recv_ior;
|
||||||
|
char *recvBuf;
|
||||||
|
|
||||||
|
LLOGLN(0, ("scard_function_transmit_return:"));
|
||||||
g_hexdump(in_s->p, len);
|
g_hexdump(in_s->p, len);
|
||||||
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR) == 0)
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR) == 0)
|
||||||
{
|
{
|
||||||
@ -538,9 +614,41 @@ scard_function_transmit_return(struct trans *con,
|
|||||||
}
|
}
|
||||||
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_TR;
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_TR;
|
||||||
|
|
||||||
// todo
|
in_uint8s(in_s, 20);
|
||||||
|
in_uint32_le(in_s, val);
|
||||||
return 0;
|
g_memset(&recv_ior, 0, sizeof(recv_ior));
|
||||||
|
got_recv_pci = 0;
|
||||||
|
if (val != 0)
|
||||||
|
{
|
||||||
|
/* pioRecvPci */
|
||||||
|
got_recv_pci = 1;
|
||||||
|
LLOGLN(0, ("scard_function_transmit_return: pioRecvPci not zero!"));
|
||||||
|
}
|
||||||
|
in_uint8s(in_s, 4);
|
||||||
|
in_uint32_le(in_s, val);
|
||||||
|
cbRecvLength = 0;
|
||||||
|
recvBuf = 0;
|
||||||
|
if (val != 0)
|
||||||
|
{
|
||||||
|
in_uint32_le(in_s, cbRecvLength);
|
||||||
|
in_uint8p(in_s, recvBuf, cbRecvLength);
|
||||||
|
}
|
||||||
|
LLOGLN(0, ("scard_function_transmit_return: cbRecvLength %d", cbRecvLength));
|
||||||
|
out_s = trans_get_out_s(con, 8192);
|
||||||
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
|
out_uint32_le(out_s, recv_ior.dwProtocol);
|
||||||
|
out_uint32_le(out_s, recv_ior.cbPciLength);
|
||||||
|
out_uint32_le(out_s, recv_ior.extra_bytes);
|
||||||
|
out_uint8a(out_s, recv_ior.extra_data, recv_ior.extra_bytes);
|
||||||
|
out_uint32_le(out_s, cbRecvLength);
|
||||||
|
out_uint8a(out_s, recvBuf, cbRecvLength);
|
||||||
|
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, 0x09); /* SCARD_TRANSMIT 0x09 */
|
||||||
|
return trans_force_write(con);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -548,6 +656,13 @@ scard_function_transmit_return(struct trans *con,
|
|||||||
int APP_CC
|
int APP_CC
|
||||||
scard_process_control(struct trans *con, struct stream *in_s)
|
scard_process_control(struct trans *con, struct stream *in_s)
|
||||||
{
|
{
|
||||||
|
tui32 context;
|
||||||
|
int hCard;
|
||||||
|
int send_bytes;
|
||||||
|
int recv_bytes;
|
||||||
|
int control_code;
|
||||||
|
char *send_data;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_control:"));
|
LLOGLN(0, ("scard_process_control:"));
|
||||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO)
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO)
|
||||||
{
|
{
|
||||||
@ -557,7 +672,16 @@ scard_process_control(struct trans *con, struct stream *in_s)
|
|||||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_CO;
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_CO;
|
||||||
LLOGLN(0, ("scard_process_control:"));
|
LLOGLN(0, ("scard_process_control:"));
|
||||||
|
|
||||||
// todo
|
in_uint32_le(in_s, hCard);
|
||||||
|
in_uint32_le(in_s, control_code);
|
||||||
|
in_uint32_le(in_s, send_bytes);
|
||||||
|
in_uint8p(in_s, send_data, send_bytes);
|
||||||
|
in_uint32_le(in_s, recv_bytes);
|
||||||
|
|
||||||
|
context = 1;
|
||||||
|
|
||||||
|
scard_send_control(con, context, hCard, send_data, send_bytes, recv_bytes,
|
||||||
|
control_code);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -571,6 +695,8 @@ scard_function_control_return(struct trans *con,
|
|||||||
{
|
{
|
||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
int cbRecvLength;
|
||||||
|
char *recvBuf;
|
||||||
|
|
||||||
g_hexdump(in_s->p, len);
|
g_hexdump(in_s->p, len);
|
||||||
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO) == 0)
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO) == 0)
|
||||||
@ -580,9 +706,22 @@ scard_function_control_return(struct trans *con,
|
|||||||
}
|
}
|
||||||
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_CO;
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_CO;
|
||||||
|
|
||||||
// todo
|
in_uint8s(in_s, 28);
|
||||||
|
in_uint32_le(in_s, cbRecvLength);
|
||||||
|
in_uint8p(in_s, recvBuf, cbRecvLength);
|
||||||
|
|
||||||
return 0;
|
LLOGLN(0, ("scard_function_control_return: cbRecvLength %d", cbRecvLength));
|
||||||
|
out_s = trans_get_out_s(con, 8192);
|
||||||
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
|
out_uint32_le(out_s, cbRecvLength);
|
||||||
|
out_uint8a(out_s, recvBuf, cbRecvLength);
|
||||||
|
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, 0x0A); /* SCARD_CONTROL 0x0A */
|
||||||
|
return trans_force_write(con);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -729,6 +868,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
|
|||||||
|
|
||||||
case 0x06: /* SCARD_DISCONNECT */
|
case 0x06: /* SCARD_DISCONNECT */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_DISCONNECT"));
|
LLOGLN(0, ("scard_process_msg: SCARD_DISCONNECT"));
|
||||||
|
rv = scard_process_disconnect(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x07: /* SCARD_BEGIN_TRANSACTION */
|
case 0x07: /* SCARD_BEGIN_TRANSACTION */
|
||||||
|
@ -38,6 +38,14 @@ int APP_CC scard_function_list_readers_return(struct trans *con,
|
|||||||
struct stream *in_s,
|
struct stream *in_s,
|
||||||
int len);
|
int len);
|
||||||
|
|
||||||
|
int APP_CC scard_function_transmit_return(struct trans *con,
|
||||||
|
struct stream *in_s,
|
||||||
|
int len);
|
||||||
|
|
||||||
|
int APP_CC scard_function_control_return(struct trans *con,
|
||||||
|
struct stream *in_s,
|
||||||
|
int len);
|
||||||
|
|
||||||
int APP_CC scard_function_get_status_change_return(struct trans *con,
|
int APP_CC scard_function_get_status_change_return(struct trans *con,
|
||||||
struct stream *in_s,
|
struct stream *in_s,
|
||||||
int len);
|
int len);
|
||||||
|
Loading…
Reference in New Issue
Block a user