From 46a3de4b5acb37274ddd132499a3243e1f92b506 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 27 May 2020 11:27:32 +0200 Subject: [PATCH] card: Take care of removed and re-inserted cards. * tools/gpg-card.c (cmd_list): Take care of the need_sn_cmd flag. (cmd_factoryreset): Clear that flag. (dispatch_command): Set flag after a reset and after a CARD_NOT_PRESENT error. -- --- tools/gpg-card.c | 22 ++++++++++++++++++---- tools/gpg-card.h | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 86ff8b111..76301eb31 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -1141,13 +1141,15 @@ cmd_list (card_info_t info, char *argstr) goto leave; } - if (!info->serialno) + if (!info->serialno || info->need_sn_cmd) { - /* This is probably the first call. We need to send a SERIALNO - * command to scd so that our session knows all cards. */ + /* This is probably the first call or was explictly requested. + * We need to send a SERIALNO command to scdaemon so that our + * session knows all cards. */ err = scd_serialno (NULL, NULL); if (err) goto leave; + info->need_sn_cmd = 0; need_learn = 1; } @@ -2807,6 +2809,8 @@ cmd_factoryreset (card_info_t info) /* Then, connect the card again. */ err = scd_serialno (NULL, NULL); + if (!err) + info->need_sn_cmd = 0; leave: if (err && any_apdu && !is_yubikey) @@ -3272,6 +3276,8 @@ dispatch_command (card_info_t info, const char *orig_command) { flush_keyblock_cache (); err = scd_apdu (NULL, NULL, NULL, NULL); + if (!err) + info->need_sn_cmd = 1; } break; @@ -3318,7 +3324,11 @@ dispatch_command (card_info_t info, const char *orig_command) err = 0; } else - log_error ("Command '%s' failed: %s\n", command, gpg_strerror (err)); + { + log_error ("Command '%s' failed: %s\n", command, gpg_strerror (err)); + if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT) + info->need_sn_cmd = 1; + } } xfree (command); @@ -3485,6 +3495,8 @@ interactive_loop (void) { flush_keyblock_cache (); err = scd_apdu (NULL, NULL, NULL, NULL); + if (!err) + info->need_sn_cmd = 1; } break; @@ -3538,6 +3550,8 @@ interactive_loop (void) break; } log_error ("Command '%s' failed: %s\n", s, gpg_strerror (err)); + if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT) + info->need_sn_cmd = 1; } } /* End of main menu loop. */ diff --git a/tools/gpg-card.h b/tools/gpg-card.h index 9627e7b30..4bcb6488a 100644 --- a/tools/gpg-card.h +++ b/tools/gpg-card.h @@ -138,6 +138,7 @@ typedef struct key_info_s *key_info_t; struct card_info_s { int initialized; /* True if a learn command was successful. */ + int need_sn_cmd; /* The SERIALNO command needs to be issued. */ int error; /* private. */ char *reader; /* Reader information. */ char *cardtype; /* NULL or type of the card. */