summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2018-03-08 08:51:51 +0100
committerNIIBE Yutaka <gniibe@fsij.org>2018-03-08 08:51:51 +0100
commitf8b8b6aac2ca1cb34d7a346aee1d874e7650557b (patch)
tree6778d134663de5d7313cb8c6f0e43a7c1004531b
parentgpg: Fix build on Windows. (diff)
downloadgnupg2-f8b8b6aac2ca1cb34d7a346aee1d874e7650557b.tar.xz
gnupg2-f8b8b6aac2ca1cb34d7a346aee1d874e7650557b.zip
scd: Fix status check when using PC/SC.
* scd/apdu.c (struct reader_table_s): Add field of current_state. (new_reader_slot): Initialize current_state. (pcsc_get_status): Keep the status in READER_TABLE array. Return SW_HOST_NO_READER when PCSC_STATE_CHANGED. * scd/scdaemon.c (handle_connections): Silence a warning. -- To detect some change of card status, including suspend/resume possibly, SCardGetStatusChange should be used keeping the dwCurrentState field. This change could improve situation for suspend/resume with Yubikey on Windows. Even not, this is doing the Right Thing. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r--scd/apdu.c15
-rw-r--r--scd/scdaemon.c2
2 files changed, 14 insertions, 3 deletions
diff --git a/scd/apdu.c b/scd/apdu.c
index c50afbde2..6758e69e8 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -119,6 +119,7 @@ struct reader_table_s {
pcsc_dword_t modify_ioctl;
int pinmin;
int pinmax;
+ pcsc_dword_t current_state;
} pcsc;
#ifdef USE_G10CODE_RAPDU
struct {
@@ -453,6 +454,7 @@ new_reader_slot (void)
reader_table[reader].pcsc.modify_ioctl = 0;
reader_table[reader].pcsc.pinmin = -1;
reader_table[reader].pcsc.pinmax = -1;
+ reader_table[reader].pcsc.current_state = PCSC_STATE_UNAWARE;
return reader;
}
@@ -652,12 +654,12 @@ pcsc_get_status (int slot, unsigned int *status, int on_wire)
(void)on_wire;
memset (rdrstates, 0, sizeof *rdrstates);
rdrstates[0].reader = reader_table[slot].rdrname;
- rdrstates[0].current_state = PCSC_STATE_UNAWARE;
+ rdrstates[0].current_state = reader_table[slot].pcsc.current_state;
err = pcsc_get_status_change (reader_table[slot].pcsc.context,
0,
rdrstates, 1);
if (err == PCSC_E_TIMEOUT)
- err = 0; /* Timeout is no error error here. */
+ err = 0; /* Timeout is no error here. */
if (err)
{
log_error ("pcsc_get_status_change failed: %s (0x%lx)\n",
@@ -665,6 +667,9 @@ pcsc_get_status (int slot, unsigned int *status, int on_wire)
return pcsc_error_to_sw (err);
}
+ reader_table[slot].pcsc.current_state =
+ (rdrstates[0].event_state & ~PCSC_STATE_CHANGED);
+
/* log_debug */
/* ("pcsc_get_status_change: %s%s%s%s%s%s%s%s%s%s\n", */
/* (rdrstates[0].event_state & PCSC_STATE_IGNORE)? " ignore":"", */
@@ -701,7 +706,11 @@ pcsc_get_status (int slot, unsigned int *status, int on_wire)
*status |= APDU_CARD_USABLE;
#endif
- return 0;
+ if (!on_wire && (rdrstates[0].event_state & PCSC_STATE_CHANGED))
+ /* Event like sleep/resume occurs, which requires RESET. */
+ return SW_HOST_NO_READER;
+ else
+ return 0;
}
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index cebeea9d3..91b559925 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -1348,6 +1348,8 @@ handle_connections (int listen_fd)
FD_SET (pipe_fd[0], &read_fdset);
if (max_fd < pipe_fd[0])
max_fd = pipe_fd[0];
+#else
+ (void)max_fd;
#endif
#ifndef HAVE_W32_SYSTEM