gpg: First patches to support a keybox storage backend.
authorWerner Koch <wk@gnupg.org>
Thu, 27 Dec 2012 14:04:29 +0000 (15:04 +0100)
committerWerner Koch <wk@gnupg.org>
Thu, 27 Dec 2012 14:04:42 +0000 (15:04 +0100)
* kbx/keybox-defs.h (_keybox_write_header_blob): Move prototype to ..
* kbx/keybox.h: here.
* kbx/keybox-init.c (keybox_lock): Add dummy function
* g10/keydb.c: Include keybox.h.
(KeydbResourceType): Add KEYDB_RESOURCE_TYPE_KEYBOX.
(struct resource_item): Add field kb.
(maybe_create_keyring_or_box): Add error descriptions to diagnostics.
Add arg IS_BOX.  Write a header for a new keybox file.
(keydb_add_resource): No more need for the force flag.  Rename the
local variable "force" to "create".  Add URL scheme "gnupg-kbx".  Add
magic test to detect a keybox file.  Add basic support for keybox.
(keydb_new, keydb_get_resource_name, keydb_delete_keyblock)
(keydb_locate_writable, keydb_search_reset, keydb_search2): Add
support for keybox.
(lock_all, unlock_all): Ditto.
* g10/Makefile.am (needed_libs): Add libkeybox.a.
(gpg2_LDADD, gpgv2_LDADD): Add KSBA_LIBS as a workaround.

* g10/keydb.h (KEYDB_RESOURCE_FLAG_PRIMARY)
KEYDB_RESOURCE_FLAG_DEFAULT, KEYDB_RESOURCE_FLAG_READONLY): New.
* g10/gpg.c, g10/gpgv.c (main): Use new constants.
--

I did most of these changes back in 2011 and only cleaned them up
now.  More to follow soon.

g10/Makefile.am
g10/gpg.c
g10/gpgv.c
g10/keydb.c
g10/keydb.h
kbx/keybox-defs.h
kbx/keybox-init.c
kbx/keybox.h

index e9f69b3..899677c 100644 (file)
@@ -27,7 +27,7 @@ include $(top_srcdir)/am/cmacros.am
 
 AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
 
-needed_libs = $(libcommon) ../gl/libgnu.a
+needed_libs = ../kbx/libkeybox.a $(libcommon) ../gl/libgnu.a
 
 bin_PROGRAMS = gpg2
 if !HAVE_W32CE_SYSTEM
@@ -120,13 +120,18 @@ gpgv2_SOURCES = gpgv.c           \
 #             ks-db.h \
 #             $(common_source)
 
+# FIXME: Libkeybox.a links to libksba thus we need to add libksba
+# here, even that it is not used by gpg.  A proper solution would
+# either to split up libkeybox.a or to use a separate keybox daemon.
 LDADD =  $(needed_libs) ../common/libgpgrl.a \
          $(ZLIBS) $(DNSLIBS) $(LIBREADLINE) \
          $(LIBINTL) $(CAPLIBS) $(NETLIBS)
-gpg2_LDADD =  $(LDADD) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
+gpg2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \
+             $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
             $(LIBICONV) $(extra_sys_libs)
 gpg2_LDFLAGS = $(extra_bin_ldflags)
-gpgv2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
+gpgv2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \
+              $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
              $(LIBICONV) $(extra_sys_libs)
 gpgv2_LDFLAGS = $(extra_bin_ldflags)
 
index b614a94..5773d5e 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -2249,8 +2249,8 @@ main (int argc, char **argv)
          case oAnswerNo: opt.answer_no = 1; break;
          case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
          case oPrimaryKeyring:
