diff options
Diffstat (limited to 'scd')
-rw-r--r-- | scd/app-openpgp.c | 11 | ||||
-rw-r--r-- | scd/command.c | 4 | ||||
-rw-r--r-- | scd/scdaemon.c | 39 |
3 files changed, 49 insertions, 5 deletions
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index fb869b2bf..54f04c612 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -348,7 +348,8 @@ get_cached_data (app_t app, int tag, err = iso7816_get_data (app->slot, exmode, tag, &p, &len); if (err) return err; - *result = p; + if (len) + *result = p; *resultlen = len; /* Check whether we should cache this object. */ @@ -370,7 +371,10 @@ get_cached_data (app_t app, int tag, c = xtrymalloc (sizeof *c + len); if (c) { - memcpy (c->data, p, len); + if (len) + memcpy (c->data, p, len); + else + xfree (p); c->length = len; c->tag = tag; c->next = app->app_local->cache; @@ -2068,7 +2072,8 @@ pin2hash_if_kdf (app_t app, int chvno, char *pinvalue, int *r_pinlen) size_t buflen; if (app->app_local->extcap.kdf_do - && (relptr = get_one_do (app, 0x00F9, &buffer, &buflen, NULL))) + && (relptr = get_one_do (app, 0x00F9, &buffer, &buflen, NULL)) + && buflen == 110 && (buffer[2] == 0x03)) { char *salt; unsigned long s2k_count; diff --git a/scd/command.c b/scd/command.c index 6bcbce4fc..701151894 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1848,7 +1848,8 @@ send_status_info (ctrl_t ctrl, const char *keyword, ...) p = buf; n = 0; - while ( (value = va_arg (arg_ptr, const unsigned char *)) ) + while ( (value = va_arg (arg_ptr, const unsigned char *)) + && n < DIM (buf)-2 ) { valuelen = va_arg (arg_ptr, size_t); if (!valuelen) @@ -1865,6 +1866,7 @@ send_status_info (ctrl_t ctrl, const char *keyword, ...) { sprintf (p, "%%%02X", *value); p += 3; + n += 2; } else if (*value == ' ') *p++ = '+'; diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 3ad265781..cebeea9d3 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -236,6 +236,10 @@ static HANDLE the_event; /* PID to notify update of usb devices. */ static pid_t main_thread_pid; #endif +#ifdef HAVE_PSELECT_NO_EINTR +/* FD to notify changes. */ +static int notify_fd; +#endif static char *create_socket_name (char *standard_name); static gnupg_fd_t create_server_socket (const char *name, @@ -1210,6 +1214,8 @@ scd_kick_the_loop (void) if (ret == 0) log_error ("SetEvent for scd_kick_the_loop failed: %s\n", w32_strerror (-1)); +#elif defined(HAVE_PSELECT_NO_EINTR) + write (notify_fd, "", 1); #else ret = kill (main_thread_pid, SIGCONT); if (ret < 0) @@ -1241,6 +1247,17 @@ handle_connections (int listen_fd) #else int signo; #endif +#ifdef HAVE_PSELECT_NO_EINTR + int pipe_fd[2]; + + ret = gnupg_create_pipe (pipe_fd); + if (ret) + { + log_error ("pipe creation failed: %s\n", gpg_strerror (ret)); + return; + } + notify_fd = pipe_fd[1]; +#endif ret = npth_attr_init(&tattr); if (ret) @@ -1298,6 +1315,7 @@ handle_connections (int listen_fd) for (;;) { int periodical_check; + int max_fd = nfd; if (shutdown_pending) { @@ -1326,8 +1344,14 @@ handle_connections (int listen_fd) thus a simple assignment is fine to copy the entire set. */ read_fdset = fdset; +#ifdef HAVE_PSELECT_NO_EINTR + FD_SET (pipe_fd[0], &read_fdset); + if (max_fd < pipe_fd[0]) + max_fd = pipe_fd[0]; +#endif + #ifndef HAVE_W32_SYSTEM - ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, t, + ret = npth_pselect (max_fd+1, &read_fdset, NULL, NULL, t, npth_sigev_sigmask ()); saved_errno = errno; @@ -1353,6 +1377,15 @@ handle_connections (int listen_fd) /* Timeout. Will be handled when calculating the next timeout. */ continue; +#ifdef HAVE_PSELECT_NO_EINTR + if (FD_ISSET (pipe_fd[0], &read_fdset)) + { + char buf[256]; + + read (pipe_fd[0], buf, sizeof buf); + } +#endif + if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset)) { ctrl_t ctrl; @@ -1394,6 +1427,10 @@ handle_connections (int listen_fd) if (the_event != INVALID_HANDLE_VALUE) CloseHandle (the_event); #endif +#ifdef HAVE_PSELECT_NO_EINTR + close (pipe_fd[0]); + close (pipe_fd[1]); +#endif cleanup (); log_info (_("%s %s stopped\n"), strusage(11), strusage(13)); npth_attr_destroy (&tattr); |