Move password repetition from gpg to gpg-agent.
authorWerner Koch <wk@gnupg.org>
Tue, 17 Mar 2009 12:13:32 +0000 (12:13 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 17 Mar 2009 12:13:32 +0000 (12:13 +0000)
agent/ChangeLog
agent/command.c
g10/ChangeLog
g10/call-agent.c
g10/call-agent.h
g10/gpg.c
g10/gpgv.c
g10/passphrase.c

index cae70f3..635259d 100644 (file)
@@ -1,3 +1,13 @@
+2009-03-17  Werner Koch  <wk@g10code.com>
+
+       * command.c (cmd_get_passphrase): Break repeat loop on error.
+
+2009-03-17  Daiki Ueno  <ueno@unixuser.org>
+
+       * command.c (option_value): New function.
+       (cmd_get_passphrase): Accept new option --repeat, which makes
+       gpg-agent to ask passphrase several times.
+
 2009-03-06  Werner Koch  <wk@g10code.com>
 
        * command.c (cmd_keyinfo): New command.
index ba0f8fc..9451f27 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <assuan.h>
 
+#include "i18n.h"
 #include "agent.h"
 
 /* maximum allowed size of the inquired ciphertext */
@@ -181,6 +182,26 @@ has_option_name (const char *line, const char *name)
           && (!s[n] || spacep (s+n) || s[n] == '='));
 }
 
+/* Return a pointer to the argument of the option with NAME.  If such
+   an option is not given, it returns NULL. */
+static char *
+option_value (const char *line, const char *name)
+{
+  char *s;
+  int n = strlen (name);
+
+  s = strstr (line, name);
+  if (s && (s == line || spacep (s-1))
+      && s[n] && (spacep (s+n) || s[n] == '='))
+    {
+      s += n + 1;
+      s += strspn (s, " ");
+      if (*s && !spacep(s))
+        return s;
+    }
+  return NULL;
+}
+
 
 /* Skip over options.  It is assumed that leading spaces have been
    removed (this is the case for lines passed to a handler from
@@ -990,7 +1011,7 @@ send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
 }
 
 
-/* GET_PASSPHRASE [--data] [--check] [--no-ask] <cache_id>
+/* GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] <cache_id>
                   [<error_message> <prompt> <description>]
 
    This function is usually used to ask for a passphrase to be used
@@ -1021,13 +1042,22 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
   const char *pw;
   char *response;
   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
+  const char *desc2 = _("Please re-enter this passphrase");
   char *p;
   void *cache_marker;
-  int opt_data, opt_check, opt_no_ask;
+  int opt_data, opt_check, opt_no_ask, opt_repeat = 0;
 
   opt_data = has_option (line, "--data");
   opt_check = has_option (line, "--check");
   opt_no_ask = has_option (line, "--no-ask");
+  if (has_option_name (line, "--repeat"))
+    {
+      p = option_value (line, "--repeat");
+      if (p)
+       opt_repeat = atoi (p);
+      else
+       opt_repeat = 1;
+    }
   line = skip_options (line);
 
   cacheid = line;
@@ -1094,21 +1124,39 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
       if (desc)
         plus_to_blank (desc);
 
-      response = NULL;
-      do
-        {
-          xfree (response);
-          rc = agent_get_passphrase (ctrl, &response, desc, prompt, errtext);
-        }
-      while (!rc
-             && opt_check
-             && check_passphrase_constraints (ctrl, response, 0));
-
+    next_try:
+      rc = agent_get_passphrase (ctrl, &response, desc, prompt, errtext);
       if (!rc)
         {
-          if (cacheid)
-            agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
-          rc = send_back_passphrase (ctx, opt_data, response);
+          int i;
+
+          if (opt_check && check_passphrase_constraints (ctrl, response, 0))
+            {
+              xfree (response);
+              goto next_try;
+            }
+          for (i = 0; i < opt_repeat; i++)
+            {
+              char *response2;
+
+              rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
+                                         errtext);
+              if (rc)
+                break;
+              if (strcmp (response2, response))
+                {
+                  xfree (response2);
+                  xfree (response);
+                  goto next_try;
+                }
+              xfree (response2);
+            }
+          if (!rc)
+            {
+              if (cacheid)
+                agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
+              rc = send_back_passphrase (ctx, opt_data, response);
+            }
           xfree (response);
         }
     }
index ba0d8eb..3bb5bf9 100644 (file)
@@ -1,3 +1,19 @@
+2009-03-17  Daiki Ueno  <ueno@unixuser.org>
+
+       * passphrase.c (passphrase_get): Add extra arg REPEAT and adjust
+       callers; remove special treatment for MODE==2.
+       (passphrase_to_dek): Move --passphrase-repeat handling to
+       gpg-agent.
+
+       * call-agent.c (agent_get_passphrase): Add extra arg REPEAT.
+       * call-agent.h: Ditto.
+
+2009-03-16  Werner Koch  <wk@g10code.com>
+
+       * gpg.c (my_strusage): Revert last change.  Systems w/o a gpg1 may,
+       and actually do, install gpg2 as gpg.
+       * gpgv.c (my_strusage): Ditto.
+
 2009-03-14  David Shaw  <dshaw@jabberwocky.com>
 
        * gpg.c (my_strusage): gpg2 and gpgv2 (not gpg and gpgv).
index 572fa85..fb66602 100644 (file)
@@ -874,11 +874,12 @@ agent_get_passphrase (const char *cache_id,
                       const char *err_msg,
                       const char *prompt,
                       const char *desc_msg,
+                      int repeat,
                       char **r_passphrase)
 {
   int rc;
   char *line, *p;
-  char cmd[] = "GET_PASSPHRASE --data -- ";
+  char cmd[] = "GET_PASSPHRASE --data --repeat=%d -- ";
   membuf_t data;
 
   *r_passphrase = NULL;
@@ -889,7 +890,7 @@ agent_get_passphrase (const char *cache_id,
 
   /* We allocate 3 times the needed space for the texts so that
      there is enough space for escaping. */
