GNUPG-1-9-BRANCH gnupg/tools (ChangeLog symcryptrun.c)

cvs user marcus cvs at cvs.gnupg.org
Mon Jul 4 06:33:43 CEST 2005


    Date: Monday, July 4, 2005 @ 06:58:04
  Author: marcus
    Path: /cvs/gnupg/gnupg/tools
     Tag: GNUPG-1-9-BRANCH

Modified: ChangeLog symcryptrun.c

2005-07-04  Marcus Brinkmann  <marcus at g10code.de>

	* symcryptrun.c (SYMC_BAD_PASSPHRASE, SYMC_CANCELED): New symbols,
	use instead constants.
	(hash_string): New function copied from simple-gettext.c.
	(confucius_get_pass): Take new argument CACHEID.
	(confucius_process): Calculate cacheid and pass it to
	confucius_get_pass.  Clear passphrase from cache if necessary.


---------------+
 ChangeLog     |    9 +++++++
 symcryptrun.c |   68 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 71 insertions(+), 6 deletions(-)


Index: gnupg/tools/ChangeLog
diff -u gnupg/tools/ChangeLog:1.25.2.80 gnupg/tools/ChangeLog:1.25.2.81
--- gnupg/tools/ChangeLog:1.25.2.80	Thu Jun 16 10:11:59 2005
+++ gnupg/tools/ChangeLog	Mon Jul  4 06:58:04 2005
@@ -1,3 +1,12 @@
+2005-07-04  Marcus Brinkmann  <marcus at g10code.de>
+
+	* symcryptrun.c (SYMC_BAD_PASSPHRASE, SYMC_CANCELED): New symbols,
+	use instead constants.
+	(hash_string): New function copied from simple-gettext.c.
+	(confucius_get_pass): Take new argument CACHEID.
+	(confucius_process): Calculate cacheid and pass it to
+	confucius_get_pass.  Clear passphrase from cache if necessary.
+
 2005-06-16  Werner Koch  <wk at g10code.com>
 
 	* gpg-connect-agent.c (read_and_print_response): Made LINELEN a
Index: gnupg/tools/symcryptrun.c
diff -u gnupg/tools/symcryptrun.c:1.1.2.10 gnupg/tools/symcryptrun.c:1.1.2.11
--- gnupg/tools/symcryptrun.c:1.1.2.10	Sat Jun  4 14:57:26 2005
+++ gnupg/tools/symcryptrun.c	Mon Jul  4 06:58:04 2005
@@ -56,6 +56,9 @@
 
    Other classes may be added in the future.  */
 
+#define SYMC_BAD_PASSPHRASE	2
+#define SYMC_CANCELED		3
+
 
 #include <config.h>
 
@@ -108,6 +111,37 @@
 }
 
 
+/* From simple-gettext.c.  */
+
+/* We assume to have `unsigned long int' value with at least 32 bits.  */
+#define HASHWORDBITS 32
+
+/* The so called `hashpjw' function by P.J. Weinberger
+   [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
+   1986, 1987 Bell Telephone Laboratories, Inc.]  */
+
+static __inline__ ulong
+hash_string( const char *str_param )
+{
+    unsigned long int hval, g;
+    const char *str = str_param;
+
+    hval = 0;
+    while (*str != '\0')
+    {
+	hval <<= 4;
+	hval += (unsigned long int) *str++;
+	g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
+	if (g != 0)
+	{
+	  hval ^= g >> (HASHWORDBITS - 8);
+	  hval ^= g;
+	}
+    }
+    return hval;
+}
+
+
 /* Constants to identify the commands and options. */
 enum cmd_and_opt_values
   {
@@ -413,9 +447,10 @@
    pointer, it will be set to true or false, depending on if the user
    canceled the operation or not.  On error (including cancelation), a
    null pointer is returned.  The passphrase must be deallocated with
-   confucius_drop_pass.  */
+   confucius_drop_pass.  CACHEID is the ID to be used for passphrase
+   caching and can be NULL to disable caching.  */
 char *
-confucius_get_pass (int again, int *canceled)
+confucius_get_pass (const char *cacheid, int again, int *canceled)
 {
   int err;
   char *pw;
@@ -444,7 +479,7 @@
     }
 #endif
 
-  pw = simple_pwquery (NULL,
+  pw = simple_pwquery (cacheid,
                        again ? _("does not match - try again"):NULL,
                        _("Passphrase:"), NULL, &err);
 
@@ -497,6 +532,7 @@
   pid_t pid;
   pid_t wpid;
   int tries = 0;
+  char cacheid[40];
 
   signal (SIGPIPE, SIG_IGN);
 
@@ -518,6 +554,10 @@
       return 1;
     }
 
+  /* Generate a hash from the keyfile name for caching.  */
+  snprintf (cacheid, sizeof (cacheid), "confucius:%lu",
+	    hash_string (opt.keyfile));
+  cacheid[sizeof (cacheid) - 1] = '\0';
   args = malloc (sizeof (char *) * (10 + argc));
   if (!args)
     {
@@ -708,13 +748,20 @@
 		      char *pass;
 		      int canceled;
 
-		      pass = confucius_get_pass (tries ? 1 : 0, &canceled);
+		      /* If this is not the first attempt, the
+			 passphrase seems to be wrong, so clear the
+			 cache.  */
+		      if (tries)
+			simple_pwclear (cacheid);
+
+		      pass = confucius_get_pass (cacheid,
+						 tries ? 1 : 0, &canceled);
 		      if (!pass)
 			{
 			  kill (pid, SIGTERM);
 			  close (master);
 			  close (cstderr[0]);
-			  return canceled ? 3 : 1;
+			  return canceled ? SYMC_CANCELED : 1;
 			}
  		      write (master, pass, strlen (pass));
  		      write (master, "\n", 1);
@@ -736,6 +783,8 @@
 	  log_error (_("waitpid failed: %s\n"), strerror (errno));
 
 	  kill (pid, SIGTERM);
+	  /* State of cached password is unclear.  Just remove it.  */
+	  simple_pwclear (cacheid);
 	  return 1;
 	}
       else
@@ -746,15 +795,22 @@
 	  if (!WIFEXITED (res))
 	    {
 	      log_error (_("child aborted with status %i\n"), res);
+
+	      /* State of cached password is unclear.  Just remove it.  */
+	      simple_pwclear (cacheid);
+
 	      return 1;
 	    }
 
 	  if (WEXITSTATUS (res))
 	    {
+	      /* The passphrase was wrong.  Remove it from the cache.  */
+	      simple_pwclear (cacheid);
+
 	      /* We probably exceeded our number of attempts at guessing
 		 the password.  */
 	      if (tries >= 3)
-		return 2;
+		return SYMC_BAD_PASSPHRASE;
 	      else
 		return 1;
 	    }




More information about the Gnupg-commits mailing list