1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-06-30 22:27:56 +02:00

* call-scd.c (inq_needpin): Skip leading spaces in of PIN

description.
* divert-scd.c (getpin_cb): Enhanced to cope with description
flags.
* query.c (agent_askpin): Add arg PROMPT_TEXT. Changed all
callers.
This commit is contained in:
Werner Koch 2005-05-24 12:37:36 +00:00
parent a43586d0e8
commit e96af3715b
10 changed files with 121 additions and 35 deletions

8
TODO
View File

@ -96,11 +96,3 @@ might want to have an agent context for each service request
* IMPORTANT:
Check that the PIN cache is cleared after failed card operations.
After receiving a HUP gpg-agent should set a flag to kill scdaemon
as soon as possible, w/o that scdaemon will continue running as a
zombie and gpg-agent won't be able to fire up a new one.
Implement an scd/agent option to wait for a card.

View File

@ -1,3 +1,12 @@
2005-05-24 Werner Koch <wk@g10code.com>
* call-scd.c (inq_needpin): Skip leading spaces in of PIN
description.
* divert-scd.c (getpin_cb): Enhanced to cope with description
flags.
* query.c (agent_askpin): Add arg PROMPT_TEXT. Changed all
callers.
2005-05-21 Werner Koch <wk@g10code.com> 2005-05-21 Werner Koch <wk@g10code.com>
* call-scd.c (start_scd): Don't test for an alive scdaemon here. * call-scd.c (start_scd): Don't test for an alive scdaemon here.

View File

@ -179,7 +179,8 @@ int agent_key_available (const unsigned char *grip);
/*-- query.c --*/ /*-- query.c --*/
void initialize_module_query (void); void initialize_module_query (void);
int agent_askpin (ctrl_t ctrl, int agent_askpin (ctrl_t ctrl,
const char *desc_text, const char *inital_errtext, const char *desc_text, const char *prompt_text,
const char *inital_errtext,
struct pin_entry_info_s *pininfo); struct pin_entry_info_s *pininfo);
int agent_get_passphrase (ctrl_t ctrl, char **retpass, int agent_get_passphrase (ctrl_t ctrl, char **retpass,
const char *desc, const char *prompt, const char *desc, const char *prompt,

View File

@ -601,6 +601,8 @@ inq_needpin (void *opaque, const char *line)
return ASSUAN_Inquire_Unknown; return ASSUAN_Inquire_Unknown;
} }
line += 7; line += 7;
while (*line == ' ')
line++;
pinlen = 90; pinlen = 90;
pin = gcry_malloc_secure (pinlen); pin = gcry_malloc_secure (pinlen);

View File

@ -2369,7 +2369,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
} }
pi->max_length = 100; pi->max_length = 100;
pi->max_tries = 1; pi->max_tries = 1;
err = agent_askpin (ctrl, description, NULL, pi); err = agent_askpin (ctrl, description, NULL, NULL, pi);
if (err) if (err)
goto out; goto out;

View File