-           sl=append_to_strlist( &nrings, pargs.r.ret_str);
-           sl->flags=2;
+           sl = append_to_strlist (&nrings, pargs.r.ret_str);
+           sl->flags = KEYDB_RESOURCE_FLAG_PRIMARY;
            break;
          case oShowKeyring:
            deprecated_warning(configname,configlineno,"--show-keyring",
@@ -3398,11 +3398,7 @@ main (int argc, char **argv)
     if( opt.verbose > 1 )
        set_packet_list_mode(1);
 
-    /* Add the keyrings, but not for some special commands.  Also
-       avoid adding the secret keyring for a couple of commands to
-       avoid unneeded access in case the secrings are stored on a
-       floppy.
-
+    /* Add the keyrings, but not for some special commands.
        We always need to add the keyrings if we are running under
        SELinux, this is so that the rings are added to the list of
        secured files. */
@@ -3410,7 +3406,8 @@ main (int argc, char **argv)
         || (cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfTest) )
       {
        if (!nrings || default_keyring)  /* Add default ring. */
-           keydb_add_resource ("pubring" EXTSEP_S "gpg", 4);
+           keydb_add_resource ("pubring" EXTSEP_S "gpg",
+                                KEYDB_RESOURCE_FLAG_DEFAULT);
        for (sl = nrings; sl; sl = sl->next )
           keydb_add_resource (sl->d, sl->flags);
       }
index 07e4a2e..5cb9c55 100644 (file)
@@ -196,11 +196,12 @@ main( int argc, char **argv )
   if (opt.verbose > 1)
     set_packet_list_mode(1);
 
-  /* Note: We open all keyrings in read-only mode (flag value: 8).  */
+  /* Note: We open all keyrings in read-only mode.  */
   if (!nrings)  /* No keyring given: use default one. */
-    keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 8);
+    keydb_add_resource ("trustedkeys" EXTSEP_S "gpg",
+                        KEYDB_RESOURCE_FLAG_READONLY);
   for (sl = nrings; sl; sl = sl->next)
-    keydb_add_resource (sl->d, 8);
+    keydb_add_resource (sl->d, KEYDB_RESOURCE_FLAG_READONLY);
 
   FREE_STRLIST (nrings);
 
index 75c036c..ab727b6 100644 (file)
@@ -34,6 +34,7 @@
 #include "main.h" /*try_make_homedir ()*/
 #include "packet.h"
 #include "keyring.h"
+#include "../kbx/keybox.h"
 #include "keydb.h"
 #include "i18n.h"
 
@@ -42,7 +43,8 @@ static int active_handles;
 typedef enum
   {
     KEYDB_RESOURCE_TYPE_NONE = 0,
-    KEYDB_RESOURCE_TYPE_KEYRING
+    KEYDB_RESOURCE_TYPE_KEYRING,
+    KEYDB_RESOURCE_TYPE_KEYBOX
   } KeydbResourceType;
 #define MAX_KEYDB_RESOURCES 40
 
@@ -51,6 +53,7 @@ struct resource_item
   KeydbResourceType type;
   union {
     KEYRING_HANDLE kr;
+    KEYBOX_HANDLE kb;
   } u;
   void *token;
 };
@@ -73,12 +76,12 @@ static int lock_all (KEYDB_HANDLE hd);
 static void unlock_all (KEYDB_HANDLE hd);
 
 
-/* Handle the creation of a keyring if it does not yet exist.  Take
-   into acount that other processes might have the keyring already
-   locked.  This lock check does not work if the directory itself is
-   not yet available. */
+/* Handle the creation of a keyring or a keybox if it does not yet
+   exist.  Take into acount that other processes might have the
+   keyring/keybox already locked.  This lock check does not work if
+   the directory itself is not yet available. */
 static int
