summaryrefslogtreecommitdiffstats
path: root/tools/gpg-card.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2019-03-28 14:46:05 +0100
committerWerner Koch <wk@gnupg.org>2019-03-28 14:46:05 +0100
commit80c069b5e1ad6fbd547de59f332eb3fabb68c572 (patch)
tree04fd8d2f177a1ce31e5a0f44fcd009438c0c6be2 /tools/gpg-card.c
parentcard: Allow "yubikey disable" only for Yubikey-5 and later. (diff)
downloadgnupg2-80c069b5e1ad6fbd547de59f332eb3fabb68c572.tar.xz
gnupg2-80c069b5e1ad6fbd547de59f332eb3fabb68c572.zip
card: For passwd add a PIV menu and make the OpenPGP menu optional.
* tools/gpg-card.c (get_selection): New. (cmd_passwd): Reworked. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'tools/gpg-card.c')
-rw-r--r--tools/gpg-card.c181
1 files changed, 101 insertions, 80 deletions
diff --git a/tools/gpg-card.c b/tools/gpg-card.c
index a3113c9c5..7b3f8a3f6 100644
--- a/tools/gpg-card.c
+++ b/tools/gpg-card.c
@@ -429,6 +429,24 @@ put_data_to_file (const char *fname, const void *buffer, size_t length)
}
+/* Return a malloced string with the number opf the menu PROMPT.
+ * Control-D is mapped to "Q". */
+static char *
+get_selection (const char *prompt)
+{
+ char *answer;
+
+ tty_printf ("\n");
+ tty_printf ("%s", prompt);
+ tty_printf ("\n");
+ answer = tty_get (_("Your selection? "));
+ tty_kill_prompt ();
+ if (*answer == CONTROL_D)
+ strcpy (answer, "q");
+ return answer;
+}
+
+
/* Simply prints TEXT to the output. Returns 0 as a convenience.
* This is a separate fucntion so that it can be extended to run
@@ -2097,21 +2115,23 @@ cmd_generate (card_info_t info, char *argstr)
-/* Sub-menu to change a PIN. */
+/* Change a PIN. */
static gpg_error_t
cmd_passwd (card_info_t info, char *argstr)
{
- gpg_error_t err;
+ gpg_error_t err = 0;
char *answer = NULL;
- const char *pinref;
+ const char *pinref = NULL;
+ int reset_mode = 0;
+ int menu_used = 0;
if (!info)
return print_help
("PASSWD [PINREF]\n\n"
- "Menu to change or unblock the PINs. Note that the\n"
- "presented menu options depend on the type of card\n"
- "and whether the admin mode is enabled. For OpenPGP\n"
- "and PIV cards defaults for PINREF are available.",
+ "Change or unblock the PINs. Note that in interactive mode\n"
+ "and without a PINREF a menu is presented for certain cards;\n"
+ "in non-interactive and without a PINREF a default value is\n"
+ "used for these cards.",
0);
if (opt.interactive || opt.verbose)
@@ -2119,92 +2139,93 @@ cmd_passwd (card_info_t info, char *argstr)
app_type_string (info->apptype),
info->dispserialno? info->dispserialno : info->serialno);
- if (!*argstr && info->apptype == APP_TYPE_OPENPGP)
+ if (*argstr)
+ pinref = argstr;
+ else if (opt.interactive && info->apptype == APP_TYPE_OPENPGP)
{
- /* For an OpenPGP card we present the well known menu if no
- * argument is given. */
- for (;;)
+ menu_used = 1;
+ while (!pinref)
{
- tty_printf ("\n");
- tty_printf ("1 - change PIN\n"
- "2 - unblock and set new PIN\n"
- "3 - change Admin PIN\n"
- "4 - set the Reset Code\n"
- "Q - quit\n");
- tty_printf ("\n");
-
- err = 0;
xfree (answer);
- answer = tty_get (_("Your selection? "));
- tty_kill_prompt ();
- if (*answer == CONTROL_D)
- break; /* Quit. */
+ answer = get_selection ("1 - change the PIN\n"
+ "2 - unblock and set new a PIN\n"
+ "3 - change the Admin PIN\n"
+ "4 - set the Reset Code\n"
+ "Q - quit\n");
if (strlen (answer) != 1)
continue;
- if (*answer == 'q' || *answer == 'Q')
- break; /* Quit. */
-
- if (*answer == '1')
- {
- /* Change PIN (same as the direct thing in non-admin mode). */
- err = scd_change_pin ("OPENPGP.1", 0);
- if (err)
- log_error ("Error changing the PIN: %s\n", gpg_strerror (err));
- else
- log_info ("PIN changed.\n");
- }
+ else if (*answer == 'q' || *answer == 'Q')
+ goto leave;
+ else if (*answer == '1')
+ pinref = "OPENPGP.1";
else if (*answer == '2')
- {
- /* Unblock PIN by setting a new PIN. */
- err = scd_change_pin ("OPENPGP.1", 1);
- if (err)
- log_error ("Error unblocking the PIN: %s\n", gpg_strerror(err));
- else
- log_info ("PIN unblocked and new PIN set.\n");
- }
+ { pinref = "OPENPGP.1"; reset_mode = 1; }
else if (*answer == '3')
- {
- /* Change Admin PIN. */
- err = scd_change_pin ("OPENPGP.3", 0);
- if (err)
- log_error ("Error changing the PIN: %s\n", gpg_strerror (err));
- else
- log_info ("PIN changed.\n");
- }
+ pinref = "OPENPGP.3";
else if (*answer == '4')
- {
- /* Set a new Reset Code. */
- err = scd_change_pin ("OPENPGP.2", 1);
- if (err)
- log_error ("Error setting the Reset Code: %s\n",
- gpg_strerror (err));
- else
- log_info ("Reset Code set.\n");
- }
-
- } /*end for loop*/
+ { pinref = "OPENPGP.2"; reset_mode = 1; }
+ }
}
- else
+ else if (info->apptype == APP_TYPE_OPENPGP)
+ pinref = "OPENPGP.1";
+ else if (opt.interactive && info->apptype == APP_TYPE_PIV)
{
- if (*argstr)
- pinref = argstr;
- else if (info->apptype == APP_TYPE_PIV)
- pinref = "PIV.80";
- else
+ menu_used = 1;
+ while (!pinref)
{
- /* Note that we do not have a default value for OpenPGP
- * because we want to be mostly compatible to "gpg
- * --card-edit" and show a menu in that case (above). */
- err = gpg_error (GPG_ERR_MISSING_VALUE);
- goto leave;
+ xfree (answer);
+ answer = get_selection ("1 - change the PIN\n"
+ "2 - change the PUK\n"
+ "3 - change the Global PIN\n"
+ "Q - quit\n");
+ if (strlen (answer) != 1)
+ ;
+ else if (*answer == 'q' || *answer == 'Q')
+ goto leave;
+ else if (*answer == '1')
+ pinref = "PIV.80";
+ else if (*answer == '2')
+ pinref = "PIV.81";
+ else if (*answer == '3')
+ pinref = "PIV.00";
}
- err = scd_change_pin (pinref, 0);
- if (err)
- goto leave;
+ }
+ else if (info->apptype == APP_TYPE_PIV)
+ pinref = "PIV.80";
+ else
+ {
+ err = gpg_error (GPG_ERR_MISSING_VALUE);
+ goto leave;
+ }
- if (info->apptype == APP_TYPE_PIV
- && !ascii_strcasecmp (pinref, "PIV.81"))
+ err = scd_change_pin (pinref, reset_mode);
+ if (err)
+ {
+ if (!opt.interactive && !menu_used && !opt.verbose)
+ ;
+ else if (!ascii_strcasecmp (pinref, "PIV.81"))
+ log_error ("Error changing the PUK.\n");
+ else if (!ascii_strcasecmp (pinref, "OPENPGP.1") && reset_mode)
+ log_error ("Error unblocking the PIN.\n");
+ else if (!ascii_strcasecmp (pinref, "OPENPGP.2") && reset_mode)
+ log_error ("Error setting the Reset Code.\n");
+ else if (!ascii_strcasecmp (pinref, "OPENPGP.3"))
+ log_error ("Error changing the Admin PIN.\n");
+ else
+ log_error ("Error changing the PIN.\n");
+ }
+ else
+ {
+ if (!opt.interactive && !opt.verbose)
+ ;
+ else if (!ascii_strcasecmp (pinref, "PIV.81"))
log_info ("PUK changed.\n");
+ else if (!ascii_strcasecmp (pinref, "OPENPGP.1") && reset_mode)
+ log_info ("PIN unblocked and new PIN set.\n");
+ else if (!ascii_strcasecmp (pinref, "OPENPGP.2") && reset_mode)
+ log_info ("Reset Code set.\n");
+ else if (!ascii_strcasecmp (pinref, "OPENPGP.3"))
+ log_info ("Admin PIN changed.\n");
else
log_info ("PIN changed.\n");
}
@@ -2261,7 +2282,7 @@ cmd_unblock (card_info_t info)
}
else
{
- log_info ("Unblocking not yet supported for '%s'\n",
+ log_info ("Unblocking not supported for '%s'.\n",
app_type_string (info->apptype));
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
}