summaryrefslogtreecommitdiffstats
path: root/g10/keydb.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2014-10-09 19:10:32 +0200
committerWerner Koch <wk@gnupg.org>2014-10-09 19:10:32 +0200
commitec332d58efc50f6508b87fc9f51db68c39cee044 (patch)
treee31b3ed8e4b220883af26b9aa42d78e61546f7ef /g10/keydb.c
parentgpg: Change wording of a migration error message. (diff)
downloadgnupg2-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.c87
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);