aboutsummaryrefslogtreecommitdiffstats
path: root/agent/call-pinentry.c
diff options
context:
space:
mode:
authorIngo Klöcker <[email protected]>2021-07-28 08:11:39 +0000
committerWerner Koch <[email protected]>2021-08-10 10:05:57 +0000
commit5976d293ef9bd953b6e9c61a45ad1f4e85a2743c (patch)
treef26584b51c71c3fed95bd1b2ba288a487509a40f /agent/call-pinentry.c
parentagent: New option --pinentry-formatted-passphrase (diff)
downloadgnupg-5976d293ef9bd953b6e9c61a45ad1f4e85a2743c.tar.gz
gnupg-5976d293ef9bd953b6e9c61a45ad1f4e85a2743c.zip
agent: Add checkpin inquiry for pinentry
* agent/call-pinentry.c (inq_cb): Handle checkpin inquiry. (setup_enforced_constraints): New. (agent_get_passphrase): Call setup_enforced_constraints if new passphrase is requested. -- This implements the gpg-agent side for checking whether a new passphrase entered by the user in pinentry satisfies the passphrase constraints. Performing a checkpin inquiry is only allowed if the passphrase constraints are enforced. setup_enforced_constraints sends necessary options and translated strings to pinentry. GnuPG-bug-id: 5517, 5532
Diffstat (limited to 'agent/call-pinentry.c')
-rw-r--r--agent/call-pinentry.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 8e28e3bc1..9842408ec 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -891,6 +891,47 @@ inq_cb (void *opaque, const char *line)
xfree (pin);
}
}
+ else if ((s = has_leading_keyword (line, "CHECKPIN")))
+ {
+ char *errtext = NULL;
+ size_t errtextlen;
+
+ if (!opt.enforce_passphrase_constraints)
+ {
+ log_error ("unexpected inquiry 'CHECKPIN' without enforced "
+ "passphrase constraints\n");
+ err = gpg_error (GPG_ERR_ASS_UNEXPECTED_CMD);
+ goto leave;
+ }
+
+ pin = unescape_passphrase_string (s);
+ if (!pin)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ if (check_passphrase_constraints (NULL, pin, 0, &errtext))
+ {
+ if (errtext)
+ {
+ /* Unescape the percent-escaped errtext because
+ assuan_send_data escapes it again. */
+ errtextlen = percent_unescape_inplace (errtext, 0);
+ err = assuan_send_data (ctx, errtext, errtextlen);
+ }
+ else
+ {
+ log_error ("passphrase check failed without error text\n");
+ err = gpg_error (GPG_ERR_GENERAL);
+ }
+ }
+ else
+ {
+ err = assuan_send_data (ctx, NULL, 0);
+ }
+ xfree (errtext);
+ xfree (pin);
+ }
+ }
else if ((s = has_leading_keyword (line, "GENPIN")))
{
int tries;
@@ -1044,6 +1085,65 @@ setup_formatted_passphrase (ctrl_t ctrl)
}
+/* Helper to setup pinentry for enforced passphrase constraints. */
+static gpg_error_t
+setup_enforced_constraints (ctrl_t ctrl)
+{
+ static const struct { const char *key, *help_id, *value; } tbl[] = {
+ { "hint-short", "pinentry.constraints.hint.short", NULL },
+ { "hint-long", "pinentry.constraints.hint.long", NULL },
+ /* TRANSLATORS: This is a text shown by pinentry as title of a dialog
+ telling the user that the entered new passphrase does not satisfy
+ the passphrase constraints. Please keep it short. */
+ { "error-title", NULL, N_("Passphrase Not Allowed") },
+ { NULL, NULL }
+ };
+
+ gpg_error_t rc;
+ char line[ASSUAN_LINELENGTH];
+ int idx;
+ char *tmpstr;
+ const char *s;
+ char *escapedstr;
+
+ (void)ctrl;
+
+ if (opt.enforce_passphrase_constraints)
+ {
+ snprintf (line, DIM(line), "OPTION constraints-enforce");
+ rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
+ return rc;
+
+ for (idx=0; tbl[idx].key; idx++)
+ {
+ tmpstr = gnupg_get_help_string (tbl[idx].help_id, 0);
+ if (tmpstr)
+ s = tmpstr;
+ else if (tbl[idx].value)
+ s = L_(tbl[idx].value);
+ else
+ {
+ log_error ("no help string found for %s\n", tbl[idx].help_id);
+ continue;
+ }
+ escapedstr = try_percent_escape (s, "\t\r\n\f\v");
+ xfree (tmpstr);
+ snprintf (line, DIM(line), "OPTION constraints-%s=%s",
+ tbl[idx].key, 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)
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+
/* Helper for agent_askpin and agent_get_passphrase. */
static gpg_error_t
setup_qualitybar (ctrl_t ctrl)
@@ -1650,6 +1750,10 @@ agent_get_passphrase (ctrl_t ctrl,
pininfo->with_repeat = 0; /* Pinentry does not support it. */
(void)setup_genpin (ctrl);
+
+ rc = setup_enforced_constraints (ctrl);
+ if (rc)
+ return unlock_pinentry (ctrl, rc);
}
pininfo->repeat_okay = 0;
pininfo->status = 0;