diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/call-agent.c | 30 | ||||
-rw-r--r-- | g10/card-util.c | 24 |
2 files changed, 47 insertions, 7 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c index 11340aaa8..c7f1c296a 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -866,8 +866,14 @@ agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list) /* Send an APDU to the current card. On success the status word is * stored at R_SW. With HEXAPDU being NULL only a RESET command is - * send to scd. With HEXAPDU being the string "undefined" the command - * "SERIALNO undefined" is send to scd. + * send to scd. HEXAPDU may also be one of these special strings: + * + * "undefined" :: Send the command "SCD SERIALNO undefined" + * "lock" :: Send the command "SCD LOCK --wait" + * "trylock" :: Send the command "SCD LOCK" + * "unlock" :: Send the command "SCD UNLOCK" + * "reset-keep-lock" :: Send the command "SCD RESET --keep-lock" + * * Used by: * card-util.c */ @@ -888,6 +894,26 @@ agent_scd_apdu (const char *hexapdu, unsigned int *r_sw) NULL, NULL, NULL, NULL, NULL, NULL); } + else if (!strcmp (hexapdu, "reset-keep-lock")) + { + err = assuan_transact (agent_ctx, "SCD RESET --keep-lock", + NULL, NULL, NULL, NULL, NULL, NULL); + } + else if (!strcmp (hexapdu, "lock")) + { + err = assuan_transact (agent_ctx, "SCD LOCK --wait", + NULL, NULL, NULL, NULL, NULL, NULL); + } + else if (!strcmp (hexapdu, "trylock")) + { + err = assuan_transact (agent_ctx, "SCD LOCK", + NULL, NULL, NULL, NULL, NULL, NULL); + } + else if (!strcmp (hexapdu, "unlock")) + { + err = assuan_transact (agent_ctx, "SCD UNLOCK", + NULL, NULL, NULL, NULL, NULL, NULL); + } else if (!strcmp (hexapdu, "undefined")) { err = assuan_transact (agent_ctx, "SCD SERIALNO undefined", diff --git a/g10/card-util.c b/g10/card-util.c index 00b64b34b..8a5ab28dc 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -1834,8 +1834,13 @@ send_apdu (const char *hexapdu, const char *desc, unsigned int ignore) if (err) tty_printf ("sending card command %s failed: %s\n", desc, gpg_strerror (err)); - else if (!hexapdu || !strcmp (hexapdu, "undefined")) - ; + else if (!hexapdu + || !strcmp (hexapdu, "undefined") + || !strcmp (hexapdu, "reset-keep-lock") + || !strcmp (hexapdu, "lock") + || !strcmp (hexapdu, "trylock") + || !strcmp (hexapdu, "unlock")) + ; /* Ignore pseudo APDUs. */ else if (ignore == 0xffff) ; /* Ignore all status words. */ else if (sw != 0x9000) @@ -1864,6 +1869,7 @@ factory_reset (void) char *answer = NULL; int termstate = 0; int i; + int locked = 0; /* The code below basically does the same what this gpg-connect-agent script does: @@ -1925,8 +1931,14 @@ factory_reset (void) goto leave; /* We need to select a card application before we can send APDUs - to the card without scdaemon doing anything on its own. */ - err = send_apdu (NULL, "RESET", 0); + to the card without scdaemon doing anything on its own. We + then lock the connection so that other tools (e.g. Kleopatra) + don't try a new select. */ + err = send_apdu ("lock", "locking connection ", 0); + if (err) + goto leave; + locked = 1; + err = send_apdu ("reset-keep-lock", "reset", 0); if (err) goto leave; err = send_apdu ("undefined", "dummy select ", 0); @@ -1968,7 +1980,7 @@ factory_reset (void) goto leave; /* Finally we reset the card reader once more. */ - err = send_apdu (NULL, "RESET", 0); + err = send_apdu ("reset-keep-lock", "reset", 0); /* Then, connect the card again. */ if (!err) @@ -1981,6 +1993,8 @@ factory_reset (void) } leave: + if (locked) + send_apdu ("unlock", "unlocking connection ", 0); xfree (answer); agent_release_card_info (&info); } |