scd,agent: Improve the OpenPGP PIN prompt texts.

* scd/app-openpgp.c (get_prompt_info): Change texts.
* agent/call-pinentry.c (struct entry_features): New.
(getinfo_features_cb): New.
(start_pinentry): Set new fucntion as status callback.
(build_cmd_setdesc): New.  Replace all snprintf for SETDESC by this
one.
--

Suggested-by: Andre Heinecke
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2017-02-22 16:54:32 +01:00
parent 7ccabbc26a
commit f98c8cb013
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 84 additions and 14 deletions

View File

@ -56,6 +56,17 @@
/* The assuan context of the current pinentry. */ /* The assuan context of the current pinentry. */
static assuan_context_t entry_ctx; static assuan_context_t entry_ctx;
/* A list of features of the current pinentry. */
static struct
{
/* The Pinentry support RS+US tabbing. This means that a RS (0x1e)
* starts a new tabbing block in which a US (0x1f) followed by a
* colon marks a colon. A pinentry can use this to pretty print
* name value pairs. */
unsigned int tabbing:1;
} entry_features;
/* The control variable of the connection owning the current pinentry. /* The control variable of the connection owning the current pinentry.
This is only valid if ENTRY_CTX is not NULL. Note, that we care This is only valid if ENTRY_CTX is not NULL. Note, that we care
only about the value of the pointer and that it should never be only about the value of the pointer and that it should never be
@ -208,6 +219,31 @@ atfork_cb (void *opaque, int where)
} }
/* Status line callback for the FEATURES status. */
static gpg_error_t
getinfo_features_cb (void *opaque, const char *line)
{
const char *args;
char **tokens;
int i;
(void)opaque;
if ((args = has_leading_keyword (line, "FEATURES")))
{
tokens = strtokenize (args, " ");
if (!tokens)
return gpg_error_from_syserror ();
for (i=0; tokens[i]; i++)
if (!strcmp (tokens[i], "tabbing"))
entry_features.tabbing = 1;
xfree (tokens);
}
return 0;
}
static gpg_error_t static gpg_error_t
getinfo_pid_cb (void *opaque, const void *buffer, size_t length) getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
{ {
@ -567,13 +603,17 @@ start_pinentry (ctrl_t ctrl)
/* Ask the pinentry for its version and flavor and store that as a /* Ask the pinentry for its version and flavor and store that as a
* string in MB. This information is useful for helping users to * string in MB. This information is useful for helping users to
* figure out Pinentry problems. */ * figure out Pinentry problems. Noet that "flavor" may also return
* a status line with the features; we use a dedicated handler for
* that. */
{ {
membuf_t mb; membuf_t mb;
init_membuf (&mb, 256); init_membuf (&mb, 256);
if (assuan_transact (entry_ctx, "GETINFO flavor", if (assuan_transact (entry_ctx, "GETINFO flavor",
put_membuf_cb, &mb, NULL, NULL, NULL, NULL)) put_membuf_cb, &mb,
NULL, NULL,
getinfo_features_cb, NULL))
put_membuf_str (&mb, "unknown"); put_membuf_str (&mb, "unknown");
put_membuf_str (&mb, " "); put_membuf_str (&mb, " ");
if (assuan_transact (entry_ctx, "GETINFO version", if (assuan_transact (entry_ctx, "GETINFO version",
@ -871,6 +911,25 @@ pinentry_status_cb (void *opaque, const char *line)
} }
/* Build a SETDESC command line. This is a dedicated funcion so that
* it can remove control characters which are not supported by the
* current Pinentry. */
static void
build_cmd_setdesc (char *line, size_t linelen, const char *desc)
{
char *src, *dst;
snprintf (line, linelen, "SETDESC %s", desc);
if (!entry_features.tabbing)
{
/* Remove RS and US. */
for (src=dst=line; *src; src++)
if (!strchr ("\x1e\x1f", *src))
*dst++ = *src;
*dst = 0;
}
}
/* Call the Entry and ask for the PIN. We do check for a valid PIN /* Call the Entry and ask for the PIN. We do check for a valid PIN
@ -961,7 +1020,7 @@ agent_askpin (ctrl_t ctrl,
if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD) if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
return unlock_pinentry (rc); return unlock_pinentry (rc);
snprintf (line, DIM(line), "SETDESC %s", desc_text); build_cmd_setdesc (line, DIM(line), desc_text);
rc = assuan_transact (entry_ctx, line, 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 (rc); return unlock_pinentry (rc);
@ -1170,7 +1229,7 @@ agent_get_passphrase (ctrl_t ctrl,
if (desc) if (desc)
snprintf (line, DIM(line), "SETDESC %s", desc); build_cmd_setdesc (line, DIM(line), desc);
else else
snprintf (line, DIM(line), "RESET"); snprintf (line, DIM(line), "RESET");
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
@ -1258,7 +1317,7 @@ agent_get_confirmation (ctrl_t ctrl,
return rc; return rc;
if (desc) if (desc)
snprintf (line, DIM(line), "SETDESC %s", desc); build_cmd_setdesc (line, DIM(line), desc);
else else
snprintf (line, DIM(line), "RESET"); snprintf (line, DIM(line), "RESET");
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
@ -1331,7 +1390,7 @@ agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
return rc; return rc;
if (desc) if (desc)
snprintf (line, DIM(line), "SETDESC %s", desc); build_cmd_setdesc (line, DIM(line), desc);
else else
snprintf (line, DIM(line), "RESET"); snprintf (line, DIM(line), "RESET");
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
@ -1401,7 +1460,7 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
return rc; return rc;
if (desc) if (desc)
snprintf (line, DIM(line), "SETDESC %s", desc); build_cmd_setdesc (line, DIM(line), desc);
else else
snprintf (line, DIM(line), "RESET"); snprintf (line, DIM(line), "RESET");
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);

View File

@ -1986,19 +1986,30 @@ get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining)
disp_name = get_disp_name (app); disp_name = get_disp_name (app);
if (chvno == 1) if (chvno == 1)
{ {
result = xtryasprintf (_("Card number:\t%s%%0A" /* TRANSLATORS: Put a \x1f right before a colon. This can be
"Signatures:\t%lu%%0A" * used by pinentry to nicely align the names and values. Keep
"Cardholder:\t%s"), * the %s at the start and end of the string. */
result = xtryasprintf (_("%s"
"Number\x1f: %s%%0A"
"Holder\x1f: %s%%0A"
"Counter\x1f: %lu"
"%s"),
"\x1e",
serial, serial,
disp_name? disp_name:"",
sigcount, sigcount,
disp_name? disp_name:""); "");
} }
else else
{ {
result = xtryasprintf (_("Card number:\t%s%%0A" result = xtryasprintf (_("%s"
"Cardholder:\t%s"), "Number\x1f: %s%%0A"
"Holder\x1f: %s"
"%s"),
"\x1e",
serial, serial,
disp_name? disp_name:""); disp_name? disp_name:"",
"");
} }
xfree (disp_name); xfree (disp_name);
xfree (serial); xfree (serial);