-maybe_create_keyring (char *filename, int force)
+maybe_create_keyring_or_box (char *filename, int is_box, int force)
 {
   dotlock_t lockhd = NULL;
   IOBUF iobuf;
@@ -139,29 +142,31 @@ maybe_create_keyring (char *filename, int force)
   lockhd = dotlock_create (filename, 0);
   if (!lockhd)
     {
+      rc = gpg_error_from_syserror ();
       /* A reason for this to fail is that the directory is not
          writable. However, this whole locking stuff does not make
          sense if this is the case. An empty non-writable directory
          with no keyring is not really useful at all. */
       if (opt.verbose)
-        log_info ("can't allocate lock for '%s'\n", filename );
+        log_info ("can't allocate lock for '%s': %s\n",
+                  filename, gpg_strerror (rc));
 
       if (!force)
         return gpg_error (GPG_ERR_ENOENT);
       else
-        return gpg_error (GPG_ERR_GENERAL);
+        return rc;
     }
 
   if ( dotlock_take (lockhd, -1) )
     {
+      rc = gpg_error_from_syserror ();
       /* This is something bad.  Probably a stale lockfile.  */
-      log_info ("can't lock '%s'\n", filename );
-      rc = G10ERR_GENERAL;
+      log_info ("can't lock '%s': %s\n", filename, gpg_strerror (rc));
       goto leave;
     }
 
   /* Now the real test while we are locked. */
-  if (!access(filename, F_OK))
+  if (!access (filename, F_OK))
     {
       rc = 0;  /* Okay, we may access the file now.  */
       goto leave;
@@ -180,17 +185,51 @@ maybe_create_keyring (char *filename, int force)
   if (!iobuf)
     {
       rc = gpg_error_from_syserror ();
-      log_error ( _("error creating keyring '%s': %s\n"),
-                  filename, strerror(errno));
+      if (is_box)
+        log_error (_("error creating keybox '%s': %s\n"),
+                   filename, gpg_strerror (rc));
+      else
+        log_error (_("error creating keyring '%s': %s\n"),
+                   filename, gpg_strerror (rc));
       goto leave;
     }
 
-  if (!opt.quiet)
-    log_info (_("keyring '%s' created\n"), filename);
-
   iobuf_close (iobuf);
   /* Must invalidate that ugly cache */
   iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, filename);
+
+  /* Make sure that at least one record is in a new keybox file, so
+     that the detection magic will work the next time it is used.  */
+  if (is_box)
+    {
+      FILE *fp = fopen (filename, "w");
+      if (!fp)
+        rc = gpg_error_from_syserror ();
+      else
+        {
+          rc = _keybox_write_header_blob (fp);
+          fclose (fp);
+        }
+      if (rc)
+        {
+          if (is_box)
+            log_error (_("error creating keybox '%s': %s\n"),
+                       filename, gpg_strerror (rc));
+          else
+            log_error (_("error creating keyring '%s': %s\n"),
+                       filename, gpg_strerror (rc));
+          goto leave;
+        }
+    }
+
+  if (!opt.quiet)
+    {
+      if (is_box)
+        log_info (_("keybox '%s' created\n"), filename);
+      else
+        log_info (_("keyring '%s' created\n"), filename);
+    }
+
   rc = 0;
 
  leave:
@@ -204,51 +243,49 @@ maybe_create_keyring (char *filename, int force)
 
 
 /*
- * Register a resource (which currently may only be a keyring file).
- * The first keyring which is added by this function is
- * created if it does not exist.
- * Note: this function may be called before secure memory is
- * available.
- * Flag 1   - Force.
- * Flag 2   - Mark resource as primary.
- * Flag 4   - This is a default resources.
- * Flag 8   - Open as read-only.
+ * Register a resource (keyring or aeybox).  The first keyring or
+ * keybox which is added by this function is created if it does not
+ * exist.  FLAGS are a combination of the KEYDB_RESOURCE_FLAG_
+ * constants as defined in keydb.h.
  */
 gpg_error_t
-keydb_add_resource (const char *url, int flags)
+keydb_add_resource (const char *url, unsigned int flags)
 {
-  static int any_public;
+  static int any_registered;
   const char *resname = url;
   char *filename = NULL;
-  int force = (flags&1);
-  int read_only = !!(flags&8);
+  int create;
+  int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY);
   int rc = 0;
   KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
   void *token;
 
-  if (read_only)
-    force = 0;
+  /* Create the resource if it is the first registered one.  */
+  create = (!read_only && !any_registered);
 
   /* Do we have an URL?
-   *   gnupg-ring:filename  := this is a plain keyring
+   *   gnupg-ring:filename  := this is a plain keyring.
+   *   gnupg-kbx:filename   := this is a keybox file.
    *   filename := See what is is, but create as plain keyring.
    */
-  if (strlen (resname) > 11)
+  if (strlen (resname) > 11 && !strncmp( resname, "gnupg-ring:", 11) )
     {
-      if (!strncmp( resname, "gnupg-ring:", 11) )
-        {
-          rt = KEYDB_RESOURCE_TYPE_KEYRING;
-          resname += 11;
-       }
+      rt = KEYDB_RESOURCE_TYPE_KEYRING;
+      resname += 11;
+    }
+  else if (strlen (resname) > 10 && !strncmp (resname, "gnupg-kbx:", 10) )
+    {
+      rt = KEYDB_RESOURCE_TYPE_KEYBOX;
+      resname += 10;
+    }
 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
-      else if (strchr (resname, ':'))
-        {
-          log_error ("invalid key resource URL '%s'\n", url );
-          rc = gpg_error (GPG_ERR_GENERAL);
-          goto leave;
-        }
-#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
+  else if (strchr (resname, ':'))
+    {
+      log_error ("invalid key resource URL '%s'\n", url );
+      rc = gpg_error (GPG_ERR_GENERAL);
+      goto leave;
     }
+#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
 
   if (*resname != DIRSEP_C )
     {
@@ -261,9 +298,6 @@ keydb_add_resource (const char *url, int flags)
   else
     filename = xstrdup (resname);
 
-  if (!force && !read_only)
-    force = !any_public;
-
   /* See whether we can determine the filetype.  */
   if (rt == KEYDB_RESOURCE_TYPE_NONE)
     {
@@ -273,20 +307,25 @@ keydb_add_resource (const char *url, int flags)
         {
           u32 magic;
 
-          if (fread&magic, 4, 1, fp) == 1 )
+          if (fread (&magic, 4, 1, fp) == 1 )
             {
               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))
+                rt = KEYDB_RESOURCE_TYPE_KEYBOX;
               else
                 rt = KEYDB_RESOURCE_TYPE_KEYRING;
            }
           else /* Maybe empty: assume keyring. */
             rt = KEYDB_RESOURCE_TYPE_KEYRING;
 
-          fclose( fp );
+          fclose (fp);
        }
