* call-scd.c (start_scd): Don't test for an alive scdaemon here.

(agent_scd_check_aliveness): New.
* gpg-agent.c (handle_tick): Test for an alive scdaemon.
(handle_signal): Print thread info on SIGUSR1.

* scdaemon.c (handle_signal): Print thread info on SIGUSR1.
This commit is contained in:
Werner Koch 2005-05-21 18:49:00 +00:00
parent 41862f5f13
commit 05e1dc22f0
9 changed files with 101 additions and 25 deletions

5
NEWS
View File

@ -1,6 +1,11 @@
Noteworthy changes in version 1.9.17
-------------------------------------------------
* gpg-connect-agent has now features to handle Assuan INQUIRE
commands.
* Internal changes for OpenPGP cards. New Assuan command WRITEKEY.
* GNU Pth is now a hard requirement.
* [scdaemon] Support for OpenSC has been removed. Instead a new and

15
TODO
View File

@ -67,6 +67,11 @@ might want to have an agent context for each service request
* sm/export.c
** Return an error code or a status info per user ID.
* scd/tlv.c
The parse_sexp fucntion should not go into this file. Check whether
we can change all S-expression handling code to make use of this
function.
* tests
** Makefile.am
We use printf(1) to setup the library path, this is not portable.
@ -89,3 +94,13 @@ might want to have an agent context for each service request
This means we can't reread a configuration
** No card status notifications.
* IMPORTANT:
Check that the PIN cache is cleared after failed card operations.
After receiving a HUP gpg-agent should set a flag to kill scdaemon
as soon as possible, w/o that scdaemon will continue running as a
zombie and gpg-agent won't be able to fire up a new one.
Implement an scd/agent option to wait for a card.

View File

@ -1,3 +1,10 @@
2005-05-21 Werner Koch <wk@g10code.com>
* call-scd.c (start_scd): Don't test for an alive scdaemon here.
(agent_scd_check_aliveness): New.
* gpg-agent.c (handle_tick): Test for an alive scdaemon.
(handle_signal): Print thread info on SIGUSR1.
2005-05-20 Werner Koch <wk@g10code.com>
* protect-tool.c: New option --canonical.

View File

