* main.h, g10.c (main), card-util.c (change_pin): If "admin" has not been
authorDavid Shaw <dshaw@jabberwocky.com>
Sat, 25 Sep 2004 13:04:55 +0000 (13:04 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Sat, 25 Sep 2004 13:04:55 +0000 (13:04 +0000)
issued, skip right to the CHV1/CHV2 PIN change.  No need to show the
unblock or admin PIN change option. (card_edit): Add "admin" command to
add admin commands to the menu.  Do not allow admin commands until "admin"
is given.

* app-openpgp.c (verify_chv3): Show a countdown of how many wrong admin
PINs can be entered before the card is locked.

* options.h, g10.c (main), app-openpgp.c (verify_chv3): Remove
--allow-admin.

g10/ChangeLog
g10/app-openpgp.c
g10/card-util.c
g10/g10.c
g10/main.h
g10/options.h

index db91da5..f30d063 100644 (file)
@@ -1,3 +1,17 @@
+2004-09-25  David Shaw  <dshaw@jabberwocky.com>
+
+       * main.h, g10.c (main), card-util.c (change_pin): If "admin" has
+       not been issued, skip right to the CHV1/CHV2 PIN change.  No need
+       to show the unblock or admin PIN change option.
+       (card_edit): Add "admin" command to add admin commands to the
+       menu.  Do not allow admin commands until "admin" is given.
+
+       * app-openpgp.c (verify_chv3): Show a countdown of how many wrong
+       admin PINs can be entered before the card is locked.
+
+       * options.h, g10.c (main), app-openpgp.c (verify_chv3): Remove
+       --allow-admin.
+
 2004-09-24  David Shaw  <dshaw@jabberwocky.com>
 
        * main.h: Create S2K_DIGEST_ALGO macro so we do not need to always
index e4c1477..7b23d0b 100644 (file)
@@ -667,18 +667,30 @@ verify_chv3 (APP app,
              int (*pincb)(void*, const char *, char **),
              void *pincb_arg)
 {
-  int rc = 0;
+  int rc=0;
 
-  if (!opt.allow_admin)
-    {
-      log_info ("access to admin commands is not configured\n");
-      return gpg_error (GPG_ERR_EACCES);
-    }
-      
   if (!app->did_chv3) 
     {
+      struct agent_card_info_s info;
       char *pinvalue;
 
+      memset(&info,0,sizeof(info));
+      rc=agent_scd_getattr("CHV-STATUS",&info);
+      if(rc)
+       log_error("error retrieving CHV status from card: %s\n",
+                 gpg_strerror(rc));
+      else
+       {
+         if(info.chvretry[2]==0)
+           {
+             log_info("card is locked!\n");
+             return gpg_error (GPG_ERR_BAD_PIN);
+           }
+         else
+           log_info("%d Admin PIN attempts remaining before card"
+                    " is permanently locked\n",info.chvretry[2]);
+       }
+
       rc = pincb (pincb_arg, "Admin PIN", &pinvalue); 
       if (rc)
         {
@@ -688,7 +700,7 @@ verify_chv3 (APP app,
 
       if (strlen (pinvalue) < 6)
         {
-          log_error ("prassphrase (CHV3) is too short; minimum length is 6\n");
+          log_error ("passphrase (CHV3) is too short; minimum length is 6\n");
           xfree (pinvalue);
           return gpg_error (GPG_ERR_BAD_PIN);
         }
index 5b3a33e..a58dda0 100644 (file)
@@ -47,7 +47,7 @@
 /* Change the PIN of a an OpenPGP card.  This is an interactive
    function. */
 void
-change_pin (int chvno)
+change_pin (int chvno, int allow_admin)
 {
   struct agent_card_info_s info;
   int rc;
@@ -71,52 +71,61 @@ change_pin (int chvno)
       return;
     }
 
-  for (;;)
+  if(!allow_admin)
     {
-      char *answer;
-
-      tty_printf ("\n");
-      tty_printf ("1 - change PIN\n"
-                  "2 - unblock PIN\n"
-                  "3 - change Admin PIN\n"
-                  "Q - quit\n");
-      tty_printf ("\n");
-
-      answer = cpr_get("cardutil.change_pin.menu",_("Your selection? "));
-      cpr_kill_prompt();
-      if (strlen (answer) != 1)
-        continue;
-
-      rc = 0;
-      if (*answer == '1')
-        {
-          rc = agent_scd_change_pin (1);
-          if (rc)
-            tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
-          else
-            tty_printf ("PIN changed.\n");
-        }
-      else if (*answer == '2')
-        {
-          rc = agent_scd_change_pin (101);
-          if (rc)
-            tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
-          else
-            tty_printf ("PIN unblocked and new PIN set.\n");
-        }
-      else if (*answer == '3')
-        {
-          rc = agent_scd_change_pin (3);
-          if (rc)
-            tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
-          else
-            tty_printf ("PIN changed.\n");
-        }
-      else if (*answer == 'q' || *answer == 'Q')
-        {
-          break;
-        }
+      rc = agent_scd_change_pin (1);
+      if (rc)
+       tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
+      else
+       tty_printf ("PIN changed.\n");
     }
+  else
+    for (;;)
+      {
+       char *answer;
+
+       tty_printf ("\n");
+       tty_printf ("1 - change PIN\n"
+                   "2 - unblock PIN\n"
+                   "3 - change Admin PIN\n"
+                   "Q - quit\n");
+       tty_printf ("\n");
+
+       answer = cpr_get("cardutil.change_pin.menu",_("Your selection? "));
+       cpr_kill_prompt();
+       if (strlen (answer) != 1)
+         continue;
+
+       rc = 0;
+       if (*answer == '1')
+         {
+           rc = agent_scd_change_pin (1);
+           if (rc)
+             tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
+           else
+             tty_printf ("PIN changed.\n");
+         }
+       else if (*answer == '2')
+         {
+           rc = agent_scd_change_pin (101);
+           if (rc)
+             tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
+           else
+             tty_printf ("PIN unblocked and new PIN set.\n");
+         }
+       else if (*answer == '3')
+         {
+           rc = agent_scd_change_pin (3);
+           if (rc)
+             tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
+           else
+             tty_printf ("PIN changed.\n");
+         }
+       else if (*answer == 'q' || *answer == 'Q')
+         {
+           break;
+         }
+      }
 }
 
 static const char *
@@ -1092,7 +1101,6 @@ card_store_subkey (KBNODE node, int use)
 }
 
 
-
 /* Menu to edit all user changeable values on an OpenPGP card.  Only
    Key creation is not handled here. */
 void
@@ -1100,7 +1108,7 @@ card_edit (STRLIST commands)
 {
   enum cmdids {
     cmdNOP = 0,
-    cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
+    cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG,
     cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
     cmdFORCESIG, cmdGENERATE, cmdPASSWD,
     cmdINVCMD
@@ -1109,35 +1117,38 @@ card_edit (STRLIST commands)
   static struct {
     const char *name;
     enum cmdids id;
+    int admin_only;
     const char *desc;
   } cmds[] = {
-    { N_("quit")  , cmdQUIT  , N_("quit this menu") },
-    { N_("q")     , cmdQUIT  , NULL   },
-    { N_("help")  , cmdHELP  , N_("show this help") },
-    {    "?"      , cmdHELP  , NULL   },
-    { N_("list")  , cmdLIST  , N_("list all available data") },
-    { N_("l")     , cmdLIST  , NULL   },
-    { N_("debug") , cmdDEBUG , NULL },
-    { N_("name")  , cmdNAME  , N_("change card holder's name") },
-    { N_("url")   , cmdURL   , N_("change URL to retrieve key") },
-    { N_("fetch") , cmdFETCH , N_("fetch the key specified in the card URL") },
-    { N_("login") , cmdLOGIN , N_("change the login name") },
-    { N_("lang")  , cmdLANG  , N_("change the language preferences") },
-    { N_("sex")   , cmdSEX   , N_("change card holder's sex") },
-    { N_("cafpr"),  cmdCAFPR,  N_("change a CA fingerprint") },
+    { N_("quit")  , cmdQUIT  , 0, N_("quit this menu") },
+    { N_("q")     , cmdQUIT  , 0, NULL   },
+    { N_("admin") , cmdADMIN , 0, N_("show admin commands") },
+    { N_("help")  , cmdHELP  , 0, N_("show this help") },
+    {    "?"      , cmdHELP  , 0, NULL   },
+    { N_("list")  , cmdLIST  , 0, N_("list all available data") },
+    { N_("l")     , cmdLIST  , 0, NULL   },
+    { N_("debug") , cmdDEBUG , 0, NULL },
+    { N_("name")  , cmdNAME  , 1, N_("change card holder's name") },
+    { N_("url")   , cmdURL   , 1, N_("change URL to retrieve key") },
+    { N_("fetch") , cmdFETCH , 0,
+                               N_("fetch the key specified in the card URL") },
+    { N_("login") , cmdLOGIN , 1, N_("change the login name") },
+    { N_("lang")  , cmdLANG  , 1, N_("change the language preferences") },
+    { N_("sex")   , cmdSEX   , 1, N_("change card holder's sex") },
+    { N_("cafpr"),  cmdCAFPR,  1, N_("change a CA fingerprint") },
     { N_("forcesig"),
-                  cmdFORCESIG, N_("toggle the signature force PIN flag") },
+                  cmdFORCESIG, 1, N_("toggle the signature force PIN flag") },
     { N_("generate"),
-                  cmdGENERATE, N_("generate new keys") },
-    { N_("passwd"), cmdPASSWD, N_("menu to change or unblock the PIN") },
-    { NULL, cmdINVCMD } 
+                  cmdGENERATE, 1, N_("generate new keys") },
+    { N_("passwd"), cmdPASSWD, 0, N_("menu to change or unblock the PIN") },
+    { NULL, cmdINVCMD, 0, NULL } 
   };
  
   enum cmdids cmd = cmdNOP;
   int have_commands = !!commands;
   int redisplay = 1;
   char *answer = NULL;
-  int did_checkpin = 0;
+  int did_checkpin = 0, allow_admin=0;
   char serialnobuf[50];
 
 
@@ -1220,26 +1231,47 @@ card_edit (STRLIST commands)
 
         cmd = cmds[i].id;
       }
-      
+
+      if(!allow_admin)
+       switch(cmd)
+         {
+         case cmdNAME:
+         case cmdURL:
+         case cmdLOGIN:
+         case cmdLANG:
+         case cmdCAFPR:
+         case cmdFORCESIG:
+         case cmdGENERATE:
+           tty_printf ("\n");
+           tty_printf (_("Admin-only command\n"));
+           continue;
+         default:
+           break;
+         }
 
       switch (cmd)
         {
         case cmdHELP:
           for (i=0; cmds[i].name; i++ )
-            if (cmds[i].desc)
+            if(cmds[i].desc
+              && (!cmds[i].admin_only || (cmds[i].admin_only && allow_admin)))
               tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
           break;
 
+       case cmdADMIN:
+         allow_admin=!allow_admin;
+         break;
+
         case cmdLIST:
           redisplay = 1;
           break;
 
         case cmdNAME:
-          change_name ();
+         change_name ();
           break;
 
         case cmdURL:
-          change_url ();
+         change_url ();
           break;
 
        case cmdFETCH:
@@ -1247,15 +1279,15 @@ card_edit (STRLIST commands)
          break;
 
         case cmdLOGIN:
-          change_login (arg_string);
+         change_login (arg_string);
           break;
 
         case cmdLANG:
-          change_lang ();
+         change_lang ();
           break;
 
         case cmdSEX:
-          change_sex ();
+         change_sex ();
           break;
 
         case cmdCAFPR:
@@ -1275,7 +1307,7 @@ card_edit (STRLIST commands)
           break;
 
         case cmdPASSWD:
-          change_pin (0);
+          change_pin (0, allow_admin);
           did_checkpin = 0; /* Need to reset it of course. */
           break;
 
index d9b3408..66a1065 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -348,8 +348,6 @@ enum cmd_and_opt_values
     octapiDriver,
     opcscDriver,
     oDisableCCID,
-    oAllowAdmin,
-    oDenyAdmin,
 
     aTest
   };
@@ -534,10 +532,6 @@ static ARGPARSE_OPTS opts[] = {
     { oSetNotation,  "notation-data", 2, "@" }, /* Alias */
     { oSigNotation,  "sig-notation", 2, "@" },
     { oCertNotation, "cert-notation", 2, "@" },
-#ifdef ENABLE_CARD_SUPPORT
-    { oAllowAdmin, "allow-admin",0,N_("allow the use of admin card commands")},
-    { oDenyAdmin,  "deny-admin",0,"@"},
-#endif
 
     { 302, NULL, 0, N_(
   "@\n(See the man page for a complete listing of all commands and options)\n"
@@ -1863,8 +1857,6 @@ main( int argc, char **argv )
           case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
           case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break;
           case oDisableCCID: opt.disable_ccid = 1; break;
-          case oAllowAdmin: opt.allow_admin = 1; break;
-          case oDenyAdmin: opt.allow_admin = 0; break;
 #endif /* ENABLE_CARD_SUPPORT*/
 
          case oArmor: opt.armor = 1; opt.no_armor=0; break;
@@ -3473,9 +3465,9 @@ main( int argc, char **argv )
 
       case aChangePIN:
         if (!argc)
-            change_pin (0);
+            change_pin (0,1);
         else if (argc == 1)
-            change_pin ( atoi (*argv));
+            change_pin (atoi (*argv),1);
         else
         wrong_args ("--change-pin [no]");
         break;
index 71c1a2b..aa213bb 100644 (file)
@@ -265,7 +265,7 @@ void unblock_all_signals(void);
 
 #ifdef ENABLE_CARD_SUPPORT
 /*-- card-util.c --*/
-void change_pin (int no);
+void change_pin (int no, int allow_admin);
 void card_status (FILE *fp, char *serialno, size_t serialnobuflen);
 void card_edit (STRLIST commands);
 int  card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
index db6932d..f952eea 100644 (file)
@@ -197,7 +197,6 @@ struct
   const char *ctapi_driver; /* Library to access the ctAPI. */
   const char *pcsc_driver;  /* Library to access the PC/SC system. */
   int disable_ccid;    /* Disable the use of the internal CCID driver. */
-  int allow_admin;     /* Allow the use of Admin commands. */
 #endif /*ENABLE_CARD_SUPPORT*/
 
 } opt;