-  line = xtrymalloc ( strlen (cmd) + 1
+  line = xtrymalloc ( strlen (cmd) + sizeof(repeat) + 1
                       + (cache_id? 3*strlen (cache_id): 1) + 1
                       + (err_msg?  3*strlen (err_msg): 1) + 1
                       + (prompt?   3*strlen (prompt): 1) + 1
@@ -898,7 +899,7 @@ agent_get_passphrase (const char *cache_id,
   if (!line)
     return gpg_error_from_syserror ();
 
-  p = stpcpy (line, cmd);
+  p = line + sprintf (line, cmd, repeat);
   if (cache_id && *cache_id)
     p = my_percent_plus_escape (p, cache_id);
   else
index ef4ad85..ebe37b1 100644 (file)
@@ -115,6 +115,7 @@ gpg_error_t agent_get_passphrase (const char *cache_id,
                                   const char *err_msg,
                                   const char *prompt,
                                   const char *desc_msg,
+                                  int repeat,
                                   char **r_passphrase);
 
 /* Send the CLEAR_PASSPHRASE command to the agent.  */
index 727c108..a88b1ff 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -800,7 +800,7 @@ my_strusage( int level )
   const char *p;
 
     switch( level ) {
-      case 11: p = "gpg2 (GnuPG)";
+      case 11: p = "gpg (GnuPG)";
        break;
       case 13: p = VERSION; break;
       case 17: p = PRINTABLE_OS_NAME; break;
@@ -828,10 +828,10 @@ my_strusage( int level )
 
       case 1:
       case 40: p =
-           _("Usage: gpg2 [options] [files] (-h for help)");
+           _("Usage: gpg [options] [files] (-h for help)");
        break;
       case 41: p =
-           _("Syntax: gpg2 [options] [files]\n"
+           _("Syntax: gpg [options] [files]\n"
              "sign, check, encrypt or decrypt\n"
              "default operation depends on the input data\n");
        break;
index 91d4e6a..88baaab 100644 (file)
@@ -107,16 +107,16 @@ my_strusage( int level )
 
   switch (level)
     {
-    case 11: p = "gpgv2 (GnuPG)";
+    case 11: p = "gpgv (GnuPG)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
     case 19: p =  _("Please report bugs to <gnupg-bugs@gnu.org>.\n");
        break;
     case 1:
-    case 40: p = _("Usage: gpgv2 [options] [files] (-h for help)");
+    case 40: p = _("Usage: gpgv [options] [files] (-h for help)");
       break;
-    case 41: p = _("Syntax: gpgv2 [options] [files]\n"
+    case 41: p = _("Syntax: gpgv [options] [files]\n"
                    "Check signatures against known trusted keys\n");
        break;
 
index 0d7580d..0950581 100644 (file)
@@ -237,7 +237,6 @@ read_passphrase_from_fd( int fd )
  * Ask the GPG Agent for the passphrase.
  * Mode 0:  Allow cached passphrase
  *      1:  No cached passphrase FIXME: Not really implemented
- *      2:  Ditto, but change the text to "repeat entry"
  *
  * Note that TRYAGAIN_TEXT must not be translated.  If CANCELED is not
  * NULL, the function does set it to 1 if the user canceled the
@@ -246,7 +245,7 @@ read_passphrase_from_fd( int fd )
  * computed, this will be used as the cacheid.
  */
 static char *
-passphrase_get ( u32 *keyid, int mode, const char *cacheid,
+passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
                  const char *tryagain_text,
                  const char *custom_description,
                  const char *custom_prompt, int *canceled)
@@ -331,8 +330,6 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid,
       }
       
     }
-  else if (mode == 2 ) 
-    atext = xstrdup ( _("Repeat passphrase\n") );
   else
     atext = xstrdup ( _("Enter passphrase\n") );
                 
@@ -349,7 +346,8 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid,
 
   my_prompt = custom_prompt ? native_to_utf8 (custom_prompt): NULL;
 
-  rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext, &pw);
+  rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext,
+                             repeat, &pw);
   
   xfree (my_prompt);
   xfree (atext); atext = NULL;
@@ -470,7 +468,7 @@ ask_passphrase (const char *description,
       strcpy (pw, fd_passwd);
     }
   else
-    pw = passphrase_get (NULL, 0, cacheid,
+    pw = passphrase_get (NULL, 0, cacheid, 0,
                          tryagain_text, description, prompt,
                          canceled );
 
@@ -611,7 +609,8 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo,
   else 
     {
       /* Divert to the gpg-agent. */
-      pw = passphrase_get ( keyid, mode == 2? 1: 0, NULL,
+      pw = passphrase_get ( keyid, mode == 2, NULL,
+                            mode == 2? opt.passwd_repeat: 0,
                             tryagain_text, NULL, NULL, canceled );
       if (*canceled)
         {
@@ -619,33 +618,6 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo,
          write_status( STATUS_MISSING_PASSPHRASE );
           return NULL;
         }
-      if (!pw)
-        pw = xstrdup ("");
-      if ( *pw && mode == 2 )
-        {
-         int i;
-         for(i=0;i<opt.passwd_repeat;i++)
-           {
-             char *pw2 = passphrase_get ( keyid, 2, NULL, NULL, NULL,
-                                          NULL, canceled );
-              if (*canceled)
-                {
-                  xfree (pw);
-                  xfree (pw2);
-                 write_status( STATUS_MISSING_PASSPHRASE );
-                  return NULL;
-                }
-             if (!pw2)
-               pw2 = xstrdup ("");
-             if ( strcmp(pw, pw2) )
-               {
-                 xfree(pw2);
-                 xfree(pw);
-                 return NULL;
-               }
-             xfree(pw2);
-           }
-       }
     }
     
   if ( !pw || !*pw )