[git] GnuPG - branch, master, updated. gnupg-2.1.10-121-g663c5d1

by Werner Koch cvs at cvs.gnupg.org
Thu Jan 14 20:57:43 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  663c5d129a8f400cc6eb8ab7b91772d6e578152d (commit)
       via  3b1248e007a6bf830a3230ee2d9cc548205ec31a (commit)
       via  8241ed59d05e06252647b26477ed5c2f84895a26 (commit)
       via  f5cceef115f0307664956d01c48b1b397fdad4b3 (commit)
      from  360534bde770f4845669de223154216d249b954b (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 663c5d129a8f400cc6eb8ab7b91772d6e578152d
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Jan 14 20:45:33 2016 +0100

    w32: Fix deadlock introduced by keybox_file_rename.
    
    * g10/keyring.c (keyring_lock) [W32]: Flush the close cache before
    locking.
    * kbx/keybox-init.c (keybox_lock) [W32]: Close the file before
    locking.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/keyring.c b/g10/keyring.c
index 7ae50a3..ca9a698 100644
--- a/g10/keyring.c
+++ b/g10/keyring.c
@@ -328,8 +328,20 @@ keyring_lock (KEYRING_HANDLE hd, int yes)
             if (!keyring_is_writable(kr))
                 continue;
             if (kr->is_locked)
-                ;
-            else if (dotlock_take (kr->lockhd, -1) ) {
+                continue;
+
+#ifdef HAVE_W32_SYSTEM
+            /* Under Windows we need to CloseHandle the file before we
+             * try to lock it.  This is because another process might
+             * have taken the lock and is using keybox_file_rename to
+             * rename the base file.  How if our dotlock_take below is
+             * waiting for the lock but we have the base file still
+             * open, keybox_file_rename will never succeed as we are
+             * in a deadlock.  */
+            iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0,
+                         (char*)kr->fname);
+#endif /*HAVE_W32_SYSTEM*/
+            if (dotlock_take (kr->lockhd, -1) ) {
                 log_info ("can't lock '%s'\n", kr->fname );
                 rc = GPG_ERR_GENERAL;
             }
@@ -343,8 +355,9 @@ keyring_lock (KEYRING_HANDLE hd, int yes)
             if (!keyring_is_writable(kr))
                 continue;
             if (!kr->is_locked)
-                ;
-            else if (dotlock_release (kr->lockhd))
+                continue;
+
+            if (dotlock_release (kr->lockhd))
                 log_info ("can't unlock '%s'\n", kr->fname );
             else
                 kr->is_locked = 0;
diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c
index 01d29f0..3b53cd5 100644
--- a/kbx/keybox-init.c
+++ b/kbx/keybox-init.c
@@ -286,27 +286,43 @@ keybox_lock (KEYBOX_HANDLE hd, int yes)
 
   if (yes) /* Take the lock.  */
     {
-      if (kb->is_locked)
-        ;
-      else if (dotlock_take (kb->lockhd, -1))
+      if (!kb->is_locked)
         {
-          err = gpg_error_from_syserror ();
-          log_info ("can't lock '%s'\n", kb->fname );
+#ifdef HAVE_W32_SYSTEM
+            /* Under Windows we need to close the file before we try
+             * to lock it.  This is because another process might have
+             * taken the lock and is using keybox_file_rename to
+             * rename the base file.  How if our dotlock_take below is
+             * waiting for the lock but we have the base file still
+             * open, keybox_file_rename will never succeed as we are
+             * in a deadlock.  */
+          if (hd->fp)
+            {
+              fclose (hd->fp);
+              hd->fp = NULL;
+            }
+#endif /*HAVE_W32_SYSTEM*/
+          if (dotlock_take (kb->lockhd, -1))
+            {
+              err = gpg_error_from_syserror ();
+              log_info ("can't lock '%s'\n", kb->fname );
+            }
+          else
+            kb->is_locked = 1;
         }
-      else
-        kb->is_locked = 1;
     }
   else /* Release the lock.  */
     {
-      if (!kb->is_locked)
-        ;
-      else if (dotlock_release (kb->lockhd))
+      if (kb->is_locked)
         {
-          err = gpg_error_from_syserror ();
-          log_info ("can't unlock '%s'\n", kb->fname );
+          if (dotlock_release (kb->lockhd))
+            {
+              err = gpg_error_from_syserror ();
+              log_info ("can't unlock '%s'\n", kb->fname );
+            }
+          else
+            kb->is_locked = 0;
         }
-      else
-        kb->is_locked = 0;
    }
 
   return err;

commit 3b1248e007a6bf830a3230ee2d9cc548205ec31a
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Jan 14 18:29:26 2016 +0100

    gpg: Detect race between pubring.gpg and pubring.kbx use.
    
    * g10/keydb.c (maybe_create_keyring_or_box): Detect race condition.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/keydb.c b/g10/keydb.c
index cf7b990..9604807 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -272,6 +272,8 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
   int rc;
   mode_t oldmask;
   char *last_slash_in_filename;
+  char *bak_fname = NULL;
+  char *tmp_fname = NULL;
   int save_slash;
 
   /* A quick test whether the filename already exists. */
@@ -350,11 +352,39 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
     }
 
   /* Now the real test while we are locked. */
+
+  /* Gpg either uses pubring.gpg or pubring.kbx and thus different
+   * lock files.  Now, when one gpg process is updating a pubring.gpg
+   * and thus holding the corresponding lock, a second gpg process may
+   * get to here at the time between the two rename operation used by
+   * the first process to update pubring.gpg.  The lock taken above
+   * may not protect the second process if it tries to create a
+   * pubring.kbx file which would be protected by a different lock
+   * file.
+   *
+   * We can detect this case by checking that the two temporary files
+   * used by the update code exist at the same time.  In that case we
+   * do not create a new file but act as if FORCE_CREATE has not been
+   * given.  Obviously there is a race between our two checks but the
+   * worst thing is that we won't create a new file, which is better
+   * than to accidentally creating one.  */
+  rc = keybox_tmp_names (filename, is_box, &bak_fname, &tmp_fname);
+  if (rc)
+    goto leave;
+
   if (!access (filename, F_OK))
     {
       rc = 0;  /* Okay, we may access the file now.  */
       goto leave;
     }
+  if (!access (bak_fname, F_OK) && !access (tmp_fname, F_OK))
+    {
+      /* Very likely another process is updating a pubring.gpg and we
+         should not create a pubring.kbx.  */
+      rc = gpg_error (GPG_ERR_ENOENT);
+      goto leave;
+    }
+
 
   /* The file does not yet exist, create it now. */
   oldmask = umask (077);
@@ -422,6 +452,8 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
       dotlock_release (lockhd);
       dotlock_destroy (lockhd);
     }
+  xfree (bak_fname);
+  xfree (tmp_fname);
   return rc;
 }
 

commit 8241ed59d05e06252647b26477ed5c2f84895a26
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Jan 14 16:50:15 2016 +0100

    kbx: New function keybox_file_rename to replace rename.
    
    * kbx/keybox-util.c: Include windows.h.
    (keybox_file_rename): New.
    * kbx/keybox-update.c (rename_tmp_file): Replace remove+rename by
    keybox_file_rename.
    * g10/keyring.c (rename_tmp_file): Ditto.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/keyring.c b/g10/keyring.c
index 535dd2b..7ae50a3 100644
--- a/g10/keyring.c
+++ b/g10/keyring.c
@@ -1337,32 +1337,19 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname)
   iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname );
 
   /* First make a backup file. */
-#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
-  gnupg_remove (bakfname);
-#endif
-  if (rename (fname, bakfname) )
-    {
-      rc = gpg_error_from_syserror ();
-      log_error ("renaming '%s' to '%s' failed: %s\n",
-                 fname, bakfname, strerror(errno) );
-      return rc;
-    }
+  rc = keybox_file_rename (fname, bakfname);
+  if (rc)
+    goto fail;
 
   /* then rename the file */
-#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
-  gnupg_remove( fname );
-#endif
-  if (rename (tmpfname, fname) )
+  rc = keybox_file_rename (tmpfname, fname);
+  if (rc)
     {
-      rc = gpg_error_from_syserror ();
-      log_error (_("renaming '%s' to '%s' failed: %s\n"),
-                 tmpfname, fname, strerror(errno) );
       register_secured_file (fname);
       goto fail;
     }
 
   /* Now make sure the file has the same permissions as the original */
