Implement command --passwd for GPG.
authorWerner Koch <wk@gnupg.org>
Mon, 11 Jan 2010 16:05:26 +0000 (16:05 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 11 Jan 2010 16:05:26 +0000 (16:05 +0000)
NEWS
doc/gpg.texi
g10/ChangeLog
g10/gpg.c
g10/keyedit.c
g10/main.h
g10/options.h
g10/passphrase.c

diff --git a/NEWS b/NEWS
index 470c201..ced6b5c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 Noteworthy changes in version 2.0.15 (unreleased)
 -------------------------------------------------
 
+ * New command --passwd for GPG.
+
 
 Noteworthy changes in version 2.0.14 (2009-12-21)
 -------------------------------------------------
index d053ed6..3952988 100644 (file)
@@ -586,6 +586,7 @@ Present a menu which enables you to do most of the key management
 related tasks.  It expects the specification of a key on the command
 line.
 
+
 @c ******** Begin Edit-key Options **********
 @table @asis
 
@@ -888,6 +889,13 @@ Signs a public key with your secret key but marks it as
 non-exportable. This is a shortcut version of the subcommand "lsign"
 from @option{--edit-key}.
 
+@ifclear gpgone
+@item --passwd @var{user_id}
+@opindex passwd
+Change the passphrase of the secret key belonging to the certificate
+specified as @var{user_id}.  This is a shortcut for the sub-command
+@code{passwd} in the edit key menu.
+@end ifclear
 
 @end table
 
index ca1d2ae..fb9c9b5 100644 (file)
@@ -1,3 +1,16 @@
+2010-01-11  Werner Koch  <wk@g10code.com>
+
+       * gpg.c: Add option --passwd.
+       (aPasswd): New.
+       (main): Implement.
+       * keyedit.c (keyedit_passwd): New.
+
+       * gpg.c (oPasswd, oPasswdFD, oPasswdFile, oPasswdRepeat): Change
+       to oPassphrase, oPassphraseFD, oPassphraseFile, oPassphraseRepeat.
+       * options.h (struct): s/passwd_repeat/passphrase_repeat/.
+       * gpg.c (main): Ditto.
+       * passphrase.c (passphrase_to_dek_ext): Ditto.
+
 2009-12-21  Werner Koch  <wk@g10code.com>
 
        * gpg.c (main): Add dummy options --skip-hidden-recipients and no
index 8fea30b..f22904e 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,6 +1,6 @@
 /* gpg.c - The GnuPG utility (main for gpg)
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- *               2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ *               2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -146,6 +146,7 @@ enum cmd_and_opt_values
     aCardStatus,
     aCardEdit,
     aChangePIN,
+    aPasswd,
     aServer,
 
     oTextmode,
@@ -207,10 +208,10 @@ enum cmd_and_opt_values
     oCompressLevel,
     oBZ2CompressLevel,
     oBZ2DecompressLowmem,
-    oPasswd,
-    oPasswdFD,
-    oPasswdFile,
-    oPasswdRepeat,
+    oPassphrase,
+    oPassphraseFD,
+    oPassphraseFile,
+    oPassphraseRepeat,
     oCommandFD,
     oCommandFile,
     oQuickRandom,
@@ -389,6 +390,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (oFingerprint, "fingerprint", N_("list keys and fingerprints")),
   ARGPARSE_c (aListSecretKeys, "list-secret-keys", N_("list secret keys")),
   ARGPARSE_c (aKeygen,    "gen-key",  N_("generate a new key pair")),
+  ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
   ARGPARSE_c (aDeleteKeys,"delete-keys", 
               N_("remove keys from the public keyring")),
   ARGPARSE_c (aDeleteSecretKeys, "delete-secret-keys",
@@ -397,7 +399,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aLSignKey, "lsign-key"  ,N_("sign a key locally")),
   ARGPARSE_c (aEditKey,  "edit-key"   ,N_("sign or edit a key")),
   ARGPARSE_c (aEditKey,  "key-edit"   ,"@"),
-  ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
+  ARGPARSE_c (aPasswd,   "passwd",     N_("change a passphrase")),
   ARGPARSE_c (aDesigRevoke, "desig-revoke","@" ),
   ARGPARSE_c (aExport, "export"           , N_("export keys") ),
   ARGPARSE_c (aSendKeys, "send-keys"     , N_("export keys to a key server") ),
@@ -599,10 +601,10 @@ static ARGPARSE_OPTS opts[] = {
               "delete-secret-and-public-keys", "@"),
   ARGPARSE_c (aRebuildKeydbCaches, "rebuild-keydb-caches", "@"),
 
-  ARGPARSE_s_s (oPasswd, "passphrase", "@"),
-  ARGPARSE_s_i (oPasswdFD, "passphrase-fd", "@"),
-  ARGPARSE_s_s (oPasswdFile, "passphrase-file", "@"),
-  ARGPARSE_s_i (oPasswdRepeat, "passphrase-repeat", "@"),
+  ARGPARSE_s_s (oPassphrase,      "passphrase", "@"),
+  ARGPARSE_s_i (oPassphraseFD,    "passphrase-fd", "@"),
+  ARGPARSE_s_s (oPassphraseFile,  "passphrase-file", "@"),
+  ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"),
   ARGPARSE_s_i (oCommandFD, "command-fd", "@"),
   ARGPARSE_s_s (oCommandFile, "command-file", "@"),
   ARGPARSE_s_n (oQuickRandom, "debug-quick-random", "@"),
@@ -628,7 +630,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (aListSigs, "list-sig", "@"),   /* alias */
   ARGPARSE_s_n (aCheckKeys, "check-sig", "@"), /* alias */
   ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"),
-  ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"),
   ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"),
   ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"),
   ARGPARSE_s_n (oCompressKeys, "compress-keys", "@"),
@@ -1430,6 +1431,7 @@ check_permissions(const char *path,int item)
 }
 
 
