aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/agent.h2
-rw-r--r--agent/call-pinentry.c57
-rw-r--r--agent/command-ssh.c6
-rw-r--r--agent/genkey.c6
4 files changed, 52 insertions, 19 deletions
diff --git a/agent/agent.h b/agent/agent.h
index 7342475e7..b80c6a05c 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -220,6 +220,8 @@ struct pin_entry_info_s
int max_tries; /* max. number of allowed tries. */
int failed_tries; /* Number of tries so far failed. */
int with_qualitybar; /* Set if the quality bar should be displayed. */
+ int with_repeat; /* Request repetition of the passphrase. */
+ int repeat_okay; /* Repetition worked. */
int (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */
void *check_cb_arg; /* optional argument which might be of use in the CB */
const char *cb_errtext; /* used by the cb to display a specific error */
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 126d6968b..e5977ad6a 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -682,23 +682,23 @@ setup_qualitybar (void)
}
-/* Check the button_info line for a close action. */
+/* Check the button_info line for a close action. Also check for the
+ PIN_REPEATED flag. */
static gpg_error_t
close_button_status_cb (void *opaque, const char *line)
{
- int *flag = opaque;
- const char *keyword = line;
- int keywordlen;
+ unsigned int *flag = opaque;
+ const char *args;
- for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
- ;
- while (spacep (line))
- line++;
- if (keywordlen == 11 && !memcmp (keyword, "BUTTON_INFO", keywordlen))
+ if ((args = has_leading_keyword (line, "BUTTON_INFO")))
{
- if ( !strcmp (line, "close") )
+ if (!strcmp (args, "close"))
*flag = 1;
}
+ else if (has_leading_keyword (line, "PIN_REPEATED"))
+ {
+ *flag |= 256;
+ }
return 0;
}
@@ -721,7 +721,7 @@ agent_askpin (ctrl_t ctrl,
const char *errtext = NULL;
int is_pin = 0;
int saveflag;
- int close_button;
+ unsigned int close_button;
if (opt.batch)
return 0; /* fixme: we should return BAD PIN */
@@ -806,6 +806,18 @@ agent_askpin (ctrl_t ctrl,
return unlock_pinentry (rc);
}
+ if (pininfo->with_repeat)
+ {
+ snprintf (line, DIM(line)-1, "SETREPEATERROR %s",
+ _("does not match - try again"));
+ line[DIM(line)-1] = 0;
+ rc = assuan_transact (entry_ctx, line,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc)
+ pininfo->with_repeat = 0; /* Pinentry does not support it. */
+ }
+ pininfo->repeat_okay = 0;
+
for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
{
memset (&parm, 0, sizeof parm);
@@ -828,6 +840,16 @@ agent_askpin (ctrl_t ctrl,
errtext = NULL;
}
+ if (pininfo->with_repeat)
+ {
+ snprintf (line, DIM(line)-1, "SETREPEAT %s", _("Repeat:"));
+ line[DIM(line)-1] = 0;
+ rc = assuan_transact (entry_ctx, line,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc)
+ return unlock_pinentry (rc);
+ }
+
saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
assuan_begin_confidential (entry_ctx);
close_button = 0;
@@ -842,9 +864,10 @@ agent_askpin (ctrl_t ctrl,
&& gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
+
/* Change error code in case the window close button was clicked
to cancel the operation. */
- if (close_button && gpg_err_code (rc) == GPG_ERR_CANCELED)
+ if ((close_button & 1) && gpg_err_code (rc) == GPG_ERR_CANCELED)
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
@@ -881,7 +904,11 @@ agent_askpin (ctrl_t ctrl,
}
if (!errtext)
- return unlock_pinentry (0); /* okay, got a PIN or passphrase */
+ {
+ if (pininfo->with_repeat && (close_button & 256))
+ pininfo->repeat_okay = 1;
+ return unlock_pinentry (0); /* okay, got a PIN or passphrase */
+ }
}
return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
@@ -902,7 +929,7 @@ agent_get_passphrase (ctrl_t ctrl,
char line[ASSUAN_LINELENGTH];
struct entry_parm_s parm;
int saveflag;
- int close_button;
+ unsigned int close_button;
*retpass = NULL;
if (opt.batch)
@@ -991,7 +1018,7 @@ agent_get_passphrase (ctrl_t ctrl,
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
/* Change error code in case the window close button was clicked
to cancel the operation. */
- if (close_button && gpg_err_code (rc) == GPG_ERR_CANCELED)
+ if ((close_button & 1) && gpg_err_code (rc) == GPG_ERR_CANCELED)
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
if (rc)
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 54273239f..f3ef30c15 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -3104,6 +3104,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
pi2 = pi + (sizeof *pi + 100 + 1);
pi->max_length = 100;
pi->max_tries = 1;
+ pi->with_repeat = 1;
pi2->max_length = 100;
pi2->max_tries = 1;
pi2->check_cb = reenter_compare_cb;
@@ -3115,8 +3116,9 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
if (err)
goto out;
- /* Unless the passphrase is empty, ask to confirm it. */
- if (pi->pin && *pi->pin)
+ /* Unless the passphrase is empty or the pinentry told us that
+ it already did the repetition check, ask to confirm it. */
+ if (pi->pin && *pi->pin && !pi->repeat_okay)
{
err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
if (err == -1)
diff --git a/agent/genkey.c b/agent/genkey.c
index 9918c12e7..91917f77b 100644
--- a/agent/genkey.c
+++ b/agent/genkey.c
@@ -363,6 +363,7 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
pi->max_length = 100;
pi->max_tries = 3;
pi->with_qualitybar = 1;
+ pi->with_repeat = 1;
pi2->max_length = 100;
pi2->max_tries = 3;
pi2->check_cb = reenter_compare_cb;
@@ -379,8 +380,9 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
pi2->failed_tries = 0;
goto next_try;
}
- /* Unless the passphrase is empty, ask to confirm it. */
- if (pi->pin && *pi->pin)
+ /* Unless the passphrase is empty or the pinentry told us that
+ it already did the repetition check, ask to confirm it. */
+ if (pi->pin && *pi->pin && !pi->repeat_okay)
{
err = agent_askpin (ctrl, text2, NULL, NULL, pi2);
if (err == -1)