common: New put_membuf_cb to replace static membuf_data_cb.
[gnupg.git] / agent / command.c
index a4932ef..a09da60 100644 (file)
@@ -1,6 +1,7 @@
 /* command.c - gpg-agent command handler
  * Copyright (C) 2001-2011 Free Software Foundation, Inc.
  * Copyright (C) 2001-2013 Werner Koch
+ * Copyright (C) 2015 g10 Code GmbH.
  *
  * This file is part of GnuPG.
  *
@@ -1438,7 +1439,7 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
   char *p;
   int opt_data, opt_check, opt_no_ask, opt_qualbar;
   int opt_repeat = 0;
-  char *repeat_errtext = NULL;
+  char *entry_errtext = NULL;
 
   if (ctrl->restricted)
     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
@@ -1522,15 +1523,16 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
 
     next_try:
       rc = agent_get_passphrase (ctrl, &response, desc, prompt,
-                                 repeat_errtext? repeat_errtext:errtext,
+                                 entry_errtext? entry_errtext:errtext,
                                  opt_qualbar, cacheid, CACHE_MODE_USER);
-      xfree (repeat_errtext);
-      repeat_errtext = NULL;
+      xfree (entry_errtext);
+      entry_errtext = NULL;
       if (!rc)
         {
           int i;
 
-          if (opt_check && check_passphrase_constraints (ctrl, response, 0))
+          if (opt_check
+             && check_passphrase_constraints (ctrl, response, &entry_errtext))
             {
               xfree (response);
               goto next_try;
@@ -1539,6 +1541,9 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
             {
               char *response2;
 
+              if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
+                break;
+
               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
                                          errtext, 0,
                                         cacheid, CACHE_MODE_USER);
@@ -1548,9 +1553,9 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
                 {
                   xfree (response2);
                   xfree (response);
-                  repeat_errtext = try_percent_escape
+                  entry_errtext = try_percent_escape
                     (_("does not match - try again"), NULL);
-                  if (!repeat_errtext)
+                  if (!entry_errtext)
                     {
                       rc = gpg_error_from_syserror ();
                       break;
@@ -1973,7 +1978,7 @@ static const char hlp_keywrap_key[] =
   "mechanism or not used at all if the key is a pre-shared key.  In any\n"
   "case wrapping the import and export of keys is a requirement for\n"
   "certain cryptographic validations and thus useful.  The key persists\n"
-  "a RESET command but may be cleared using the option --clear.\n"
+  "until a RESET command but may be cleared using the option --clear.\n"
   "\n"
   "Supported modes are:\n"
   "  --import  - Return a key to import a key into gpg-agent\n"
@@ -2023,7 +2028,7 @@ cmd_keywrap_key (assuan_context_t ctx, char *line)
 
 \f
 static const char hlp_import_key[] =
-  "IMPORT_KEY [--unattended] [<cache_nonce>]\n"
+  "IMPORT_KEY [--unattended] [--force] [<cache_nonce>]\n"
   "\n"
   "Import a secret key into the key store.  The key is expected to be\n"
   "encrypted using the current session's key wrapping key (cf. command\n"
@@ -2031,13 +2036,14 @@ static const char hlp_import_key[] =
   "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
   "key data.  The unwrapped key must be a canonical S-expression.  The\n"
   "option --unattended tries to import the key as-is without any\n"
-  "re-encryption";
+  "re-encryption.  Existing key can be overwritten with --force.";
 static gpg_error_t
 cmd_import_key (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   gpg_error_t err;
   int opt_unattended;
+  int force;
   unsigned char *wrappedkey = NULL;
   size_t wrappedkeylen;
   gcry_cipher_hd_t cipherhd = NULL;
@@ -2061,6 +2067,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
     }
 
   opt_unattended = has_option (line, "--unattended");
+  force = has_option (line, "--force");
   line = skip_options (line);
 
   p = line;
@@ -2144,7 +2151,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
 
       xfree (key);
       key = NULL;
-      err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
+      err = convert_from_openpgp (ctrl, openpgp_sexp, force, grip,
                                   ctrl->server_local->keydesc, cache_nonce,
                                   &key, opt_unattended? NULL : &passphrase);
       if (err)
@@ -2175,7 +2182,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
     }
   else
     {
-      if (!agent_key_available (grip))
+      if (!force && !agent_key_available (grip))
         err = gpg_error (GPG_ERR_EEXIST);
       else
         {
@@ -2197,10 +2204,10 @@ cmd_import_key (assuan_context_t ctx, char *line)
       err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
                            ctrl->s2k_count);
       if (!err)
-        err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
+        err = agent_write_private_key (grip, finalkey, finalkeylen, force);
     }
   else
-    err = agent_write_private_key (grip, key, realkeylen, 0);
+    err = agent_write_private_key (grip, key, realkeylen, force);
 
  leave:
   gcry_sexp_release (openpgp_sexp);
@@ -2386,27 +2393,29 @@ cmd_export_key (assuan_context_t ctx, char *line)
 
 \f
 static const char hlp_delete_key[] =
-  "DELETE_KEY <hexstring_with_keygrip>\n"
+  "DELETE_KEY [--force] <hexstring_with_keygrip>\n"
   "\n"
   "Delete a secret key from the key store.\n"
-  "As safeguard the agent asks the user for confirmation.\n";
+  "Unless --force is used the agent asks the user for confirmation.\n";
 static gpg_error_t
 cmd_delete_key (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   gpg_error_t err;
+  int force;
   unsigned char grip[20];
 
   if (ctrl->restricted)
     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
 
+  force = has_option (line, "--force");
   line = skip_options (line);
 
   err = parse_keygrip (ctx, line, grip);
   if (err)
     goto leave;
 
-  err = agent_delete_key (ctrl, ctrl->server_local->keydesc, grip);
+  err = agent_delete_key (ctrl, ctrl->server_local->keydesc, grip, force );
   if (err)
     goto leave;
 
@@ -2578,7 +2587,7 @@ static const char hlp_putval[] =
   "\n"
   "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
-  "corresponsing value; they should be similar to the values of\n"
+  "corresponding value; they should be similar to the values of\n"
   "envronment variables but gpg-agent does not enforce any\n"
   "restrictions.  If that value is not given any value under that KEY\n"
   "is removed from this special environment.";