From b519a52ceaff0a6c2b01f1013f8f34b96261f4ad Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 15 Oct 2008 13:23:10 +0000 Subject: [PATCH] Made scdaemon more robust on Windows. --- NEWS | 4 +++- agent/ChangeLog | 5 +++++ agent/call-scd.c | 13 ++++++++++--- jnlib/ChangeLog | 4 ++++ jnlib/logging.c | 4 ++++ scd/ChangeLog | 9 +++++++++ scd/apdu.c | 4 ---- scd/command.c | 10 +++++++--- scd/scdaemon.c | 22 ++++++++++++---------- scd/scdaemon.h | 2 +- 10 files changed, 55 insertions(+), 22 deletions(-) diff --git a/NEWS b/NEWS index bb14d52ac..39eebe0ed 100644 --- a/NEWS +++ b/NEWS @@ -20,7 +20,7 @@ Noteworthy changes in version 2.0.10 (unreleased) * [gpgsm] Made --output option work with --export-secret-key-p12. - * gpg-connect-agent accepts commands given as command line arguments. + * [gpg-connect-agent] Accept commands given as command line arguments. * [gpg] The option --fixed-list-mode is now implicitly used and obsolete. @@ -35,6 +35,8 @@ Noteworthy changes in version 2.0.10 (unreleased) * Support for version 2 OpenPGP cards. + * [scdaemon] Made it more robust on W32. + * Libgcrypt 1.4 is now required. diff --git a/agent/ChangeLog b/agent/ChangeLog index c3798c143..f45c6d7f3 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,8 @@ +2008-10-15 Werner Koch + + * call-scd.c (start_scd): Enable assuan loggging if requested. + (agent_scd_check_aliveness) [W32]: Fix use of GetExitCodeProcess. + 2008-10-14 Werner Koch * gpg-agent.c (get_agent_scd_notify_event): Need to use a manual diff --git a/agent/call-scd.c b/agent/call-scd.c index 55f2d4ffb..65483e55d 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -343,6 +343,9 @@ start_scd (ctrl_t ctrl) if (opt.verbose) log_debug ("first connection to SCdaemon established\n"); + if (DBG_ASSUAN) + assuan_set_log_stream (ctx, log_get_stream ()); + /* Get the name of the additional socket opened by scdaemon. */ { membuf_t data; @@ -412,9 +415,10 @@ agent_scd_check_aliveness (void) { pth_event_t evt; pid_t pid; - int rc; #ifdef HAVE_W32_SYSTEM - DWORD dummyec; + DWORD rc; +#else + int rc; #endif if (!primary_scd_ctx) @@ -443,8 +447,11 @@ agent_scd_check_aliveness (void) { pid = assuan_get_pid (primary_scd_ctx); #ifdef HAVE_W32_SYSTEM + /* If we have a PID we disconnect if either GetExitProcessCode + fails or if ir returns the exit code of the scdaemon. 259 is + the error code for STILL_ALIVE. */ if (pid != (pid_t)(void*)(-1) && pid - && !GetExitCodeProcess ((HANDLE)pid, &dummyec)) + && (!GetExitCodeProcess ((HANDLE)pid, &rc) || rc != 259)) #else if (pid != (pid_t)(-1) && pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) ) diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index a530a478d..c8ea2efa7 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,7 @@ +2008-10-15 Werner Koch + + * logging.c (do_logv) [W32]: Flush the log stream. + 2008-09-29 Werner Koch * argparse.c (ARGERR_): Use constants for error values. diff --git a/jnlib/logging.c b/jnlib/logging.c index d4418c915..df2ec4463 100644 --- a/jnlib/logging.c +++ b/jnlib/logging.c @@ -490,6 +490,10 @@ do_logv (int level, const char *fmt, va_list arg_ptr) vfprintf(logstream,fmt,arg_ptr) ; if (*fmt && fmt[strlen(fmt)-1] != '\n') missing_lf = 1; +#ifdef HAVE_W32_SYSTEM + else + fflush (logstream); +#endif } if (level == JNLIB_LOG_FATAL) diff --git a/scd/ChangeLog b/scd/ChangeLog index 85177e535..b0550cd26 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,12 @@ +2008-10-15 Werner Koch + + * command.c (scd_command_handler): Return true if there is no more + active session. + * scdaemon.c (start_connection_thread): Set shutdown flag if + requested by command handler. + (main): Make PIPE_SERVER module global. + (handle_connections): Disable listen_fd if a shutdown is pending. + 2008-10-14 Werner Koch diff --git a/scd/apdu.c b/scd/apdu.c index c0c5c5d3e..274d27b6e 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2442,11 +2442,7 @@ apdu_open_reader (const char *portstr) pcsc_api_loaded = 1; } -#ifdef NEED_PCSC_WRAPPER - return open_pcsc_reader_wrapped (portstr); -#else return open_pcsc_reader (portstr); -#endif } diff --git a/scd/command.c b/scd/command.c index aabd93c25..7d2515474 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1,6 +1,6 @@ /* command.c - SCdaemon command handler * Copyright (C) 2001, 2002, 2003, 2004, 2005, - * 2007 Free Software Foundation, Inc. + * 2007, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1776,8 +1776,9 @@ register_commands (assuan_context_t ctx) /* Startup the server. If FD is given as -1 this is simple pipe - server, otherwise it is a regular server. */ -void + server, otherwise it is a regular server. Returns true if there + are no more active asessions. */ +int scd_command_handler (ctrl_t ctrl, int fd) { int rc; @@ -1872,6 +1873,9 @@ scd_command_handler (ctrl_t ctrl, int fd) /* Release the Assuan context. */ assuan_deinit_server (ctx); + + /* If there are no more sessions return true. */ + return !session_list; } diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 384df51bf..0366703b7 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -1,6 +1,6 @@ /* scdaemon.c - The GnuPG Smartcard Daemon * Copyright (C) 2001, 2002, 2004, 2005, - * 2007 Free Software Foundation, Inc. + * 2007, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -167,6 +167,9 @@ static int shutdown_pending; /* It is possible that we are currently running under setuid permissions */ static int maybe_setuid = 1; +/* Flag telling whether we are running as a pipe server. */ +static int pipe_server; + /* Name of the communication socket */ static char *socket_name; @@ -304,7 +307,6 @@ main (int argc, char **argv ) int default_config =1; int greeting = 0; int nogreeting = 0; - int pipe_server = 0; int multi_server = 0; int is_daemon = 0; int nodetach = 0; @@ -1027,19 +1029,18 @@ start_connection_thread (void *arg) log_info (_("handler for fd %d started\n"), FD2INT(ctrl->thread_startup.fd)); - scd_command_handler (ctrl, FD2INT(ctrl->thread_startup.fd)); + /* If this is a pipe server, we request a shutdown if the command + hanlder asked for it. With the next ticker event and given that + no other connections are running the shutdown will then + happen. */ + if (scd_command_handler (ctrl, FD2INT(ctrl->thread_startup.fd)) + && pipe_server) + shutdown_pending = 1; if (opt.verbose) log_info (_("handler for fd %d terminated\n"), FD2INT (ctrl->thread_startup.fd)); - /* If this thread is the pipe connection thread, flag that a - shutdown is required. With the next ticker event and given that - no other connections are running the shutdown will then - happen. */ - if (ctrl->thread_startup.fd == GNUPG_INVALID_FD) - shutdown_pending = 1; - scd_deinit_default_ctrl (ctrl); xfree (ctrl); return NULL; @@ -1105,6 +1106,7 @@ handle_connections (int listen_fd) file descriptors to wait for, so that the select will be used to just wait on a signal or timeout event. */ FD_ZERO (&fdset); + listen_fd = -1; } /* Create a timeout event if needed. */ diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 054aaa0f6..c0857e91b 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -121,7 +121,7 @@ const char *scd_get_socket_name (void); /*-- command.c --*/ void initialize_module_command (void); -void scd_command_handler (ctrl_t, int); +int scd_command_handler (ctrl_t, int); void send_status_info (ctrl_t ctrl, const char *keyword, ...) GNUPG_GCC_A_SENTINEL(1); void scd_update_reader_status_file (void);