mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
PIN caching of cards does now work.
This commit is contained in:
parent
3d7b030025
commit
4472efd12c
9 changed files with 256 additions and 30 deletions
|
@ -45,6 +45,16 @@
|
|||
/* Definition of module local data of the CTRL structure. */
|
||||
struct scd_local_s
|
||||
{
|
||||
/* We keep a list of all allocated context with a an achnor at
|
||||
SCD_LOCAL_LIST (see below). */
|
||||
struct scd_local_s *next_local;
|
||||
|
||||
/* We need to get back to the ctrl object actually referencing this
|
||||
structure. This is really an awkward way of enumerint the lcoal
|
||||
contects. A much cleaner way would be to keep a global list of
|
||||
ctrl objects to enumerate them. */
|
||||
ctrl_t ctrl_backlink;
|
||||
|
||||
assuan_context_t ctx; /* NULL or session context for the SCdaemon
|
||||
used with this connection. */
|
||||
int locked; /* This flag is used to assert proper use of
|
||||
|
@ -72,6 +82,10 @@ struct inq_needpin_s
|
|||
};
|
||||
|
||||
|
||||
/* To keep track of all active SCD contexts, we keep a linked list
|
||||
anchored at this variable. */
|
||||
static struct scd_local_s *scd_local_list;
|
||||
|
||||
/* A Mutex used inside the start_scd function. */
|
||||
static pth_mutex_t start_scd_lock;
|
||||
|
||||
|
@ -202,6 +216,9 @@ start_scd (ctrl_t ctrl)
|
|||
ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local);
|
||||
if (!ctrl->scd_local)
|
||||
return gpg_error_from_errno (errno);
|
||||
ctrl->scd_local->ctrl_backlink = ctrl;
|
||||
ctrl->scd_local->next_local = scd_local_list;
|
||||
scd_local_list = ctrl->scd_local;
|
||||
}
|
||||
|
||||
|
||||
|
@ -216,7 +233,7 @@ start_scd (ctrl_t ctrl)
|
|||
|
||||
if (ctrl->scd_local->ctx)
|
||||
return 0; /* Okay, the context is fine. We used to test for an
|
||||
alive context here and do an disconnect. How that we
|
||||
alive context here and do an disconnect. Now 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. */
|
||||
|
@ -404,12 +421,30 @@ agent_scd_check_aliveness (void)
|
|||
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. */
|
||||
/* Okay, scdaemon died. Disconnect the primary connection
|
||||
now but take care that it won't do another wait. Also
|
||||
cleanup all other connections and release their
|
||||
resources. The next use will start a new daemon then.
|
||||
Due to the use of the START_SCD_LOCAL we are sure that
|
||||
none of these context are actually in use. */
|
||||
struct scd_local_s *sl;
|
||||
|
||||
assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1);
|
||||
assuan_disconnect (primary_scd_ctx);
|
||||
|
||||
for (sl=scd_local_list; sl; sl = sl->next_local)
|
||||
{
|
||||
if (sl->ctx)
|
||||
{
|
||||
if (sl->ctx != primary_scd_ctx)
|
||||
assuan_disconnect (sl->ctx);
|
||||
sl->ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
primary_scd_ctx = NULL;
|
||||
primary_scd_ctx_reusable = 0;
|
||||
|
||||
xfree (socket_name);
|
||||
socket_name = NULL;
|
||||
}
|
||||
|
@ -422,7 +457,8 @@ agent_scd_check_aliveness (void)
|
|||
|
||||
|
||||
|
||||
/* Reset the SCD if it has been used. */
|
||||
/* Reset the SCD if it has been used. Actually it is not a reset but
|
||||
a cleanup of resources used by the current connection. */
|
||||
int
|
||||
agent_reset_scd (ctrl_t ctrl)
|
||||
{
|
||||
|
@ -436,16 +472,40 @@ agent_reset_scd (ctrl_t ctrl)
|
|||
reuse. */
|
||||
if (ctrl->scd_local->ctx == primary_scd_ctx)
|
||||
{
|
||||
/* 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",
|
||||
/* Send a RESTART to the SCD. This is required for the
|
||||
primary connection as a kind of virtual EOF; we don't
|
||||
have another way to tell it that the next command
|
||||
should be viewed as if a new connection has been
|
||||
made. For the non-primary connections this is not
|
||||
needed as we simply close the socket. We don't check
|
||||
for an error here because the RESTART may fail for
|
||||
example if the scdaemon has already been terminated.
|
||||
Anyway, we need to set the reusable flag to make sure
|
||||
that the aliveness check can clean it up. */
|
||||
assuan_transact (primary_scd_ctx, "RESTART",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
primary_scd_ctx_reusable = 1;
|
||||
}
|
||||
else
|
||||
assuan_disconnect (ctrl->scd_local->ctx);
|
||||
ctrl->scd_local->ctx = NULL;
|
||||
}
|
||||
|
||||
/* Remove the local context from our list and release it. */
|
||||
if (!scd_local_list)
|
||||
BUG ();
|
||||
else if (scd_local_list == ctrl->scd_local)
|
||||
scd_local_list = ctrl->scd_local->next_local;
|
||||
else
|
||||
{
|
||||
struct scd_local_s *sl;
|
||||
|
||||
for (sl=scd_local_list; sl->next_local; sl = sl->next_local)
|
||||
if (sl->next_local == ctrl->scd_local)
|
||||
break;
|
||||
if (!sl->next_local)
|
||||
BUG ();
|
||||
sl->next_local = ctrl->scd_local->next_local;
|
||||
}
|
||||
xfree (ctrl->scd_local);
|
||||
ctrl->scd_local = NULL;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue