[svn] GnuPG - r4973 - in trunk: . agent common g10

svn author wk cvs at cvs.gnupg.org
Wed Apr 1 15:23:27 CEST 2009


Author: wk
Date: 2009-04-01 15:23:27 +0200 (Wed, 01 Apr 2009)
New Revision: 4973

Modified:
   trunk/ChangeLog
   trunk/agent/findkey.c
   trunk/common/ChangeLog
   trunk/common/iobuf.c
   trunk/configure.ac
   trunk/g10/ChangeLog
   trunk/g10/gpg.c
   trunk/g10/keyring.c
Log:
Ported changes from 1.4.


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2009-04-01 10:51:53 UTC (rev 4972)
+++ trunk/ChangeLog	2009-04-01 13:23:27 UTC (rev 4973)
@@ -1,3 +1,7 @@
+2009-04-01  Werner Koch  <wk at g10code.com>
+
+	* configure.ac: Test for fsync.
+
 2009-03-18  Werner Koch  <wk at g10code.com>
 
 	* configure.ac: Test for getrlimit.

Modified: trunk/common/ChangeLog
===================================================================
--- trunk/common/ChangeLog	2009-04-01 10:51:53 UTC (rev 4972)
+++ trunk/common/ChangeLog	2009-04-01 13:23:27 UTC (rev 4973)
@@ -1,5 +1,14 @@
 2009-04-01  Werner Koch  <wk at g10code.com>
 
+	* iobuf.c: Port David's changes from 1.4:
+	(fd_cache_invalidate): Pass return code from close back.
+	(direct_open, iobuf_ioctl): Check that eturn value.
+	(fd_cache_synchronize): New.
+	(iobuf_ioctl): Add new sub command 4 (fsync).
+
+	* iobuf.c (fd_cache_strcmp): New. Taken from 1.4.
+	(fd_cache_invalidate, fd_cache_close, fd_cache_open):  Use it.
+
 	* exechelp.c (gnupg_spawn_process): Implement new flag bit 6.
 	* sysutils.c (gnupg_allow_set_foregound_window): Allow the use of
 	ASFW_ANY.

Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog	2009-04-01 10:51:53 UTC (rev 4972)
+++ trunk/g10/ChangeLog	2009-04-01 13:23:27 UTC (rev 4973)
@@ -1,3 +1,16 @@
+2009-04-01  Werner Koch  <wk at g10code.com>
+
+	* gpg.c (main): Properly handle UTF8 usernames with --sign-key and
+	--lsign-key.  From 1.4, David 2008-12-21.
+
+2009-03-20  David Shaw  <dshaw at jabberwocky.com>  (wk)
+
+	* keyring.c (rename_tmp_file): Force a fsync (via iobuf_ioctl) on
+	secret keyring files to be extra safe on filesystems that may not
+	sync data and metadata together (ext4).  Also check return code
+	from the cache invalidation to make sure we're safe over NFS and
+	similar.
+
 2009-03-31  Werner Koch  <wk at g10code.com>
 
 	* passphrase.c (ask_passphrase): Use percent_plus_unescape.

Modified: trunk/agent/findkey.c
===================================================================
--- trunk/agent/findkey.c	2009-04-01 10:51:53 UTC (rev 4972)
+++ trunk/agent/findkey.c	2009-04-01 13:23:27 UTC (rev 4973)
@@ -50,7 +50,7 @@
 
 
 /* Write an S-expression formatted key to our key storage.  With FORCE
-   pased as true an existing key with the given GRIP will get
+   passed as true an existing key with the given GRIP will get
    overwritten.  */
 int
 agent_write_private_key (const unsigned char *grip,

Modified: trunk/common/iobuf.c
===================================================================
--- trunk/common/iobuf.c	2009-04-01 10:51:53 UTC (rev 4972)
+++ trunk/common/iobuf.c	2009-04-01 13:23:27 UTC (rev 4973)
@@ -1,6 +1,6 @@
 /* iobuf.c  -  File Handling for OpenPGP.
  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006,
- *               2007, 2008  Free Software Foundation, Inc.
+ *               2007, 2008, 2009  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -48,7 +48,8 @@
    test "armored_key_8192" in armor.test! */
 #define IOBUF_BUFFER_SIZE  8192
 
-/* We don't want to use the STDIO based backend.  */
+/* We don't want to use the STDIO based backend.  If you change this
+   be aware that there is no fsync support for the stdio backend.  */
 #undef FILE_FILTER_USES_STDIO
 
 /*-- End configurable part.  --*/
@@ -187,13 +188,32 @@
 
 
 #ifndef FILE_FILTER_USES_STDIO
+/* This is a replacement for strcmp.  Under W32 it does not
+   distinguish between backslash and slash.  */
+static int
+fd_cache_strcmp (const char *a, const char *b)
+{
+#ifdef HAVE_DOSISH_SYSTEM
+  for (; *a && *b; a++, b++)
+    {
+      if (*a != *b && !((*a == '/' && *b == '\\') 
+                        || (*a == '\\' && *b == '/')) )
+        break;
+    }
+  return *(const unsigned char *)a - *(const unsigned char *)b;
+#else
+  return strcmp (a, b);
+#endif
+}
+
 /*
  * Invalidate (i.e. close) a cached iobuf
  */
-static void
+static int
 fd_cache_invalidate (const char *fname)
 {
   close_cache_t cc;
+  int rc = 0;
 
   assert (fname);
   if (DBG_IOBUF)
@@ -201,21 +221,55 @@
 
   for (cc = close_cache; cc; cc = cc->next)
     {
-      if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname))
+      if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
 	{
 	  if (DBG_IOBUF)
 	    log_debug ("                did (%s)\n", cc->fname);
 #ifdef HAVE_W32_SYSTEM
-	  CloseHandle (cc->fp);
+	  if (!CloseHandle (cc->fp))
+            rc = -1;
 #else
-	  close (cc->fp);
+	  rc = close (cc->fp);
 #endif
 	  cc->fp = INVALID_FP;
 	}
     }
+  return rc;
 }
 
 
+/* Try to sync changes to the disk.  This is to avoid data loss during
+   a system crash in write/close/rename cycle on some file
+   systems.  */
+static int
+fd_cache_synchronize (const char *fname)
+{
+  int err = 0;
+
+#ifdef HAVE_FSYNC
+  close_cache_t cc;
+
+  if (DBG_IOBUF)
+    log_debug ("fd_cache_synchronize (%s)\n", fname);
+
+  for (cc=close_cache; cc; cc = cc->next )
+    {
+      if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
+	{
+	  if (DBG_IOBUF)
+	    log_debug ("                 did (%s)\n", cc->fname);
+
+	  err = fsync (cc->fp);
+	}
+    }
+#else
+  (void)fname;
+#endif /*HAVE_FSYNC*/
+
+  return err;
+}
+
+
 static fp_or_fd_t
 direct_open (const char *fname, const char *mode)
 {
@@ -226,19 +280,21 @@
   /* Note, that we do not handle all mode combinations */
 
   /* According to the ReactOS source it seems that open() of the
-   * standard MSW32 crt does open the file in share mode which is
+   * standard MSW32 crt does open the file in shared mode which is
    * something new for MS applications ;-)
    */
   if (strchr (mode, '+'))
     {
-      fd_cache_invalidate (fname);
+      if (fd_cache_invalidate (fname))
+        return INVALID_FP;
       da = GENERIC_READ | GENERIC_WRITE;
       cd = OPEN_EXISTING;
       sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
     }
   else if (strchr (mode, 'w'))
     {
-      fd_cache_invalidate (fname);
+      if (fd_cache_invalidate (fname))
+        return INVALID_FP;
       da = GENERIC_WRITE;
       cd = CREATE_ALWAYS;
       sm = FILE_SHARE_WRITE;
@@ -259,12 +315,14 @@
   /* Note, that we do not handle all mode combinations */
   if (strchr (mode, '+'))
     {
-      fd_cache_invalidate (fname);
+      if (fd_cache_invalidate (fname))
+        return INVALID_FP;
       oflag = O_RDWR;
     }
   else if (strchr (mode, 'w'))
     {
-      fd_cache_invalidate (fname);
+      if (fd_cache_invalidate (fname))
+        return INVALID_FP;
       oflag = O_WRONLY | O_CREAT | O_TRUNC;
     }
   else
@@ -318,7 +376,7 @@
   /* try to reuse a slot */
   for (cc = close_cache; cc; cc = cc->next)
     {
-      if (cc->fp == INVALID_FP && !strcmp (cc->fname, fname))
+      if (cc->fp == INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
 	{
 	  cc->fp = fp;
 	  if (DBG_IOBUF)
@@ -347,7 +405,7 @@
   assert (fname);
   for (cc = close_cache; cc; cc = cc->next)
     {
-      if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname))
+      if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
 	{
 	  fp_or_fd_t fp = cc->fp;
 	  cc->fp = INVALID_FP;
@@ -1449,7 +1507,8 @@
       if (!a && !intval && ptrval)
 	{
 #ifndef FILE_FILTER_USES_STDIO
-	  fd_cache_invalidate (ptrval);
+	  if (fd_cache_invalidate (ptrval))
+            return -1;
 #endif
 	  return 0;
 	}
@@ -1477,7 +1536,25 @@
 	  }
 #endif
     }
+  else if (cmd == 4)
+    {
+      /* Do a fsync on the open fd and return any errors to the caller
+         of iobuf_ioctl.  Note that we work on a file name here. */
+      if (DBG_IOBUF)
+        log_debug ("iobuf-*.*: ioctl `%s' fsync\n",
+                   ptrval? (const char*)ptrval:"<null>");
 
+	if (!a && !intval && ptrval)
+	  {
+#ifndef FILE_FILTER_USES_STDIO
+	    return fd_cache_synchronize (ptrval);
+#else
+	    return 0;
+#endif
+	  }
+      }
+
+
   return -1;
 }
 
@@ -2310,7 +2387,6 @@
 	file_filter_ctx_t *b = a->filter_ov;
 	return b->fname;
       }
-
   return NULL;
 }
 

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2009-04-01 10:51:53 UTC (rev 4972)
+++ trunk/configure.ac	2009-04-01 13:23:27 UTC (rev 4973)
@@ -1062,7 +1062,7 @@
 AC_CHECK_FUNCS([gettimeofday getrusage getrlimit setrlimit clock_gettime])
 AC_CHECK_FUNCS([atexit raise getpagesize strftime nl_langinfo setlocale])
 AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe stat getaddrinfo])
-AC_CHECK_FUNCS([ttyname rand ftello])
+AC_CHECK_FUNCS([ttyname rand ftello fsync])
 
 AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include <signal.h>])
 

Modified: trunk/g10/gpg.c
===================================================================
--- trunk/g10/gpg.c	2009-04-01 10:51:53 UTC (rev 4972)
+++ trunk/g10/gpg.c	2009-04-01 13:23:27 UTC (rev 4973)
@@ -3562,7 +3562,7 @@
 
 	append_to_strlist( &sl, "save" );
 	username = make_username( fname );
-	keyedit_menu(fname, locusr, sl, 0, 0 );
+	keyedit_menu (username, locusr, sl, 0, 0 );
 	xfree(username);
 	free_strlist(sl);
 	break;

Modified: trunk/g10/keyring.c
===================================================================
--- trunk/g10/keyring.c	2009-04-01 10:51:53 UTC (rev 4972)
+++ trunk/g10/keyring.c	2009-04-01 13:23:27 UTC (rev 4973)
@@ -1,5 +1,5 @@
 /* keyring.c - keyring file handling
- * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2004, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -1219,10 +1219,23 @@
 rename_tmp_file (const char *bakfname, const char *tmpfname,
                  const char *fname, int secret )
 {
-  int rc=0;
+  int rc = 0;
 
-  /* invalidate close caches*/
-  iobuf_ioctl (NULL, 2, 0, (char*)tmpfname );
+  /* It's a secret keyring, so let's force a fsync just to be safe on
+     filesystems that may not sync data and metadata together
+     (e.g. ext4). */
+  if (secret && iobuf_ioctl (NULL, 4, 0, (char*)tmpfname))
+    {
+      rc = gpg_error_from_syserror ();
+      goto fail;
+    }
+
+  /* Invalidate close caches.  */
+  if (iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ))
+    {
+      rc = gpg_error_from_syserror ();
+      goto fail;
+    }
   iobuf_ioctl (NULL, 2, 0, (char*)bakfname );
   iobuf_ioctl (NULL, 2, 0, (char*)fname );
 
@@ -1253,15 +1266,7 @@
       log_error (_("renaming `%s' to `%s' failed: %s\n"),
                  tmpfname, fname, strerror(errno) );
       register_secured_file (fname);
-      if (secret)
-        {
-          log_info(_("WARNING: 2 files with confidential"
-                     " information exists.\n"));
-          log_info(_("%s is the unchanged one\n"), fname );
-          log_info(_("%s is the new one\n"), tmpfname );
-          log_info(_("Please fix this possible security flaw\n"));
-	}
-      return rc;
+      goto fail;
     }
 
   /* Now make sure the file has the same permissions as the original */
@@ -1272,17 +1277,27 @@
 
     statbuf.st_mode=S_IRUSR | S_IWUSR;
 
-    if(((secret && !opt.preserve_permissions) ||
-	(stat(bakfname,&statbuf)==0)) &&
-       (chmod(fname,statbuf.st_mode)==0))
+    if (((secret && !opt.preserve_permissions)
+         || !stat (bakfname,&statbuf)) 
+        && !chmod (fname,statbuf.st_mode))
       ;
     else
-      log_error("WARNING: unable to restore permissions to `%s': %s",
-		fname,strerror(errno));
+      log_error ("WARNING: unable to restore permissions to `%s': %s",
+                 fname, strerror(errno));
   }
 #endif
 
   return 0;
+
+ fail:
+  if (secret)
+    {
+      log_info(_("WARNING: 2 files with confidential information exists.\n"));
+      log_info(_("%s is the unchanged one\n"), fname );
+      log_info(_("%s is the new one\n"), tmpfname );
+      log_info(_("Please fix this possible security flaw\n"));
+    }
+  return rc;
 }
 
 




More information about the Gnupg-commits mailing list