1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00
This commit is contained in:
Werner Koch 2006-10-19 14:22:06 +00:00
parent 0f49adb44e
commit df52700f5c
41 changed files with 6137 additions and 6033 deletions

View file

@ -1,3 +1,9 @@
2006-10-19 Werner Koch <wk@g10code.com>
* findkey.c (unprotect): Use it to avoid unnecessary calls to
agent_askpin.
* call-pinentry.c (pinentry_active_p): New.
2006-10-17 Werner Koch <wk@g10code.com>
* Makefile.am (gpg_agent_LDADD): Link to libcommonpth.

View file

@ -205,6 +205,7 @@ int agent_key_available (const unsigned char *grip);
void initialize_module_query (void);
void agent_query_dump_state (void);
void agent_reset_query (ctrl_t ctrl);
int pinentry_active_p (ctrl_t ctrl, int waitseconds);
int agent_askpin (ctrl_t ctrl,
const char *desc_text, const char *prompt_text,
const char *inital_errtext,

View file

@ -300,6 +300,40 @@ start_pinentry (ctrl_t ctrl)
return 0;
}
/* Returns True is the pinentry is currently active. If WAITSECONDS is
greater than zero the function will wait for this many seconds
before returning. */
int
pinentry_active_p (ctrl_t ctrl, int waitseconds)
{
if (waitseconds > 0)
{
pth_event_t evt;
int rc;
evt = pth_event (PTH_EVENT_TIME, pth_timeout (waitseconds, 0));
if (!pth_mutex_acquire (&entry_lock, 0, evt))
{
if (pth_event_occurred (evt))
rc = gpg_error (GPG_ERR_TIMEOUT);
else
rc = gpg_error (GPG_ERR_INTERNAL);
pth_event_free (evt, PTH_FREE_THIS);
return rc;
}
pth_event_free (evt, PTH_FREE_THIS);
}
else
{
if (!pth_mutex_acquire (&entry_lock, 1, NULL))
return gpg_error (GPG_ERR_LOCKED);
}
if (!pth_mutex_release (&entry_lock))
log_error ("failed to release the entry lock at %d\n", __LINE__);
return 0;
}
static int
getpin_cb (void *opaque, const void *buffer, size_t length)

View file

@ -30,6 +30,7 @@
#include <unistd.h>
#include <sys/stat.h>
#include <assert.h>
#include <pth.h> /* (we use pth_sleep) */
#include "agent.h"
@ -41,7 +42,7 @@ struct try_unprotect_arg_s {
/* Write an S-expression formatted key to our key storage. With FORCE
pased as true an existsing key with the given GRIP will get
pased as true an existing key with the given GRIP will get
overwritten. */
int
agent_write_private_key (const unsigned char *grip,
@ -253,6 +254,7 @@ unprotect (ctrl_t ctrl, const char *desc_text,
void *cache_marker;
const char *pw;
retry:
pw = agent_get_cache (hexgrip, cache_mode, &cache_marker);
if (pw)
{
@ -266,6 +268,29 @@ unprotect (ctrl_t ctrl, const char *desc_text,
}
rc = 0;
}
/* If the pinentry is currently in use, we wait up to 60 seconds
for it close and check the cache again. This solves a common
situation where several requests for unprotecting a key have
been made but the user is still entering the passphrase for
the first request. Because all requests to agent_askpin are
serialized they would then pop up one after the other to
request the passphrase - despite that the user has already
entered it and is then available in the cache. This
implementation is not race free but in the worst case the
user has to enter the passphrase only once more. */
if (pinentry_active_p (ctrl, 0))
{
/* Active - wait */
if (!pinentry_active_p (ctrl, 60))
{
/* We need to give the other thread a chance to actually put
it into the cache. */
pth_sleep (1);
goto retry;
}
/* Timeout - better call pinentry now the plain way. */
}
}
pi = gcry_calloc_secure (1, sizeof (*pi) + 100);