Support gpgme_op_apsswd for GPG.
authorWerner Koch <wk@gnupg.org>
Fri, 8 Jan 2010 19:15:06 +0000 (19:15 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 8 Jan 2010 19:15:06 +0000 (19:15 +0000)
doc/gpgme.texi
src/ChangeLog
src/context.h
src/engine-gpg.c
src/engine-gpgsm.c
src/gpgme-tool.c
src/passwd.c

index b98db55..e530e16 100644 (file)
@@ -3744,6 +3744,9 @@ private key associated with @var{key}.  The only allowed value for
 to ask for the old and the new passphrase.  Thus this function is not
 useful in a server application (where passphrases are not required
 anyway).
+
+Note that old @code{gpg} engines (before version 2.0.15) do not support
+this comamnd and will silently ignore it.
 @end deftypefun
 
 @deftypefun gpgme_error_t gpgme_op_passwd_start      @
index aee1be0..3292f4c 100644 (file)
@@ -1,3 +1,10 @@
+2010-01-08  Werner Koch  <wk@g10code.com>
+
+       * engine-gpg.c (gpg_passwd): New.
+       (_gpgme_engine_ops_gpg): Register.
+       * passwd.c (parse_error): New.
+       (passwd_status_handler): Use it.
+
 2010-01-07  Marcus Brinkmann  <marcus@g10code.de>
 
        * gpgme-tool.c (result_xml_write_cb_t, struct result_xml_state):
index 6ab0154..19c7194 100644 (file)
@@ -1,6 +1,6 @@
 /* context.h - Definitions for a GPGME context.
    Copyright (C) 2000 Werner Koch (dd9jn)
-   Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2010 g10 Code GmbH
 
    This file is part of GPGME.
  
@@ -15,9 +15,8 @@
    Lesser General Public License for more details.
    
    You should have received a copy of the GNU Lesser General Public
-   License along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
 
 #ifndef CONTEXT_H
 #define CONTEXT_H
index d4683b6..abfaaa3 100644 (file)
@@ -1,7 +1,7 @@
 /* engine-gpg.c - Gpg Engine.
    Copyright (C) 2000 Werner Koch (dd9jn)
    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-                 2009 g10 Code GmbH
+                 2009, 2010 g10 Code GmbH
  
    This file is part of GPGME.
  
@@ -1437,6 +1437,24 @@ gpg_delete (void *engine, gpgme_key_t key, int allow_secret)
 
 
 static gpgme_error_t
+gpg_passwd (void *engine, gpgme_key_t key, unsigned int flags)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  if (!key || !key->subkeys || !key->subkeys->fpr)
+    return gpg_error (GPG_ERR_INV_CERT_OBJ);
+
+  err = add_arg (gpg, "--passwd");
+  if (!err)
+    err = add_arg (gpg, key->subkeys->fpr);
+  if (!err)
+    start (gpg);
+  return err;
+}
+
+
+static gpgme_error_t
 append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
 {
   gpgme_error_t err = 0;
@@ -2370,5 +2388,6 @@ struct engine_ops _gpgme_engine_ops_gpg =
     gpg_set_io_cbs,
     gpg_io_event,
     gpg_cancel,
-    NULL               /* cancel_op */
+    NULL,              /* cancel_op */
+    gpg_passwd
   };
index 2dda733..88039d7 100644 (file)
@@ -1908,7 +1908,7 @@ gpgsm_passwd (void *engine, gpgme_key_t key, unsigned int flags)
   char *line;
 
   if (!key || !key->subkeys || !key->subkeys->fpr)
-    return gpg_error (GPG_ERR_INV_VALUE);
+    return gpg_error (GPG_ERR_INV_CERT_OBJ);
 
   if (asprintf (&line, "PASSWD -- %s", key->subkeys->fpr) < 0)
     return gpg_error_from_syserror ();
index be35514..59d13e5 100644 (file)
@@ -1729,7 +1729,7 @@ gt_passwd (gpgme_tool_t gt, char *fpr)
 
   err = gpgme_get_key (gt->ctx, fpr, &key, 0);
   if (err)
-    return err;
+    return gpg_err_code (err) == GPG_ERR_EOF? gpg_error (GPG_ERR_NO_PUBKEY):err;
 
   err = gpgme_op_passwd (gt->ctx, key, 0);
   gpgme_key_unref (key);
index d189814..6766877 100644 (file)
@@ -20,6 +20,7 @@
 #if HAVE_CONFIG_H
 #include <config.h>
 #endif
+#include <stdlib.h>
 
 #include "gpgme.h"
 #include "debug.h"
 #include "ops.h"
 
 \f
+/* Parse an error status line and return the error code.  */
 static gpgme_error_t
-passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
+parse_error (char *args)
 {
-  (void)priv;
-  (void)code;
-  (void)args;
+  gpgme_error_t err;
+  char *where = strchr (args, ' ');
+  char *which;
+
+  if (where)
+    {
+      *where = '\0';
+      which = where + 1;
+
+      where = strchr (which, ' ');
+      if (where)
+       *where = '\0';
+
+      where = args;      
+    }
+  else
+    return gpg_error (GPG_ERR_INV_ENGINE);
+
+  err = atoi (which);
+
+  if (!strcmp (where, "keyedit.passwd"))
+    return err;
+
   return 0;
 }
 
 
 static gpgme_error_t
+passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err = 0;
+
+  (void)ctx;
+
+  switch (code)
+    {
+    case GPGME_STATUS_ERROR:
+      err = parse_error (args);
+      break;
+                         
+    default:
+      break;
+    }
+
+  return err;
+}
+
+
+static gpgme_error_t
 passwd_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key,
               unsigned int flags)
 {