+/* Print the OpenPGP defined algo numbers.  */
 static void
 print_algo_numbers(int (*checker)(int))
 {
@@ -1997,7 +1999,7 @@ main (int argc, char **argv)
     opt.def_sig_expire="0";
     opt.def_cert_expire="0";
     set_homedir ( default_homedir () );
-    opt.passwd_repeat=1;
+    opt.passphrase_repeat=1;
 
     /* Check whether we have a config file on the command line.  */
     orig_argc = argc;
@@ -2179,6 +2181,7 @@ main (int argc, char **argv)
          case aDeleteSecretKeys:
          case aDeleteSecretAndPublicKeys:
          case aDeleteKeys:
+          case aPasswd:
             set_cmd (&cmd, pargs.r_opt);
             greeting=1;
             break;
@@ -2558,16 +2561,16 @@ main (int argc, char **argv)
          case oCompressLevel: opt.compress_level = pargs.r.ret_int; break;
          case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
          case oBZ2DecompressLowmem: opt.bz2_decompress_lowmem=1; break;
-         case oPasswd:
+         case oPassphrase:
            set_passphrase_from_string(pargs.r.ret_str);
            break;
-         case oPasswdFD:
+         case oPassphraseFD:
             pwfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
             break;
-         case oPasswdFile:
+         case oPassphraseFile:
             pwfd = open_info_file (pargs.r.ret_str, 0, 1);
             break;
-         case oPasswdRepeat: opt.passwd_repeat=pargs.r.ret_int; break;
+         case oPassphraseRepeat: opt.passphrase_repeat=pargs.r.ret_int; break;
          case oCommandFD:
             opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
             break;
@@ -3621,6 +3624,17 @@ main (int argc, char **argv)
        xfree(username);
        break;
 
+      case aPasswd:
+        if (argc != 1)
+          wrong_args (_("--passwd <user-id>"));
+        else
+          {
+            username = make_username (fname);
+            keyedit_passwd (username);
+            xfree (username);
+          }
+        break;
+
       case aDeleteKeys:
       case aDeleteSecretKeys:
       case aDeleteSecretAndPublicKeys:
index bc79e8f..d55cbbf 100644 (file)
@@ -1,6 +1,6 @@
 /* keyedit.c - keyedit stuff
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- *               2008, 2009 Free Software Foundation, Inc.
+ *               2008, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -2299,6 +2299,72 @@ keyedit_menu( const char *username, strlist_t locusr,
     xfree(answer);
 }
 
+
+/* Change the passphrase of the secret key identified by USERNAME.  */
+void
+keyedit_passwd (const char *username)
+{
+  gpg_error_t err;
+  PKT_public_key *pk;
+  unsigned char fpr[MAX_FINGERPRINT_LEN];
+  size_t fprlen;
+  KEYDB_HANDLE kdh = NULL;
+  KBNODE keyblock = NULL;
+
+  pk = xtrycalloc (1, sizeof *pk);
+  if (!pk)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  err = get_pubkey_byname (NULL, pk, username, NULL, NULL, 1, 1);
+  if (err)
+    goto leave;
+  fingerprint_from_pk (pk, fpr, &fprlen);
+  while (fprlen < MAX_FINGERPRINT_LEN) 
+    fpr[fprlen++] = 0;
+  
+  kdh = keydb_new (1);
+  if (!kdh)
+    {
+      err = gpg_error (GPG_ERR_GENERAL);
+      goto leave;
+    }
+
+  err = keydb_search_fpr (kdh, fpr);
+  if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
+    err = gpg_error (GPG_ERR_NO_SECKEY);
+  if (err)
+    goto leave;
+
+  err = keydb_get_keyblock (kdh, &keyblock);
+  if (err) 
+    goto leave;
+
+  if (!change_passphrase (keyblock))
+    {
+      err = gpg_error (GPG_ERR_GENERAL);
+      goto leave;
+    }
+
+  err = keydb_update_keyblock (kdh, keyblock);
+  if (err)
+    log_error( _("update secret failed: %s\n"), gpg_strerror (err));
+
+ leave:
+  release_kbnode (keyblock);
+  if (pk)
+    free_public_key (pk);
+  keydb_release (kdh);
+  if (err)
+    {
+      log_info ("error changing the passphrase for `%s': %s\n", 
+                username, gpg_strerror (err));
+      write_status_error ("keyedit.passwd", gpg_err_code (err));
+    }
+}
+
+
 static void
 tty_print_notations(int indent,PKT_signature *sig)
 {
index d46c0ff..3a42137 100644 (file)
@@ -213,6 +213,7 @@ int delete_keys( strlist_t names, int secret, int allow_both );
 /*-- keyedit.c --*/
 void keyedit_menu( const char *username, strlist_t locusr,
                   strlist_t commands, int quiet, int seckey_check );
+void keyedit_passwd (const char *username);
 void show_basic_key_info (KBNODE keyblock);
 
 /*-- keygen.c --*/
index a99ca22..46f746d 100644 (file)
@@ -246,7 +246,7 @@ struct
     struct akl *next;
   } *auto_key_locate;
 
-  int passwd_repeat;
+  int passphrase_repeat;
 } opt;
 
 /* CTRL is used to keep some global variables we currently can't
index eb1701b..2133de5 100644 (file)
@@ -644,7 +644,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
 
       /* Divert to the gpg-agent. */
       pw = passphrase_get (keyid, mode == 2, s2k_cacheid,
-                           (mode == 2 || mode == 4)? opt.passwd_repeat : 0,
+                           (mode == 2 || mode == 4)? opt.passphrase_repeat : 0,
                            tryagain_text, custdesc, custprompt, canceled);
       if (*canceled)
         {