-
 #ifndef HAVE_DOSISH_SYSTEM
   {
     struct stat statbuf;
diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c
index eebcfca..ff65904 100644
--- a/kbx/keybox-update.c
+++ b/kbx/keybox-update.c
@@ -119,22 +119,15 @@ rename_tmp_file (const char *bakfname, const char *tmpfname,
   /* First make a backup file except for secret keyboxes. */
   if (!secret)
     {
-#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
-      gnupg_remove (bakfname);
-#endif
-      if (rename (fname, bakfname) )
-        {
-          return gpg_error_from_syserror ();
-	}
+      rc = keybox_file_rename (fname, bakfname);
+      if (rc)
+        return rc;
     }
 
   /* Then rename the file. */
-#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
-  gnupg_remove (fname);
-#endif
-  if (rename (tmpfname, fname) )
+  rc = keybox_file_rename (tmpfname, fname);
+  if (rc)
     {
-      rc = gpg_error_from_syserror ();
       if (secret)
         {
 /*            log_info ("WARNING: 2 files with confidential" */
diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c
index f7efd1a..740ea73 100644
--- a/kbx/keybox-util.c
+++ b/kbx/keybox-util.c
@@ -21,6 +21,10 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#ifdef  HAVE_DOSISH_SYSTEM
+# define WIN32_LEAN_AND_MEAN  /* We only need the OS core stuff.  */
+# include <windows.h>
+#endif
 
 #include "keybox-defs.h"
 
@@ -141,3 +145,64 @@ keybox_tmp_names (const char *filename, int for_keyring,
   *r_tmpname = tmp_name;
   return 0;
 }
+
+
+/* Wrapper for rename(2) to handle Windows peculiarities.  */
+gpg_error_t
+keybox_file_rename (const char *oldname, const char *newname)
+{
+  gpg_error_t err = 0;
+
+#ifdef HAVE_DOSISH_SYSTEM
+  int wtime = 0;
+
+  gnupg_remove (newname);
+ again:
+  if (rename (oldname, newname))
+    {
+      if (GetLastError () == ERROR_SHARING_VIOLATION)
+        {
+          /* Another process has the file open.  We do not use a lock
+           * for read but instead we wait until the other process has
+           * closed the file.  This may take long but that would also
+           * be the case with a dotlock approach for read and write.
+           * Note that we don't need this on Unix due to the inode
+           * concept.
+           *
+           * So let's wait until the rename has worked.  We use the
+           * same retry intervals as used by dotlock.c, namely 50ms,
+           * 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s.  */
+          if (!wtime)
+            wtime = 50;
+          else if (wtime < 800)
+            wtime *= 2;
+          else if (wtime == 800)
+            wtime = 2000;
+          else if (wtime < 8000)
+            wtime *= 2;
+
+          if (wtime >= 800)
+            log_info ("waiting for file '%s' to become accessible ...\n",
+                      oldname);
+
+          Sleep (wtime);
+          goto again;
+        }
+      err = gpg_error_from_syserror ();
+    }
+
+#else /* Unix */
+
+#ifdef __riscos__
+  gnupg_remove (newname);
+#endif
+  if (rename (oldname, newname) )
+    err = gpg_error_from_syserror ();
+
+#endif /* Unix */
+
+  if (err)
+    log_error ("renaming '%s' to '%s' failed: %s\n",
+               oldname, newname, gpg_strerror (err));
+  return err;
+}
diff --git a/kbx/keybox.h b/kbx/keybox.h
index 4d556c5..bfc3586 100644
--- a/kbx/keybox.h
+++ b/kbx/keybox.h
@@ -134,6 +134,7 @@ void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
 
 gpg_error_t keybox_tmp_names (const char *filename, int for_keyring,
                               char **r_bakname, char **r_tmpname);
+gpg_error_t keybox_file_rename (const char *oldname, const char *newname);
 
 
 #ifdef __cplusplus

commit f5cceef115f0307664956d01c48b1b397fdad4b3
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Jan 14 16:29:45 2016 +0100

    kbx: Add function keybox_tmp_names to avoid code duplication.
    
    * kbx/keybox-update.c (create_tmp_file): Move some code to...
    * kbx/keybox-util.c (keybox_tmp_names): new.
    * g10/keyring.c: Include keybox.h.
    (create_tmp_file): Replace parts by keybox_tmp_names.
    --
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/keyring.c b/g10/keyring.c
index a0b7a0e..535dd2b 100644
--- a/g10/keyring.c
+++ b/g10/keyring.c
@@ -36,6 +36,8 @@
 #include "options.h"
 #include "main.h" /*for check_key_signature()*/
 #include "i18n.h"
+#include "../kbx/keybox.h"
+
 
 typedef struct keyring_resource *KR_RESOURCE;
 struct keyring_resource
@@ -1287,69 +1289,36 @@ static int
 create_tmp_file (const char *template,
                  char **r_bakfname, char **r_tmpfname, IOBUF *r_fp)
 {
-  char *bakfname, *tmpfname;
+  gpg_error_t err;
   mode_t oldmask;
 
-  *r_bakfname = NULL;
-  *r_tmpfname = NULL;
-
-# ifdef USE_ONLY_8DOT3
-  /* Here is another Windoze bug?:
-   * you can't rename("pubring.gpg.tmp", "pubring.gpg");
-   * but	rename("pubring.gpg.tmp", "pubring.aaa");
-   * works.  So we replace .gpg by .bak or .tmp
-   */
-  if (strlen (template) > 4
-      && !strcmp (template+strlen(template)-4, EXTSEP_S GPGEXT_GPG) )
-    {
-      bakfname = xmalloc (strlen (template) + 1);
-      strcpy (bakfname, template);
-      strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak");
+  err = keybox_tmp_names (template, 1, r_bakfname, r_tmpfname);
+  if (err)
+    return err;
 
-      tmpfname = xmalloc (strlen( template ) + 1 );
-      strcpy (tmpfname,template);
-      strcpy (tmpfname+strlen(template)-4, EXTSEP_S "tmp");
+  /* Create the temp file with limited access.  Note that the umask
+     call is not anymore needed because iobuf_create now takes care of
+     it.  However, it does not harm and thus we keep it.  */
+  oldmask = umask (077);
+  if (is_secured_filename (*r_tmpfname))
+    {
+      *r_fp = NULL;
+      gpg_err_set_errno (EPERM);
     }
-    else
-      { /* file does not end with gpg; hmmm */
-	bakfname = xmalloc (strlen( template ) + 5);
-	strcpy (stpcpy(bakfname, template), EXTSEP_S "bak");
-
-	tmpfname = xmalloc (strlen( template ) + 5);
-	strcpy (stpcpy(tmpfname, template), EXTSEP_S "tmp");
+  else
+    *r_fp = iobuf_create (*r_tmpfname, 1);
+  umask (oldmask);
+  if (!*r_fp)
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("can't create '%s': %s\n"), *r_tmpfname, gpg_strerror (err));
+      xfree (*r_tmpfname);
+      *r_tmpfname = NULL;
+      xfree (*r_bakfname);
+      *r_bakfname = NULL;
     }
-# else /* Posix file names */
-    bakfname = xmalloc (strlen( template ) + 2);
-    strcpy (stpcpy (bakfname,template),"~");
-
-    tmpfname = xmalloc (strlen( template ) + 5);
-    strcpy (stpcpy(tmpfname,template), EXTSEP_S "tmp");
-# endif /* Posix filename */
-
-    /* Create the temp file with limited access.  Note that the umask
-       call is not anymore needed because iobuf_create now takes care
-       of it.  However, it does not harm and thus we keep it.  */
-    oldmask=umask(077);
-    if (is_secured_filename (tmpfname))
-      {
-        *r_fp = NULL;
-        gpg_err_set_errno (EPERM);
-      }
-    else
-      *r_fp = iobuf_create (tmpfname, 1);
-    umask(oldmask);
-    if (!*r_fp)
-      {
-        int rc = gpg_error_from_syserror ();
-	log_error(_("can't create '%s': %s\n"), tmpfname, strerror(errno) );
-        xfree (tmpfname);
-        xfree (bakfname);
-	return rc;
-      }
 
-    *r_bakfname = bakfname;
-    *r_tmpfname = tmpfname;
-    return 0;
+  return err;
 }
 
 
diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c
index aa80865..eebcfca 100644
--- a/kbx/keybox-update.c
+++ b/kbx/keybox-update.c
@@ -68,88 +68,27 @@ fseeko (FILE * stream, off_t newpos, int whence)
 #endif /* !defined(HAVE_FSEEKO) && !defined(fseeko) */
 
 
-
 static int
 create_tmp_file (const char *template,
                  char **r_bakfname, char **r_tmpfname, FILE **r_fp)
 {
-  char *bakfname, *tmpfname;
-
-  *r_bakfname = NULL;
-  *r_tmpfname = NULL;
-
-# ifdef USE_ONLY_8DOT3
-  /* Here is another Windoze bug?:
-   * you can't rename("pubring.kbx.tmp", "pubring.kbx");
-   * but	rename("pubring.kbx.tmp", "pubring.aaa");
-   * works.  So we replace ".kbx" by ".kb_" or ".k__".  Note that we
-   * can't use ".bak" and ".tmp", because these suffixes are used by
-   * gpg and would lead to a sharing violation or data corruption.
-   */
-  if (strlen (template) > 4
-      && !strcmp (template+strlen(template)-4, EXTSEP_S "kbx") )
-    {
-      bakfname = xtrymalloc (strlen (template) + 1);
-      if (!bakfname)
-        return gpg_error_from_syserror ();
-      strcpy (bakfname, template);
-      strcpy (bakfname+strlen(template)-4, EXTSEP_S "kb_");
-
-      tmpfname = xtrymalloc (strlen (template) + 1);
-      if (!tmpfname)
-        {
-          gpg_error_t tmperr = gpg_error_from_syserror ();
-          xfree (bakfname);
-          return tmperr;
-        }
-      strcpy (tmpfname,template);
-      strcpy (tmpfname + strlen (template)-4, EXTSEP_S "k__");
-    }
-  else
-    { /* File does not end with kbx, thus we hope we are working on a
-         modern file system and appending a suffix works. */
-      bakfname = xtrymalloc ( strlen (template) + 5);
-      if (!bakfname)
-        return gpg_error_from_syserror ();
-      strcpy (stpcpy (bakfname, template), EXTSEP_S "kb_");
+  gpg_error_t err;
 
-      tmpfname = xtrymalloc ( strlen (template) + 5);
-      if (!tmpfname)
+  err = keybox_tmp_names (template, 0, r_bakfname, r_tmpfname);
+  if (!err)
+    {
+      *r_fp = fopen (*r_tmpfname, "wb");
+      if (!*r_fp)
         {
-          gpg_error_t tmperr = gpg_error_from_syserror ();
-          xfree (bakfname);
-          return tmperr;
+          err = gpg_error_from_syserror ();
+          xfree (*r_tmpfname);
+          *r_tmpfname = NULL;
+          xfree (*r_bakfname);
+          *r_bakfname = NULL;
         }
-      strcpy (stpcpy (tmpfname, template), EXTSEP_S "k__");
-    }
-# else /* Posix file names */
-  bakfname = xtrymalloc (strlen (template) + 2);
-  if (!bakfname)
-    return gpg_error_from_syserror ();
-  strcpy (stpcpy (bakfname,template),"~");
-
-  tmpfname = xtrymalloc ( strlen (template) + 5);
-  if (!tmpfname)
-    {
-      gpg_error_t tmperr = gpg_error_from_syserror ();
-      xfree (bakfname);
-      return tmperr;
     }
-  strcpy (stpcpy (tmpfname,template), EXTSEP_S "tmp");
-# endif /* Posix filename */
 
-  *r_fp = fopen (tmpfname, "wb");
-  if (!*r_fp)
-    {
-      gpg_error_t tmperr = gpg_error_from_syserror ();
-      xfree (tmpfname);
-      xfree (bakfname);
-      return tmperr;
-    }
-
-  *r_bakfname = bakfname;
-  *r_tmpfname = tmpfname;
-  return 0;
+  return err;
 }
 
 
diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c
index 9fe9290..f7efd1a 100644
--- a/kbx/keybox-util.c
+++ b/kbx/keybox-util.c
@@ -68,3 +68,76 @@ _keybox_free (void *p)
   if (p)
     free_func (p);
 }
+
+
+/* Store the two malloced temporary file names used for keybox updates
+   of file FILENAME at R_BAKNAME and R_TMPNAME.  On error an error
+   code is returned and NULL stored at R_BAKNAME and R_TMPNAME.  If
+   FOR_KEYRING is true the returned names match those used by GnuPG's
+   keyring code.  */
+gpg_error_t
+keybox_tmp_names (const char *filename, int for_keyring,
+                  char **r_bakname, char **r_tmpname)
+{
+  gpg_error_t err;
+  char *bak_name, *tmp_name;
+
+  *r_bakname = NULL;
+  *r_tmpname = NULL;
+
+# ifdef USE_ONLY_8DOT3
+  /* Here is another Windoze bug?:
+   * you can't rename("pubring.kbx.tmp", "pubring.kbx");
+   * but	rename("pubring.kbx.tmp", "pubring.aaa");
+   * works.  So we replace ".kbx" by ".kb_" or ".k__".  Note that we
+   * can't use ".bak" and ".tmp", because these suffixes are used by
+   * gpg's keyrings and would lead to a sharing violation or data
+   * corruption.  If the name does not end in ".kbx" we assume working
+   * on a modern file system and append the suffix.  */
+  {
+    const char *ext   = for_keyring? EXTSEP_S GPGEXT_GPG : EXTSEP_S "kbx";
+    const char *b_ext = for_keyring? EXTSEP_S "bak"      : EXTSEP_S "kb_";
+    const char *t_ext = for_keyring? EXTSEP_S "tmp"      : EXTSEP_S "k__";
+    int repl;
+
+    if (strlen (ext) != 4 || strlen (b_ext) != 4)
+      BUG ();
+    repl = (strlen (filename) > 4
+            && !strcmp (filename + strlen (filename) - 4, ext));
+    bak_name = xtrymalloc (strlen (filename) + (repl?0:4) + 1);
+    if (!bak_name)
+      return gpg_error_from_syserror ();
+    strcpy (bak_name, filename);
+    strcpy (bak_name + strlen (filename) - (repl?4:0), b_ext);
+
+    tmp_name = xtrymalloc (strlen (filename) + (repl?0:4) + 1);
+    if (!tmp_name)
+      {
+        err = gpg_error_from_syserror ();
+        xfree (bak_name);
+        return err;
+      }
+    strcpy (tmp_name, filename);
+    strcpy (tmp_name + strlen (filename) - (repl?4:0), t_ext);
+  }
+# else /* Posix file names */
+  (void)for_keyring;
+  bak_name = xtrymalloc (strlen (filename) + 2);
+  if (!bak_name)
+    return gpg_error_from_syserror ();
+  strcpy (stpcpy (bak_name, filename), "~");
+
+  tmp_name = xtrymalloc (strlen (filename) + 5);
+  if (!tmp_name)
+    {
+      err = gpg_error_from_syserror ();
+      xfree (bak_name);
+      return err;
+    }
+  strcpy (stpcpy (tmp_name,filename), EXTSEP_S "tmp");
+# endif /* Posix filename */
+
+  *r_bakname = bak_name;
+  *r_tmpname = tmp_name;
+  return 0;
+}
diff --git a/kbx/keybox.h b/kbx/keybox.h
index 3c60971..4d556c5 100644
--- a/kbx/keybox.h
+++ b/kbx/keybox.h
@@ -132,6 +132,9 @@ void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
                                void *(*new_realloc_func)(void *p, size_t n),
                                void (*new_free_func)(void*) );
 
+gpg_error_t keybox_tmp_names (const char *filename, int for_keyring,
+                              char **r_bakname, char **r_tmpname);
+
 
 #ifdef __cplusplus
 }

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

Summary of changes:
 g10/keydb.c         |  32 ++++++++++++
 g10/keyring.c       | 127 ++++++++++++++++++-----------------------------
 kbx/keybox-init.c   |  44 +++++++++++------
 kbx/keybox-update.c | 102 +++++++-------------------------------
 kbx/keybox-util.c   | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 kbx/keybox.h        |   4 ++
 6 files changed, 269 insertions(+), 178 deletions(-)


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




More information about the Gnupg-commits mailing list