agent: Fix for zero length help string in pinentry hints.

* agent/call-pinentry.c: Remove unused assert.h.
(inq_cb): Fix use use of assuan_end_confidential in case of nested
use.
(do_getpin): Ditto.
(setup_formatted_passphrase): Escape the help string.
(setup_enforced_constraints): Ignore empty help strings.
--

(Ported from 2.2)
This commit is contained in:
Werner Koch 2021-08-18 10:20:22 +02:00
parent 629f4a5cff
commit 9fb6466602
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
1 changed files with 31 additions and 13 deletions

View File

@ -199,7 +199,7 @@ unlock_pinentry (ctrl_t ctrl, gpg_error_t rc)
/* Helper for at_fork_cb which can also be called by the parent to /* Helper for at_fork_cb which can also be called by the parent to
* show shich envvars will be set. */ * show which envvars will be set. */
static void static void
atfork_core (ctrl_t ctrl, int debug_mode) atfork_core (ctrl_t ctrl, int debug_mode)
{ {
@ -434,7 +434,7 @@ start_pinentry (ctrl_t ctrl)
log_debug ("connection to PIN entry established\n"); log_debug ("connection to PIN entry established\n");
if (opt.debug_pinentry) if (opt.debug_pinentry)
atfork_core (ctrl, 1); atfork_core (ctrl, 1); /* Just show the envvars set after the fork. */
value = session_env_getenv (ctrl->session_env, "PINENTRY_USER_DATA"); value = session_env_getenv (ctrl->session_env, "PINENTRY_USER_DATA");
if (value != NULL) if (value != NULL)
@ -962,9 +962,11 @@ inq_cb (void *opaque, const char *line)
} }
if (!check_passphrase_constraints (NULL, pin, parm->flags, NULL)) if (!check_passphrase_constraints (NULL, pin, parm->flags, NULL))
{ {
int wasconf = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
assuan_begin_confidential (parm->ctx); assuan_begin_confidential (parm->ctx);
err = assuan_send_data (parm->ctx, pin, strlen (pin)); err = assuan_send_data (parm->ctx, pin, strlen (pin));
assuan_end_confidential (parm->ctx); if (!wasconf)
assuan_end_confidential (parm->ctx);
xfree (pin); xfree (pin);
goto leave; goto leave;
} }
@ -1057,6 +1059,7 @@ setup_formatted_passphrase (ctrl_t ctrl)
int idx; int idx;
char *tmpstr; char *tmpstr;
const char *s; const char *s;
char *escapedstr;
(void)ctrl; (void)ctrl;
@ -1075,11 +1078,18 @@ setup_formatted_passphrase (ctrl_t ctrl)
s = tmpstr; s = tmpstr;
else else
s = L_(tbl[idx].value); s = L_(tbl[idx].value);
snprintf (line, DIM(line), "OPTION formatted-passphrase-%s=%s", escapedstr = try_percent_escape (s, "\t\r\n\f\v");
tbl[idx].key, s);
xfree (tmpstr); xfree (tmpstr);
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, if (escapedstr && *escapedstr)
NULL); {
snprintf (line, DIM(line), "OPTION formatted-passphrase-%s=%s",
tbl[idx].key, escapedstr);
rc = assuan_transact (entry_ctx, line,
NULL, NULL, NULL, NULL, NULL, NULL);
}
else
rc = 0;
xfree (escapedstr);
if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION) if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
return rc; return rc;
} }
@ -1134,11 +1144,16 @@ setup_enforced_constraints (ctrl_t ctrl)
} }
escapedstr = try_percent_escape (s, "\t\r\n\f\v"); escapedstr = try_percent_escape (s, "\t\r\n\f\v");
xfree (tmpstr); xfree (tmpstr);
snprintf (line, DIM(line), "OPTION constraints-%s=%s", if (escapedstr && *escapedstr)
tbl[idx].key, escapedstr); {
snprintf (line, DIM(line), "OPTION constraints-%s=%s",
tbl[idx].key, escapedstr);
rc = assuan_transact (entry_ctx, line,
NULL, NULL, NULL, NULL, NULL, NULL);
}
else
rc = 0; /* Ignore an empty string (would give an IPC error). */
xfree (escapedstr); xfree (escapedstr);
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL,
NULL);
if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION) if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
return rc; return rc;
} }
@ -1345,9 +1360,9 @@ static gpg_error_t
do_getpin (ctrl_t ctrl, struct entry_parm_s *parm) do_getpin (ctrl_t ctrl, struct entry_parm_s *parm)
{ {
gpg_error_t rc; gpg_error_t rc;
int saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
gnupg_fd_t sock_watched = ctrl->thread_startup.fd; gnupg_fd_t sock_watched = ctrl->thread_startup.fd;
npth_t thread; npth_t thread;
int wasconf;
struct inq_cb_parm_s inq_cb_parm; struct inq_cb_parm_s inq_cb_parm;
rc = watch_sock_start (&sock_watched, &thread); rc = watch_sock_start (&sock_watched, &thread);
@ -1357,11 +1372,14 @@ do_getpin (ctrl_t ctrl, struct entry_parm_s *parm)
inq_cb_parm.ctx = entry_ctx; inq_cb_parm.ctx = entry_ctx;
inq_cb_parm.flags = parm->constraints_flags; inq_cb_parm.flags = parm->constraints_flags;
wasconf = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
assuan_begin_confidential (entry_ctx); assuan_begin_confidential (entry_ctx);
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, parm, rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, parm,
inq_cb, &inq_cb_parm, inq_cb, &inq_cb_parm,
pinentry_status_cb, &parm->status); pinentry_status_cb, &parm->status);
assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); if (!wasconf)
assuan_end_confidential (entry_ctx);
/* Most pinentries out in the wild return the old Assuan error code /* Most pinentries out in the wild return the old Assuan error code
for canceled which gets translated to an assuan Cancel error and for canceled which gets translated to an assuan Cancel error and
not to the code for a user cancel. Fix this here. */ not to the code for a user cancel. Fix this here. */