-      else /* No file yet: create keyring.  */
-        rt = KEYDB_RESOURCE_TYPE_KEYRING;
+      else /* No file yet: create keybox. */
+        rt = KEYDB_RESOURCE_TYPE_KEYBOX;
     }
 
   switch (rt)
@@ -297,7 +336,7 @@ keydb_add_resource (const char *url, int flags)
       goto leave;
 
     case KEYDB_RESOURCE_TYPE_KEYRING:
-      rc = maybe_create_keyring (filename, force);
+      rc = maybe_create_keyring_or_box (filename, create, 0);
       if (rc)
         goto leave;
 
@@ -307,7 +346,7 @@ keydb_add_resource (const char *url, int flags)
             rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
           else
             {
-              if (flags&2)
+              if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
                 primary_keyring = token;
               all_resources[used_resources].type = rt;
               all_resources[used_resources].u.kr = NULL; /* Not used here */
@@ -320,24 +359,61 @@ keydb_add_resource (const char *url, int flags)
           /* This keyring was already registered, so ignore it.
              However, we can still mark it as primary even if it was
              already registered.  */
-          if (flags&2)
+          if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
             primary_keyring = token;
         }
       break;
 
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      {
+        rc = maybe_create_keyring_or_box (filename, create, 1);
+        if (rc)
+          goto leave;
+
+        /* FIXME: How do we register a read-only keybox?  */
+        token = keybox_register_file (filename, 0);
+        if (token)
+          {
+            if (used_resources >= MAX_KEYDB_RESOURCES)
+              rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
+            else
+              {
+                /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
+                /*   primary_keyring = token; */
+                all_resources[used_resources].type = rt;
+                all_resources[used_resources].u.kb = NULL; /* Not used here */
+                all_resources[used_resources].token = token;
+
+                /* FIXME: Do a compress run if needed and no other
+                   user is currently using the keybox. */
+
+                used_resources++;
+              }
+          }
+        else
+          {
+            /* 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; */
+          }
+      }
+      break;
+
       default:
        log_error ("resource type of '%s' not supported\n", url);
        rc = gpg_error (GPG_ERR_GENERAL);
        goto leave;
     }
 
