diff --git a/g10/ChangeLog b/g10/ChangeLog index db91da5dd..f30d063f9 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,17 @@ +2004-09-25 David Shaw + + * 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 * main.h: Create S2K_DIGEST_ALGO macro so we do not need to always diff --git a/g10/app-openpgp.c b/g10/app-openpgp.c index e4c147714..7b23d0b24 100644 --- a/g10/app-openpgp.c +++ b/g10/app-openpgp.c @@ -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); } diff --git a/g10/card-util.c b/g10/card-util.c index 5b3a33e5b..a58dda097 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -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; diff --git a/g10/g10.c b/g10/g10.c index d9b340853..66a106526 100644 --- 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; diff --git a/g10/main.h b/g10/main.h index 71c1a2b3e..aa213bbe0 100644 --- a/g10/main.h +++ b/g10/main.h @@ -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); diff --git a/g10/options.h b/g10/options.h index db6932dc6..f952eeab4 100644 --- a/g10/options.h +++ b/g10/options.h @@ -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;