aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2019-04-03 08:27:08 +0000
committerWerner Koch <[email protected]>2019-04-03 08:27:08 +0000
commitbcca3acb87c36213fef9311236ea949d006f759c (patch)
tree56764c6a28d5fdd9c7730409dc0712848e90d46c
parentgpg: Print modern style key info for non-decryptable keys. (diff)
downloadgnupg-bcca3acb87c36213fef9311236ea949d006f759c.tar.gz
gnupg-bcca3acb87c36213fef9311236ea949d006f759c.zip
card: Allow card selection with LIST.
* tools/card-call-scd.c (start_agent): Request serialno only whean started. (scd_serialno): Allow NULL for r_serialno. * tools/gpg-card.c (cmd_factoryreset): Use changed scd_serialno. (cmd_list): New. (dispatch_command): Use cmd_list for cmdLIST. (interactive_loop): Ditto. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--tools/card-call-scd.c13
-rw-r--r--tools/gpg-card.c114
2 files changed, 90 insertions, 37 deletions
diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c
index 0a01bf5ca..c2580bf5c 100644
--- a/tools/card-call-scd.c
+++ b/tools/card-call-scd.c
@@ -310,11 +310,13 @@ static gpg_error_t
start_agent (unsigned int flags)
{
gpg_error_t err;
+ int started = 0;
if (agent_ctx)
err = 0;
else
{
+ started = 1;
err = start_new_gpg_agent (&agent_ctx,
GPG_ERR_SOURCE_DEFAULT,
opt.agent_program,
@@ -347,7 +349,7 @@ start_agent (unsigned int flags)
}
}
- if (!err && !(flags & START_AGENT_NO_STARTUP_CMDS))
+ if (started && !err && !(flags & START_AGENT_NO_STARTUP_CMDS))
{
/* Request the serial number of the card for an early test. */
struct card_info_s info;
@@ -990,7 +992,7 @@ learn_status_cb (void *opaque, const char *line)
/* Call the scdaemon to learn about a smartcard. This fills INFO
- * wioth data from the card. */
+ * with data from the card. */
gpg_error_t
scd_learn (card_info_t info)
{
@@ -1268,7 +1270,7 @@ scd_genkey (const char *keyref, int force, const char *algo, u32 *createtime)
/* Return the serial number of the card or an appropriate error. The
* serial number is returned as a hexstring. If DEMAND is not NULL
- * the reader with the a card of the serilanumber DEMAND is
+ * the reader with the a card of the serial number DEMAND is
* requested. */
gpg_error_t
scd_serialno (char **r_serialno, const char *demand)
@@ -1295,7 +1297,10 @@ scd_serialno (char **r_serialno, const char *demand)
return err;
}
- *r_serialno = serialno;
+ if (r_serialno)
+ *r_serialno = serialno;
+ else
+ xfree (serialno);
return 0;
}
diff --git a/tools/gpg-card.c b/tools/gpg-card.c
index d98a545ff..ddc4d12bf 100644
--- a/tools/gpg-card.c
+++ b/tools/gpg-card.c
@@ -1000,6 +1000,81 @@ list_card (card_info_t info)
+/* The LIST command. This also updates INFO. */
+static gpg_error_t
+cmd_list (card_info_t info, char *argstr)
+{
+ gpg_error_t err;
+ int opt_cards;
+ strlist_t cards = NULL;
+ strlist_t sl;
+ estream_t fp = opt.interactive? NULL : es_stdout;
+ int cardno, count;
+
+
+ if (!info)
+ return print_help
+ ("LIST [--cards] [N]\n\n"
+ "Show the content of the current card or with N given the N-th card.\n"
+ "Option --cards lists available cards.",
+ 0);
+
+ opt_cards = has_leading_option (argstr, "--cards");
+ argstr = skip_options (argstr);
+
+
+ if (digitp (argstr))
+ {
+ cardno = atoi (argstr);
+ while (digitp (argstr))
+ argstr++;
+ while (spacep (argstr))
+ argstr++;
+ }
+ else
+ cardno = -1;
+
+
+ if (opt_cards)
+ {
+ err = scd_cardlist (&cards);
+ if (err)
+ goto leave;
+ for (count = 0, sl = cards; sl; sl = sl->next, count++)
+ tty_fprintf (fp, "%d %s\n", count, sl->d);
+ }
+ else
+ {
+ if (cardno != -1)
+ {
+ err = scd_cardlist (&cards);
+ if (err)
+ goto leave;
+ for (count = 0, sl = cards; sl; sl = sl->next, count++)
+ if (count == cardno)
+ break;
+ if (!sl)
+ {
+ err = gpg_error (GPG_ERR_INV_INDEX);
+ goto leave;
+ }
+ err = scd_serialno (NULL, sl->d);
+ if (err)
+ goto leave;
+ }
+
+ err = scd_learn (info);
+ if (!err)
+ list_card (info);
+ }
+
+ leave:
+ free_strlist (cards);
+ return err;
+}
+
+
+
/* The VERIFY command. */
static gpg_error_t
cmd_verify (card_info_t info, char *argstr)
@@ -2478,9 +2553,8 @@ cmd_factoryreset (card_info_t info)
if (err)
goto leave;
- /* Then, connect the card again (answer used as a dummy). */
- xfree (answer); answer = NULL;
- err = scd_serialno (&answer, NULL);
+ /* Then, connect the card again. */
+ err = scd_serialno (NULL, NULL);
leave:
if (err && any_apdu && !is_yubikey)
@@ -3158,20 +3232,6 @@ dispatch_command (card_info_t info, const char *orig_command)
}
break;
- case cmdLIST:
- if (!info)
- print_help ("LIST\n\n"
- "Show content of the card.", 0);
- else
- {
- err = scd_learn (info);
- if (err)
- log_error ("Error reading card: %s\n", gpg_strerror (err));
- else
- list_card (info);
- }
- break;
-
case cmdRESET:
if (!info)
print_help ("RESET\n\n"
@@ -3183,6 +3243,7 @@ dispatch_command (card_info_t info, const char *orig_command)
}
break;
+ case cmdLIST: err = cmd_list (info, argstr); break;
case cmdVERIFY: err = cmd_verify (info, argstr); break;
case cmdAUTH: err = cmd_authenticate (info, argstr); break;
case cmdNAME: err = cmd_name (info, argstr); break;
@@ -3268,14 +3329,11 @@ interactive_loop (void)
}
else if (redisplay)
{
- err = scd_learn (info);
+ err = cmd_list (info, "");
if (err)
- {
- log_error ("Error reading card: %s\n", gpg_strerror (err));
- }
+ log_error ("Error reading card: %s\n", gpg_strerror (err));
else
{
- list_card (info);
tty_printf("\n");
redisplay = 0;
}
@@ -3388,17 +3446,6 @@ interactive_loop (void)
}
break;
- case cmdLIST:
- if (!info)
- print_help ("LIST\n\n"
- "Show content of the card.", 0);
- else
- {
- /* Actual work is done by the redisplay code block. */
- redisplay = 1;
- }
- break;
-
case cmdRESET:
if (!info)
print_help ("RESET\n\n"
@@ -3410,6 +3457,7 @@ interactive_loop (void)
}
break;
+ case cmdLIST: err = cmd_list (info, argstr); break;
case cmdVERIFY:
err = cmd_verify (info, argstr);
if (!err)