mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
* no-pth.c, Makefile.am: Removed.
* call-scd.c: Seirialized all scdaeom access when using Pth. * cache.c: Made the cache Pth-thread-safe. (agent_unlock_cache_entry): New. * findkey.c (unprotect): Unlock the returned cache value. * command.c (cmd_get_passphrase): Ditto. * gpg-agent.c (main): Register pth_read/write with Assuan.
This commit is contained in:
parent
72f48d9e8a
commit
b209c17be9
12 changed files with 416 additions and 162 deletions
|
@ -40,6 +40,7 @@ struct cache_item_s {
|
|||
time_t created;
|
||||
time_t accessed;
|
||||
int ttl; /* max. lifetime given in seonds */
|
||||
int lockcount;
|
||||
struct secret_data_s *pw;
|
||||
char key[1];
|
||||
};
|
||||
|
@ -87,7 +88,7 @@ housekeeping (void)
|
|||
/* first expire the actual data */
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (r->pw && r->accessed + r->ttl < current)
|
||||
if (!r->lockcount && r->pw && r->accessed + r->ttl < current)
|
||||
{
|
||||
if (DBG_CACHE)
|
||||
log_debug (" expired `%s' (%ds after last access)\n",
|
||||
|
@ -99,10 +100,10 @@ housekeeping (void)
|
|||
}
|
||||
|
||||
/* second, make sure that we also remove them based on the created stamp so
|
||||
that the used has to enter it from time to time. We do this every hour */
|
||||
that the user has to enter it from time to time. We do this every hour */
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (r->pw && r->created + 60*60 < current)
|
||||
if (!r->lockcount && r->pw && r->created + 60*60 < current)
|
||||
{
|
||||
if (DBG_CACHE)
|
||||
log_debug (" expired `%s' (1h after creation)\n", r->key);
|
||||
|
@ -118,15 +119,27 @@ housekeeping (void)
|
|||
{
|
||||
if (!r->pw && r->accessed + 60*30 < current)
|
||||
{
|
||||
ITEM r2 = r->next;
|
||||
if (DBG_CACHE)
|
||||
log_debug (" removed `%s' (slot not used for 30m)\n", r->key);
|
||||
xfree (r);
|
||||
if (!rprev)
|
||||
thecache = r2;
|
||||
if (r->lockcount)
|
||||
{
|
||||
log_error ("can't remove unused cache entry `%s' due to"
|
||||
" lockcount=%d\n",
|
||||
r->key, r->lockcount);
|
||||
r->accessed += 60*10; /* next error message in 10 minutes */
|
||||
rprev = r;
|
||||
r = r->next;
|
||||
}
|
||||
else
|
||||
rprev->next = r2;
|
||||
r = r2;
|
||||
{
|
||||
ITEM r2 = r->next;
|
||||
if (DBG_CACHE)
|
||||
log_debug (" removed `%s' (slot not used for 30m)\n", r->key);
|
||||
xfree (r);
|
||||
if (!rprev)
|
||||
thecache = r2;
|
||||
else
|
||||
rprev->next = r2;
|
||||
r = r2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -158,7 +171,7 @@ agent_put_cache (const char *key, const char *data, int ttl)
|
|||
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if ( !strcmp (r->key, key))
|
||||
if (!r->lockcount && !strcmp (r->key, key))
|
||||
break;
|
||||
}
|
||||
if (r)
|
||||
|
@ -206,34 +219,67 @@ agent_put_cache (const char *key, const char *data, int ttl)
|
|||
|
||||
/* Try to find an item in the cache */
|
||||
const char *
|
||||
agent_get_cache (const char *key)
|
||||
agent_get_cache (const char *key, void **cache_id)
|
||||
{
|
||||
ITEM r;
|
||||
int count = 0;
|
||||
|
||||
if (DBG_CACHE)
|
||||
log_debug ("agent_get_cache `%s'...\n", key);
|
||||
housekeeping ();
|
||||
|
||||
/* FIXME: Returning pointers is not thread safe - add a reference
|
||||
counter */
|
||||
for (r=thecache; r; r = r->next, count++)
|
||||
/* first try to find one with no locks - this is an updated cache
|
||||
entry: We might have entries with a lockcount and without a
|
||||
lockcount. */
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (r->pw && !strcmp (r->key, key))
|
||||
if (!r->lockcount && r->pw && !strcmp (r->key, key))
|
||||
{
|
||||
/* put_cache does only put strings into the cache, so we
|
||||
don't need the lengths */
|
||||
r->accessed = gnupg_get_time ();
|
||||
if (DBG_CACHE)
|
||||
log_debug ("... hit\n");
|
||||
r->lockcount++;
|
||||
*cache_id = r;
|
||||
return r->pw->data;
|
||||
}
|
||||
}
|
||||
/* again, but this time get even one with a lockcount set */
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (r->pw && !strcmp (r->key, key))
|
||||
{
|
||||
r->accessed = gnupg_get_time ();
|
||||
if (DBG_CACHE)
|
||||
log_debug ("... hit (locked)\n");
|
||||
r->lockcount++;
|
||||
*cache_id = r;
|
||||
return r->pw->data;
|
||||
}
|
||||
}
|
||||
if (DBG_CACHE)
|
||||
log_debug ("... miss\n");
|
||||
|
||||
*cache_id = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
agent_unlock_cache_entry (void **cache_id)
|
||||
{
|
||||
ITEM r;
|
||||
|
||||
for (r=thecache; r; r = r->next)
|
||||
{
|
||||
if (r == *cache_id)
|
||||
{
|
||||
if (!r->lockcount)
|
||||
log_error ("trying to unlock non-locked cache entry `%s'\n",
|
||||
r->key);
|
||||
else
|
||||
r->lockcount--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue