mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-11 22:01:08 +02:00
* 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. * miscutil.c (answer_is_okay_cancel): New.
This commit is contained in:
parent
be239a058a
commit
fcc72f915b
@ -462,6 +462,14 @@ more arguments in future versions.
|
|||||||
0x02 = this attribute packet is revoked
|
0x02 = this attribute packet is revoked
|
||||||
0x04 = this attribute packet is expired
|
0x04 = this attribute packet is expired
|
||||||
|
|
||||||
|
STATUSCTRL <what> [<serialno>]
|
||||||
|
This is used to control smartcard operations.
|
||||||
|
Defined values for WHAT are:
|
||||||
|
1 = Request insertion of a card. Serialnumber may be given
|
||||||
|
to request a specific card.
|
||||||
|
2 = Request removal of a card.
|
||||||
|
3 = Card with serialnumber detected
|
||||||
|
|
||||||
|
|
||||||
Format of the "--attribute-fd" output
|
Format of the "--attribute-fd" output
|
||||||
=====================================
|
=====================================
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
2003-10-29 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* 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 <wk@gnupg.org>
|
2003-10-28 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* keylist.c (list_keyblock_print): Denote secrets keys stored on a
|
* keylist.c (list_keyblock_print): Denote secrets keys stored on a
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#ifndef ENABLE_CARD_SUPPORT
|
#ifndef ENABLE_CARD_SUPPORT
|
||||||
#error no configured for card support.
|
#error not configured for card support.
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -36,6 +36,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
|
#include "ttyio.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
#include "cardglue.h"
|
#include "cardglue.h"
|
||||||
@ -250,6 +251,8 @@ open_card (void)
|
|||||||
APP app;
|
APP app;
|
||||||
|
|
||||||
card_close ();
|
card_close ();
|
||||||
|
|
||||||
|
retry:
|
||||||
slot = apdu_open_reader (default_reader_port);
|
slot = apdu_open_reader (default_reader_port);
|
||||||
if (slot == -1)
|
if (slot == -1)
|
||||||
{
|
{
|
||||||
@ -260,16 +263,42 @@ open_card (void)
|
|||||||
app = xcalloc (1, sizeof *app);
|
app = xcalloc (1, sizeof *app);
|
||||||
app->slot = slot;
|
app->slot = slot;
|
||||||
rc = app_select_openpgp (app, &app->serialno, &app->serialnolen);
|
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)
|
if (rc)
|
||||||
{
|
{
|
||||||
apdu_close_reader (slot);
|
|
||||||
log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
|
log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
|
||||||
|
apdu_close_reader (slot);
|
||||||
xfree (app);
|
xfree (app);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
app->initialized = 1;
|
app->initialized = 1;
|
||||||
current_app = app;
|
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;
|
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
|
/* Return a new malloced string by unescaping the string S. Escaping
|
||||||
is percent escaping and '+'/space mapping. A binary nul will
|
is percent escaping and '+'/space mapping. A binary nul will
|
||||||
silently be replaced by a 0xFF. Function returns NULL to indicate
|
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)
|
unsigned char **r_buf, size_t *r_buflen)
|
||||||
{
|
{
|
||||||
APP app;
|
APP app;
|
||||||
|
int rc;
|
||||||
|
|
||||||
*r_buf = NULL;
|
*r_buf = NULL;
|
||||||
*r_buflen = 0;
|
*r_buflen = 0;
|
||||||
|
retry:
|
||||||
app = current_app? current_app : open_card ();
|
app = current_app? current_app : open_card ();
|
||||||
if (!app)
|
if (!app)
|
||||||
return gpg_error (GPG_ERR_CARD);
|
return gpg_error (GPG_ERR_CARD);
|
||||||
|
|
||||||
/* Check that the card's serialnumber is as required.*/
|
/* 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,
|
return app->fnc.sign (app, serialno, hashalgo,
|
||||||
pin_cb, NULL,
|
pin_cb, NULL,
|
||||||
@ -649,13 +735,22 @@ agent_scd_pkdecrypt (const char *serialno,
|
|||||||
unsigned char **r_buf, size_t *r_buflen)
|
unsigned char **r_buf, size_t *r_buflen)
|
||||||
{
|
{
|
||||||
APP app;
|
APP app;
|
||||||
|
int rc;
|
||||||
|
|
||||||
*r_buf = NULL;
|
*r_buf = NULL;
|
||||||
*r_buflen = 0;
|
*r_buflen = 0;
|
||||||
|
retry:
|
||||||
app = current_app? current_app : open_card ();
|
app = current_app? current_app : open_card ();
|
||||||
if (!app)
|
if (!app)
|
||||||
return gpg_error (GPG_ERR_CARD);
|
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,
|
return app->fnc.decipher (app, serialno,
|
||||||
pin_cb, NULL,
|
pin_cb, NULL,
|
||||||
indata, indatalen,
|
indata, indatalen,
|
||||||
|
45
g10/status.c
45
g10/status.c
@ -150,6 +150,7 @@ get_status_string ( int no )
|
|||||||
case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break;
|
case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break;
|
||||||
case STATUS_REVKEYSIG : s = "REVKEYSIG"; break;
|
case STATUS_REVKEYSIG : s = "REVKEYSIG"; break;
|
||||||
case STATUS_ATTRIBUTE : s = "ATTRIBUTE"; break;
|
case STATUS_ATTRIBUTE : s = "ATTRIBUTE"; break;
|
||||||
|
case STATUS_CARDCTRL : s = "CARDCTRL"; break;
|
||||||
default: s = "?"; break;
|
default: s = "?"; break;
|
||||||
}
|
}
|
||||||
return s;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -100,6 +100,7 @@
|
|||||||
#define STATUS_IMPORT_OK 68
|
#define STATUS_IMPORT_OK 68
|
||||||
#define STATUS_IMPORT_CHECK 69
|
#define STATUS_IMPORT_CHECK 69
|
||||||
#define STATUS_REVKEYSIG 70
|
#define STATUS_REVKEYSIG 70
|
||||||
|
#define STATUS_CARDCTRL 71
|
||||||
|
|
||||||
/*-- status.c --*/
|
/*-- status.c --*/
|
||||||
void set_status_fd ( int fd );
|
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);
|
void cpr_kill_prompt(void);
|
||||||
int cpr_get_answer_is_yes( const char *keyword, const char *prompt );
|
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_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*/
|
#endif /*G10_STATUS_H*/
|
||||||
|
@ -175,6 +175,7 @@ char *make_printable_string( const byte *p, size_t n, int delim );
|
|||||||
int answer_is_yes_no_default( const char *s, int def_answer );
|
int answer_is_yes_no_default( const char *s, int def_answer );
|
||||||
int answer_is_yes( const char *s );
|
int answer_is_yes( const char *s );
|
||||||
int answer_is_yes_no_quit( const char *s );
|
int answer_is_yes_no_quit( const char *s );
|
||||||
|
int answer_is_okay_cancel (const char *s, int def_answer);
|
||||||
|
|
||||||
/*-- strgutil.c --*/
|
/*-- strgutil.c --*/
|
||||||
void free_strlist( STRLIST sl );
|
void free_strlist( STRLIST sl );
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2003-10-29 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* miscutil.c (answer_is_okay_cancel): New.
|
||||||
|
|
||||||
2003-10-25 Werner Koch <wk@gnupg.org>
|
2003-10-25 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* Makefile.am: Replaced INTLLIBS by LIBINTL.
|
* Makefile.am: Replaced INTLLIBS by LIBINTL.
|
||||||
|
@ -359,3 +359,38 @@ answer_is_yes_no_quit( const char *s )
|
|||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return 1 for okay, 0 for for cancel or DEF_ANSWER for default.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
answer_is_okay_cancel (const char *s, int def_answer)
|
||||||
|
{
|
||||||
|
const char *long_okay = _("okay");
|
||||||
|
const char *long_cancel = _("cancel");
|
||||||
|
const char *short_okay = _("oO");
|
||||||
|
const char *short_cancel = _("cC");
|
||||||
|
|
||||||
|
/* Note: We have to use the locale dependent strcasecmp */
|
||||||
|
if ( !strcasecmp(s, long_okay ) )
|
||||||
|
return 1;
|
||||||
|
if ( !strcasecmp(s, long_cancel ) )
|
||||||
|
return 0;
|
||||||
|
if ( *s && strchr( short_okay, *s ) && !s[1] )
|
||||||
|
return 1;
|
||||||
|
if ( *s && strchr( short_cancel, *s ) && !s[1] )
|
||||||
|
return 0;
|
||||||
|
/* Always test for the English values (not locale here) */
|
||||||
|
if ( !ascii_strcasecmp(s, "okay" ) )
|
||||||
|
return 1;
|
||||||
|
if ( !ascii_strcasecmp(s, "ok" ) )
|
||||||
|
return 1;
|
||||||
|
if ( !ascii_strcasecmp(s, "cancel" ) )
|
||||||
|
return 0;
|
||||||
|
if ( *s && strchr( "oO", *s ) && !s[1] )
|
||||||
|
return 1;
|
||||||
|
if ( *s && strchr( "cC", *s ) && !s[1] )
|
||||||
|
return 0;
|
||||||
|
return def_answer;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user