aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2020-05-27 09:27:32 +0000
committerWerner Koch <[email protected]>2020-05-27 09:27:32 +0000
commit46a3de4b5acb37274ddd132499a3243e1f92b506 (patch)
treea20724173e83f7c674c8152192ecf17f2a219ec0
parentcard: Implement UID command and print capabilities. (diff)
downloadgnupg-46a3de4b5acb37274ddd132499a3243e1f92b506.tar.gz
gnupg-46a3de4b5acb37274ddd132499a3243e1f92b506.zip
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. --
-rw-r--r--tools/gpg-card.c22
-rw-r--r--tools/gpg-card.h1
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. */