mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
Re-implemented GPG's --passwd command and improved it.
This commit is contained in:
parent
c212133918
commit
02e4c3cb7e
@ -1,3 +1,20 @@
|
|||||||
|
2010-10-26 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* cache.c (agent_put_cache): Allow deletion even if TTL is passwd
|
||||||
|
as 0.
|
||||||
|
|
||||||
|
* genkey.c (agent_protect_and_store): Add arg PASSPHRASE_ADDR.
|
||||||
|
* command.c (cmd_passwd): Add option --passwd-nonce.
|
||||||
|
(struct server_local_s): Add LAST_CACHE_NONCE and LAST_PASSWD_NONCE.
|
||||||
|
(clear_nonce_cache): New.
|
||||||
|
(reset_notify): Clear the nonce cache.
|
||||||
|
(start_command_handler): Ditto.
|
||||||
|
|
||||||
|
2010-10-25 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* command.c (cmd_export_key): Free CACHE_NONCE.
|
||||||
|
(cmd_passwd): Add option --cache-nonce.
|
||||||
|
|
||||||
2010-10-18 Werner Koch <wk@g10code.com>
|
2010-10-18 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* call-pinentry.c (start_pinentry): Print name of pinentry on
|
* call-pinentry.c (start_pinentry): Print name of pinentry on
|
||||||
|
@ -295,7 +295,8 @@ gpg_error_t agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
|
|||||||
int agent_genkey (ctrl_t ctrl, const char *cache_nonce,
|
int agent_genkey (ctrl_t ctrl, const char *cache_nonce,
|
||||||
const char *keyparam, size_t keyparmlen,
|
const char *keyparam, size_t keyparmlen,
|
||||||
int no_protection, membuf_t *outbuf);
|
int no_protection, membuf_t *outbuf);
|
||||||
int agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey);
|
gpg_error_t agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
|
||||||
|
char **passphrase_addr);
|
||||||
|
|
||||||
/*-- protect.c --*/
|
/*-- protect.c --*/
|
||||||
unsigned long get_standard_s2k_count (void);
|
unsigned long get_standard_s2k_count (void);
|
||||||
|
@ -284,7 +284,7 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
|
|||||||
default: ttl = opt.def_cache_ttl; break;
|
default: ttl = opt.def_cache_ttl; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ttl || cache_mode == CACHE_MODE_IGNORE)
|
if ((!ttl && data) || cache_mode == CACHE_MODE_IGNORE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (r=thecache; r; r = r->next)
|
for (r=thecache; r; r = r->next)
|
||||||
|
140
agent/command.c
140
agent/command.c
@ -72,6 +72,8 @@ struct server_local_s
|
|||||||
void *import_key; /* Malloced KEK for the import_key command. */
|
void *import_key; /* Malloced KEK for the import_key command. */
|
||||||
void *export_key; /* Malloced KEK for the export_key command. */
|
void *export_key; /* Malloced KEK for the export_key command. */
|
||||||
int allow_fully_canceled; /* Client is aware of GPG_ERR_FULLY_CANCELED. */
|
int allow_fully_canceled; /* Client is aware of GPG_ERR_FULLY_CANCELED. */
|
||||||
|
char *last_cache_nonce; /* Last CACHE_NOCNE sent as status (malloced). */
|
||||||
|
char *last_passwd_nonce; /* Last PASSWD_NOCNE sent as status (malloced). */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -153,6 +155,26 @@ write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_nonce_cache (ctrl_t ctrl)
|
||||||
|
{
|
||||||
|
if (ctrl->server_local->last_cache_nonce)
|
||||||
|
{
|
||||||
|
agent_put_cache (ctrl->server_local->last_cache_nonce,
|
||||||
|
CACHE_MODE_NONCE, NULL, 0);
|
||||||
|
xfree (ctrl->server_local->last_cache_nonce);
|
||||||
|
ctrl->server_local->last_cache_nonce = NULL;
|
||||||
|
}
|
||||||
|
if (ctrl->server_local->last_passwd_nonce)
|
||||||
|
{
|
||||||
|
agent_put_cache (ctrl->server_local->last_passwd_nonce,
|
||||||
|
CACHE_MODE_NONCE, NULL, 0);
|
||||||
|
xfree (ctrl->server_local->last_passwd_nonce);
|
||||||
|
ctrl->server_local->last_passwd_nonce = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
reset_notify (assuan_context_t ctx, char *line)
|
reset_notify (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
@ -166,6 +188,9 @@ reset_notify (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
xfree (ctrl->server_local->keydesc);
|
xfree (ctrl->server_local->keydesc);
|
||||||
ctrl->server_local->keydesc = NULL;
|
ctrl->server_local->keydesc = NULL;
|
||||||
|
|
||||||
|
clear_nonce_cache (ctrl);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1331,44 +1356,135 @@ cmd_learn (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
static const char hlp_passwd[] =
|
static const char hlp_passwd[] =
|
||||||
"PASSWD <hexstring_with_keygrip>\n"
|
"PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] <hexstring_with_keygrip>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Change the passphrase/PIN for the key identified by keygrip in LINE.";
|
"Change the passphrase/PIN for the key identified by keygrip in LINE.";
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_passwd (assuan_context_t ctx, char *line)
|
cmd_passwd (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
int rc;
|
gpg_error_t err;
|
||||||
|
int c;
|
||||||
|
char *cache_nonce = NULL;
|
||||||
|
char *passwd_nonce = NULL;
|
||||||
unsigned char grip[20];
|
unsigned char grip[20];
|
||||||
gcry_sexp_t s_skey = NULL;
|
gcry_sexp_t s_skey = NULL;
|
||||||
unsigned char *shadow_info = NULL;
|
unsigned char *shadow_info = NULL;
|
||||||
|
char *passphrase = NULL;
|
||||||
|
char *pend;
|
||||||
|
|
||||||
rc = parse_keygrip (ctx, line, grip);
|
cache_nonce = option_value (line, "--cache-nonce");
|
||||||
if (rc)
|
if (cache_nonce)
|
||||||
|
{
|
||||||
|
for (pend = cache_nonce; *pend && !spacep (pend); pend++)
|
||||||
|
;
|
||||||
|
c = *pend;
|
||||||
|
*pend = '\0';
|
||||||
|
cache_nonce = xtrystrdup (cache_nonce);
|
||||||
|
*pend = c;
|
||||||
|
if (!cache_nonce)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
passwd_nonce = option_value (line, "--passwd-nonce");
|
||||||
|
if (passwd_nonce)
|
||||||
|
{
|
||||||
|
for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
|
||||||
|
;
|
||||||
|
c = *pend;
|
||||||
|
*pend = '\0';
|
||||||
|
passwd_nonce = xtrystrdup (passwd_nonce);
|
||||||
|
*pend = c;
|
||||||
|
if (!passwd_nonce)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line = skip_options (line);
|
||||||
|
|
||||||
|
err = parse_keygrip (ctx, line, grip);
|
||||||
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
ctrl->in_passwd++;
|
ctrl->in_passwd++;
|
||||||
rc = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc,
|
err = agent_key_from_file (ctrl, cache_nonce, ctrl->server_local->keydesc,
|
||||||
grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
|
grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
|
||||||
&s_skey, NULL);
|
&s_skey, &passphrase);
|
||||||
if (rc)
|
if (err)
|
||||||
;
|
;
|
||||||
else if (!s_skey)
|
else if (!s_skey)
|
||||||
{
|
{
|
||||||
log_error ("changing a smartcard PIN is not yet supported\n");
|
log_error ("changing a smartcard PIN is not yet supported\n");
|
||||||
rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rc = agent_protect_and_store (ctrl, s_skey);
|
{
|
||||||
|
char *newpass = NULL;
|
||||||
|
|
||||||
|
if (passwd_nonce)
|
||||||
|
newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
|
||||||
|
err = agent_protect_and_store (ctrl, s_skey, &newpass);
|
||||||
|
if (!err && passphrase)
|
||||||
|
{
|
||||||
|
/* A passphrase existed on the old key and the change was
|
||||||
|
successful. Return a nonce for that old passphrase to
|
||||||
|
let the caller try to unprotect the other subkeys with
|
||||||
|
the same key. */
|
||||||
|
if (!cache_nonce)
|
||||||
|
{
|
||||||
|
char buf[12];
|
||||||
|
gcry_create_nonce (buf, 12);
|
||||||
|
cache_nonce = bin2hex (buf, 12, NULL);
|
||||||
|
}
|
||||||
|
if (cache_nonce
|
||||||
|
&& !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
|
||||||
|
passphrase, 120 /*seconds*/))
|
||||||
|
{
|
||||||
|
assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
|
||||||
|
xfree (ctrl->server_local->last_cache_nonce);
|
||||||
|
ctrl->server_local->last_cache_nonce = cache_nonce;
|
||||||
|
cache_nonce = NULL;
|
||||||
|
}
|
||||||
|
if (newpass)
|
||||||
|
{
|
||||||
|
/* If we have a new passphrase (which might be empty) we
|
||||||
|
store it under a passwd nonce so that the caller may
|
||||||
|
send that nonce again to use it for another key. */
|
||||||
|
if (!passwd_nonce)
|
||||||
|
{
|
||||||
|
char buf[12];
|
||||||
|
gcry_create_nonce (buf, 12);
|
||||||
|
passwd_nonce = bin2hex (buf, 12, NULL);
|
||||||
|
}
|
||||||
|
if (passwd_nonce
|
||||||
|
&& !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
|
||||||
|
newpass, 120 /*seconds*/))
|
||||||
|
{
|
||||||
|
assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
|
||||||
|
xfree (ctrl->server_local->last_passwd_nonce);
|
||||||
|
ctrl->server_local->last_passwd_nonce = passwd_nonce;
|
||||||
|
passwd_nonce = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xfree (newpass);
|
||||||
|
}
|
||||||
ctrl->in_passwd--;
|
ctrl->in_passwd--;
|
||||||
|
|
||||||
xfree (ctrl->server_local->keydesc);
|
xfree (ctrl->server_local->keydesc);
|
||||||
ctrl->server_local->keydesc = NULL;
|
ctrl->server_local->keydesc = NULL;
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
xfree (passphrase);
|
||||||
gcry_sexp_release (s_skey);
|
gcry_sexp_release (s_skey);
|
||||||
xfree (shadow_info);
|
xfree (shadow_info);
|
||||||
return leave_cmd (ctx, rc);
|
xfree (cache_nonce);
|
||||||
|
return leave_cmd (ctx, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1812,6 +1928,7 @@ cmd_export_key (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
xfree (cache_nonce);
|
||||||
xfree (passphrase);
|
xfree (passphrase);
|
||||||
xfree (wrappedkey);
|
xfree (wrappedkey);
|
||||||
gcry_cipher_close (cipherhd);
|
gcry_cipher_close (cipherhd);
|
||||||
@ -2448,6 +2565,9 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset the nonce caches. */
|
||||||
|
clear_nonce_cache (ctrl);
|
||||||
|
|
||||||
/* Reset the SCD if needed. */
|
/* Reset the SCD if needed. */
|
||||||
agent_reset_scd (ctrl);
|
agent_reset_scd (ctrl);
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
|||||||
xfree (pi);
|
xfree (pi);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
rc = agent_protect_and_store (ctrl, s_skey);
|
rc = agent_protect_and_store (ctrl, s_skey, NULL);
|
||||||
gcry_sexp_release (s_skey);
|
gcry_sexp_release (s_skey);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
|
@ -468,20 +468,40 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Apply a new passphrase to the key S_SKEY and store it. */
|
/* Apply a new passphrase to the key S_SKEY and store it. If
|
||||||
int
|
PASSPHRASE_ADDR and *PASSPHRASE_ADDR are not NULL, use that
|
||||||
agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey)
|
passphrase. If PASSPHRASE_ADDR is not NULL store a newly entered
|
||||||
|
passphrase at that address. */
|
||||||
|
gpg_error_t
|
||||||
|
agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
|
||||||
|
char **passphrase_addr)
|
||||||
{
|
{
|
||||||
int rc;
|
gpg_error_t err;
|
||||||
char *passphrase;
|
|
||||||
|
|
||||||
rc = agent_ask_new_passphrase (ctrl,
|
if (passphrase_addr && *passphrase_addr)
|
||||||
_("Please enter the new passphrase"),
|
|
||||||
&passphrase);
|
|
||||||
if (!rc)
|
|
||||||
{
|
{
|
||||||
rc = store_key (s_skey, passphrase, 1);
|
/* Take an empty string as request not to protect the key. */
|
||||||
xfree (passphrase);
|
err = store_key (s_skey, **passphrase_addr? *passphrase_addr:NULL, 1);
|
||||||
}
|
}
|
||||||
return rc;
|
else
|
||||||
|
{
|
||||||
|
char *pass = NULL;
|
||||||
|
|
||||||
|
if (passphrase_addr)
|
||||||
|
{
|
||||||
|
xfree (*passphrase_addr);
|
||||||
|
*passphrase_addr = NULL;
|
||||||
|
}
|
||||||
|
err = agent_ask_new_passphrase (ctrl,
|
||||||
|
_("Please enter the new passphrase"),
|
||||||
|
&pass);
|
||||||
|
if (!err)
|
||||||
|
err = store_key (s_skey, pass, 1);
|
||||||
|
if (!err && passphrase_addr)
|
||||||
|
*passphrase_addr = pass;
|
||||||
|
else
|
||||||
|
xfree (pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2010-10-25 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* logging.c (do_log): Rename to log_log and make global.
|
||||||
|
|
||||||
2010-10-20 Werner Koch <wk@g10code.com>
|
2010-10-20 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* i18n.c (i18n_init) [USE_SIMPLE_GETTEXT]: Call textdomain.
|
* i18n.c (i18n_init) [USE_SIMPLE_GETTEXT]: Call textdomain.
|
||||||
|
@ -670,8 +670,8 @@ do_logv (int level, int ignore_arg_ptr, const char *fmt, va_list arg_ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
do_log (int level, const char *fmt, ...)
|
log_log (int level, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list arg_ptr ;
|
va_list arg_ptr ;
|
||||||
|
|
||||||
@ -812,14 +812,14 @@ log_printhex (const char *text, const void *buffer, size_t length)
|
|||||||
void
|
void
|
||||||
bug_at( const char *file, int line, const char *func )
|
bug_at( const char *file, int line, const char *func )
|
||||||
{
|
{
|
||||||
do_log (JNLIB_LOG_BUG, ("... this is a bug (%s:%d:%s)\n"), file, line, func);
|
log_log (JNLIB_LOG_BUG, ("... this is a bug (%s:%d:%s)\n"), file, line, func);
|
||||||
abort (); /* Never called; just to make the compiler happy. */
|
abort (); /* Never called; just to make the compiler happy. */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void
|
void
|
||||||
bug_at( const char *file, int line )
|
bug_at( const char *file, int line )
|
||||||
{
|
{
|
||||||
do_log (JNLIB_LOG_BUG, _("you found a bug ... (%s:%d)\n"), file, line);
|
log_log (JNLIB_LOG_BUG, _("you found a bug ... (%s:%d)\n"), file, line);
|
||||||
abort (); /* Never called; just to make the compiler happy. */
|
abort (); /* Never called; just to make the compiler happy. */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -65,6 +65,7 @@ enum jnlib_log_levels {
|
|||||||
JNLIB_LOG_BUG,
|
JNLIB_LOG_BUG,
|
||||||
JNLIB_LOG_DEBUG
|
JNLIB_LOG_DEBUG
|
||||||
};
|
};
|
||||||
|
void log_log (int level, const char *fmt, ...) JNLIB_GCC_A_PRINTF(2,3);
|
||||||
void log_logv (int level, const char *fmt, va_list arg_ptr);
|
void log_logv (int level, const char *fmt, va_list arg_ptr);
|
||||||
void log_string (int level, const char *string);
|
void log_string (int level, const char *string);
|
||||||
#endif /*JNLIB_NEED_LOG_LOGV*/
|
#endif /*JNLIB_NEED_LOG_LOGV*/
|
||||||
|
@ -1,5 +1,24 @@
|
|||||||
|
2010-10-26 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* keyedit.c (change_passphrase): Handle the passwd_nonce.
|
||||||
|
* call-agent.c (cache_nonce_parm_s): New.
|
||||||
|
(cache_nonce_status_cb): Use that new struct.
|
||||||
|
(agent_genkey, agent_import_key, agent_export_key, agent_passwd):
|
||||||
|
Adjust for that change.
|
||||||
|
|
||||||
|
2010-10-25 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* passphrase.c (gpg_format_keydesc): Fix printing of main keyid.
|
||||||
|
|
||||||
|
* keyedit.c (JNLIB_NEED_LOG_LOGV): Define.
|
||||||
|
* call-agent.c (agent_passwd): New.
|
||||||
|
|
||||||
2010-10-21 Werner Koch <wk@g10code.com>
|
2010-10-21 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* keyedit.c (keyedit_passwd): Simplify.
|
||||||
|
(change_passphrase): Return an error code and not the change
|
||||||
|
flag. Remove editing of the keyring.
|
||||||
|
|
||||||
* seckey-cert.c: Remove.
|
* seckey-cert.c: Remove.
|
||||||
* Makefile.am (gpg2_SOURCES): Remove seckey-cert.c
|
* Makefile.am (gpg2_SOURCES): Remove seckey-cert.c
|
||||||
|
|
||||||
|
@ -86,6 +86,13 @@ struct import_key_parm_s
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct cache_nonce_parm_s
|
||||||
|
{
|
||||||
|
char **cache_nonce_addr;
|
||||||
|
char **passwd_nonce_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static gpg_error_t learn_status_cb (void *opaque, const char *line);
|
static gpg_error_t learn_status_cb (void *opaque, const char *line);
|
||||||
|
|
||||||
|
|
||||||
@ -1470,7 +1477,7 @@ agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cache_nonce_status_cb (void *opaque, const char *line)
|
cache_nonce_status_cb (void *opaque, const char *line)
|
||||||
{
|
{
|
||||||
char **cache_nonce = opaque;
|
struct cache_nonce_parm_s *parm = opaque;
|
||||||
const char *keyword = line;
|
const char *keyword = line;
|
||||||
int keywordlen;
|
int keywordlen;
|
||||||
|
|
||||||
@ -1481,10 +1488,18 @@ cache_nonce_status_cb (void *opaque, const char *line)
|
|||||||
|
|
||||||
if (keywordlen == 11 && !memcmp (keyword, "CACHE_NONCE", keywordlen))
|
if (keywordlen == 11 && !memcmp (keyword, "CACHE_NONCE", keywordlen))
|
||||||
{
|
{
|
||||||
if (cache_nonce)
|
if (parm->cache_nonce_addr)
|
||||||
{
|
{
|
||||||
xfree (*cache_nonce);
|
xfree (*parm->cache_nonce_addr);
|
||||||
*cache_nonce = xtrystrdup (line);
|
*parm->cache_nonce_addr = xtrystrdup (line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keywordlen == 12 && !memcmp (keyword, "PASSWD_NONCE", keywordlen))
|
||||||
|
{
|
||||||
|
if (parm->passwd_nonce_addr)
|
||||||
|
{
|
||||||
|
xfree (*parm->passwd_nonce_addr);
|
||||||
|
*parm->passwd_nonce_addr = xtrystrdup (line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1523,6 +1538,7 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
|
|||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
struct genkey_parm_s gk_parm;
|
struct genkey_parm_s gk_parm;
|
||||||
|
struct cache_nonce_parm_s cn_parm;
|
||||||
membuf_t data;
|
membuf_t data;
|
||||||
size_t len;
|
size_t len;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
@ -1546,10 +1562,12 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
|
|||||||
no_protection? " --no-protection":"",
|
no_protection? " --no-protection":"",
|
||||||
cache_nonce_addr && *cache_nonce_addr? " ":"",
|
cache_nonce_addr && *cache_nonce_addr? " ":"",
|
||||||
cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
|
cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
|
||||||
|
cn_parm.cache_nonce_addr = cache_nonce_addr;
|
||||||
|
cn_parm.passwd_nonce_addr = NULL;
|
||||||
err = assuan_transact (agent_ctx, line,
|
err = assuan_transact (agent_ctx, line,
|
||||||
membuf_data_cb, &data,
|
membuf_data_cb, &data,
|
||||||
inq_genkey_parms, &gk_parm,
|
inq_genkey_parms, &gk_parm,
|
||||||
cache_nonce_status_cb, cache_nonce_addr);
|
cache_nonce_status_cb, &cn_parm);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
xfree (get_membuf (&data, &len));
|
xfree (get_membuf (&data, &len));
|
||||||
@ -1625,7 +1643,7 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
|
|||||||
displayed if the agent needs to ask for the PIN. DIGEST and
|
displayed if the agent needs to ask for the PIN. DIGEST and
|
||||||
DIGESTLEN is the hash value to sign and DIGESTALGO the algorithm id
|
DIGESTLEN is the hash value to sign and DIGESTALGO the algorithm id
|
||||||
used to compute the digest. If CACHE_NONCE is used the agent is
|
used to compute the digest. If CACHE_NONCE is used the agent is
|
||||||
advised to firts try a passphrase associated with that nonce. */
|
advised to first try a passphrase associated with that nonce. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
agent_pksign (ctrl_t ctrl, const char *cache_nonce,
|
agent_pksign (ctrl_t ctrl, const char *cache_nonce,
|
||||||
const char *keygrip, const char *desc,
|
const char *keygrip, const char *desc,
|
||||||
@ -1890,6 +1908,7 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
|
|||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
struct import_key_parm_s parm;
|
struct import_key_parm_s parm;
|
||||||
|
struct cache_nonce_parm_s cn_parm;
|
||||||
char line[ASSUAN_LINELENGTH];
|
char line[ASSUAN_LINELENGTH];
|
||||||
|
|
||||||
err = start_agent (ctrl, 0);
|
err = start_agent (ctrl, 0);
|
||||||
@ -1914,9 +1933,11 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
|
|||||||
snprintf (line, sizeof line, "IMPORT_KEY%s%s",
|
snprintf (line, sizeof line, "IMPORT_KEY%s%s",
|
||||||
cache_nonce_addr && *cache_nonce_addr? " ":"",
|
cache_nonce_addr && *cache_nonce_addr? " ":"",
|
||||||
cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
|
cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
|
||||||
|
cn_parm.cache_nonce_addr = cache_nonce_addr;
|
||||||
|
cn_parm.passwd_nonce_addr = NULL;
|
||||||
err = assuan_transact (agent_ctx, line,
|
err = assuan_transact (agent_ctx, line,
|
||||||
NULL, NULL, inq_import_key_parms, &parm,
|
NULL, NULL, inq_import_key_parms, &parm,
|
||||||
cache_nonce_status_cb, cache_nonce_addr);
|
cache_nonce_status_cb, &cn_parm);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1932,6 +1953,7 @@ agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
|
|||||||
unsigned char **r_result, size_t *r_resultlen)
|
unsigned char **r_result, size_t *r_resultlen)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
|
struct cache_nonce_parm_s cn_parm;
|
||||||
membuf_t data;
|
membuf_t data;
|
||||||
size_t len;
|
size_t len;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
@ -1958,10 +1980,12 @@ agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
|
|||||||
hexkeygrip);
|
hexkeygrip);
|
||||||
|
|
||||||
init_membuf_secure (&data, 1024);
|
init_membuf_secure (&data, 1024);
|
||||||
|
cn_parm.cache_nonce_addr = cache_nonce_addr;
|
||||||
|
cn_parm.passwd_nonce_addr = NULL;
|
||||||
err = assuan_transact (agent_ctx, line,
|
err = assuan_transact (agent_ctx, line,
|
||||||
membuf_data_cb, &data,
|
membuf_data_cb, &data,
|
||||||
default_inq_cb, ctrl,
|
default_inq_cb, ctrl,
|
||||||
cache_nonce_status_cb, cache_nonce_addr);
|
cache_nonce_status_cb, &cn_parm);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
xfree (get_membuf (&data, &len));
|
xfree (get_membuf (&data, &len));
|
||||||
@ -1974,3 +1998,49 @@ agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
|
|||||||
*r_resultlen = len;
|
*r_resultlen = len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Ask the agent to change the passphrase of the key identified by
|
||||||
|
HEXKEYGRIP. If DESC is not NULL, display DESC instead of the
|
||||||
|
default description message. If CACHE_NONCE_ADDR is not NULL the
|
||||||
|
agent is advised to first try a passphrase associated with that
|
||||||
|
nonce. If PASSWD_NONCE_ADDR is not NULL the agent will try to use
|
||||||
|
the passphrase associated with that nonce. */
|
||||||
|
gpg_error_t
|
||||||
|
agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
|
||||||
|
char **cache_nonce_addr, char **passwd_nonce_addr)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
struct cache_nonce_parm_s cn_parm;
|
||||||
|
char line[ASSUAN_LINELENGTH];
|
||||||
|
|
||||||
|
err = start_agent (ctrl, 0);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (!hexkeygrip || strlen (hexkeygrip) != 40)
|
||||||
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
|
if (desc)
|
||||||
|
{
|
||||||
|
snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
|
||||||
|
err = assuan_transact (agent_ctx, line,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf (line, DIM(line)-1, "PASSWD %s%s %s%s %s",
|
||||||
|
cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
|
||||||
|
cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
|
||||||
|
passwd_nonce_addr && *passwd_nonce_addr? "--passwd-nonce=":"",
|
||||||
|
passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
|
||||||
|
hexkeygrip);
|
||||||
|
cn_parm.cache_nonce_addr = cache_nonce_addr;
|
||||||
|
cn_parm.passwd_nonce_addr = passwd_nonce_addr;
|
||||||
|
err = assuan_transact (agent_ctx, line, NULL, NULL,
|
||||||
|
default_inq_cb, ctrl,
|
||||||
|
cache_nonce_status_cb, &cn_parm);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
@ -184,6 +184,9 @@ gpg_error_t agent_export_key (ctrl_t ctrl, const char *keygrip,
|
|||||||
const char *desc, char **cache_nonce_addr,
|
const char *desc, char **cache_nonce_addr,
|
||||||
unsigned char **r_result, size_t *r_resultlen);
|
unsigned char **r_result, size_t *r_resultlen);
|
||||||
|
|
||||||
|
/* Change the passphrase of a key. */
|
||||||
|
gpg_error_t agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
|
||||||
|
char **cache_nonce_addr, char **passwd_nonce_addr);
|
||||||
|
|
||||||
|
|
||||||
#endif /*GNUPG_G10_CALL_AGENT_H*/
|
#endif /*GNUPG_G10_CALL_AGENT_H*/
|
||||||
|
|
||||||
|
@ -3657,7 +3657,7 @@ main (int argc, char **argv)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
username = make_username (fname);
|
username = make_username (fname);
|
||||||
keyedit_passwd (username);
|
keyedit_passwd (ctrl, username);
|
||||||
xfree (username);
|
xfree (username);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
272
g10/keyedit.c
272
g10/keyedit.c
@ -30,6 +30,7 @@
|
|||||||
# include <readline/readline.h>
|
# include <readline/readline.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define JNLIB_NEED_LOG_LOGV
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
@ -1124,44 +1125,63 @@ leave:
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change the passphrase of the primary and all secondary keys.
|
* Change the passphrase of the primary and all secondary keys. Note
|
||||||
* We use only one passphrase for all keys.
|
* that it is common to use only one passphrase for the primary and
|
||||||
|
* all subkeys. However, this is now (since GnuPG 2.1) all up to the
|
||||||
|
* gpg-agent. Returns 0 on success or an error code.
|
||||||
*/
|
*/
|
||||||
static int
|
static gpg_error_t
|
||||||
change_passphrase (KBNODE keyblock, int *r_err)
|
change_passphrase (ctrl_t ctrl, kbnode_t keyblock)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
gpg_error_t err;
|
||||||
int changed = 0;
|
kbnode_t node;
|
||||||
KBNODE node;
|
PKT_public_key *pk;
|
||||||
PKT_public_key *pksk;
|
|
||||||
char *passphrase = NULL;
|
|
||||||
int no_primary_secrets = 0;
|
|
||||||
int any;
|
int any;
|
||||||
|
u32 keyid[2], subid[2];
|
||||||
|
char *hexgrip = NULL;
|
||||||
|
char *cache_nonce = NULL;
|
||||||
|
char *passwd_nonce = NULL;
|
||||||
|
|
||||||
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
|
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
|
||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
log_error ("Oops; public key missing!\n");
|
log_error ("Oops; public key missing!\n");
|
||||||
|
err = gpg_error (GPG_ERR_INTERNAL);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
pksk = node->pkt->pkt.public_key;
|
pk = node->pkt->pkt.public_key;
|
||||||
|
keyid_from_pk (pk, keyid);
|
||||||
|
|
||||||
|
/* Check whether it is likely that we will be able to change the
|
||||||
|
passphrase for any subkey. */
|
||||||
for (any = 0, node = keyblock; node; node = node->next)
|
for (any = 0, node = keyblock; node; node = node->next)
|
||||||
{
|
{
|
||||||
if (node->pkt->pkttype == PKT_PUBLIC_KEY
|
if (node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||||
{
|
{
|
||||||
log_debug ("FIXME\n");
|
char *serialno;
|
||||||
/* PKT_public_key *tmpsk = node->pkt->pkt.public_key; */
|
|
||||||
/* if (!(tmpsk->is_protected */
|
pk = node->pkt->pkt.public_key;
|
||||||
/* && (tmpsk->protect.s2k.mode == 1001 */
|
keyid_from_pk (pk, subid);
|
||||||
/* || tmpsk->protect.s2k.mode == 1002))) */
|
|
||||||
/* { */
|
xfree (hexgrip);
|
||||||
/* any = 1; */
|
err = hexkeygrip_from_pk (pk, &hexgrip);
|
||||||
/* break; */
|
if (err)
|
||||||
/* } */
|
goto leave;
|
||||||
|
err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
|
||||||
|
if (!err && serialno)
|
||||||
|
; /* Key on card. */
|
||||||
|
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||||
|
; /* Maybe stub key. */
|
||||||
|
else if (!err)
|
||||||
|
any = 1; /* Key is known. */
|
||||||
|
else
|
||||||
|
log_error ("key %s: error getting keyinfo from agent: %s\n",
|
||||||
|
keystr_with_sub (keyid, subid), gpg_strerror (err));
|
||||||
|
xfree (serialno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
err = 0;
|
||||||
if (!any)
|
if (!any)
|
||||||
{
|
{
|
||||||
tty_printf (_("Key has only stub or on-card key items - "
|
tty_printf (_("Key has only stub or on-card key items - "
|
||||||
@ -1169,162 +1189,43 @@ change_passphrase (KBNODE keyblock, int *r_err)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug ("FIXME\n");
|
/* Change the passphrase for all keys. */
|
||||||
/* See how to handle this key. */
|
for (any = 0, node = keyblock; node; node = node->next)
|
||||||
/* switch (is_secret_key_protected (pksk)) */
|
|
||||||
/* { */
|
|
||||||
/* case -1: */
|
|
||||||
/* rc = G10ERR_PUBKEY_ALGO; */
|
|
||||||
/* break; */
|
|
||||||
/* case 0: */
|
|
||||||
/* tty_printf (_("This key is not protected.\n")); */
|
|
||||||
/* break; */
|
|
||||||
/* default: */
|
|
||||||
/* if (sk->protect.s2k.mode == 1001) */
|
|
||||||
/* { */
|
|
||||||
/* tty_printf (_("Secret parts of key are not available.\n")); */
|
|
||||||
/* no_primary_secrets = 1; */
|
|
||||||
/* } */
|
|
||||||
/* else if (sk->protect.s2k.mode == 1002) */
|
|
||||||
/* { */
|
|
||||||
/* tty_printf (_("Secret parts of key are stored on-card.\n")); */
|
|
||||||
/* no_primary_secrets = 1; */
|
|
||||||
/* } */
|
|
||||||
/* else */
|
|
||||||
/* { */
|
|
||||||
/* u32 keyid[2]; */
|
|
||||||
|
|
||||||
/* tty_printf (_("Key is protected.\n")); */
|
|
||||||
|
|
||||||
/* /\* Clear the passphrase cache so that the user is required */
|
|
||||||
/* to enter the old passphrase. *\/ */
|
|
||||||
/* keyid_from_pk (pksk, keyid); */
|
|
||||||
/* passphrase_clear_cache (keyid, NULL, 0); */
|
|
||||||
|
|
||||||
/* /\* rc = check_secret_key( sk, 0 ); *\/ */
|
|
||||||
/* /\* if( !rc ) *\/ */
|
|
||||||
/* /\* passphrase = get_last_passphrase(); *\/ */
|
|
||||||
/* } */
|
|
||||||
/* break; */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* Unprotect all subkeys (use the supplied passphrase or ask) */
|
|
||||||
for (node = keyblock; !rc && node; node = node->next)
|
|
||||||
{
|
{
|
||||||
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
if (node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||||
|
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||||
{
|
{
|
||||||
log_debug ("FIXME\n");
|
char *desc;
|
||||||
/* PKT_pubic_key *subsk = node->pkt->pkt.public_key; */
|
|
||||||
/* if (!(subsk->is_protected */
|
|
||||||
/* && (subsk->protect.s2k.mode == 1001 */
|
|
||||||
/* || subsk->protect.s2k.mode == 1002))) */
|
|
||||||
/* { */
|
|
||||||
/* set_next_passphrase (passphrase); */
|
|
||||||
/* /\* rc = check_secret_key( subsk, 0 ); *\/ */
|
|
||||||
/* /\* if( !rc && !passphrase ) *\/ */
|
|
||||||
/* /\* passphrase = get_last_passphrase(); *\/ */
|
|
||||||
/* } */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc)
|
pk = node->pkt->pkt.public_key;
|
||||||
tty_printf (_("Can't edit this key: %s\n"), g10_errstr (rc));
|
keyid_from_pk (pk, subid);
|
||||||
else
|
|
||||||
{
|
|
||||||
DEK *dek = NULL;
|
|
||||||
STRING2KEY *s2k = xmalloc_secure (sizeof *s2k);
|
|
||||||
const char *errtext = NULL;
|
|
||||||
|
|
||||||
tty_printf (_("Enter the new passphrase for this secret key.\n\n"));
|
xfree (hexgrip);
|
||||||
|
err = hexkeygrip_from_pk (pk, &hexgrip);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
set_next_passphrase (NULL);
|
desc = gpg_format_keydesc (pk, 0, 1);
|
||||||
for (;;)
|
err = agent_passwd (ctrl, hexgrip, desc, &cache_nonce, &passwd_nonce);
|
||||||
{
|
xfree (desc);
|
||||||
int canceled;
|
|
||||||
|
|
||||||
s2k->mode = opt.s2k_mode;
|
if (err)
|
||||||
s2k->hash_algo = S2K_DIGEST_ALGO;
|
log_log ((gpg_err_code (err) == GPG_ERR_CANCELED
|
||||||
dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo,
|
|| gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
|
||||||
s2k, 2, errtext, &canceled);
|
? JNLIB_LOG_INFO : JNLIB_LOG_ERROR,
|
||||||
if (!dek && canceled)
|
_("key %s: error changing passphrase: %s\n"),
|
||||||
{
|
keystr_with_sub (keyid, subid),
|
||||||
rc = GPG_ERR_CANCELED;
|
gpg_strerror (err));
|
||||||
break;
|
if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
|
||||||
}
|
|
||||||
else if (!dek)
|
|
||||||
{
|
|
||||||
errtext = N_("passphrase not correctly repeated; try again");
|
|
||||||
tty_printf ("%s.\n", _(errtext));
|
|
||||||
}
|
|
||||||
else if (!dek->keylen)
|
|
||||||
{
|
|
||||||
rc = 0;
|
|
||||||
tty_printf (_("You don't want a passphrase -"
|
|
||||||
" this is probably a *bad* idea!\n\n"));
|
|
||||||
if (cpr_get_answer_is_yes
|
|
||||||
("change_passwd.empty.okay",
|
|
||||||
_("Do you really want to do this? (y/N) ")))
|
|
||||||
{
|
|
||||||
changed++;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{ /* okay */
|
|
||||||
rc = 0;
|
|
||||||
if (!no_primary_secrets)
|
|
||||||
{
|
|
||||||
/* sk->protect.algo = dek->algo; */
|
|
||||||
/* sk->protect.s2k = *s2k; */
|
|
||||||
rc = 0;
|
|
||||||
/* rc = protect_secret_key( sk, dek ); */
|
|
||||||
}
|
|
||||||
for (node = keyblock; !rc && node; node = node->next)
|
|
||||||
{
|
|
||||||
if (node->pkt->pkttype == PKT_SECRET_SUBKEY)
|
|
||||||
{
|
|
||||||
log_debug ("FIXME\n");
|
|
||||||
/* PKT_secret_key *subsk = node->pkt->pkt.secret_key; */
|
|
||||||
/* if (!(subsk->is_protected */
|
|
||||||
/* && (subsk->protect.s2k.mode == 1001 */
|
|
||||||
/* || subsk->protect.s2k.mode == 1002))) */
|
|
||||||
/* { */
|
|
||||||
/* subsk->protect.algo = dek->algo; */
|
|
||||||
/* subsk->protect.s2k = *s2k; */
|
|
||||||
/* #warning fixme */
|
|
||||||
/* rc = 0; */
|
|
||||||
/* /\* rc = protect_secret_key( subsk, dek ); *\/ */
|
|
||||||
/* } */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rc)
|
|
||||||
log_error ("protect_secret_key failed: %s\n",
|
|
||||||
g10_errstr (rc));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
u32 keyid[2];
|
|
||||||
|
|
||||||
/* Clear the cahce again so that the user is
|
leave:
|
||||||
required to enter the new passphrase at the
|
xfree (hexgrip);
|
||||||
next operation. */
|
xfree (cache_nonce);
|
||||||
/* FIXME keyid_from_sk (sk, keyid); */
|
xfree (passwd_nonce);
|
||||||
passphrase_clear_cache (keyid, NULL, 0);
|
return err;
|
||||||
|
|
||||||
changed++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xfree (s2k);
|
|
||||||
xfree (dek);
|
|
||||||
}
|
|
||||||
|
|
||||||
leave:
|
|
||||||
xfree (passphrase);
|
|
||||||
set_next_passphrase (NULL);
|
|
||||||
if (r_err)
|
|
||||||
*r_err = rc;
|
|
||||||
return changed && !rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2184,7 +2085,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case cmdPASSWD:
|
case cmdPASSWD:
|
||||||
change_passphrase (keyblock, NULL);
|
change_passphrase (ctrl, keyblock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmdTRUST:
|
case cmdTRUST:
|
||||||
@ -2361,13 +2262,10 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
|
|||||||
|
|
||||||
/* Change the passphrase of the secret key identified by USERNAME. */
|
/* Change the passphrase of the secret key identified by USERNAME. */
|
||||||
void
|
void
|
||||||
keyedit_passwd (const char *username)
|
keyedit_passwd (ctrl_t ctrl, const char *username)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
unsigned char fpr[MAX_FINGERPRINT_LEN];
|
|
||||||
size_t fprlen;
|
|
||||||
KEYDB_HANDLE kdh = NULL;
|
|
||||||
kbnode_t keyblock = NULL;
|
kbnode_t keyblock = NULL;
|
||||||
|
|
||||||
pk = xtrycalloc (1, sizeof *pk);
|
pk = xtrycalloc (1, sizeof *pk);
|
||||||
@ -2376,44 +2274,16 @@ keyedit_passwd (const char *username)
|
|||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
err = getkey_byname (NULL, pk, username, 1, NULL);
|
err = getkey_byname (NULL, pk, username, 1, &keyblock);
|
||||||
if (err)
|
|
||||||
goto leave;
|
|
||||||
fingerprint_from_pk (pk, fpr, &fprlen);
|
|
||||||
while (fprlen < MAX_FINGERPRINT_LEN)
|
|
||||||
fpr[fprlen++] = 0;
|
|
||||||
|
|
||||||
/* FIXME: Call an agent function instead. */
|
|
||||||
|
|
||||||
kdh = NULL /*keydb_new (1)*/;
|
|
||||||
if (!kdh)
|
|
||||||
{
|
|
||||||
err = gpg_error (GPG_ERR_GENERAL);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = keydb_search_fpr (kdh, fpr);
|
|
||||||
if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
|
|
||||||
err = gpg_error (GPG_ERR_NO_SECKEY);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
err = keydb_get_keyblock (kdh, &keyblock);
|
err = change_passphrase (ctrl, keyblock);
|
||||||
if (err)
|
|
||||||
goto leave;
|
|
||||||
|
|
||||||
if (!change_passphrase (keyblock, &err))
|
|
||||||
goto leave;
|
|
||||||
|
|
||||||
err = keydb_update_keyblock (kdh, keyblock);
|
|
||||||
if (err)
|
|
||||||
log_error (_("update secret failed: %s\n"), gpg_strerror (err));
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
release_kbnode (keyblock);
|
release_kbnode (keyblock);
|
||||||
if (pk)
|
if (pk)
|
||||||
free_public_key (pk);
|
free_public_key (pk);
|
||||||
keydb_release (kdh);
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_info ("error changing the passphrase for `%s': %s\n",
|
log_info ("error changing the passphrase for `%s': %s\n",
|
||||||
|
@ -224,7 +224,7 @@ int delete_keys( strlist_t names, int secret, int allow_both );
|
|||||||
/*-- keyedit.c --*/
|
/*-- keyedit.c --*/
|
||||||
void keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
|
void keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
|
||||||
strlist_t commands, int quiet, int seckey_check );
|
strlist_t commands, int quiet, int seckey_check );
|
||||||
void keyedit_passwd (const char *username);
|
void keyedit_passwd (ctrl_t ctrl, const char *username);
|
||||||
void show_basic_key_info (KBNODE keyblock);
|
void show_basic_key_info (KBNODE keyblock);
|
||||||
|
|
||||||
/*-- keygen.c --*/
|
/*-- keygen.c --*/
|
||||||
|
@ -675,7 +675,7 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return an allocated utf-8 string describing the key PK. IF ESCAPED
|
/* Return an allocated utf-8 string describing the key PK. If ESCAPED
|
||||||
is true spaces and control characters are percent or plus escaped.
|
is true spaces and control characters are percent or plus escaped.
|
||||||
MODE 0 is for the common prompt, MODE 1 for the import prompt. */
|
MODE 0 is for the common prompt, MODE 1 for the import prompt. */
|
||||||
char *
|
char *
|
||||||
@ -696,9 +696,9 @@ gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
|
|||||||
|
|
||||||
orig_codeset = i18n_switchto_utf8 ();
|
orig_codeset = i18n_switchto_utf8 ();
|
||||||
|
|
||||||
if (pk->main_keyid[2] && pk->main_keyid[3]
|
if (pk->main_keyid[0] && pk->main_keyid[1]
|
||||||
&& pk->keyid[0] != pk->main_keyid[2]
|
&& pk->keyid[0] != pk->main_keyid[0]
|
||||||
&& pk->keyid[1] != pk->main_keyid[3])
|
&& pk->keyid[1] != pk->main_keyid[1])
|
||||||
maink = xtryasprintf (_(" (main key ID %s)"), keystr (pk->main_keyid));
|
maink = xtryasprintf (_(" (main key ID %s)"), keystr (pk->main_keyid));
|
||||||
else
|
else
|
||||||
maink = NULL;
|
maink = NULL;
|
||||||
|
@ -163,7 +163,9 @@ close_message_fd (ctrl_t ctrl)
|
|||||||
{
|
{
|
||||||
if (ctrl->server_local->message_fd != -1)
|
if (ctrl->server_local->message_fd != -1)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_W32CE_SYSTEM
|
||||||
#warning Is this correct for W32/W32CE?
|
#warning Is this correct for W32/W32CE?
|
||||||
|
#endif
|
||||||
close (ctrl->server_local->message_fd);
|
close (ctrl->server_local->message_fd);
|
||||||
ctrl->server_local->message_fd = -1;
|
ctrl->server_local->message_fd = -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user