-    /* fixme: check directory permissions and print a warning */
+  /* fixme: check directory permissions and print a warning */
 
  leave:
   if (rc)
     log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (rc));
   else
-    any_public = 1;
+    any_registered = 1;
   xfree (filename);
   return rc;
 }
@@ -371,6 +447,17 @@ keydb_new (void)
           }
           j++;
           break;
+        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);
+          if (!hd->active[j].u.kb)
+            {
+              xfree (hd);
+              return NULL; /* fixme: release all previously allocated handles*/
+            }
+          j++;
+          break;
         }
     }
   hd->used = j;
@@ -399,6 +486,9 @@ keydb_release (KEYDB_HANDLE hd)
         case KEYDB_RESOURCE_TYPE_KEYRING:
           keyring_release (hd->active[i].u.kr);
           break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          keybox_release (hd->active[i].u.kb);
+          break;
         }
     }
 
@@ -438,6 +528,9 @@ keydb_get_resource_name (KEYDB_HANDLE hd)
     case KEYDB_RESOURCE_TYPE_KEYRING:
       s = keyring_get_resource_name (hd->active[idx].u.kr);
       break;
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      s = keybox_get_resource_name (hd->active[idx].u.kb);
+      break;
     }
 
   return s? s: "";
@@ -450,6 +543,13 @@ lock_all (KEYDB_HANDLE hd)
 {
   int i, rc = 0;
 
+  /* Fixme: This locking scheme may lead to a deadlock if the resources
+     are not added in the same order by all processes.  We are
+     currently only allowing one resource so it is not a problem.
+     [Oops: Who claimed the latter]
+
+     To fix this we need to use a lock file to protect lock_all.  */
+
   for (i=0; !rc && i < hd->used; i++)
     {
       switch (hd->active[i].type)
@@ -459,12 +559,15 @@ lock_all (KEYDB_HANDLE hd)
         case KEYDB_RESOURCE_TYPE_KEYRING:
           rc = keyring_lock (hd->active[i].u.kr, 1);
           break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          rc = keybox_lock (hd->active[i].u.kb, 1);
+          break;
         }
     }
 
   if (rc)
     {
-      /* Revert the already set locks.  */
+      /* Revert the already taken locks.  */
       for (i--; i >= 0; i--)
         {
           switch (hd->active[i].type)
@@ -474,6 +577,9 @@ lock_all (KEYDB_HANDLE hd)
             case KEYDB_RESOURCE_TYPE_KEYRING:
               keyring_lock (hd->active[i].u.kr, 0);
               break;
+            case KEYDB_RESOURCE_TYPE_KEYBOX:
+              rc = keybox_lock (hd->active[i].u.kb, 0);
+              break;
             }
         }
     }
@@ -501,6 +607,9 @@ unlock_all (KEYDB_HANDLE hd)
         case KEYDB_RESOURCE_TYPE_KEYRING:
           keyring_lock (hd->active[i].u.kr, 0);
           break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          keybox_lock (hd->active[i].u.kb, 0);
+          break;
         }
     }
   hd->locked = 0;
@@ -532,6 +641,11 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
     case KEYDB_RESOURCE_TYPE_KEYRING:
       err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
       break;
+    /* case KEYDB_RESOURCE_TYPE_KEYBOX: */
+    /*   err = keybox_get_keyblock (hd->active[hd->found].u.kb, ret_kb); */
+    /*   if (!err) */
+    /*     err = parse_keyblock (image, imagelen) */
+    /*   break; */
     }
 
   return err;
@@ -566,6 +680,12 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
     case KEYDB_RESOURCE_TYPE_KEYRING:
       rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
       break;
+    /* case KEYDB_RESOURCE_TYPE_KEYRING: */
+    /*   rc = build_keyblock (kb, &image, &imagelen); */
+    /*   if (!rc) */
+    /*     rc = keybox_update_keyblock (hd->active[hd->found].u.kb, */
+    /*                                  image, imagelen); */
+    /*   break; */
     }
 
   unlock_all (hd);
@@ -607,6 +727,11 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
     case KEYDB_RESOURCE_TYPE_KEYRING:
       rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
       break;
