[git] GnuPG - branch, master, updated. gnupg-2.1.10-111-g1608629

by Werner Koch cvs at cvs.gnupg.org
Wed Jan 13 10:51:25 CET 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  160862978628b07ed5150ec2c8abad6af1656bc3 (commit)
       via  9dc355ad3ae0026ab04c424dc984d748b8fad393 (commit)
      from  96237b9a63a50aed1884cb06f84279b977d6a8fa (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 160862978628b07ed5150ec2c8abad6af1656bc3
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Jan 13 10:16:27 2016 +0100

    kbx: Implement keybox_lock for use by gpg.
    
    * kbx/keybox-defs.h: Include dotlock.h and logging.h.
    (CONST_KB_NAME): Remove.  Replace usage by KB_NAME.
    (struct keybox_name): Add field "lockhd".
    * kbx/keybox-init.c (keybox_register_file): Init LOCKHD.
    (keybox_lock): Chnage to return gpg_error_t.  Implement locking.
    --
    
    The keybox locking for gpg was not implemented - This needs to be
    fixed of course.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h
index 6fe9847..6af5448 100644
--- a/kbx/keybox-defs.h
+++ b/kbx/keybox-defs.h
@@ -40,6 +40,8 @@
    fixme: Better use the LIBOBJ mechnism. */
 #include "../common/types.h"
 #include "../common/stringhelp.h"
+#include "../common/dotlock.h"
+#include "../common/logging.h"
 
 #include "keybox.h"
 
@@ -48,7 +50,6 @@ typedef struct keyboxblob *KEYBOXBLOB;
 
 
 typedef struct keybox_name *KB_NAME;
-typedef struct keybox_name const *CONST_KB_NAME;
 struct keybox_name
 {
   /* Link to the next resources, so that we can walk all
@@ -58,14 +59,15 @@ struct keybox_name
   /* True if this is a keybox with secret keys.  */
   int secret;
 
-  /*DOTLOCK lockhd;*/
-
   /* A table with all the handles accessing this resources.
      HANDLE_TABLE_SIZE gives the allocated length of this table unused
      entrues are set to NULL.  HANDLE_TABLE may be NULL. */
   KEYBOX_HANDLE *handle_table;
   size_t handle_table_size;
 
+  /* The lock handle or NULL it not yet initialized.  */
+  dotlock_t lockhd;
+
   /* Not yet used.  */
   int is_locked;
 
@@ -85,7 +87,7 @@ struct keybox_found_s
 };
 
 struct keybox_handle {
-  CONST_KB_NAME kb;
+  KB_NAME kb;
   int secret;             /* this is for a secret keybox */
   FILE *fp;
   int eof;
diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c
index 3ff592e..cfee7b8 100644
--- a/kbx/keybox-init.c
+++ b/kbx/keybox-init.c
@@ -60,7 +60,7 @@ keybox_register_file (const char *fname, int secret, void **r_token)
   kr->handle_table = NULL;
   kr->handle_table_size = 0;
 
-  /* kr->lockhd = NULL;*/
+  kr->lockhd = NULL;
   kr->is_locked = 0;
   kr->did_full_scan = 0;
   /* keep a list of all issued pointers */
@@ -261,17 +261,55 @@ _keybox_close_file (KEYBOX_HANDLE hd)
 
 
 /*
- * Lock the keybox at handle HD, or unlock if YES is false.  Note that
- * we currently ignore the handle and lock all registered keyboxes.
+ * Lock the keybox at handle HD, or unlock if YES is false.
  */
-int
+gpg_error_t
 keybox_lock (KEYBOX_HANDLE hd, int yes)
 {
-  /* FIXME: We need to implement it before we can use it with gpg.
-     gpgsm does the locking in its local keydb.c driver; this should
-     be changed as well.  */
+  gpg_error_t err;
+  KB_NAME kb = hd->kb;
 
-  (void)hd;
-  (void)yes;
-  return 0;
+  if (!keybox_is_writable ((void*)kb))
+    return 0;
+
+  /* Make sure the lock handle has been created.  */
+  if (!kb->lockhd)
+    {
+      kb->lockhd = dotlock_create (kb->fname, 0);
+      if (!kb->lockhd)
+        {
+          /* Unfortuntaley dotlock_create does not properly set ERRNO.  */
+          log_info ("can't allocate lock for '%s'\n", kb->fname );
+          return gpg_error (GPG_ERR_GENERAL);
+        }
+    }
+
+  if (yes) /* Take the lock.  */
+    {
+      if (kb->is_locked)
+        ;
+      else if (!dotlock_take (kb->lockhd, -1))
+        kb->is_locked = 1;
+      else
+        {
+          /* Unfortuntaley dotlock_take does not properly set ERRNO.  */
+          log_info ("can't lock '%s'\n", kb->fname );
+          err = gpg_error (GPG_ERR_GENERAL);
+        }
+    }
+  else /* Release the lock.  */
+    {
+      if (!kb->is_locked)
+        ;
+      else if (!dotlock_release (kb->lockhd))
+        kb->is_locked = 0;
+      else
+        {
+          /* Unfortuntaley dotlock_release does not properly set ERRNO.  */
+          log_info ("can't unlock '%s'\n", kb->fname );
+          err = gpg_error (GPG_ERR_GENERAL);
+        }
+    }
+
+  return err;
 }
diff --git a/kbx/keybox.h b/kbx/keybox.h
index acd7a4f..9f91c53 100644
--- a/kbx/keybox.h
+++ b/kbx/keybox.h
@@ -76,7 +76,7 @@ void keybox_pop_found_state (KEYBOX_HANDLE hd);
 const char *keybox_get_resource_name (KEYBOX_HANDLE hd);
 int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes);
 
-int keybox_lock (KEYBOX_HANDLE hd, int yes);
+gpg_error_t keybox_lock (KEYBOX_HANDLE hd, int yes);
 
 /*-- keybox-file.c --*/
 /* Fixme: This function does not belong here: Provide a better

commit 9dc355ad3ae0026ab04c424dc984d748b8fad393
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Jan 13 09:29:39 2016 +0100

    gpg: Make sure to mark a duplicate registered keybox as primary.
    
    * kbx/keybox-init.c (keybox_register_file): Change interface to return
    the token even if the file has already been registered.
    * g10/keydb.c (primary_keyring): Rename to primary_keydb.
    (maybe_create_keyring_or_box): Change return type to gpg_error_t.
    (keydb_add_resource): Ditto. s/rc/err/.
    (keydb_add_resource): Mark an already registered as primary.
    * sm/keydb.c (maybe_create_keybox): Change return type to gpg_error_t.
    (keydb_add_resource): Ditto. s/rc/err/.
    (keydb_add_resource): Adjust for changed keybox_register_file.
    --
    
    This change aligns the registering of keyboxes with those of
    keyrings.  This fixes a potential bug:
    
      gpg --keyring foo.kbx --keyring bar.gpg --keyring foo.kbx
    
    would have marked bar.gpg as primary resource and thus inserting new
    keys there.  The correct and now fixed behavior is to insert to
    foo.kbx.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/keydb.c b/g10/keydb.c
index e1814fe..3ee9dfd 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 e91911c..3ff592e 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 8b75db4..acd7a4f 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 168cf2c..0ef3c8f 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 aec31c3..03de1c6 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);

-----------------------------------------------------------------------

Summary of changes:
 g10/keydb.c       | 57 +++++++++++++++++++-------------------
 kbx/keybox-defs.h | 10 ++++---
 kbx/keybox-init.c | 82 +++++++++++++++++++++++++++++++++++++++++++------------
 kbx/keybox.h      |  5 ++--
 sm/keydb.c        | 34 +++++++++++++----------
 sm/keydb.h        |  4 +--
 6 files changed, 123 insertions(+), 69 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list