--- trunk/src/OEPassphraseCBDlg.c 2006/04/13 07:41:30 18 +++ trunk/src/OEPassphraseCBDlg.c 2006/06/04 10:12:47 19 @@ -28,89 +28,65 @@ #include "GPGOE.h" -/* Structure for the passphrase cache. */ -struct pass_cache_s { - struct pass_cache_s *next; - char *keyid; - char *pass; -}; -typedef struct pass_cache_s *pass_cache_t; - /* Structure for the passphrase callback. */ struct pass_cb_s { const char *uid_hint; const char *passphrase_info; char keyid[8+2]; char *pass; - pass_cache_t cache; HWND main_wnd; int cancel; int prev_was_bad; }; -/* Global passphrase cache. */ -static pass_cache_t the_cache = NULL; - +extern char gpgoe_pass_cache[HASH_BUCKETS][256]; -/* Release the passphrase cache @ctx and invalidate all passphrases. */ -static void -invalidate_cache (pass_cache_t ctx) -{ - pass_cache_t c; - while (ctx) { - c = ctx->next; - free_if_alloc (ctx->keyid); - wipememory (ctx->pass, strlen (ctx->pass)); - free_if_alloc (ctx->pass); - ctx = c; - } -} +DWORD hash_string (const char *str_param); -/* Put the passphrase @pass into the passphrase cache @ctx. */ +/* Store the passphrase @pass in the hash table using the keyid @keyid + as the index. */ static void -passphrase_put (pass_cache_t *ctx, const char *keyid, const char *pass) +passphrase_put (char ctx[HASH_BUCKETS][256], const char *keyid, const char *pass) { - pass_cache_t c, n; + int pos = hash_string (keyid) % HASH_BUCKETS; + int n = 0; - /* check if the item is already present. */ - for (n = *ctx; n; n = n->next) { - if (!strcmp (n->keyid, keyid)) - return; - } - - c = xcalloc (1, sizeof *c); - c->keyid = xstrdup (keyid); - c->pass = xstrdup (pass); - - if (!*ctx) - *ctx = c; - else { - for (n = *ctx; n->next; n = n->next) - ; - n->next = c; + while (n < HASH_BUCKETS) { + if (strlen (ctx[(pos+n) % HASH_BUCKETS]) == 0) { + memcpy (ctx[(pos+n) % HASH_BUCKETS], keyid, strlen (keyid)); + strncpy (ctx[(pos+n) % HASH_BUCKETS]+strlen (keyid), pass, 240); + break; + } + n++; } } -/* Return the passphrase for the key with the keyid @keyid - or NULL if the passphrase was not cached for this key. */ +/* Return the requested passphrase from the hash table @ctx + using the keyid @keyid as the index. Or NULL if there is + no stored passphrase. */ static const char* -passphrase_get (pass_cache_t ctx, const char *keyid) +passphrase_get (char ctx[HASH_BUCKETS][256], const char *keyid) { - pass_cache_t c; + const char *item; + int pos = hash_string (keyid) % HASH_BUCKETS; + int n=0; - for (c = ctx; c; c = c->next) { - if (!strcmp (c->keyid, keyid)) - return c->pass; + item = gpgoe_pass_cache[pos]; + while (strncmp (item, keyid, strlen (keyid)) && + n < HASH_BUCKETS) { + item = ctx[(pos+n) % HASH_BUCKETS]; + n++; } + + if (strlen (item) > 0 && !strncmp (item, keyid, strlen (keyid))) + return item+strlen (keyid); return NULL; } - - /* Extract public key algorithm from passwd info. */ const char* get_pubkey_algo (const char *passphrase_info) @@ -197,7 +173,8 @@ ctx->pass = xcalloc (1, n+2); GetDlgItemText (dlg, IDC_DECRYPT_PWD, ctx->pass, n+1); - /*passphrase_put (&the_cache, ctx->keyid, ctx->pass);*/ + if (gpgoe_get_active_modes () & GPGOE_MODE_CACHEPASS) + passphrase_put (gpgoe_pass_cache, ctx->keyid, ctx->pass); EndDialog (dlg, TRUE); break; } @@ -219,6 +196,7 @@ const char *pass; DWORD nwritten = 0; + assert (cb); cb->prev_was_bad = prev_was_bad; if (prev_was_bad && !cb->cancel) { wipememory (cb->pass, strlen (cb->pass)); @@ -230,7 +208,8 @@ memset (cb->keyid, 0, sizeof (cb->keyid)); memcpy (cb->keyid, cb->passphrase_info+8, 8); - if (the_cache && (pass=passphrase_get (the_cache, cb->keyid))) + pass = passphrase_get (gpgoe_pass_cache, cb->keyid); + if (pass) cb->pass = xstrdup (pass); else DialogBoxParam (mod_hinst_dll, (LPCTSTR)IDD_DECRYPT, @@ -280,10 +259,12 @@ } -/* Release the passphrase cache. */ +/* Reset the passphrase cache. */ void -free_pass_cache (void) +reset_pass_cache (void) { - invalidate_cache (the_cache); - the_cache = NULL; + int i; + + for (i=0; i < HASH_BUCKETS; i++) + wipememory (gpgoe_pass_cache[i], 256); }