aboutsummaryrefslogtreecommitdiffstats
path: root/agent
diff options
context:
space:
mode:
Diffstat (limited to 'agent')
-rw-r--r--agent/ChangeLog21
-rw-r--r--agent/agent.h49
-rw-r--r--agent/cache.c36
-rw-r--r--agent/call-scd.c30
-rw-r--r--agent/command-ssh.c5
-rw-r--r--agent/command.c21
-rw-r--r--agent/findkey.c24
-rw-r--r--agent/gpg-agent.c6
-rw-r--r--agent/pkdecrypt.c3
-rw-r--r--agent/pksign.c18
-rw-r--r--agent/query.c30
11 files changed, 173 insertions, 70 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog
index 9621e5de0..1a157fa52 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,24 @@
+2005-06-06 Werner Koch <[email protected]>
+
+ * gpg-agent.c: New option --default-cache-ttl-ssh.
+ * agent.h (cache_mode_t): New.
+ * pksign.c (agent_pksign_do): New arg CACHE_MODE to replace the
+ ARG IGNORE_CACHE. Changed all callers.
+ (agent_pksign): Ditto.
+ * findkey.c (agent_key_from_file): Ditto. Canged all callers.
+ (unprotect): Ditto.
+ * command-ssh.c (data_sign): Use CACHE_MODE_SSH.
+ * cache.c (agent_get_cache): New arg CACHE_MODE.
+ (agent_put_cache): Ditto. Store it in the cache.
+
+ * query.c (agent_query_dump_state, dump_mutex_state): New.
+ (unlock_pinentry): Reset the global context before releasing the
+ mutex.
+ * gpg-agent.c (handle_signal): Dump query.c info on SIGUSR1.
+
+ * call-scd.c (agent_scd_check_aliveness): Always do a waitpid and
+ add a timeout to the locking.
+
2005-06-03 Werner Koch <[email protected]>
* command.c (cmd_updatestartuptty): New.
diff --git a/agent/agent.h b/agent/agent.h
index 51e66abee..350e5c0d2 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -69,9 +69,13 @@ struct {
smartcard tasks. */
int disable_scdaemon; /* Never use the SCdaemon. */
int no_grab; /* Don't let the pinentry grab the keyboard */
- unsigned long def_cache_ttl;
+
+ /* The default and maximum TTL of cache entries. */
+ unsigned long def_cache_ttl; /* Normal. */
+ unsigned long def_cache_ttl_ssh; /* SSH. */
unsigned long max_cache_ttl;
+
int running_detached; /* We are running detached from the tty. */
int ignore_cache_for_signing;
@@ -147,12 +151,26 @@ struct pin_entry_info_s {
};
-enum {
- PRIVATE_KEY_UNKNOWN = 0,
- PRIVATE_KEY_CLEAR = 1,
- PRIVATE_KEY_PROTECTED = 2,
- PRIVATE_KEY_SHADOWED = 3
-};
+enum
+ {
+ PRIVATE_KEY_UNKNOWN = 0,
+ PRIVATE_KEY_CLEAR = 1,
+ PRIVATE_KEY_PROTECTED = 2,
+ PRIVATE_KEY_SHADOWED = 3
+ };
+
+
+/* Values for the cache_mode arguments. */
+typedef enum
+ {
+ CACHE_MODE_IGNORE = 0, /* Special mode to by pass the cache. */
+ CACHE_MODE_ANY, /* Any mode except ignore matches. */
+ CACHE_MODE_NORMAL, /* Normal cache (gpg-agent). */
+ CACHE_MODE_USER, /* GET_PASSPHRASE related cache. */
+ CACHE_MODE_SSH /* SSH related cache. */
+ }
+cache_mode_t;
+
/*-- gpg-agent.c --*/
void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */
@@ -171,7 +189,8 @@ gpg_error_t agent_key_from_file (ctrl_t ctrl,
const char *desc_text,
const unsigned char *grip,
unsigned char **shadow_info,
- int ignore_cache, gcry_sexp_t *result);
+ cache_mode_t cache_mode,
+ gcry_sexp_t *result);
gpg_error_t agent_public_key_from_file (ctrl_t ctrl,
const unsigned char *grip,
gcry_sexp_t *result);
@@ -179,6 +198,7 @@ int agent_key_available (const unsigned char *grip);
/*-- query.c --*/
void initialize_module_query (void);
+void agent_query_dump_state (void);
int agent_askpin (ctrl_t ctrl,
const char *desc_text, const char *prompt_text,
const char *inital_errtext,
@@ -191,16 +211,19 @@ int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok,
/*-- cache.c --*/
void agent_flush_cache (void);
-int agent_put_cache (const char *key, const char *data, int ttl);
-const char *agent_get_cache (const char *key, void **cache_id);
+int agent_put_cache (const char *key, cache_mode_t cache_mode,
+ const char *data, int ttl);
+const char *agent_get_cache (const char *key, cache_mode_t cache_mode,
+ void **cache_id);
void agent_unlock_cache_entry (void **cache_id);
/*-- pksign.c --*/
-int agent_pksign_do (CTRL ctrl, const char *desc_text,
- gcry_sexp_t *signature_sexp, int ignore_cache);
+int agent_pksign_do (ctrl_t ctrl, const char *desc_text,
+ gcry_sexp_t *signature_sexp,
+ cache_mode_t cache_mode);
int agent_pksign (ctrl_t ctrl, const char *desc_text,
- membuf_t *outbuf, int ignore_cache);
+ membuf_t *outbuf, cache_mode_t cache_mode);
/*-- pkdecrypt.c --*/
int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
diff --git a/agent/cache.c b/agent/cache.c
index 18aa7653b..a032b4fa7 100644
--- a/agent/cache.c
+++ b/agent/cache.c
@@ -42,6 +42,7 @@ struct cache_item_s {
int ttl; /* max. lifetime given in seconds, -1 one means infinite */
int lockcount;
struct secret_data_s *pw;
+ cache_mode_t cache_mode;
char key[1];
};
@@ -78,6 +79,7 @@ new_data (const void *data, size_t length)
}
+
/* check whether there are items to expire */
static void
housekeeping (void)
@@ -85,7 +87,7 @@ housekeeping (void)
ITEM r, rprev;
time_t current = gnupg_get_time ();
- /* first expire the actual data */
+ /* First expire the actual data */
for (r=thecache; r; r = r->next)
{
if (!r->lockcount && r->pw
@@ -100,7 +102,7 @@ housekeeping (void)
}
}
- /* second, make sure that we also remove them based on the created stamp so
+ /* Second, make sure that we also remove them based on the created stamp so
that the user has to enter it from time to time. We do this every hour */
for (r=thecache; r; r = r->next)
{
@@ -115,7 +117,7 @@ housekeeping (void)
}
}
- /* third, make sure that we don't have too many items in the list.
+ /* Third, make sure that we don't have too many items in the list.
Expire old and unused entries after 30 minutes */
for (rprev=NULL, r=thecache; r; )
{
@@ -186,19 +188,27 @@ agent_flush_cache (void)
with a maximum lifetime of TTL seconds. If there is already data
under this key, it will be replaced. Using a DATA of NULL deletes
the entry. A TTL of 0 is replaced by the default TTL and a TTL of
- -1 set infinite timeout. */
+ -1 set infinite timeout. CACHE_MODE is stored with the cache entry
+ and used t select different timeouts. */
int
-agent_put_cache (const char *key, const char *data, int ttl)
+agent_put_cache (const char *key, cache_mode_t cache_mode,
+ const char *data, int ttl)
{
ITEM r;
if (DBG_CACHE)
- log_debug ("agent_put_cache `%s' requested ttl=%d\n", key, ttl);
+ log_debug ("agent_put_cache `%s' requested ttl=%d mode=%d\n",
+ key, ttl, cache_mode);
housekeeping ();
if (!ttl)
- ttl = opt.def_cache_ttl;
- if (!ttl)
+ {
+ if (cache_mode == CACHE_MODE_SSH)
+ ttl = opt.def_cache_ttl_ssh;
+ else
+ ttl = opt.def_cache_ttl;
+ }
+ if (!ttl || cache_mode == CACHE_MODE_IGNORE)
return 0;
for (r=thecache; r; r = r->next)
@@ -217,6 +227,7 @@ agent_put_cache (const char *key, const char *data, int ttl)
{
r->created = r->accessed = gnupg_get_time ();
r->ttl = ttl;
+ r->cache_mode = cache_mode;
r->pw = new_data (data, strlen (data)+1);
if (!r->pw)
log_error ("out of core while allocating new cache item\n");
@@ -232,6 +243,7 @@ agent_put_cache (const char *key, const char *data, int ttl)
strcpy (r->key, key);
r->created = r->accessed = gnupg_get_time ();
r->ttl = ttl;
+ r->cache_mode = cache_mode;
r->pw = new_data (data, strlen (data)+1);
if (!r->pw)
{
@@ -249,12 +261,16 @@ agent_put_cache (const char *key, const char *data, int ttl)
}
-/* Try to find an item in the cache */
+/* Try to find an item in the cache. Note that we currently don't
+ make use of CACHE_MODE. */
const char *
-agent_get_cache (const char *key, void **cache_id)
+agent_get_cache (const char *key, cache_mode_t cache_mode, void **cache_id)
{
ITEM r;
+ if (cache_mode == CACHE_MODE_IGNORE)
+ return NULL;
+
if (DBG_CACHE)
log_debug ("agent_get_cache `%s'...\n", key);
housekeeping ();
diff --git a/agent/call-scd.c b/agent/call-scd.c
index 00c9df2a7..4dff8e3c1 100644
--- a/agent/call-scd.c
+++ b/agent/call-scd.c
@@ -372,25 +372,33 @@ start_scd (ctrl_t ctrl)
void
agent_scd_check_aliveness (void)
{
+ pth_event_t evt;
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 (!primary_scd_ctx)
+ return; /* No scdaemon running. */
- if (!pth_mutex_acquire (&start_scd_lock, 0, NULL))
+ /* This is not a critical function so we use a short timeout while
+ acquiring the lock. */
+ evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0));
+ if (!pth_mutex_acquire (&start_scd_lock, 0, evt))
{
- log_error ("failed to acquire the start_scd lock while"
- " doing an aliveness check: %s\n",
- strerror (errno));
+ if (pth_event_occurred (evt))
+ {
+ if (opt.verbose > 1)
+ log_info ("failed to acquire the start_scd lock while"
+ " doing an aliveness check: %s\n", "timeout");
+ }
+ else
+ log_error ("failed to acquire the start_scd lock while"
+ " doing an aliveness check: %s\n", strerror (errno));
+ pth_event_free (evt, PTH_FREE_THIS);
return;
}
+ pth_event_free (evt, PTH_FREE_THIS);
- if (primary_scd_ctx && primary_scd_ctx_reusable)
+ if (primary_scd_ctx)
{
pid = assuan_get_pid (primary_scd_ctx);
if (pid != (pid_t)(-1) && pid
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 030cc70a0..870afe059 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -2014,7 +2014,8 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder,
ctrl->use_auth_call = 1;
err = agent_pksign_do (ctrl,
_("Please enter the passphrase "
- "for the ssh key%0A %c"), &signature_sexp, 0);
+ "for the ssh key%0A %c"), &signature_sexp,
+ CACHE_MODE_SSH);
ctrl->use_auth_call = 0;
if (err)
goto out;
@@ -2386,7 +2387,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
for (i = 0; i < 20; i++)
sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
- err = agent_put_cache (key_grip, pi->pin, ttl);
+ err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
if (err)
goto out;
diff --git a/agent/command.c b/agent/command.c
index 56167118d..ebf3a8220 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -404,19 +404,19 @@ static int
cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
{
int rc;
- int ignore_cache = 0;
+ cache_mode_t cache_mode = CACHE_MODE_NORMAL;
ctrl_t ctrl = assuan_get_pointer (ctx);
membuf_t outbuf;
-
+
if (opt.ignore_cache_for_signing)
- ignore_cache = 1;
+ cache_mode = CACHE_MODE_IGNORE;
else if (!ctrl->server_local->use_cache_for_signing)
- ignore_cache = 1;
+ cache_mode = CACHE_MODE_IGNORE;
init_membuf (&outbuf, 512);
rc = agent_pksign (ctrl, ctrl->server_local->keydesc,
- &outbuf, ignore_cache);
+ &outbuf, cache_mode);
if (rc)
clear_outbuf (&outbuf);
else
@@ -623,7 +623,8 @@ cmd_get_passphrase (ASSUAN_CONTEXT ctx, char *line)
desc = NULL;
/* Note: we store the hexified versions in the cache. */
- pw = cacheid ? agent_get_cache (cacheid, &cache_marker) : NULL;
+ pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker)
+ : NULL;
if (pw)
{
assuan_begin_confidential (ctx);
@@ -647,7 +648,7 @@ cmd_get_passphrase (ASSUAN_CONTEXT ctx, char *line)
if (!rc)
{
if (cacheid)
- agent_put_cache (cacheid, response, 0);
+ agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
assuan_begin_confidential (ctx);
rc = assuan_set_okay_line (ctx, response);
xfree (response);
@@ -682,7 +683,7 @@ cmd_clear_passphrase (ASSUAN_CONTEXT ctx, char *line)
if (!cacheid || !*cacheid || strlen (cacheid) > 50)
return set_error (Parameter_Error, "invalid length of cacheID");
- agent_put_cache (cacheid, NULL, 0);
+ agent_put_cache (cacheid, CACHE_MODE_USER, NULL, 0);
return 0;
}
@@ -772,7 +773,7 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
Assuan error code. */
rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc,
- grip, &shadow_info, 1, &s_skey);
+ grip, &shadow_info, CACHE_MODE_IGNORE, &s_skey);
if (rc)
;
else if (!s_skey)
@@ -842,7 +843,7 @@ cmd_preset_passphrase (ASSUAN_CONTEXT ctx, char *line)
else
return map_to_assuan_status (gpg_error (GPG_ERR_NOT_IMPLEMENTED));
- rc = agent_put_cache (grip_clear, passphrase, ttl);
+ rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
if (rc)
log_error ("command preset_passwd failed: %s\n", gpg_strerror (rc));
diff --git a/agent/findkey.c b/agent/findkey.c
index 999a5d620..56433c9c4 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -230,8 +230,9 @@ modify_description (const char *in, const char *comment, char **result)
caching mechanism. DESC_TEXT may be set to override the default
description used for the pinentry. */
static int
-unprotect (CTRL ctrl, const char *desc_text,
- unsigned char **keybuf, const unsigned char *grip, int ignore_cache)
+unprotect (ctrl_t ctrl, const char *desc_text,
+ unsigned char **keybuf, const unsigned char *grip,
+ cache_mode_t cache_mode)
{
struct pin_entry_info_s *pi;
struct try_unprotect_arg_s arg;
@@ -246,10 +247,12 @@ unprotect (CTRL ctrl, const char *desc_text,
/* First try to get it from the cache - if there is none or we can't
unprotect it, we fall back to ask the user */
- if (!ignore_cache)
+ if (cache_mode != CACHE_MODE_IGNORE)
{
void *cache_marker;
- const char *pw = agent_get_cache (hexgrip, &cache_marker);
+ const char *pw;
+
+ pw = agent_get_cache (hexgrip, cache_mode, &cache_marker);
if (pw)
{
rc = agent_unprotect (*keybuf, pw, &result, &resultlen);
@@ -280,7 +283,7 @@ unprotect (CTRL ctrl, const char *desc_text,
if (!rc)
{
assert (arg.unprotected_key);
- agent_put_cache (hexgrip, pi->pin, 0);
+ agent_put_cache (hexgrip, cache_mode, pi->pin, 0);
xfree (*keybuf);
*keybuf = arg.unprotected_key;
}
@@ -360,14 +363,13 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
/* Return the secret key as an S-Exp in RESULT after locating it using
the grip. Returns NULL in RESULT if the operation should be
diverted to a token; SHADOW_INFO will point then to an allocated
- S-Expression with the shadow_info part from the file. With
- IGNORE_CACHE passed as true the passphrase is not taken from the
- cache. DESC_TEXT may be set to present a custom description for the
- pinentry. */
+ S-Expression with the shadow_info part from the file. CACHE_MODE
+ defines now the cache shall be used. DESC_TEXT may be set to
+ present a custom description for the pinentry. */
gpg_error_t
agent_key_from_file (ctrl_t ctrl, const char *desc_text,
const unsigned char *grip, unsigned char **shadow_info,
- int ignore_cache, gcry_sexp_t *result)
+ cache_mode_t cache_mode, gcry_sexp_t *result)
{
int rc;
unsigned char *buf;
@@ -447,7 +449,7 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text,
if (!rc)
{
- rc = unprotect (ctrl, desc_text_final, &buf, grip, ignore_cache);
+ rc = unprotect (ctrl, desc_text_final, &buf, grip, cache_mode);
if (rc)
log_error ("failed to unprotect the secret key: %s\n",
gpg_strerror (rc));
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 90b071d5e..6cc08f845 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -83,6 +83,7 @@ enum cmd_and_opt_values
oLCmessages,
oScdaemonProgram,
oDefCacheTTL,
+ oDefCacheTTLSSH,
oMaxCacheTTL,
oUseStandardSocket,
oNoUseStandardSocket,
@@ -140,6 +141,7 @@ static ARGPARSE_OPTS opts[] = {
{ oDefCacheTTL, "default-cache-ttl", 4,
N_("|N|expire cached PINs after N seconds")},
+ { oDefCacheTTLSSH, "default-cache-ttl-ssh", 4, "@" },
{ oMaxCacheTTL, "max-cache-ttl", 4, "@" },
{ oIgnoreCacheForSigning, "ignore-cache-for-signing", 0,
N_("do not use the PIN cache when signing")},
@@ -367,6 +369,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
opt.pinentry_program = NULL;
opt.scdaemon_program = NULL;
opt.def_cache_ttl = DEFAULT_CACHE_TTL;
+ opt.def_cache_ttl_ssh = DEFAULT_CACHE_TTL;
opt.max_cache_ttl = MAX_CACHE_TTL;
opt.ignore_cache_for_signing = 0;
opt.allow_mark_trusted = 0;
@@ -402,6 +405,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
case oDisableScdaemon: opt.disable_scdaemon = 1; break;
case oDefCacheTTL: opt.def_cache_ttl = pargs->r.ret_ulong; break;
+ case oDefCacheTTLSSH: opt.def_cache_ttl_ssh = pargs->r.ret_ulong; break;
case oMaxCacheTTL: opt.max_cache_ttl = pargs->r.ret_ulong; break;
case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break;
@@ -413,6 +417,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
default:
return 0; /* not handled */
}
+
return 1; /* handled */
}
@@ -1339,6 +1344,7 @@ handle_signal (int signo)
case SIGUSR1:
log_info ("SIGUSR1 received - printing internal information:\n");
pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ());
+ agent_query_dump_state ();
agent_scd_dump_state ();
break;
diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c
index 7a93e58f8..42ce69697 100644
--- a/agent/pkdecrypt.c
+++ b/agent/pkdecrypt.c
@@ -66,7 +66,8 @@ agent_pkdecrypt (CTRL ctrl, const char *desc_text,
log_printhex ("cipher: ", ciphertext, ciphertextlen);
}
rc = agent_key_from_file (ctrl, desc_text,
- ctrl->keygrip, &shadow_info, 0, &s_skey);
+ ctrl->keygrip, &shadow_info,
+ CACHE_MODE_NORMAL, &s_skey);
if (rc)
{
log_error ("failed to read the secret key\n");
diff --git a/agent/pksign.c b/agent/pksign.c
index 3337e188c..2a355e43e 100644
--- a/agent/pksign.c
+++ b/agent/pksign.c
@@ -79,8 +79,8 @@ do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash,
/* SIGN whatever information we have accumulated in CTRL and return
the signature S-Expression. */
int
-agent_pksign_do (CTRL ctrl, const char *desc_text,
- gcry_sexp_t *signature_sexp, int ignore_cache)
+agent_pksign_do (ctrl_t ctrl, const char *desc_text,
+ gcry_sexp_t *signature_sexp, cache_mode_t cache_mode)
{
gcry_sexp_t s_skey = NULL, s_sig = NULL;
unsigned char *shadow_info = NULL;
@@ -90,16 +90,16 @@ agent_pksign_do (CTRL ctrl, const char *desc_text,
return gpg_error (GPG_ERR_NO_SECKEY);
rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip,
- &shadow_info, ignore_cache, &s_skey);
+ &shadow_info, cache_mode, &s_skey);
if (rc)
{
log_error ("failed to read the secret key\n");
goto leave;
}
- if (! s_skey)
+ if (!s_skey)
{
- /* divert operation to the smartcard */
+ /* Divert operation to the smartcard */
unsigned char *buf = NULL;
size_t len = 0;
@@ -128,7 +128,7 @@ agent_pksign_do (CTRL ctrl, const char *desc_text,
}
else
{
- /* no smartcard, but a private key */
+ /* No smartcard, but a private key */
gcry_sexp_t s_hash = NULL;
@@ -176,15 +176,15 @@ agent_pksign_do (CTRL ctrl, const char *desc_text,
/* SIGN whatever information we have accumulated in CTRL and write it
back to OUTFP. */
int
-agent_pksign (CTRL ctrl, const char *desc_text,
- membuf_t *outbuf, int ignore_cache)
+agent_pksign (ctrl_t ctrl, const char *desc_text,
+ membuf_t *outbuf, cache_mode_t cache_mode)
{
gcry_sexp_t s_sig = NULL;
char *buf = NULL;
size_t len = 0;
int rc = 0;
- rc = agent_pksign_do (ctrl, desc_text, &s_sig, ignore_cache);
+ rc = agent_pksign_do (ctrl, desc_text, &s_sig, cache_mode);
if (rc)
goto leave;
diff --git a/agent/query.c b/agent/query.c
index d3b42a416..c1e4dbacc 100644
--- a/agent/query.c
+++ b/agent/query.c
@@ -49,7 +49,7 @@
#define LOCK_TIMEOUT (1*60)
-static ASSUAN_CONTEXT entry_ctx = NULL;
+static assuan_context_t entry_ctx = NULL;
#ifdef USE_GNU_PTH
static pth_mutex_t entry_lock;
#endif
@@ -82,6 +82,30 @@ initialize_module_query (void)
+static void
+dump_mutex_state (pth_mutex_t *m)
+{
+ if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
+ log_printf ("not_initialized");
+ else if (!(m->mx_state & PTH_MUTEX_LOCKED))
+ log_printf ("not_locked");
+ else
+ log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
+}
+
+
+/* This function may be called to print infromation pertaining to the
+ current state of this module to the log. */
+void
+agent_query_dump_state (void)
+{
+ log_info ("agent_query_dump_state: entry_lock=");
+ dump_mutex_state (&entry_lock);
+ log_printf ("\n");
+ log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld\n",
+ entry_ctx, (long)assuan_get_pid (entry_ctx));
+}
+
/* Unlock the pinentry so that another thread can start one and
disconnect that pinentry - we do this after the unlock so that a
@@ -90,8 +114,9 @@ initialize_module_query (void)
static int
unlock_pinentry (int rc)
{
- ASSUAN_CONTEXT ctx = entry_ctx;
+ assuan_context_t ctx = entry_ctx;
+ entry_ctx = NULL;
#ifdef USE_GNU_PTH
if (!pth_mutex_release (&entry_lock))
{
@@ -100,7 +125,6 @@ unlock_pinentry (int rc)
rc = gpg_error (GPG_ERR_INTERNAL);
}
#endif
- entry_ctx = NULL;
assuan_disconnect (ctx);
return rc;
}