1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-02 22:38:02 +02:00

card: New option --info for command list and select by s/n.

* tools/gpg-card.c (cmd_list): add option --info.  Factor soem code
out to ...
(print_card_list): new.
--

This change allows to use the printed s/n to sleect another card
instead of using the index.  For example:

  gpg/card> l --cards
  0* D276000124010200FFFE50FF6E060000
  1  D2760001240102000005000000370000

Now select the second card but do not print the entire listing, just
the card index, s/n and applications.  We also select by s/n:

  gpg/card> l --info D2760001240102000005000000370000
  1* D2760001240102000005000000370000

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-02-18 20:12:46 +01:00
parent 41913d76f7
commit ee911df979
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -1011,53 +1011,92 @@ list_card (card_info_t info, int no_key_lookup)
/* Helper for cmd_list. */
static void
print_card_list (estream_t fp, card_info_t info, strlist_t cards,
int only_current)
{
int count;
strlist_t sl;
size_t snlen;
int star;
const char *s;
for (count = 0, sl = cards; sl; sl = sl->next, count++)
{
if (info && info->serialno)
{
s = strchr (sl->d, ' ');
if (s)
snlen = s - sl->d;
else
snlen = strlen (sl->d);
star = (strlen (info->serialno) == snlen
&& !memcmp (info->serialno, sl->d, snlen));
}
else
star = 0;
if (!only_current || star)
tty_fprintf (fp, "%d%c %s\n", count, star? '*':' ', sl->d);
}
}
/* The LIST command. This also updates INFO if needed. */ /* The LIST command. This also updates INFO if needed. */
static gpg_error_t static gpg_error_t
cmd_list (card_info_t info, char *argstr) cmd_list (card_info_t info, char *argstr)
{ {
gpg_error_t err; gpg_error_t err;
int opt_cards, opt_apps, opt_no_key_lookup; int opt_cards, opt_apps, opt_info, opt_no_key_lookup;
strlist_t cards = NULL; strlist_t cards = NULL;
strlist_t sl; strlist_t sl;
estream_t fp = opt.interactive? NULL : es_stdout; estream_t fp = opt.interactive? NULL : es_stdout;
int cardno = -1; const char *cardsn = NULL;
char *appstr = NULL; char *appstr = NULL;
int count; int count;
int need_learn = 0; int need_learn = 0;
int star;
size_t snlen;
const char *s;
if (!info) if (!info)
return print_help return print_help
("LIST [--cards] [--apps] [--no-key-lookup] [N] [APP]\n\n" ("LIST [--cards] [--apps] [--info] [--no-key-lookup] [N] [APP]\n\n"
"Show the content of the current card.\n" "Show the content of the current card.\n"
"With N given select and list the n-th card;\n" "With N given select and list the N-th card;\n"
"with APP also given select that application.\n" "with APP also given select that application.\n"
"To select an APP on the current card use '-' for N.\n" "To select an APP on the current card use '-' for N.\n"
" --cards lists available cards\n" "The S/N of the card may be used instead of N.\n"
" --apps lists additional card applications\n" " --cards lists available cards\n"
" --apps lists additional card applications\n"
" --info selects a card and prints its s/n\n"
" --no-key-lookup does not list matching OpenPGP or X.509 keys\n" " --no-key-lookup does not list matching OpenPGP or X.509 keys\n"
, 0); , 0);
opt_cards = has_leading_option (argstr, "--cards"); opt_cards = has_leading_option (argstr, "--cards");
opt_apps = has_leading_option (argstr, "--apps"); opt_apps = has_leading_option (argstr, "--apps");
opt_info = has_leading_option (argstr, "--info");
opt_no_key_lookup = has_leading_option (argstr, "--no-key-lookup"); opt_no_key_lookup = has_leading_option (argstr, "--no-key-lookup");
argstr = skip_options (argstr); argstr = skip_options (argstr);
if (opt.no_key_lookup) if (opt.no_key_lookup)
opt_no_key_lookup = 1; opt_no_key_lookup = 1;
if (digitp (argstr) || (*argstr == '-' && spacep (argstr+1))) if (hexdigitp (argstr) || (*argstr == '-' && spacep (argstr+1)))
{ {
if (*argstr == '-' && (argstr[1] || spacep (argstr+1))) if (*argstr == '-' && (argstr[1] || spacep (argstr+1)))
argstr++; /* Keep current card. */ argstr++; /* Keep current card. */
else else
{ {
cardno = atoi (argstr); cardsn = argstr;
while (digitp (argstr)) while (hexdigitp (argstr))
argstr++; argstr++;
if (*argstr && !spacep (argstr))
{
err = gpg_error (GPG_ERR_INV_ARG);
goto leave;
}
if (*argstr)
*argstr++ = 0;
} }
while (spacep (argstr)) while (spacep (argstr))
argstr++; argstr++;
if (*argstr) if (*argstr)
@ -1082,7 +1121,6 @@ cmd_list (card_info_t info, char *argstr)
goto leave; goto leave;
} }
if (!info->serialno) if (!info->serialno)
{ {
/* This is probably the first call. We need to send a SERIALNO /* This is probably the first call. We need to send a SERIALNO
@ -1093,7 +1131,6 @@ cmd_list (card_info_t info, char *argstr)
need_learn = 1; need_learn = 1;
} }
if (opt_cards || opt_apps) if (opt_cards || opt_apps)
{ {
/* Note that with option --apps CARDS is here the list of all /* Note that with option --apps CARDS is here the list of all
@ -1105,42 +1142,53 @@ cmd_list (card_info_t info, char *argstr)
err = scd_cardlist (&cards); err = scd_cardlist (&cards);
if (err) if (err)
goto leave; goto leave;
for (count = 0, sl = cards; sl; sl = sl->next, count++) print_card_list (fp, info, cards, 0);
{
if (info && info->serialno)
{
s = strchr (sl->d, ' ');
if (s)
snlen = s - sl->d;
else
snlen = strlen (sl->d);
star = (strlen (info->serialno) == snlen
&& !memcmp (info->serialno, sl->d, snlen));
}
else
star = 0;
tty_fprintf (fp, "%d%c %s\n", count, star? '*':' ', sl->d);
}
} }
else else
{ {
if (cardno != -1) if (cardsn)
{ {
/* Switch to the requested card. */ int i, cardno;
err = scd_cardlist (&cards); err = scd_cardlist (&cards);
if (err) if (err)
goto leave; goto leave;
for (count = 0, sl = cards; sl; sl = sl->next, count++)
if (count == cardno) /* Switch to the requested card. */
break; for (i=0; digitp (cardsn+i); i++)
if (!sl) ;
if (i && i < 4 && !cardsn[i])
{ /* Looks like an index into the card list. */
cardno = atoi (cardsn);
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;
}
}
else /* S/N of card specified. */
{ {
err = gpg_error (GPG_ERR_INV_INDEX); for (sl = cards; sl; sl = sl->next)
goto leave; if (!ascii_strcasecmp (sl->d, cardsn))
break;
if (!sl)
{
err = gpg_error (GPG_ERR_INV_INDEX);
goto leave;
}
} }
err = scd_switchcard (sl->d); err = scd_switchcard (sl->d);
need_learn = 1; need_learn = 1;
} }
else /* --info with not args - show app list. */
{
err = scd_applist (&cards, 1);
if (err)
goto leave;
}
if (appstr && *appstr) if (appstr && *appstr)
{ {
@ -1155,7 +1203,12 @@ cmd_list (card_info_t info, char *argstr)
err = scd_learn (info); err = scd_learn (info);
else else
err = 0; err = 0;
if (!err)
if (err)
;
else if (opt_info)
print_card_list (fp, info, cards, 1);
else
list_card (info, opt_no_key_lookup); list_card (info, opt_no_key_lookup);
} }