@ -168,35 +168,113 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo,
buf has been allocated by the caller and is of size MAXBUF which buf has been allocated by the caller and is of size MAXBUF which
includes the terminating null. The function should return an UTF-8 includes the terminating null. The function should return an UTF-8
string with the passphrase, the buffer may optionally be padded string with the passphrase, the buffer may optionally be padded
with arbitrary characters */ with arbitrary characters.
INFO gets displayed as part of a generic string. However if the
first character of INFO is a vertical bar all up to the next
verical bar are considered flags and only everything after the
second vertical bar gets displayed as the full prompt.
Flags:
'N' = New PIN, this requests a second prompt to repeat the the
PIN. If the PIN is not correctly repeated it starts from
all over.
'A' = The PIN is an Admin PIN, SO-PIN, PUK or alike.
Example:
"|AN|Please enter the new security officer's PIN"
The text "Please ..." will get displayed and the flags 'A' and 'N'
are considered.
*/
static int static int
getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
{ {
struct pin_entry_info_s *pi; struct pin_entry_info_s *pi;
int rc; int rc;
char *desc; ctrl_t ctrl = opaque;
CTRL ctrl = opaque; const char *ends, *s;
int any_flags = 0;
int newpin = 0;
const char *again_text = NULL;
const char *prompt = "PIN";
if (maxbuf < 2) if (maxbuf < 2)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
/* Parse the flags. */
if (info && *info =='|' && (ends=strchr (info+1, '|')))
{
for (s=info+1; s < ends; s++)
{
if (*s == 'A')
prompt = _("Admin PIN");
else if (*s == 'N')
newpin = 1;
}
info = ends+1;
any_flags = 1;
}
else if (info && *info == '|')
log_debug ("pin_cb called without proper PIN info hack\n");
/* FIXME: keep PI and TRIES in OPAQUE. Frankly this is a whole /* FIXME: keep PI and TRIES in OPAQUE. Frankly this is a whole
mess because we should call the card's verify function from the mess because we should call the card's verify function from the
pinentry check pin CB. */ pinentry check pin CB. */
pi = gcry_calloc_secure (1, sizeof (*pi) + 100); again:
pi = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10);
if (!pi)
return gpg_error_from_errno (errno);
pi->max_length = maxbuf-1; pi->max_length = maxbuf-1;
pi->min_digits = 0; /* we want a real passphrase */ pi->min_digits = 0; /* we want a real passphrase */
pi->max_digits = 8; pi->max_digits = 8;
pi->max_tries = 3; pi->max_tries = 3;
if ( asprintf (&desc, _("Please enter the PIN%s%s%s to unlock the card"), if (any_flags)
{
rc = agent_askpin (ctrl, info, prompt, again_text, pi);
again_text = NULL;
if (!rc && newpin)
{
struct pin_entry_info_s *pi2;
pi2 = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10);
if (!pi2)
{
rc = gpg_error_from_errno (errno);
xfree (pi);
return rc;
}
pi2->max_length = maxbuf-1;
pi2->min_digits = 0;
pi2->max_digits = 8;
pi2->max_tries = 1;
rc = agent_askpin (ctrl, _("Repeat this PIN"), prompt, NULL, pi2);
if (!rc && strcmp (pi->pin, pi2->pin))
{
again_text = N_("PIN not correctly repeated; try again");
xfree (pi2);
xfree (pi);
goto again;
}
xfree (pi2);
}
}
else
{
char *desc;
if ( asprintf (&desc,
_("Please enter the PIN%s%s%s to unlock the card"),
info? " (`":"", info? " (`":"",
info? info:"", info? info:"",
info? "')":"") < 0) info? "')":"") < 0)
desc = NULL; desc = NULL;
rc = agent_askpin (ctrl, desc?desc:info, NULL, pi); rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi);
free (desc); free (desc);
}
if (!rc) if (!rc)
{ {
strncpy (buf, pi->pin, maxbuf-1); strncpy (buf, pi->pin, maxbuf-1);

View File

@ -276,7 +276,7 @@ unprotect (CTRL ctrl, const char *desc_text,
arg.unprotected_key = NULL; arg.unprotected_key = NULL;
pi->check_cb_arg = &arg; pi->check_cb_arg = &arg;
rc = agent_askpin (ctrl, desc_text, NULL, pi); rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi);
if (!rc) if (!rc)
{ {
assert (arg.unprotected_key); assert (arg.unprotected_key);

View File

@ -120,11 +120,11 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
pi2->check_cb_arg = pi->pin; pi2->check_cb_arg = pi->pin;
next_try: next_try:
rc = agent_askpin (ctrl, text1, initial_errtext, pi); rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
initial_errtext = NULL; initial_errtext = NULL;
if (!rc) if (!rc)
{ {
rc = agent_askpin (ctrl, text2, NULL, pi2); rc = agent_askpin (ctrl, text2, NULL, NULL, pi2);
if (rc == -1) if (rc == -1)
{ /* The re-entered one did not match and the user did not { /* The re-entered one did not match and the user did not
hit cancel. */ hit cancel. */
@ -228,10 +228,10 @@ agent_protect_and_store (CTRL ctrl, gcry_sexp_t s_skey)
pi2->check_cb_arg = pi->pin; pi2->check_cb_arg = pi->pin;
next_try: next_try:
rc = agent_askpin (ctrl, text1, initial_errtext, pi); rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
if (!rc) if (!rc)
{ {
rc = agent_askpin (ctrl, text2, NULL, pi2); rc = agent_askpin (ctrl, text2, NULL, NULL, pi2);
if (rc == -1) if (rc == -1)
{ /* The re-entered one did not match and the user did not { /* The re-entered one did not match and the user did not
hit cancel. */ hit cancel. */

View File

@ -288,8 +288,9 @@ all_digitsp( const char *s)
number here and repeat it as long as we have invalid formed number here and repeat it as long as we have invalid formed
numbers. */ numbers. */
int int
agent_askpin (CTRL ctrl, agent_askpin (ctrl_t ctrl,
const char *desc_text, const char *initial_errtext, const char *desc_text, const char *prompt_text,
const char *initial_errtext,
struct pin_entry_info_s *pininfo) struct pin_entry_info_s *pininfo)
{ {
int rc; int rc;
@ -310,6 +311,9 @@ agent_askpin (CTRL ctrl,
desc_text = _("Please enter your passphrase, so that the secret key " desc_text = _("Please enter your passphrase, so that the secret key "
"can be unlocked for this session"); "can be unlocked for this session");
if (prompt_text)
is_pin = !!strstr (prompt_text, "PIN");
else
is_pin = desc_text && strstr (desc_text, "PIN"); is_pin = desc_text && strstr (desc_text, "PIN");
rc = start_pinentry (ctrl); rc = start_pinentry (ctrl);
@ -322,10 +326,10 @@ agent_askpin (CTRL ctrl,
if (rc) if (rc)
return unlock_pinentry (map_assuan_err (rc)); return unlock_pinentry (map_assuan_err (rc));
rc = assuan_transact (entry_ctx, snprintf (line, DIM(line)-1, "SETPROMPT %s",
is_pin? "SETPROMPT PIN:" prompt_text? prompt_text : is_pin? "PIN:" : "Passphrase:");
: "SETPROMPT Passphrase:", line[DIM(line)-1] = 0;
NULL, NULL, NULL, NULL, NULL, NULL); rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc) if (rc)
return unlock_pinentry (map_assuan_err (rc)); return unlock_pinentry (map_assuan_err (rc));

View File

@ -1528,7 +1528,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
/* Check whether a key already exists. KEYIDX is the index of the key /* Check whether a key already exists. KEYIDX is the index of the key
(0..2). If FORCE is TRUE a diagnositivc will be printed but no (0..2). If FORCE is TRUE a diagnositic will be printed but no
error returned if the key already exists. */ error returned if the key already exists. */
static gpg_error_t static gpg_error_t
does_key_exist (app_t app, int keyidx, int force) does_key_exist (app_t app, int keyidx, int force)
@ -2134,7 +2134,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
{ {
char *prompt; char *prompt;
#define PROMPTSTRING _("PIN [sigs done: %lu]") #define PROMPTSTRING _("||Please enter the PIN%%0A[sigs done: %lu]")
prompt = malloc (strlen (PROMPTSTRING) + 50); prompt = malloc (strlen (PROMPTSTRING) + 50);
if (!prompt) if (!prompt)