summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Zakharov <uglym8@gmail.com>2018-04-27 12:03:06 +0300
committerGitHub <noreply@github.com>2018-04-27 12:03:06 +0300
commit0f9e410094fcb5d25433ffdd1dd34dcd8783f952 (patch)
tree0282c1bf000205f74a6608aa34e67fb257c1883e
parent567b1f74326c8ccacbeedc39f4833f543ace23c7 (diff)
parentb77d00ceba32da5db3d6232ff16cf280c0ad337b (diff)
downloadrdesktop-0f9e410094fcb5d25433ffdd1dd34dcd8783f952.zip
Merge pull request #258 from uglym8/sc_drop_refs
Fix scard logon
-rw-r--r--configure.ac4
-rw-r--r--proto.h1
-rw-r--r--rdpdr.c24
-rw-r--r--scard.c54
4 files changed, 55 insertions, 28 deletions
diff --git a/configure.ac b/configure.ac
index 6c9fe41..6ac9432 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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>
diff --git a/proto.h b/proto.h
index ac9242d..ca87d63 100644
--- a/proto.h
+++ b/proto.h
@@ -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
diff --git a/rdpdr.c b/rdpdr.c
index 65c92da..894f4a2 100644
--- a/rdpdr.c
+++ b/rdpdr.c
@@ -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;
diff --git a/scard.c b/scard.c
index 6622318..65297c9 100644
--- a/scard.c
+++ b/scard.c
@@ -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;
+}
+