mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Add user defined pinentry prompts for SCD.
This adds scdaemon "OPTION pin-prompt" and "OPTION pin-admin-prompt" along with special escapes to replace in the prompt string to inform the user of a signature count and admin PIN attempts remaining. It also adds another "standard" pinentry escape "|I|" to ignore the default pinentry prompt from gpg-agent and use the supplied 'info' parameter unmodified (cannot be used with other pinentry flags). * agent/divert-scd.c (getpin_cb): Add |I| pinentry flag to ignore the default prompt and use the 'info' parameter as the entire prompt. * scd/app-common.h (PIN_PROMPT_NONE, PIN_SIGN_PROMPT, PIN_ADMIN_PROMPT): New enumeration. (set_pin_prompt): New application callback to set a user-defined pinentry prompt. * scd/app-openpgp.c (verify_a_chv): Expand a user-defined pinentry prompt. (build_enter_admin_pin_prompt): Ditto. (do_change_pin): Ditto. (do_set_pin_prompt): New. * scd/app.c (expand_pin_prompt): New. (app_set_pin_prompt): Ditto. * scd/command.c (set_pinentry_prompt): New. (option_handler): Add option 'pin-prompt' and 'pin-admin-prompt'. (open_card): Set the user-defined pinentry prompts after selecting an application.
This commit is contained in:
parent
30ec869b8c
commit
633ea8531e
2
NEWS
2
NEWS
@ -4,6 +4,8 @@ Noteworthy changes in version 2.1.0beta4 (unreleased)
|
|||||||
* GPG now accepts a space separated fingerprint as a user ID. This
|
* GPG now accepts a space separated fingerprint as a user ID. This
|
||||||
allows to copy and paste the fingerprint from the key listing.
|
allows to copy and paste the fingerprint from the key listing.
|
||||||
|
|
||||||
|
* New option for SCDAEMON to set a user defined pinentry prompt.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 2.1.0beta3 (2011-12-20)
|
Noteworthy changes in version 2.1.0beta3 (2011-12-20)
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
@ -166,6 +166,8 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo,
|
|||||||
'A' = The PIN is an Admin PIN, SO-PIN or alike.
|
'A' = The PIN is an Admin PIN, SO-PIN or alike.
|
||||||
'P' = The PIN is a PUK (Personal Unblocking Key).
|
'P' = The PIN is a PUK (Personal Unblocking Key).
|
||||||
'R' = The PIN is a Reset Code.
|
'R' = The PIN is a Reset Code.
|
||||||
|
'I' = Ignore using the default prompt and use 'info' as the entire
|
||||||
|
prompt. Cannot be used with other flags.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@ -185,6 +187,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
|
|||||||
int newpin = 0;
|
int newpin = 0;
|
||||||
int resetcode = 0;
|
int resetcode = 0;
|
||||||
int is_puk = 0;
|
int is_puk = 0;
|
||||||
|
int ignore = 0;
|
||||||
const char *again_text = NULL;
|
const char *again_text = NULL;
|
||||||
const char *prompt = "PIN";
|
const char *prompt = "PIN";
|
||||||
|
|
||||||
@ -212,6 +215,8 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
|
|||||||
prompt = _("Reset Code");
|
prompt = _("Reset Code");
|
||||||
resetcode = 1;
|
resetcode = 1;
|
||||||
}
|
}
|
||||||
|
else if (*s == 'I')
|
||||||
|
ignore = 1;
|
||||||
}
|
}
|
||||||
info = ends+1;
|
info = ends+1;
|
||||||
any_flags = 1;
|
any_flags = 1;
|
||||||
@ -219,6 +224,9 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
|
|||||||
else if (info && *info == '|')
|
else if (info && *info == '|')
|
||||||
log_debug ("pin_cb called without proper PIN info hack\n");
|
log_debug ("pin_cb called without proper PIN info hack\n");
|
||||||
|
|
||||||
|
if (ignore)
|
||||||
|
any_flags = 0;
|
||||||
|
|
||||||
/* If BUF has been passed as NULL, we are in keypad mode: The
|
/* If BUF has been passed as NULL, we are in keypad mode: The
|
||||||
callback opens the popup and immediatley returns. */
|
callback opens the popup and immediatley returns. */
|
||||||
if (!buf)
|
if (!buf)
|
||||||
@ -305,8 +313,8 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *desc;
|
char *desc = NULL;
|
||||||
if ( asprintf (&desc,
|
if (!ignore && asprintf (&desc,
|
||||||
_("Please enter the PIN%s%s%s to unlock the card"),
|
_("Please enter the PIN%s%s%s to unlock the card"),
|
||||||
info? " (`":"",
|
info? " (`":"",
|
||||||
info? info:"",
|
info? info:"",
|
||||||
|
@ -34,6 +34,12 @@
|
|||||||
#define APP_CHANGE_FLAG_RESET 1
|
#define APP_CHANGE_FLAG_RESET 1
|
||||||
#define APP_CHANGE_FLAG_NULLPIN 2
|
#define APP_CHANGE_FLAG_NULLPIN 2
|
||||||
|
|
||||||
|
/* For user defined pinentry prompts. */
|
||||||
|
enum {
|
||||||
|
PIN_PROMPT_NONE = -1,
|
||||||
|
PIN_SIGN_PROMPT,
|
||||||
|
PIN_ADMIN_PROMPT,
|
||||||
|
};
|
||||||
|
|
||||||
struct app_local_s; /* Defined by all app-*.c. */
|
struct app_local_s; /* Defined by all app-*.c. */
|
||||||
|
|
||||||
@ -119,6 +125,7 @@ struct app_ctx_s {
|
|||||||
gpg_error_t (*check_pin) (app_t app, const char *keyidstr,
|
gpg_error_t (*check_pin) (app_t app, const char *keyidstr,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg);
|
void *pincb_arg);
|
||||||
|
gpg_error_t (*set_pin_prompt)(app_t app, int which, const char *prompt);
|
||||||
} fnc;
|
} fnc;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -192,6 +199,7 @@ gpg_error_t app_genkey (app_t app, ctrl_t ctrl,
|
|||||||
time_t createtime,
|
time_t createtime,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg);
|
void *pincb_arg);
|
||||||
|
gpg_error_t app_set_pin_prompt (app_t app, int which, const char *prompt);
|
||||||
gpg_error_t app_get_challenge (app_t app, size_t nbytes,
|
gpg_error_t app_get_challenge (app_t app, size_t nbytes,
|
||||||
unsigned char *buffer);
|
unsigned char *buffer);
|
||||||
gpg_error_t app_change_pin (app_t app, ctrl_t ctrl,
|
gpg_error_t app_change_pin (app_t app, ctrl_t ctrl,
|
||||||
@ -201,6 +209,8 @@ gpg_error_t app_change_pin (app_t app, ctrl_t ctrl,
|
|||||||
gpg_error_t app_check_pin (app_t app, const char *keyidstr,
|
gpg_error_t app_check_pin (app_t app, const char *keyidstr,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg);
|
void *pincb_arg);
|
||||||
|
char *expand_pin_prompt(const char *prompt, const char *prepend, int which,
|
||||||
|
...);
|
||||||
|
|
||||||
|
|
||||||
/*-- app-openpgp.c --*/
|
/*-- app-openpgp.c --*/
|
||||||
|
@ -198,6 +198,8 @@ struct app_local_s {
|
|||||||
rsa_key_format_t format;
|
rsa_key_format_t format;
|
||||||
} keyattr[3];
|
} keyattr[3];
|
||||||
|
|
||||||
|
char *pin_prompt; /* As set with set_pin_prompt() or a default. */
|
||||||
|
char *pin_admin_prompt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -242,6 +244,8 @@ do_deinit (app_t app)
|
|||||||
xfree (app->app_local->pk[i].key);
|
xfree (app->app_local->pk[i].key);
|
||||||
app->app_local->pk[i].read_done = 0;
|
app->app_local->pk[i].read_done = 0;
|
||||||
}
|
}
|
||||||
|
xfree (app->app_local->pin_prompt);
|
||||||
|
xfree (app->app_local->pin_admin_prompt);
|
||||||
xfree (app->app_local);
|
xfree (app->app_local);
|
||||||
app->app_local = NULL;
|
app->app_local = NULL;
|
||||||
}
|
}
|
||||||
@ -1520,19 +1524,41 @@ verify_a_chv (app_t app,
|
|||||||
|
|
||||||
if (chvno == 1)
|
if (chvno == 1)
|
||||||
{
|
{
|
||||||
|
if (app->app_local->pin_prompt)
|
||||||
|
{
|
||||||
|
prompt_buffer = expand_pin_prompt (app->app_local->pin_prompt, "|I|",
|
||||||
|
PIN_SIGN_PROMPT, sigcount);
|
||||||
|
if (!prompt_buffer)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#define PROMPTSTRING _("||Please enter the PIN%%0A[sigs done: %lu]")
|
#define PROMPTSTRING _("||Please enter the PIN%%0A[sigs done: %lu]")
|
||||||
size_t promptsize = strlen (PROMPTSTRING) + 50;
|
size_t promptsize;
|
||||||
|
|
||||||
|
promptsize = strlen (PROMPTSTRING) + 50;
|
||||||
prompt_buffer = xtrymalloc (promptsize);
|
prompt_buffer = xtrymalloc (promptsize);
|
||||||
if (!prompt_buffer)
|
if (!prompt_buffer)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
snprintf (prompt_buffer, promptsize-1, PROMPTSTRING, sigcount);
|
snprintf (prompt_buffer, promptsize-1, PROMPTSTRING, sigcount);
|
||||||
prompt = prompt_buffer;
|
|
||||||
#undef PROMPTSTRING
|
#undef PROMPTSTRING
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prompt = prompt_buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (app->app_local->pin_prompt)
|
||||||
|
{
|
||||||
|
prompt_buffer = expand_pin_prompt (app->app_local->pin_prompt, "|I|",
|
||||||
|
PIN_PROMPT_NONE, NULL);
|
||||||
|
if (!prompt_buffer)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
prompt = prompt_buffer;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
prompt = _("||Please enter the PIN");
|
prompt = _("||Please enter the PIN");
|
||||||
|
}
|
||||||
|
|
||||||
if (!opt.disable_keypad
|
if (!opt.disable_keypad
|
||||||
&& !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
|
&& !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
|
||||||
@ -1673,11 +1699,21 @@ build_enter_admin_pin_prompt (app_t app, char **r_prompt)
|
|||||||
{
|
{
|
||||||
/* TRANSLATORS: Do not translate the "|A|" prefix but keep it at
|
/* TRANSLATORS: Do not translate the "|A|" prefix but keep it at
|
||||||
the start of the string. Use %%0A to force a linefeed. */
|
the start of the string. Use %%0A to force a linefeed. */
|
||||||
|
if (app->app_local->pin_admin_prompt)
|
||||||
|
prompt = expand_pin_prompt (app->app_local->pin_admin_prompt, "|I|",
|
||||||
|
PIN_ADMIN_PROMPT, remaining);
|
||||||
|
else
|
||||||
prompt = xtryasprintf (_("|A|Please enter the Admin PIN%%0A"
|
prompt = xtryasprintf (_("|A|Please enter the Admin PIN%%0A"
|
||||||
"[remaining attempts: %d]"), remaining);
|
"[remaining attempts: %d]"), remaining);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (app->app_local->pin_admin_prompt)
|
||||||
|
prompt = expand_pin_prompt (app->app_local->pin_admin_prompt, "|I|",
|
||||||
|
PIN_PROMPT_NONE, NULL);
|
||||||
else
|
else
|
||||||
prompt = xtrystrdup (_("|A|Please enter the Admin PIN"));
|
prompt = xtrystrdup (_("|A|Please enter the Admin PIN"));
|
||||||
|
}
|
||||||
|
|
||||||
if (!prompt)
|
if (!prompt)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
@ -1998,8 +2034,22 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
|
|||||||
goto leave;
|
goto leave;
|
||||||
prompt = promptbuf;
|
prompt = promptbuf;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (app->app_local->pin_prompt)
|
||||||
|
{
|
||||||
|
promptbuf = expand_pin_prompt (app->app_local->pin_prompt,
|
||||||
|
"|I|", PIN_PROMPT_NONE, NULL);
|
||||||
|
if (!promptbuf)
|
||||||
|
{
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
prompt = promptbuf;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
prompt = _("||Please enter the PIN");
|
prompt = _("||Please enter the PIN");
|
||||||
|
}
|
||||||
rc = pincb (pincb_arg, prompt, &oldpinvalue);
|
rc = pincb (pincb_arg, prompt, &oldpinvalue);
|
||||||
xfree (promptbuf);
|
xfree (promptbuf);
|
||||||
promptbuf = NULL;
|
promptbuf = NULL;
|
||||||
@ -3707,6 +3757,40 @@ parse_algorithm_attribute (app_t app, int keyno)
|
|||||||
xfree (relptr);
|
xfree (relptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpg_error_t
|
||||||
|
do_set_pin_prompt(app_t app, int which, const char *prompt)
|
||||||
|
{
|
||||||
|
gpg_error_t rc = 0;
|
||||||
|
char **p = NULL;
|
||||||
|
|
||||||
|
switch (which)
|
||||||
|
{
|
||||||
|
case PIN_SIGN_PROMPT:
|
||||||
|
p = &app->app_local->pin_prompt;
|
||||||
|
break;
|
||||||
|
case PIN_ADMIN_PROMPT:
|
||||||
|
p = &app->app_local->pin_admin_prompt;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
xfree (*p);
|
||||||
|
*p = NULL;
|
||||||
|
|
||||||
|
if (prompt && *prompt != '-' && *(prompt+1) != 0)
|
||||||
|
{
|
||||||
|
*p = xtrystrdup (prompt);
|
||||||
|
if (!*p)
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Select the OpenPGP application on the card in SLOT. This function
|
/* Select the OpenPGP application on the card in SLOT. This function
|
||||||
must be used before any other OpenPGP application functions. */
|
must be used before any other OpenPGP application functions. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
@ -3850,6 +3934,7 @@ app_select_openpgp (app_t app)
|
|||||||
app->fnc.decipher = do_decipher;
|
app->fnc.decipher = do_decipher;
|
||||||
app->fnc.change_pin = do_change_pin;
|
app->fnc.change_pin = do_change_pin;
|
||||||
app->fnc.check_pin = do_check_pin;
|
app->fnc.check_pin = do_check_pin;
|
||||||
|
app->fnc.set_pin_prompt = do_set_pin_prompt;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
125
scd/app.c
125
scd/app.c
@ -922,6 +922,131 @@ app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For use with user-defined pinentry prompts that are set with the OPTION
|
||||||
|
* command. This function is called from an application before a pinentry is
|
||||||
|
* invoked. It replaces special escape strings in the user-defined 'prompt'
|
||||||
|
* with a single (for now) value set by the calling function. What data type
|
||||||
|
* the vararg value is depends on the 'which' parameter and is set in the
|
||||||
|
* calling function.
|
||||||
|
*
|
||||||
|
* The 'prepend' parameter are any pinentry flags to be prepended to the
|
||||||
|
* expanded prompt. These flags, if any, are not set by the user-defined
|
||||||
|
* prompt but the calling function. In most cases it will be NULL or "|I|".
|
||||||
|
*
|
||||||
|
* The following expandos are recognized:
|
||||||
|
*
|
||||||
|
* expando | which | description
|
||||||
|
* ----------------------------------------
|
||||||
|
* PIN_PROMPT_NONE NOP. The user-defined prompt is returned along
|
||||||
|
* with any 'prepend' parameter.
|
||||||
|
* |S| PIN_SIGN_PROMPT signature count (unsigned long)
|
||||||
|
* |A| PIN_ADMIN_PROMPT remaining attempts (int)
|
||||||
|
*
|
||||||
|
* The following example shows the default pinentry prompt when no
|
||||||
|
* user-defined prompt is set:
|
||||||
|
*
|
||||||
|
* "Please enter the PIN%%0A[sigs done: |S|]"
|
||||||
|
*
|
||||||
|
* Here, |S| is expanded to the number of signatures created so far.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
expand_pin_prompt(const char *prompt, const char *prepend, int which, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
size_t len, n;
|
||||||
|
char *buf;
|
||||||
|
unsigned long luval;
|
||||||
|
int intval;
|
||||||
|
char valuebuf[50] = {0};
|
||||||
|
char *p, *token = NULL, *tokenp;
|
||||||
|
|
||||||
|
if (!prompt)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
len = strlen (prompt);
|
||||||
|
len += prepend ? strlen (prepend) : 0;
|
||||||
|
va_start (ap, which);
|
||||||
|
|
||||||
|
switch (which)
|
||||||
|
{
|
||||||
|
/* Signature count. */
|
||||||
|
case PIN_SIGN_PROMPT:
|
||||||
|
luval = va_arg (ap, unsigned long);
|
||||||
|
snprintf (valuebuf, sizeof (valuebuf), "%lu", luval);
|
||||||
|
token = "|S|";
|
||||||
|
break;
|
||||||
|
/* Pin tries remaining. */
|
||||||
|
case PIN_ADMIN_PROMPT:
|
||||||
|
intval = va_arg (ap, int);
|
||||||
|
snprintf (valuebuf, sizeof (valuebuf), "%i", intval);
|
||||||
|
token = "|A|";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
if (!token)
|
||||||
|
{
|
||||||
|
if (prepend)
|
||||||
|
{
|
||||||
|
len = strlen (prepend)+strlen (prompt)+1;
|
||||||
|
p = xtrymalloc (len);
|
||||||
|
if (!p)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
snprintf (p, len, "%s%s", prepend, prompt);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xtrystrdup (prompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
len += strlen (valuebuf)+1;
|
||||||
|
buf = xtrymalloc (len);
|
||||||
|
if (!buf)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
buf[0] = 0;
|
||||||
|
if (prepend)
|
||||||
|
strcpy (buf, prepend);
|
||||||
|
|
||||||
|
strcat (buf, prompt);
|
||||||
|
|
||||||
|
if (prepend)
|
||||||
|
p = buf+strlen (prepend);
|
||||||
|
else
|
||||||
|
p = buf;
|
||||||
|
|
||||||
|
tokenp = strstr (p, token);
|
||||||
|
if (!tokenp)
|
||||||
|
return buf;
|
||||||
|
|
||||||
|
p = tokenp+strlen (token);
|
||||||
|
len -= strlen (token)+1;
|
||||||
|
memmove(&buf[len-strlen (p)], p, strlen (p));
|
||||||
|
|
||||||
|
for (n = 0; valuebuf[n]; n++)
|
||||||
|
*tokenp++ = valuebuf[n];
|
||||||
|
|
||||||
|
buf[len] = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the prompt shown in the pinentry dialog. If not set then a default will
|
||||||
|
* be used. */
|
||||||
|
gpg_error_t
|
||||||
|
app_set_pin_prompt(app_t app, int which, const char *prompt)
|
||||||
|
{
|
||||||
|
if (!app)
|
||||||
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
|
if (!app->fnc.set_pin_prompt)
|
||||||
|
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
|
||||||
|
|
||||||
|
return app->fnc.set_pin_prompt (app, which, prompt);
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform a GET CHALLENGE operation. This fucntion is special as it
|
/* Perform a GET CHALLENGE operation. This fucntion is special as it
|
||||||
directly accesses the card without any application specific
|
directly accesses the card without any application specific
|
||||||
|
@ -139,6 +139,13 @@ struct server_local_s
|
|||||||
this session. */
|
this session. */
|
||||||
int stopme;
|
int stopme;
|
||||||
|
|
||||||
|
/* User-defined pinentry prompt strings. Needed both here and in the app
|
||||||
|
* since they may be set by the user before an app is selected with
|
||||||
|
* select_application(). They are copied to the app when
|
||||||
|
* select_application() succeeds and further modifications done in the app.
|
||||||
|
* */
|
||||||
|
char *pin_prompt;
|
||||||
|
char *pin_admin_prompt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -387,6 +394,39 @@ reset_notify (assuan_context_t ctx, char *line)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gpg_error_t
|
||||||
|
set_pinentry_prompt(struct server_local_s *srv, int which, const char *prompt)
|
||||||
|
{
|
||||||
|
gpg_error_t rc = 0;
|
||||||
|
char **p = NULL;
|
||||||
|
|
||||||
|
switch (which)
|
||||||
|
{
|
||||||
|
case PIN_SIGN_PROMPT:
|
||||||
|
p = &srv->pin_prompt;
|
||||||
|
break;
|
||||||
|
case PIN_ADMIN_PROMPT:
|
||||||
|
p = &srv->pin_admin_prompt;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
xfree (*p);
|
||||||
|
*p = NULL;
|
||||||
|
|
||||||
|
if (prompt && *prompt != '-' && *(prompt+1) != 0)
|
||||||
|
{
|
||||||
|
*p = xtrystrdup (prompt);
|
||||||
|
if (!*p)
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
option_handler (assuan_context_t ctx, const char *key, const char *value)
|
option_handler (assuan_context_t ctx, const char *key, const char *value)
|
||||||
@ -407,6 +447,22 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
|
|||||||
ctrl->server_local->event_signal = i;
|
ctrl->server_local->event_signal = i;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
/* A user-defined prompt to show in a pinentry overriding the default. See
|
||||||
|
* app.c:expand_pin_prompt() for details. */
|
||||||
|
else if (!strcmp (key, "pin-prompt"))
|
||||||
|
{
|
||||||
|
if (ctrl->app_ctx)
|
||||||
|
return app_set_pin_prompt (ctrl->app_ctx, PIN_SIGN_PROMPT, value);
|
||||||
|
else
|
||||||
|
return set_pinentry_prompt (ctrl->server_local, PIN_SIGN_PROMPT, value);
|
||||||
|
}
|
||||||
|
else if (!strcmp (key, "pin-admin-prompt"))
|
||||||
|
{
|
||||||
|
if (ctrl->app_ctx)
|
||||||
|
return app_set_pin_prompt (ctrl->app_ctx, PIN_ADMIN_PROMPT, value);
|
||||||
|
else
|
||||||
|
return set_pinentry_prompt (ctrl->server_local, PIN_ADMIN_PROMPT, value);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -523,7 +579,17 @@ open_card (ctrl_t ctrl, const char *apptype)
|
|||||||
err = gpg_error (GPG_ERR_CARD);
|
err = gpg_error (GPG_ERR_CARD);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
|
err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
err = app_set_pin_prompt(ctrl->app_ctx, PIN_SIGN_PROMPT,
|
||||||
|
ctrl->server_local->pin_prompt);
|
||||||
|
if (!err)
|
||||||
|
err = app_set_pin_prompt(ctrl->app_ctx, PIN_ADMIN_PROMPT,
|
||||||
|
ctrl->server_local->pin_admin_prompt);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CARD_REMOVAL (ctrl, err);
|
TEST_CARD_REMOVAL (ctrl, err);
|
||||||
@ -2097,6 +2163,8 @@ scd_command_handler (ctrl_t ctrl, int fd)
|
|||||||
sl->next_session = ctrl->server_local->next_session;
|
sl->next_session = ctrl->server_local->next_session;
|
||||||
}
|
}
|
||||||
stopme = ctrl->server_local->stopme || reader_disabled;
|
stopme = ctrl->server_local->stopme || reader_disabled;
|
||||||
|
xfree (ctrl->server_local->pin_prompt);
|
||||||
|
xfree (ctrl->server_local->pin_admin_prompt);
|
||||||
xfree (ctrl->server_local);
|
xfree (ctrl->server_local);
|
||||||
ctrl->server_local = NULL;
|
ctrl->server_local = NULL;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user