From 7911a5ed86925eb24ce2df962965ee3ee51c47ff Mon Sep 17 00:00:00 2001 From: David Shaw Date: Fri, 8 Nov 2002 03:31:21 +0000 Subject: [PATCH] * keyring.h, keyring.c (keyring_register_filename): Return the pointer if a given keyring is registered twice. * keydb.h, keydb.c (keydb_add_resource): Use flags to indicate a default keyring. (keydb_locate_writable): Prefer the default keyring if possible. * g10.c (main): Add --default-keyring option. --- g10/ChangeLog | 11 ++++++++++ g10/g10.c | 8 ++++++- g10/keydb.c | 61 +++++++++++++++++++++++++++++++++++++++------------ g10/keydb.h | 7 +++++- g10/keyring.c | 29 ++++++++++++++---------- g10/keyring.h | 2 +- 6 files changed, 89 insertions(+), 29 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 769f945cb..7201918f1 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,14 @@ +2002-11-07 David Shaw + + * keyring.h, keyring.c (keyring_register_filename): Return the + pointer if a given keyring is registered twice. + + * keydb.h, keydb.c (keydb_add_resource): Use flags to indicate a + default keyring. + (keydb_locate_writable): Prefer the default keyring if possible. + + * g10.c (main): Add --default-keyring option. + 2002-11-06 David Shaw * options.h, g10.c (main), trustdb.c (ask_ownertrust): Add diff --git a/g10/g10.c b/g10/g10.c index 19c1828e6..d83589eb1 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -141,6 +141,7 @@ enum cmd_and_opt_values { aNull = 0, oAnswerNo, oDefCertCheckLevel, oKeyring, + oDefaultKeyring, oSecretKeyring, oShowKeyring, oDefaultKey, @@ -420,6 +421,7 @@ static ARGPARSE_OPTS opts[] = { { oAnswerYes, "yes", 0, N_("assume yes on most questions")}, { oAnswerNo, "no", 0, N_("assume no on most questions")}, { oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")}, + { oDefaultKeyring, "default-keyring",2, "@" }, { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")}, { oShowKeyring, "show-keyring", 0, N_("show which keyring a listed key is on")}, { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")}, @@ -1368,6 +1370,10 @@ main( int argc, char **argv ) case oAnswerYes: opt.answer_yes = 1; break; case oAnswerNo: opt.answer_no = 1; break; case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; + case oDefaultKeyring: + sl=append_to_strlist( &nrings, pargs.r.ret_str); + sl->flags=2; + break; case oShowKeyring: opt.show_keyring = 1; break; case oDebug: opt.debug |= pargs.r.ret_ulong; break; case oDebugAll: opt.debug = ~0; break; @@ -2052,7 +2058,7 @@ main( int argc, char **argv ) if( !nrings || default_keyring ) /* add default ring */ keydb_add_resource ("pubring" EXTSEP_S "gpg", 0, 0); for(sl = nrings; sl; sl = sl->next ) - keydb_add_resource ( sl->d, 0, 0 ); + keydb_add_resource ( sl->d, sl->flags, 0 ); } FREE_STRLIST(nrings); FREE_STRLIST(sec_nrings); diff --git a/g10/keydb.c b/g10/keydb.c index d8dd83fe6..7b31e2dd0 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -55,6 +55,7 @@ struct resource_item { static struct resource_item all_resources[MAX_KEYDB_RESOURCES]; static int used_resources; +static void *default_keyring=NULL; struct keydb_handle { int locked; @@ -75,14 +76,17 @@ static void unlock_all (KEYDB_HANDLE hd); * created if it does not exist. * Note: this function may be called before secure memory is * available. + * Flag 1 == force + * Flag 2 == default */ int -keydb_add_resource (const char *url, int force, int secret) +keydb_add_resource (const char *url, int flags, int secret) { static int any_secret, any_public; const char *resname = url; IOBUF iobuf = NULL; char *filename = NULL; + int force=(flags&1); int rc = 0; KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; void *token; @@ -189,19 +193,29 @@ keydb_add_resource (const char *url, int force, int secret) iobuf_ioctl (NULL, 2, 0, (char*)filename); } /* end file creation */ - token = keyring_register_filename (filename, secret); - if (!token) - ; /* already registered - ignore it */ - else if (used_resources >= MAX_KEYDB_RESOURCES) - rc = G10ERR_RESOURCE_LIMIT; - else - { - all_resources[used_resources].type = rt; - all_resources[used_resources].u.kr = NULL; /* Not used here */ - all_resources[used_resources].token = token; - all_resources[used_resources].secret = secret; - used_resources++; - } + if(keyring_register_filename (filename, secret, &token)) + { + if (used_resources >= MAX_KEYDB_RESOURCES) + rc = G10ERR_RESOURCE_LIMIT; + else + { + if(flags&2) + default_keyring=token; + all_resources[used_resources].type = rt; + all_resources[used_resources].u.kr = NULL; /* Not used here */ + all_resources[used_resources].token = token; + all_resources[used_resources].secret = secret; + used_resources++; + } + } + else + { + /* This keyring was already registered, so ignore it. + However, we can still mark it as default even if it was + already registered. */ + if(flags&2) + default_keyring=token; + } break; default: @@ -536,6 +550,25 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) if (rc) return rc; + /* If we have a default set, try that one first */ + if(default_keyring) + { + for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) + { + if(hd->active[hd->current].token==default_keyring) + { + if(keyring_is_writable (hd->active[hd->current].token)) + return 0; + else + break; + } + } + + rc = keydb_search_reset (hd); /* this does reset hd->current */ + if (rc) + return rc; + } + for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) { switch (hd->active[hd->current].type) diff --git a/g10/keydb.h b/g10/keydb.h index ebb63a4ba..c4b12dde5 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -143,7 +143,12 @@ struct keydb_search_desc { }; /*-- keydb.c --*/ -int keydb_add_resource (const char *url, int force, int secret); + +/* + Flag 1 == force + Flag 2 == default +*/ +int keydb_add_resource (const char *url, int flags, int secret); KEYDB_HANDLE keydb_new (int secret); void keydb_release (KEYDB_HANDLE hd); const char *keydb_get_resource_name (KEYDB_HANDLE hd); diff --git a/g10/keyring.c b/g10/keyring.c index 3160b1c37..405167122 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -190,25 +190,28 @@ update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off) } } - - - /* - * Register a filename for plain keyring files. Returns a pointer to - * be used to create a handles etc or NULL to indicate that it has - * already been registered */ -void * -keyring_register_filename (const char *fname, int secret) + * Register a filename for plain keyring files. ptr is set to a + * pointer to be used to create a handles etc, or the already-issued + * pointer if it has already been registered. The function returns 1 + * if a new keyring was registered. +*/ +int +keyring_register_filename (const char *fname, int secret, void **ptr) { KR_NAME kr; if (active_handles) BUG (); /* We don't allow that */ - for (kr=kr_names; kr; kr = kr->next) { + for (kr=kr_names; kr; kr = kr->next) + { if ( !compare_filenames (kr->fname, fname) ) - return NULL; /* already registered */ - } + { + *ptr=kr; + return 0; /* already registered */ + } + } kr = m_alloc (sizeof *kr + strlen (fname)); strcpy (kr->fname, fname); @@ -224,7 +227,9 @@ keyring_register_filename (const char *fname, int secret) if (!kr_offtbl) kr_offtbl = new_offset_hash_table (); - return kr; + *ptr=kr; + + return 1; } int diff --git a/g10/keyring.h b/g10/keyring.h index cb8e404a4..1a6d1f976 100644 --- a/g10/keyring.h +++ b/g10/keyring.h @@ -26,7 +26,7 @@ typedef struct keyring_handle *KEYRING_HANDLE; -void *keyring_register_filename (const char *fname, int secret); +int keyring_register_filename (const char *fname, int secret, void **ptr); int keyring_is_writable (void *token); KEYRING_HANDLE keyring_new (void *token, int secret);