mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
agent: Serialize access to passphrase cache.
* agent/cache.c (encryption_lock): Remove. (cache_lock): New. Now, we have coarse grain lock to serialize entire cache access. (initialize_module_cache): Use CACHE_LOCK. (init_encryption, new_data): Remove ENCRYPTION_LOCK. (agent_flush_cache, agent_put_cache, agent_get_cache): Lock the cache. -- GnuPG-bug-id: 3027 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
f1dc34f502
commit
ebe12be034
@ -31,9 +31,8 @@
|
|||||||
/* The size of the encryption key in bytes. */
|
/* The size of the encryption key in bytes. */
|
||||||
#define ENCRYPTION_KEYSIZE (128/8)
|
#define ENCRYPTION_KEYSIZE (128/8)
|
||||||
|
|
||||||
/* A mutex used to protect the encryption. This is required because
|
/* A mutex used to serialize access to the cache. */
|
||||||
we use one context to do all encryption and decryption. */
|
static npth_mutex_t cache_lock;
|
||||||
static npth_mutex_t encryption_lock;
|
|
||||||
/* The encryption context. This is the only place where the
|
/* The encryption context. This is the only place where the
|
||||||
encryption key for all cached entries is available. It would be nice
|
encryption key for all cached entries is available. It would be nice
|
||||||
to keep this (or just the key) in some hardware device, for example
|
to keep this (or just the key) in some hardware device, for example
|
||||||
@ -76,7 +75,7 @@ initialize_module_cache (void)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = npth_mutex_init (&encryption_lock, NULL);
|
err = npth_mutex_init (&cache_lock, NULL);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
log_fatal ("error initializing cache module: %s\n", strerror (err));
|
log_fatal ("error initializing cache module: %s\n", strerror (err));
|
||||||
@ -102,15 +101,10 @@ init_encryption (void)
|
|||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
void *key;
|
void *key;
|
||||||
int res;
|
|
||||||
|
|
||||||
if (encryption_handle)
|
if (encryption_handle)
|
||||||
return 0; /* Shortcut - Already initialized. */
|
return 0; /* Shortcut - Already initialized. */
|
||||||
|
|
||||||
res = npth_mutex_lock (&encryption_lock);
|
|
||||||
if (res)
|
|
||||||
log_fatal ("failed to acquire cache encryption mutex: %s\n", strerror (res));
|
|
||||||
|
|
||||||
err = gcry_cipher_open (&encryption_handle, GCRY_CIPHER_AES128,
|
err = gcry_cipher_open (&encryption_handle, GCRY_CIPHER_AES128,
|
||||||
GCRY_CIPHER_MODE_AESWRAP, GCRY_CIPHER_SECURE);
|
GCRY_CIPHER_MODE_AESWRAP, GCRY_CIPHER_SECURE);
|
||||||
if (!err)
|
if (!err)
|
||||||
@ -133,10 +127,6 @@ init_encryption (void)
|
|||||||
log_error ("error initializing cache encryption context: %s\n",
|
log_error ("error initializing cache encryption context: %s\n",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
|
|
||||||
res = npth_mutex_unlock (&encryption_lock);
|
|
||||||
if (res)
|
|
||||||
log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res));
|
|
||||||
|
|
||||||
return err? gpg_error (GPG_ERR_NOT_INITIALIZED) : 0;
|
return err? gpg_error (GPG_ERR_NOT_INITIALIZED) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +145,6 @@ new_data (const char *string, struct secret_data_s **r_data)
|
|||||||
struct secret_data_s *d, *d_enc;
|
struct secret_data_s *d, *d_enc;
|
||||||
size_t length;
|
size_t length;
|
||||||
int total;
|
int total;
|
||||||
int res;
|
|
||||||
|
|
||||||
*r_data = NULL;
|
*r_data = NULL;
|
||||||
|
|
||||||
@ -186,17 +175,9 @@ new_data (const char *string, struct secret_data_s **r_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
d_enc->totallen = total;
|
d_enc->totallen = total;
|
||||||
res = npth_mutex_lock (&encryption_lock);
|
|
||||||
if (res)
|
|
||||||
log_fatal ("failed to acquire cache encryption mutex: %s\n",
|
|
||||||
strerror (res));
|
|
||||||
|
|
||||||
err = gcry_cipher_encrypt (encryption_handle, d_enc->data, total,
|
err = gcry_cipher_encrypt (encryption_handle, d_enc->data, total,
|
||||||
d->data, total - 8);
|
d->data, total - 8);
|
||||||
xfree (d);
|
xfree (d);
|
||||||
res = npth_mutex_unlock (&encryption_lock);
|
|
||||||
if (res)
|
|
||||||
log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res));
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
xfree (d_enc);
|
xfree (d_enc);
|
||||||
@ -281,10 +262,15 @@ void
|
|||||||
agent_flush_cache (void)
|
agent_flush_cache (void)
|
||||||
{
|
{
|
||||||
ITEM r;
|
ITEM r;
|
||||||
|
int res;
|
||||||
|
|
||||||
if (DBG_CACHE)
|
if (DBG_CACHE)
|
||||||
log_debug ("agent_flush_cache\n");
|
log_debug ("agent_flush_cache\n");
|
||||||
|
|
||||||
|
res = npth_mutex_lock (&cache_lock);
|
||||||
|
if (res)
|
||||||
|
log_fatal ("failed to acquire cache mutex: %s\n", strerror (res));
|
||||||
|
|
||||||
for (r=thecache; r; r = r->next)
|
for (r=thecache; r; r = r->next)
|
||||||
{
|
{
|
||||||
if (r->pw)
|
if (r->pw)
|
||||||
@ -296,6 +282,10 @@ agent_flush_cache (void)
|
|||||||
r->accessed = 0;
|
r->accessed = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res = npth_mutex_unlock (&cache_lock);
|
||||||
|
if (res)
|
||||||
|
log_fatal ("failed to release cache mutex: %s\n", strerror (res));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -321,6 +311,11 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
|
|||||||
{
|
{
|
||||||
gpg_error_t err = 0;
|
gpg_error_t err = 0;
|
||||||
ITEM r;
|
ITEM r;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = npth_mutex_lock (&cache_lock);
|
||||||
|
if (res)
|
||||||
|
log_fatal ("failed to acquire cache mutex: %s\n", strerror (res));
|
||||||
|
|
||||||
if (DBG_CACHE)
|
if (DBG_CACHE)
|
||||||
log_debug ("agent_put_cache '%s' (mode %d) requested ttl=%d\n",
|
log_debug ("agent_put_cache '%s' (mode %d) requested ttl=%d\n",
|
||||||
@ -336,7 +331,7 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((!ttl && data) || cache_mode == CACHE_MODE_IGNORE)
|
if ((!ttl && data) || cache_mode == CACHE_MODE_IGNORE)
|
||||||
return 0;
|
goto out;
|
||||||
|
|
||||||
for (r=thecache; r; r = r->next)
|
for (r=thecache; r; r = r->next)
|
||||||
{
|
{
|
||||||
@ -386,6 +381,12 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
|
|||||||
if (err)
|
if (err)
|
||||||
log_error ("error inserting cache item: %s\n", gpg_strerror (err));
|
log_error ("error inserting cache item: %s\n", gpg_strerror (err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
res = npth_mutex_unlock (&cache_lock);
|
||||||
|
if (res)
|
||||||
|
log_fatal ("failed to release cache mutex: %s\n", strerror (res));
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,15 +406,18 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
|
|||||||
if (cache_mode == CACHE_MODE_IGNORE)
|
if (cache_mode == CACHE_MODE_IGNORE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
res = npth_mutex_lock (&cache_lock);
|
||||||
|
if (res)
|
||||||
|
log_fatal ("failed to acquire cache mutex: %s\n", strerror (res));
|
||||||
|
|
||||||
if (!key)
|
if (!key)
|
||||||
{
|
{
|
||||||
key = last_stored_cache_key;
|
key = last_stored_cache_key;
|
||||||
if (!key)
|
if (!key)
|
||||||
return NULL;
|
goto out;
|
||||||
last_stored = 1;
|
last_stored = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (DBG_CACHE)
|
if (DBG_CACHE)
|
||||||
log_debug ("agent_get_cache '%s' (mode %d)%s ...\n",
|
log_debug ("agent_get_cache '%s' (mode %d)%s ...\n",
|
||||||
key, cache_mode,
|
key, cache_mode,
|
||||||
@ -440,17 +444,9 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
|
|||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = npth_mutex_lock (&encryption_lock);
|
|
||||||
if (res)
|
|
||||||
log_fatal ("failed to acquire cache encryption mutex: %s\n",
|
|
||||||
strerror (res));
|
|
||||||
err = gcry_cipher_decrypt (encryption_handle,
|
err = gcry_cipher_decrypt (encryption_handle,
|
||||||
value, r->pw->totallen - 8,
|
value, r->pw->totallen - 8,
|
||||||
r->pw->data, r->pw->totallen);
|
r->pw->data, r->pw->totallen);
|
||||||
res = npth_mutex_unlock (&encryption_lock);
|
|
||||||
if (res)
|
|
||||||
log_fatal ("failed to release cache encryption mutex: %s\n",
|
|
||||||
strerror (res));
|
|
||||||
}
|
}
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -459,13 +455,18 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
|
|||||||
log_error ("retrieving cache entry '%s' failed: %s\n",
|
log_error ("retrieving cache entry '%s' failed: %s\n",
|
||||||
key, gpg_strerror (err));
|
key, gpg_strerror (err));
|
||||||
}
|
}
|
||||||
return value;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (DBG_CACHE)
|
if (DBG_CACHE && value == NULL)
|
||||||
log_debug ("... miss\n");
|
log_debug ("... miss\n");
|
||||||
|
|
||||||
return NULL;
|
out:
|
||||||
|
res = npth_mutex_unlock (&cache_lock);
|
||||||
|
if (res)
|
||||||
|
log_fatal ("failed to release cache mutex: %s\n", strerror (res));
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user