+    /* case KEYDB_RESOURCE_TYPE_KEYBOX: */
+    /*   rc = build_keyblock (kb, &image, &imagelen); */
+    /*   if (!rc) */
+    /*     rc = keybox_insert_keyblock (hd->active[idx].u.kb, image, imagelen); */
+    /*   break; */
     }
 
   unlock_all (hd);
@@ -643,6 +768,9 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
     case KEYDB_RESOURCE_TYPE_KEYRING:
       rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
       break;
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      rc = keybox_delete (hd->active[hd->found].u.kb);
+      break;
     }
 
   unlock_all (hd);
@@ -700,6 +828,10 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
           if (keyring_is_writable (hd->active[hd->current].token))
             return 0; /* found (hd->current is set to it) */
           break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          if (keybox_is_writable (hd->active[hd->current].token))
+            return 0; /* found (hd->current is set to it) */
+          break;
         }
     }
 
@@ -758,6 +890,9 @@ keydb_search_reset (KEYDB_HANDLE hd)
         case KEYDB_RESOURCE_TYPE_KEYRING:
           rc = keyring_search_reset (hd->active[i].u.kr);
           break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          rc = keybox_search_reset (hd->active[i].u.kb);
+          break;
         }
     }
   return rc;
@@ -792,6 +927,9 @@ keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
           rc = keyring_search (hd->active[hd->current].u.kr, desc,
                                ndesc, descindex);
           break;
+        case KEYDB_RESOURCE_TYPE_KEYBOX:
+          rc = keybox_search (hd->active[hd->current].u.kb, desc, ndesc);
+          break;
         }
       if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
         {
index 22c2b67..3ba9573 100644 (file)
@@ -128,11 +128,12 @@ union pref_hint
 
 /*-- keydb.c --*/
 
-/*
-  Flag 1 == force
-  Flag 2 == default
-*/
-gpg_error_t keydb_add_resource (const char *url, int flags);
+#define KEYDB_RESOURCE_FLAG_PRIMARY  2  /* The primary resource.  */
+#define KEYDB_RESOURCE_FLAG_DEFAULT  4  /* The default one.  */
+#define KEYDB_RESOURCE_FLAG_READONLY 8  /* Open in read only mode.  */
+
+gpg_error_t keydb_add_resource (const char *url, unsigned int flags);
+
 KEYDB_HANDLE keydb_new (void);
 void keydb_release (KEYDB_HANDLE hd);
 const char *keydb_get_resource_name (KEYDB_HANDLE hd);
index ee48ca3..890e4dd 100644 (file)
@@ -182,7 +182,6 @@ void _keybox_destroy_openpgp_info (keybox_openpgp_info_t info);
 int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp);
 int _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted);
 int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp);
-int _keybox_write_header_blob (FILE *fp);
 
 /*-- keybox-search.c --*/
 gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer,
index 60594e3..d329941 100644 (file)
@@ -200,3 +200,20 @@ _keybox_close_file (KEYBOX_HANDLE hd)
       }
   assert (!hd->fp);
 }
+
+
+/*
+ * Lock the keybox at handle HD, or unlock if YES is false.  Note that
+ * we currently ignore the handle and lock all registered keyboxes.
+ */
+int
+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.  */
+
+  (void)hd;
+  (void)yes;
+  return 0;
+}
index 52bbe21..52c1638 100644 (file)
@@ -71,6 +71,12 @@ void keybox_release (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);
+
+/*-- keybox-file.c --*/
+/* Fixme: This function does not belong here: Provide a better
+   interface to create a new keybox file.  */
+int _keybox_write_header_blob (FILE *fp);
 
 /*-- keybox-search.c --*/
 #ifdef KEYBOX_WITH_X509
@@ -98,7 +104,6 @@ int keybox_compress (KEYBOX_HANDLE hd);
 /*--  --*/
 
 #if 0
-int keybox_lock (KEYBOX_HANDLE hd, int yes);
 int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb);
 int keybox_locate_writable (KEYBOX_HANDLE hd);
 int keybox_search_reset (KEYBOX_HANDLE hd);