diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 10 | ||||
-rw-r--r-- | g10/cardglue.c | 99 | ||||
-rw-r--r-- | g10/status.c | 45 | ||||
-rw-r--r-- | g10/status.h | 4 |
4 files changed, 156 insertions, 2 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 5896c5d88..2c6b1bc3e 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,13 @@ +2003-10-29 Werner Koch <[email protected]> + + * cardglue.c (open_card): Ask for card insertion. + (check_card_serialno): New. + (agent_scd_pksign, agent_scd_pkdecrypt): Use it here. + * cardglue.c (open_card): Issue insertion status message. + * status.h, status.c (STATUS_CARDCTRL): New. + + * status.c (cpr_get_answer_okay_cancel): New. + 2003-10-28 Werner Koch <[email protected]> * keylist.c (list_keyblock_print): Denote secrets keys stored on a diff --git a/g10/cardglue.c b/g10/cardglue.c index 3173248cb..55729bf7d 100644 --- a/g10/cardglue.c +++ b/g10/cardglue.c @@ -20,7 +20,7 @@ #include <config.h> #ifndef ENABLE_CARD_SUPPORT -#error no configured for card support. +#error not configured for card support. #endif #include <stdio.h> #include <stdlib.h> @@ -36,6 +36,7 @@ #include "util.h" #include "main.h" #include "status.h" +#include "ttyio.h" #include "i18n.h" #include "cardglue.h" @@ -250,6 +251,8 @@ open_card (void) APP app; card_close (); + + retry: slot = apdu_open_reader (default_reader_port); if (slot == -1) { @@ -260,16 +263,42 @@ open_card (void) app = xcalloc (1, sizeof *app); app->slot = slot; rc = app_select_openpgp (app, &app->serialno, &app->serialnolen); + if (rc && !opt.batch) + { + write_status_text (STATUS_CARDCTRL, "1"); + + if ( cpr_get_answer_okay_cancel ("cardctrl.insert_card.okay", + _("Please insert the card and hit return or enter 'c' to cancel: "), + 1) ) + { + apdu_close_reader (slot); + xfree (app); + goto retry; + } + } if (rc) { - apdu_close_reader (slot); log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc)); + apdu_close_reader (slot); xfree (app); return NULL; } app->initialized = 1; current_app = app; + if (is_status_enabled () ) + { + int i; + char *p, *buf; + + buf = xmalloc (5 + app->serialnolen * 2 + 1); + p = stpcpy (buf, "3 "); + for (i=0; i < app->serialnolen; p +=2, i++) + sprintf (p, "%02X", app->serialno[i]); + write_status_text (STATUS_CARDCTRL, buf); + xfree (buf); + } + return app; } @@ -287,6 +316,56 @@ card_close (void) } +/* Check that the serial number of the current card (as described by + APP) matches SERIALNO. If there is no match and we are not in + batch mode, present a prompt to insert the desired card. The + function return 0 is the present card is okay, -1 if the user + selected to insert a new card or an error value. Note that the + card context will be closed in all cases except for 0 as return + value. */ +static int +check_card_serialno (APP app, const char *serialno) +{ + const char *s; + int ask = 0; + int n; + + for (s = serialno, n=0; *s != '/' && hexdigitp (s); s++, n++) + ; + if (n != 32) + { + log_error ("invalid serial number in keyring detected\n"); + return gpg_error (GPG_ERR_INV_ID); + } + if (app->serialnolen != 16) + ask = 1; + for (s = serialno, n=0; !ask && n < 16; s += 2, n++) + if (app->serialno[n] != xtoi_2 (s)) + ask = 1; + if (ask) + { + char buf[5+32+1]; + + card_close (); + tty_printf (_("Please remove the current card and " + "insert the one with the serial number:\n" + " %.*s\n"), 32, serialno); + + sprintf (buf, "1 %.32s", serialno); + write_status_text (STATUS_CARDCTRL, buf); + + if ( cpr_get_answer_okay_cancel ("cardctrl.change_card.okay", + _("Hit return when ready " + "or enter 'c' to cancel: "), + 1) ) + return -1; + return gpg_error (GPG_ERR_INV_ID); + } + return 0; +} + + + /* Return a new malloced string by unescaping the string S. Escaping is percent escaping and '+'/space mapping. A binary nul will silently be replaced by a 0xFF. Function returns NULL to indicate @@ -626,14 +705,21 @@ agent_scd_pksign (const char *serialno, int hashalgo, unsigned char **r_buf, size_t *r_buflen) { APP app; + int rc; *r_buf = NULL; *r_buflen = 0; + retry: app = current_app? current_app : open_card (); if (!app) return gpg_error (GPG_ERR_CARD); /* Check that the card's serialnumber is as required.*/ + rc = check_card_serialno (app, serialno); + if (rc == -1) + goto retry; + if (rc) + return rc; return app->fnc.sign (app, serialno, hashalgo, pin_cb, NULL, @@ -649,13 +735,22 @@ agent_scd_pkdecrypt (const char *serialno, unsigned char **r_buf, size_t *r_buflen) { APP app; + int rc; *r_buf = NULL; *r_buflen = 0; + retry: app = current_app? current_app : open_card (); if (!app) return gpg_error (GPG_ERR_CARD); + /* Check that the card's serialnumber is as required.*/ + rc = check_card_serialno (app, serialno); + if (rc == -1) + goto retry; + if (rc) + return rc; + return app->fnc.decipher (app, serialno, pin_cb, NULL, indata, indatalen, diff --git a/g10/status.c b/g10/status.c index cde0c8d77..d39bc683b 100644 --- a/g10/status.c +++ b/g10/status.c @@ -150,6 +150,7 @@ get_status_string ( int no ) case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break; case STATUS_REVKEYSIG : s = "REVKEYSIG"; break; case STATUS_ATTRIBUTE : s = "ATTRIBUTE"; break; + case STATUS_CARDCTRL : s = "CARDCTRL"; break; default: s = "?"; break; } return s; @@ -692,3 +693,47 @@ cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt ) } } } + + +int +cpr_get_answer_okay_cancel (const char *keyword, + const char *prompt, + int def_answer) +{ + int yes; + char *answer = NULL; + char *p; + + if( opt.command_fd != -1 ) + answer = do_get_from_fd ( keyword, 0, 0 ); +#ifdef USE_SHM_COPROCESSING + else if( opt.shm_coprocess ) + answer = do_shm_get( keyword, 0, 0 ); +#endif + + if (answer) + { + yes = answer_is_okay_cancel (answer, def_answer); + m_free (answer); + return yes; + } + + for(;;) + { + p = tty_get( prompt ); + trim_spaces(p); /* it is okay to do this here */ + if (*p == '?' && !p[1]) + { + m_free(p); + display_online_help (keyword); + } + else + { + tty_kill_prompt(); + yes = answer_is_okay_cancel (p, def_answer); + m_free(p); + return yes; + } + } +} + diff --git a/g10/status.h b/g10/status.h index 68da60d28..73cc3f1a9 100644 --- a/g10/status.h +++ b/g10/status.h @@ -100,6 +100,7 @@ #define STATUS_IMPORT_OK 68 #define STATUS_IMPORT_CHECK 69 #define STATUS_REVKEYSIG 70 +#define STATUS_CARDCTRL 71 /*-- status.c --*/ void set_status_fd ( int fd ); @@ -123,6 +124,9 @@ char *cpr_get_hidden( const char *keyword, const char *prompt ); void cpr_kill_prompt(void); int cpr_get_answer_is_yes( const char *keyword, const char *prompt ); int cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt ); +int cpr_get_answer_okay_cancel (const char *keyword, + const char *prompt, + int def_answer); #endif /*G10_STATUS_H*/ |