Merge pull request #258 from uglym8/sc_drop_refs

Fix scard logon
This commit is contained in:
Alexander Zakharov 2018-04-27 12:03:06 +03:00 committed by GitHub
commit 0f9e410094
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 28 deletions

View File

@ -218,6 +218,10 @@ AS_IF([test "x$enable_smartcard" != "xno"], [
exit 1
fi
AC_MSG_CHECKING([for PCSC-lite >= 1.6.0 (PnP/Notifications support)])
PKG_CHECK_MODULES(PNP_NOTIFICATIONS, libpcsclite >= 1.6.0, [WITH_PNP_NOTIFICATIONS=1], [WITH_PNP_NOTIFICATIONS=0])
AC_DEFINE(WITH_PNP_NOTIFICATIONS)
AC_MSG_CHECKING([for old version of PCSC])
AC_TRY_LINK([
#include <stdlib.h>

View File

@ -360,6 +360,7 @@ void scard_unlock(int lock);
int scard_enum_devices(uint32 * id, char *optarg);
void scardSetInfo(uint32 epoch, uint32 device, uint32 id, uint32 bytes_out);
void scard_reset_state();
void scard_release_all_contexts(void);
/* *INDENT-OFF* */
#ifdef __cplusplus

24
rdpdr.c
View File

@ -879,6 +879,30 @@ rdpdr_process(STREAM s)
g_client_id = 0x815ed39d; /* IP address (use 127.0.0.1) 0x815ed39d */
g_epoch++;
#if WITH_SCARD
/*
* We need to release all SCARD contexts to end all
* current transactions and pending calls
*/
scard_release_all_contexts();
/*
* According to [MS-RDPEFS] 3.2.5.1.2:
*
* If this packet appears after a sequence of other packets,
* it is a signal that the server has reconnected to a new session
* and the whole sequence has been reset. The client MUST treat
* this packet as the beginning of a new sequence.
* The client MUST also cancel all outstanding requests and release
* previous references to all devices.
*
* If any problem arises in the future, please, pay attention to the
* "If this packet appears after a sequence of other packets" part
*
*/
#endif
rdpdr_send_client_announce_reply();
rdpdr_send_client_name_request();
break;

54
scard.c
View File

@ -4,6 +4,7 @@
Copyright (C) Alexi Volkov <alexi@myrealbox.com> 2006
Copyright 2010-2013 Pierre Ossman <ossman@cendio.se> for Cendio AB
Copyright 2011-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
Copyright 2015 Rostislav Kondratenko <r.kondratenk@wwpass.com>
Copyright 2017 Karl Mikaelsson <derfian@cendio.se> for Cendio AB
Copyright 2018 Alexander Zakharov <uglym8@gmail.com>
@ -683,8 +684,6 @@ TS_SCardEstablishContext(STREAM in, STREAM out)
MYPCSC_DWORD rv;
MYPCSC_SCARDCONTEXT myHContext;
SERVER_SCARDCONTEXT hContext;
char *readers = NULL;
DWORD readerCount = 1024;
hContext = 0;
@ -705,21 +704,6 @@ TS_SCardEstablishContext(STREAM in, STREAM out)
goto bail_out;
}
/* This is a workaround where windows application generally
behaves better with polling of smartcard subsystem
availability than were there are no readers available. */
rv = SCardListReaders(myHContext, NULL, readers, &readerCount);
if (rv != SCARD_S_SUCCESS)
{
logger(SmartCard, Debug,
"TS_SCardEstablishContext(), No readers connected, return no service to client.");
rv = SCARD_E_NO_SERVICE;
SCardReleaseContext(myHContext);
goto bail_out;
}
/* add context to list of handle and get server handle */
_scard_handle_list_add(myHContext);
hContext = _scard_handle_list_get_server_handle(myHContext);
@ -779,9 +763,6 @@ TS_SCardIsValidContext(STREAM in, STREAM out)
MYPCSC_DWORD rv;
SERVER_SCARDCONTEXT hContext;
MYPCSC_SCARDCONTEXT myHContext;
char *readers;
DWORD readerCount = 1024;
PMEM_HANDLE lcHandle = NULL;
in->p += 0x1C;
in_uint32_le(in, hContext);
@ -791,13 +772,7 @@ TS_SCardIsValidContext(STREAM in, STREAM out)
logger(SmartCard, Debug, "TS_SCardIsValidContext(), context: 0x%08x [0x%lx]",
(unsigned) hContext, myHContext);
/* There is no realization of SCardIsValidContext in PC/SC Lite so we call SCardListReaders */
readers = SC_xmalloc(&lcHandle, 1024);
if (!readers)
return SC_returnNoMemoryError(&lcHandle, in, out);
rv = SCardListReaders(myHContext, NULL, readers, &readerCount);
rv = SCardIsValidContext(myHContext);
if (rv)
{
@ -813,7 +788,6 @@ TS_SCardIsValidContext(STREAM in, STREAM out)
}
outForceAlignment(out, 8);
SC_xfreeallmemory(&lcHandle);
return rv;
}
@ -1231,8 +1205,10 @@ TS_SCardGetStatusChange(STREAM in, STREAM out, RD_BOOL wide)
inString(&lcHandle, in, (char **) &(cur->szReader),
dataLength, wide));
#if !WITH_PNP_NOTIFICATIONS
if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0)
cur->dwCurrentState |= SCARD_STATE_IGNORE;
#endif
}
logger(SmartCard, Debug,
@ -2752,3 +2728,25 @@ scard_reset_state()
queueFirst = queueLast = NULL;
}
void scard_release_all_contexts(void)
{
_scard_handle_list_t *item, *next;
item = g_scard_handle_list;
while (item)
{
/* Cancelling ScardGetStatusChange calls */
SCardCancel(item->handle);
/* releasing context to end all transactions on it */
SCardReleaseContext(item->handle);
next = item->next;
xfree(item);
item = next;
}
g_scard_handle_list = NULL;
}