diff options
-rw-r--r-- | g10/keydb.c | 57 | ||||
-rw-r--r-- | kbx/keybox-init.c | 24 | ||||
-rw-r--r-- | kbx/keybox.h | 3 | ||||
-rw-r--r-- | sm/keydb.c | 34 | ||||
-rw-r--r-- | sm/keydb.h | 4 |
5 files changed, 68 insertions, 54 deletions
diff --git a/g10/keydb.c b/g10/keydb.c index e1814feba..3ee9dfd4e 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -60,7 +60,10 @@ struct resource_item static struct resource_item all_resources[MAX_KEYDB_RESOURCES]; static int used_resources; -static void *primary_keyring=NULL; + +/* A pointer used to check for the primary key database by comparing + to the struct resource_item's TOKEN. */ +static void *primary_keydb; /* This is a simple cache used to return the last result of a @@ -261,7 +264,7 @@ keyblock_cache_clear (struct keydb_handle *hd) the keyring or keybox will be created. Return 0 if it is okay to access the specified file. */ -static int +static gpg_error_t maybe_create_keyring_or_box (char *filename, int is_box, int force_create) { dotlock_t lockhd = NULL; @@ -592,7 +595,7 @@ keydb_add_resource (const char *url, unsigned int flags) int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY); int is_default = !!(flags&KEYDB_RESOURCE_FLAG_DEFAULT); int is_gpgvdef = !!(flags&KEYDB_RESOURCE_FLAG_GPGVDEF); - int rc = 0; + gpg_error_t err = 0; KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; void *token; @@ -613,7 +616,7 @@ keydb_add_resource (const char *url, unsigned int flags) else if (strchr (resname, ':')) { log_error ("invalid key resource URL '%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; } #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ @@ -708,22 +711,22 @@ keydb_add_resource (const char *url, unsigned int flags) { case KEYDB_RESOURCE_TYPE_NONE: log_error ("unknown type of key resource '%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; case KEYDB_RESOURCE_TYPE_KEYRING: - rc = maybe_create_keyring_or_box (filename, 0, create); - if (rc) + err = maybe_create_keyring_or_box (filename, 0, create); + if (err) goto leave; if (keyring_register_filename (filename, read_only, &token)) { if (used_resources >= MAX_KEYDB_RESOURCES) - rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); + err = gpg_error (GPG_ERR_RESOURCE_LIMIT); else { if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) - primary_keyring = token; + primary_keydb = token; all_resources[used_resources].type = rt; all_resources[used_resources].u.kr = NULL; /* Not used here */ all_resources[used_resources].token = token; @@ -736,26 +739,25 @@ keydb_add_resource (const char *url, unsigned int flags) However, we can still mark it as primary even if it was already registered. */ if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) - primary_keyring = token; + primary_keydb = token; } break; case KEYDB_RESOURCE_TYPE_KEYBOX: { - rc = maybe_create_keyring_or_box (filename, 1, create); - if (rc) + err = maybe_create_keyring_or_box (filename, 1, create); + if (err) goto leave; - /* FIXME: How do we register a read-only keybox? */ - token = keybox_register_file (filename, 0); - if (token) + err = keybox_register_file (filename, 0, &token); + if (!err) { if (used_resources >= MAX_KEYDB_RESOURCES) - rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); + err = gpg_error (GPG_ERR_RESOURCE_LIMIT); else { - /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */ - /* primary_keyring = token; */ + if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) + primary_keydb = token; all_resources[used_resources].type = rt; all_resources[used_resources].u.kb = NULL; /* Not used here */ all_resources[used_resources].token = token; @@ -766,32 +768,31 @@ keydb_add_resource (const char *url, unsigned int flags) used_resources++; } } - else + else if (gpg_err_code (err) == GPG_ERR_EEXIST) { /* Already registered. We will mark it as the primary key if requested. */ - /* FIXME: How to do that? Change the keybox interface? */ - /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */ - /* primary_keyring = token; */ + if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) + primary_keydb = token; } } break; default: log_error ("resource type of '%s' not supported\n", url); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; } /* fixme: check directory permissions and print a warning */ leave: - if (rc) - log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (rc)); + if (err) + log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (err)); else any_registered = 1; xfree (filename); - return rc; + return err; } @@ -1685,11 +1686,11 @@ keydb_locate_writable (KEYDB_HANDLE hd) return rc; /* If we have a primary set, try that one first */ - if (primary_keyring) + if (primary_keydb) { for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) { - if(hd->active[hd->current].token==primary_keyring) + if(hd->active[hd->current].token == primary_keydb) { if(keyring_is_writable (hd->active[hd->current].token)) return 0; diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index e91911c37..3ff592eaf 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -30,23 +30,30 @@ static KB_NAME kb_names; -/* Register a filename for plain keybox files. Returns a pointer to - be used to create a handles and so on. Returns NULL to indicate - that FNAME has already been registered. */ -void * -keybox_register_file (const char *fname, int secret) +/* Register a filename for plain keybox files. Returns 0 on success, + * GPG_ERR_EEXIST if it has already been registered, or another error + * code. On success or with error code GPG_ERR_EEXIST a token usable + * to access the keybox handle is stored at R_TOKEN, NULL is stored + * for all other errors. */ +gpg_error_t +keybox_register_file (const char *fname, int secret, void **r_token) { KB_NAME kr; + *r_token = NULL; + for (kr=kb_names; kr; kr = kr->next) { if (same_file_p (kr->fname, fname) ) - return NULL; /* Already registered. */ + { + *r_token = kr; + return gpg_error (GPG_ERR_EEXIST); /* Already registered. */ + } } kr = xtrymalloc (sizeof *kr + strlen (fname)); if (!kr) - return NULL; + return gpg_error_from_syserror (); strcpy (kr->fname, fname); kr->secret = !!secret; @@ -64,7 +71,8 @@ keybox_register_file (const char *fname, int secret) /* if (!kb_offtbl) */ /* kb_offtbl = new_offset_hash_table (); */ - return kr; + *r_token = kr; + return 0; } int diff --git a/kbx/keybox.h b/kbx/keybox.h index 8b75db45c..acd7a4f89 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -64,7 +64,8 @@ typedef enum /*-- keybox-init.c --*/ -void *keybox_register_file (const char *fname, int secret); +gpg_error_t keybox_register_file (const char *fname, int secret, + void **r_token); int keybox_is_writable (void *token); KEYBOX_HANDLE keybox_new_openpgp (void *token, int secret); diff --git a/sm/keydb.c b/sm/keydb.c index 168cf2ce7..0ef3c8f42 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -107,7 +107,7 @@ try_make_homedir (const char *fname) locked. This lock check does not work if the directory itself is not yet available. If R_CREATED is not NULL it will be set to true if the function created a new keybox. */ -static int +static gpg_error_t maybe_create_keybox (char *filename, int force, int *r_created) { dotlock_t lockhd = NULL; @@ -237,13 +237,13 @@ maybe_create_keybox (char *filename, int force, int *r_created) * does not exist. If AUTO_CREATED is not NULL it will be set to true * if the function has created a new keybox. */ -int +gpg_error_t keydb_add_resource (const char *url, int force, int secret, int *auto_created) { static int any_secret, any_public; const char *resname = url; char *filename = NULL; - int rc = 0; + gpg_error_t err = 0; KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; if (auto_created) @@ -264,7 +264,7 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created) else if (strchr (resname, ':')) { log_error ("invalid key resource URL '%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; } #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ @@ -312,20 +312,24 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created) { case KEYDB_RESOURCE_TYPE_NONE: log_error ("unknown type of key resource '%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = maybe_create_keybox (filename, force, auto_created); - if (rc) + err = maybe_create_keybox (filename, force, auto_created); + if (err) goto leave; /* Now register the file */ { - void *token = keybox_register_file (filename, secret); - if (!token) - ; /* already registered - ignore it */ + void *token; + + err = keybox_register_file (filename, secret, &token); + if (gpg_err_code (err) == GPG_ERR_EEXIST) + ; /* Already registered - ignore. */ + else if (err) + ; /* Other error. */ else if (used_resources >= MAX_KEYDB_RESOURCES) - rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); + err = gpg_error (GPG_ERR_RESOURCE_LIMIT); else { all_resources[used_resources].type = rt; @@ -358,21 +362,21 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created) default: log_error ("resource type of '%s' not supported\n", url); - rc = gpg_error (GPG_ERR_NOT_SUPPORTED); + err = gpg_error (GPG_ERR_NOT_SUPPORTED); goto leave; } /* fixme: check directory permissions and print a warning */ leave: - if (rc) - log_error ("keyblock resource '%s': %s\n", filename, gpg_strerror(rc)); + if (err) + log_error ("keyblock resource '%s': %s\n", filename, gpg_strerror (err)); else if (secret) any_secret = 1; else any_public = 1; xfree (filename); - return rc; + return err; } diff --git a/sm/keydb.h b/sm/keydb.h index aec31c399..03de1c69e 100644 --- a/sm/keydb.h +++ b/sm/keydb.h @@ -31,8 +31,8 @@ typedef struct keydb_handle *KEYDB_HANDLE; /*-- keydb.c --*/ -int keydb_add_resource (const char *url, int force, int secret, - int *auto_created); +gpg_error_t keydb_add_resource (const char *url, int force, int secret, + int *auto_created); KEYDB_HANDLE keydb_new (int secret); void keydb_release (KEYDB_HANDLE hd); int keydb_set_ephemeral (KEYDB_HANDLE hd, int yes); |