@ -247,6 +247,7 @@ int divert_generic_cmd (ctrl_t ctrl,
/*-- call-scd.c --*/
void initialize_module_call_scd (void);
void agent_scd_check_aliveness (void);
int agent_reset_scd (ctrl_t ctrl);
int agent_card_learn (ctrl_t ctrl,
void (*kpinfo_cb)(void*, const char *),

View File

@ -185,26 +185,15 @@ start_scd (ctrl_t ctrl)
}
ctrl->scd_local->locked++;
/* If we already have a context, we better do a sanity check now to
see whether it has accidently died. This avoids annoying
timeouts and hung connections. */
if (ctrl->scd_local->ctx)
{
pid_t pid;
#ifndef HAVE_W32_SYSTEM
pid = assuan_get_pid (ctrl->scd_local->ctx);
if (pid != (pid_t)(-1) && pid
&& ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
{
assuan_disconnect (ctrl->scd_local->ctx);
ctrl->scd_local->ctx = NULL;
}
else
#endif
return 0; /* Okay, the context is fine. */
}
return 0; /* Okay, the context is fine. We used to test for an
alive context here and do an disconnect. How that we
have a ticker function to check for it, it is easier
not to check here but to let the connection run on an
error instead. */
/* We need to protect the lowwing code. */
/* We need to protect the following code. */
if (!pth_mutex_acquire (&start_scd_lock, 0, NULL))
{
log_error ("failed to acquire the start_scd lock: %s\n",
@ -350,6 +339,50 @@ start_scd (ctrl_t ctrl)
}
/* Check whether the Scdaemon is still alive and clean it up if not. */
void
agent_scd_check_aliveness (void)
{
pid_t pid;
int rc;
/* We can do so only if there is no more active primary connection.
With an active primary connection, this is all no problem because
with the end of gpg-agent's session a disconnect is send and the
this function will be used at a later time. */
if (!primary_scd_ctx || !primary_scd_ctx_reusable)
return;
if (!pth_mutex_acquire (&start_scd_lock, 0, NULL))
{
log_error ("failed to acquire the start_scd lock while"
" doing an aliveness check: %s\n",
strerror (errno));
return;
}
if (primary_scd_ctx && primary_scd_ctx_reusable)
{
pid = assuan_get_pid (primary_scd_ctx);
if (pid != (pid_t)(-1) && pid
&& ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
{
/* Okay, scdaemon died. Disconnect the primary connection now
but take care that it won't do another wait. */
assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1);
assuan_disconnect (primary_scd_ctx);
primary_scd_ctx = NULL;
primary_scd_ctx_reusable = 0;
xfree (socket_name);
socket_name = NULL;
}
}
if (!pth_mutex_release (&start_scd_lock))
log_error ("failed to release the start_scd lock while"
" doing the aliveness check: %s\n", strerror (errno));
}
/* Reset the SCD if it has been used. */
int
@ -359,15 +392,19 @@ agent_reset_scd (ctrl_t ctrl)
{
if (ctrl->scd_local->ctx)
{
/* We can't disconnect the primary context becuase libassuan
/* We can't disconnect the primary context because libassuan
does a waitpid on it and thus the system would hang.
Instead we send a reset and keep that connection for
reuse. */
if (ctrl->scd_local->ctx == primary_scd_ctx)
{
if (!assuan_transact (primary_scd_ctx, "RESET",
NULL, NULL, NULL, NULL, NULL, NULL))
primary_scd_ctx_reusable = 1;
/* The RESET may fail for example if the scdaemon has
already been terminated. We need to set the reusable
flag anyway to make sure that the aliveness check can
clean it up. */
assuan_transact (primary_scd_ctx, "RESET",
NULL, NULL, NULL, NULL, NULL, NULL);
primary_scd_ctx_reusable = 1;
}
else
assuan_disconnect (ctrl->scd_local->ctx);

View File

@ -1270,6 +1270,11 @@ create_directories (void)
static void
handle_tick (void)
{
/* Check whether the scdaemon has dies and cleanup in this case. */
agent_scd_check_aliveness ();
/* If we are running as a child of another process, check whether
the parent is still alive and shutdwon if now. */
#ifndef HAVE_W32_SYSTEM
if (parent_pid != (pid_t)(-1))
{
@ -1301,7 +1306,8 @@ handle_signal (int signo)
break;
case SIGUSR1:
log_info ("SIGUSR1 received - no action defined\n");
log_info ("SIGUSR1 received - printing internal information:\n");
pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ());
break;
case SIGUSR2:

View File

@ -1,3 +1,7 @@
2005-05-21 Werner Koch <wk@g10code.com>
* scdaemon.c (handle_signal): Print thread info on SIGUSR1.
2005-05-20 Werner Koch <wk@g10code.com>
* ccid-driver.c: Replaced macro DEBUG_T1 by a new debug level.

View File

@ -1634,7 +1634,7 @@ do_writekey (app_t app, ctrl_t ctrl,
log_info ("protected-private-key passed to writekey\n");
else if (toklen == 20 && !memcmp ("shadowed-private-key", tok, toklen))
log_info ("shadowed-private-key passed to writekey\n");
err = gpg_error (GPG_ERR_BAD_KEY);
err = gpg_error (GPG_ERR_BAD_SECKEY);
goto leave;
}
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))

View File

@ -807,7 +807,8 @@ handle_signal (int signo)
break;
case SIGUSR1:
log_info ("SIGUSR1 received - no action defined\n");
log_info ("SIGUSR1 received - printing internal information:\n");
pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ());
break;
case SIGUSR2: