diff options
author | Werner Koch <wk@gnupg.org> | 2014-10-09 19:10:32 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2014-10-09 19:10:32 +0200 |
commit | ec332d58efc50f6508b87fc9f51db68c39cee044 (patch) | |
tree | e31b3ed8e4b220883af26b9aa42d78e61546f7ef /g10/keydb.c | |
parent | gpg: Change wording of a migration error message. (diff) | |
download | gnupg2-ec332d58efc50f6508b87fc9f51db68c39cee044.tar.xz gnupg2-ec332d58efc50f6508b87fc9f51db68c39cee044.zip |
gpg: Take care to use pubring.kbx if it has ever been used.
* kbx/keybox-defs.h (struct keybox_handle): Add field for_openpgp.
* kbx/keybox-file.c (_keybox_write_header_blob): Set openpgp header
flag.
* kbx/keybox-blob.c (_keybox_update_header_blob): Add arg for_openpgp
and set header flag.
* kbx/keybox-init.c (keybox_new): Rename to do_keybox_new, make static
and add arg for_openpgp.
(keybox_new_openpgp, keybox_new_x509): New. Use them instead of the
former keybox_new.
* kbx/keybox-update.c (blob_filecopy): Add arg for_openpgp and set the
openpgp header flags.
* g10/keydb.c (rt_from_file): New. Factored out and extended from
keydb_add_resource.
(keydb_add_resource): Switch to the kbx file if it has the openpgp
flag set.
* kbx/keybox-dump.c (dump_header_blob): Print header flags.
--
The problem was reported by dkg on gnupg-devel (2014-10-07):
I just discovered a new problem, though, which will affect people on
systems that have gpg and gpg2 coinstalled:
0) create a new keyring with gpg2, and use it exclusively with gpg2
for a while.
1) somehow (accidentally?) use gpg (1.4.x) again -- this creates
~/.gnupg/pubring.gpg
2) future runs of gpg2 now only look at pubring.gpg and ignore
pubring.kbx -- the keys you had accumulated in the keybox are no
longer listed in the output of gpg2 --list-keys
Note that gpgsm has always used pubring.kbx and thus this file might
already be there but without gpg ever inserted a key. The new flag in
the KBX header gives us an indication whether a KBX file has ever been
written by gpg >= 2.1. If that is the case we will use it instead of
the default pubring.gpg.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'g10/keydb.c')
-rw-r--r-- | g10/keydb.c | 87 |
1 files changed, 66 insertions, 21 deletions
diff --git a/g10/keydb.c b/g10/keydb.c index 178456aaa..a38795120 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -242,7 +242,7 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create) rc = gpg_error_from_syserror (); else { - rc = _keybox_write_header_blob (fp); + rc = _keybox_write_header_blob (fp, 1); fclose (fp); } if (rc) @@ -277,6 +277,50 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create) } +/* Helper for keydb_add_resource. Opens FILENAME to figures out the + resource type. Returns the resource type and a flag at R_NOTFOUND + indicating whether FILENAME could be opened at all. If the openpgp + flag is set in a keybox header, R_OPENPGP will be set to true. */ +static KeydbResourceType +rt_from_file (const char *filename, int *r_found, int *r_openpgp) +{ + u32 magic; + unsigned char verbuf[4]; + FILE *fp; + KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; + + *r_found = *r_openpgp = 0; + fp = fopen (filename, "rb"); + if (fp) + { + *r_found = 1; + + if (fread (&magic, 4, 1, fp) == 1 ) + { + if (magic == 0x13579ace || magic == 0xce9a5713) + ; /* GDBM magic - not anymore supported. */ + else if (fread (&verbuf, 4, 1, fp) == 1 + && verbuf[0] == 1 + && fread (&magic, 4, 1, fp) == 1 + && !memcmp (&magic, "KBXf", 4)) + { + if ((verbuf[3] & 0x02)) + *r_openpgp = 1; + rt = KEYDB_RESOURCE_TYPE_KEYBOX; + } + else + rt = KEYDB_RESOURCE_TYPE_KEYRING; + } + else /* Maybe empty: assume keyring. */ + rt = KEYDB_RESOURCE_TYPE_KEYRING; + + fclose (fp); + } + + return rt; +} + + /* * Register a resource (keyring or aeybox). The first keyring or * keybox which is added by this function is created if it does not @@ -337,33 +381,34 @@ keydb_add_resource (const char *url, unsigned int flags) /* See whether we can determine the filetype. */ if (rt == KEYDB_RESOURCE_TYPE_NONE) { - FILE *fp; + int found, openpgp_flag; int pass = 0; size_t filenamelen; check_again: filenamelen = strlen (filename); - fp = fopen (filename, "rb"); - if (fp) + rt = rt_from_file (filename, &found, &openpgp_flag); + if (found) { - u32 magic; - - if (fread (&magic, 4, 1, fp) == 1 ) + /* The file exists and we have the resource type in RT. + + Now let us check whether in addition to the "pubring.gpg" + a "pubring.kbx with openpgp keys exists. This is so that + GPG 2.1 will use an existing "pubring.kbx" by default iff + that file has been created or used by 2.1. This check is + needed because after creation or use of the kbx file with + 2.1 an older version of gpg may have created a new + pubring.gpg for its own use. */ + if (!pass && is_default && rt == KEYDB_RESOURCE_TYPE_KEYRING + && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".gpg")) { - if (magic == 0x13579ace || magic == 0xce9a5713) - ; /* GDBM magic - not anymore supported. */ - else if (fread (&magic, 4, 1, fp) == 1 - && !memcmp (&magic, "\x01", 1) - && fread (&magic, 4, 1, fp) == 1 - && !memcmp (&magic, "KBXf", 4)) + strcpy (filename+filenamelen-4, ".kbx"); + if ((rt_from_file (filename, &found, &openpgp_flag) + == KEYDB_RESOURCE_TYPE_KEYBOX) && found && openpgp_flag) rt = KEYDB_RESOURCE_TYPE_KEYBOX; - else - rt = KEYDB_RESOURCE_TYPE_KEYRING; - } - else /* Maybe empty: assume keyring. */ - rt = KEYDB_RESOURCE_TYPE_KEYRING; - - fclose (fp); + else /* Restore filename */ + strcpy (filename+filenamelen-4, ".gpg"); + } } else if (!pass && is_default && create @@ -508,7 +553,7 @@ keydb_new (void) case KEYDB_RESOURCE_TYPE_KEYBOX: hd->active[j].type = all_resources[i].type; hd->active[j].token = all_resources[i].token; - hd->active[j].u.kb = keybox_new (all_resources[i].token, 0); + hd->active[j].u.kb = keybox_new_openpgp (all_resources[i].token, 0); if (!hd->active[j].u.kb) { xfree (hd); |