diff --git a/agent/ChangeLog b/agent/ChangeLog index cae70f3bb..635259d44 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,13 @@ +2009-03-17 Werner Koch + + * command.c (cmd_get_passphrase): Break repeat loop on error. + +2009-03-17 Daiki Ueno + + * command.c (option_value): New function. + (cmd_get_passphrase): Accept new option --repeat, which makes + gpg-agent to ask passphrase several times. + 2009-03-06 Werner Koch * command.c (cmd_keyinfo): New command. diff --git a/agent/command.c b/agent/command.c index ba0f8fc4c..9451f27fe 100644 --- a/agent/command.c +++ b/agent/command.c @@ -36,6 +36,7 @@ #include +#include "i18n.h" #include "agent.h" /* maximum allowed size of the inquired ciphertext */ @@ -181,6 +182,26 @@ has_option_name (const char *line, const char *name) && (!s[n] || spacep (s+n) || s[n] == '=')); } +/* Return a pointer to the argument of the option with NAME. If such + an option is not given, it returns NULL. */ +static char * +option_value (const char *line, const char *name) +{ + char *s; + int n = strlen (name); + + s = strstr (line, name); + if (s && (s == line || spacep (s-1)) + && s[n] && (spacep (s+n) || s[n] == '=')) + { + s += n + 1; + s += strspn (s, " "); + if (*s && !spacep(s)) + return s; + } + return NULL; +} + /* Skip over options. It is assumed that leading spaces have been removed (this is the case for lines passed to a handler from @@ -990,7 +1011,7 @@ send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw) } -/* GET_PASSPHRASE [--data] [--check] [--no-ask] +/* GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] [ ] This function is usually used to ask for a passphrase to be used @@ -1021,13 +1042,22 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) const char *pw; char *response; char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL; + const char *desc2 = _("Please re-enter this passphrase"); char *p; void *cache_marker; - int opt_data, opt_check, opt_no_ask; + int opt_data, opt_check, opt_no_ask, opt_repeat = 0; opt_data = has_option (line, "--data"); opt_check = has_option (line, "--check"); opt_no_ask = has_option (line, "--no-ask"); + if (has_option_name (line, "--repeat")) + { + p = option_value (line, "--repeat"); + if (p) + opt_repeat = atoi (p); + else + opt_repeat = 1; + } line = skip_options (line); cacheid = line; @@ -1094,21 +1124,39 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) if (desc) plus_to_blank (desc); - response = NULL; - do - { - xfree (response); - rc = agent_get_passphrase (ctrl, &response, desc, prompt, errtext); - } - while (!rc - && opt_check - && check_passphrase_constraints (ctrl, response, 0)); - + next_try: + rc = agent_get_passphrase (ctrl, &response, desc, prompt, errtext); if (!rc) { - if (cacheid) - agent_put_cache (cacheid, CACHE_MODE_USER, response, 0); - rc = send_back_passphrase (ctx, opt_data, response); + int i; + + if (opt_check && check_passphrase_constraints (ctrl, response, 0)) + { + xfree (response); + goto next_try; + } + for (i = 0; i < opt_repeat; i++) + { + char *response2; + + rc = agent_get_passphrase (ctrl, &response2, desc2, prompt, + errtext); + if (rc) + break; + if (strcmp (response2, response)) + { + xfree (response2); + xfree (response); + goto next_try; + } + xfree (response2); + } + if (!rc) + { + if (cacheid) + agent_put_cache (cacheid, CACHE_MODE_USER, response, 0); + rc = send_back_passphrase (ctx, opt_data, response); + } xfree (response); } } diff --git a/g10/ChangeLog b/g10/ChangeLog index ba0d8eb2d..3bb5bf992 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,19 @@ +2009-03-17 Daiki Ueno + + * passphrase.c (passphrase_get): Add extra arg REPEAT and adjust + callers; remove special treatment for MODE==2. + (passphrase_to_dek): Move --passphrase-repeat handling to + gpg-agent. + + * call-agent.c (agent_get_passphrase): Add extra arg REPEAT. + * call-agent.h: Ditto. + +2009-03-16 Werner Koch + + * gpg.c (my_strusage): Revert last change. Systems w/o a gpg1 may, + and actually do, install gpg2 as gpg. + * gpgv.c (my_strusage): Ditto. + 2009-03-14 David Shaw * gpg.c (my_strusage): gpg2 and gpgv2 (not gpg and gpgv). diff --git a/g10/call-agent.c b/g10/call-agent.c index 572fa8513..fb66602f8 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -874,11 +874,12 @@ agent_get_passphrase (const char *cache_id, const char *err_msg, const char *prompt, const char *desc_msg, + int repeat, char **r_passphrase) { int rc; char *line, *p; - char cmd[] = "GET_PASSPHRASE --data -- "; + char cmd[] = "GET_PASSPHRASE --data --repeat=%d -- "; membuf_t data; *r_passphrase = NULL; @@ -889,7 +890,7 @@ agent_get_passphrase (const char *cache_id, /* We allocate 3 times the needed space for the texts so that there is enough space for escaping. */ - line = xtrymalloc ( strlen (cmd) + 1 + line = xtrymalloc ( strlen (cmd) + sizeof(repeat) + 1 + (cache_id? 3*strlen (cache_id): 1) + 1 + (err_msg? 3*strlen (err_msg): 1) + 1 + (prompt? 3*strlen (prompt): 1) + 1 @@ -898,7 +899,7 @@ agent_get_passphrase (const char *cache_id, if (!line) return gpg_error_from_syserror (); - p = stpcpy (line, cmd); + p = line + sprintf (line, cmd, repeat); if (cache_id && *cache_id) p = my_percent_plus_escape (p, cache_id); else diff --git a/g10/call-agent.h b/g10/call-agent.h index ef4ad85c5..ebe37b1cd 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -115,6 +115,7 @@ gpg_error_t agent_get_passphrase (const char *cache_id, const char *err_msg, const char *prompt, const char *desc_msg, + int repeat, char **r_passphrase); /* Send the CLEAR_PASSPHRASE command to the agent. */ diff --git a/g10/gpg.c b/g10/gpg.c index 727c108d2..a88b1ffc3 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -800,7 +800,7 @@ my_strusage( int level ) const char *p; switch( level ) { - case 11: p = "gpg2 (GnuPG)"; + case 11: p = "gpg (GnuPG)"; break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; @@ -828,10 +828,10 @@ my_strusage( int level ) case 1: case 40: p = - _("Usage: gpg2 [options] [files] (-h for help)"); + _("Usage: gpg [options] [files] (-h for help)"); break; case 41: p = - _("Syntax: gpg2 [options] [files]\n" + _("Syntax: gpg [options] [files]\n" "sign, check, encrypt or decrypt\n" "default operation depends on the input data\n"); break; diff --git a/g10/gpgv.c b/g10/gpgv.c index 91d4e6af1..88baaabab 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -107,16 +107,16 @@ my_strusage( int level ) switch (level) { - case 11: p = "gpgv2 (GnuPG)"; + case 11: p = "gpgv (GnuPG)"; break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; case 19: p = _("Please report bugs to .\n"); break; case 1: - case 40: p = _("Usage: gpgv2 [options] [files] (-h for help)"); + case 40: p = _("Usage: gpgv [options] [files] (-h for help)"); break; - case 41: p = _("Syntax: gpgv2 [options] [files]\n" + case 41: p = _("Syntax: gpgv [options] [files]\n" "Check signatures against known trusted keys\n"); break; diff --git a/g10/passphrase.c b/g10/passphrase.c index 0d7580d36..0950581c9 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -237,7 +237,6 @@ read_passphrase_from_fd( int fd ) * Ask the GPG Agent for the passphrase. * Mode 0: Allow cached passphrase * 1: No cached passphrase FIXME: Not really implemented - * 2: Ditto, but change the text to "repeat entry" * * Note that TRYAGAIN_TEXT must not be translated. If CANCELED is not * NULL, the function does set it to 1 if the user canceled the @@ -246,7 +245,7 @@ read_passphrase_from_fd( int fd ) * computed, this will be used as the cacheid. */ static char * -passphrase_get ( u32 *keyid, int mode, const char *cacheid, +passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, const char *tryagain_text, const char *custom_description, const char *custom_prompt, int *canceled) @@ -331,8 +330,6 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, } } - else if (mode == 2 ) - atext = xstrdup ( _("Repeat passphrase\n") ); else atext = xstrdup ( _("Enter passphrase\n") ); @@ -349,7 +346,8 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, my_prompt = custom_prompt ? native_to_utf8 (custom_prompt): NULL; - rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext, &pw); + rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext, + repeat, &pw); xfree (my_prompt); xfree (atext); atext = NULL; @@ -470,7 +468,7 @@ ask_passphrase (const char *description, strcpy (pw, fd_passwd); } else - pw = passphrase_get (NULL, 0, cacheid, + pw = passphrase_get (NULL, 0, cacheid, 0, tryagain_text, description, prompt, canceled ); @@ -611,7 +609,8 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, else { /* Divert to the gpg-agent. */ - pw = passphrase_get ( keyid, mode == 2? 1: 0, NULL, + pw = passphrase_get ( keyid, mode == 2, NULL, + mode == 2? opt.passwd_repeat: 0, tryagain_text, NULL, NULL, canceled ); if (*canceled) { @@ -619,33 +618,6 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, write_status( STATUS_MISSING_PASSPHRASE ); return NULL; } - if (!pw) - pw = xstrdup (""); - if ( *pw && mode == 2 ) - { - int i; - for(i=0;i