mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Support a confirm flag for ssh.
This implements the suggestion from bug#1349. With this change the fingerprint of the ssh key is also displayed in the pinentry prompts.
This commit is contained in:
parent
69f8a7f15d
commit
d479906991
2
NEWS
2
NEWS
@ -5,6 +5,8 @@ Noteworthy changes in version 2.1.0beta3
|
||||
|
||||
* Allow generation of card keys up to 4096 bit.
|
||||
|
||||
* Support the SSH confirm flag.
|
||||
|
||||
|
||||
Noteworthy changes in version 2.1.0beta2 (2011-03-08)
|
||||
-----------------------------------------------------
|
||||
|
@ -1,3 +1,17 @@
|
||||
2011-07-20 Werner Koch <wk@g10code.com>
|
||||
|
||||
* command-ssh.c (ssh_identity_register): Display the ssh
|
||||
fingerprint in the prompt.
|
||||
(add_control_entry): Add arg FMTFPR and use it as comment in
|
||||
sshcontrol.
|
||||
(confirm_flag_from_sshcontrol): New.
|
||||
(data_sign): Ask for confirmaton if requested.
|
||||
(search_control_file): Add new arg R_CONFIRM and enhance parser.
|
||||
* findkey.c (agent_raw_key_from_file): New.
|
||||
(modify_description): Add format letter %F.
|
||||
* findkey.c (agent_key_from_file): Simplify comment extraction by
|
||||
using gcry_sexp_nth_string.
|
||||
|
||||
2011-06-28 Ben Kibbey <bjk@luxsci.net>
|
||||
|
||||
* command.c (option_handler): Add option s2k-count.
|
||||
|
@ -268,6 +268,8 @@ gpg_error_t agent_key_from_file (ctrl_t ctrl,
|
||||
lookup_ttl_t lookup_ttl,
|
||||
gcry_sexp_t *result,
|
||||
char **r_passphrase);
|
||||
gpg_error_t agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip,
|
||||
gcry_sexp_t *result);
|
||||
gpg_error_t agent_public_key_from_file (ctrl_t ctrl,
|
||||
const unsigned char *grip,
|
||||
gcry_sexp_t *result);
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "agent.h"
|
||||
|
||||
#include "i18n.h"
|
||||
#include "../common/ssh-utils.h"
|
||||
|
||||
|
||||
|
||||
|
||||
@ -708,17 +710,23 @@ open_control_file (FILE **r_fp, int append)
|
||||
/* Search the file at stream FP from the beginning until a matching
|
||||
HEXGRIP is found; return success in this case and store true at
|
||||
DISABLED if the found key has been disabled. If R_TTL is not NULL
|
||||
a specified TTL for that key is stored there. */
|
||||
a specified TTL for that key is stored there. If R_CONFIRM is not
|
||||
NULL it is set to 1 if the key has the confirm flag set. */
|
||||
static gpg_error_t
|
||||
search_control_file (FILE *fp, const char *hexgrip,
|
||||
int *r_disabled, int *r_ttl)
|
||||
int *r_disabled, int *r_ttl, int *r_confirm)
|
||||
{
|
||||
int c, i;
|
||||
int c, i, n;
|
||||
char *p, *pend, line[256];
|
||||
long ttl;
|
||||
int lnr = 0;
|
||||
const char fname[] = "sshcontrol";
|
||||
|
||||
assert (strlen (hexgrip) == 40 );
|
||||
|
||||
if (r_confirm)
|
||||
*r_confirm = 0;
|
||||
|
||||
fseek (fp, 0, SEEK_SET);
|
||||
clearerr (fp);
|
||||
*r_disabled = 0;
|
||||
@ -731,6 +739,7 @@ search_control_file (FILE *fp, const char *hexgrip,
|
||||
return gpg_error (GPG_ERR_EOF);
|
||||
return gpg_error (gpg_err_code_from_errno (errno));
|
||||
}
|
||||
lnr++;
|
||||
|
||||
if (!*line || line[strlen(line)-1] != '\n')
|
||||
{
|
||||
@ -760,7 +769,7 @@ search_control_file (FILE *fp, const char *hexgrip,
|
||||
goto next_line;
|
||||
if (i != 40 || !(spacep (p) || *p == '\n'))
|
||||
{
|
||||
log_error ("invalid formatted line in ssh control file\n");
|
||||
log_error ("invalid formatted line in `%s', line %d\n", fname, lnr);
|
||||
return gpg_error (GPG_ERR_BAD_DATA);
|
||||
}
|
||||
|
||||
@ -768,13 +777,37 @@ search_control_file (FILE *fp, const char *hexgrip,
|
||||
p = pend;
|
||||
if (!(spacep (p) || *p == '\n') || ttl < -1)
|
||||
{
|
||||
log_error ("invalid TTL value in ssh control file; assuming 0\n");
|
||||
log_error ("invalid TTL value in `%s', line %d; assuming 0\n",
|
||||
fname, lnr);
|
||||
ttl = 0;
|
||||
}
|
||||
if (r_ttl)
|
||||
*r_ttl = ttl;
|
||||
|
||||
/* Here is the place to parse flags if we need them. */
|
||||
/* Now check for key-value pairs of the form NAME[=VALUE]. */
|
||||
while (*p)
|
||||
{
|
||||
for (; spacep (p) && *p != '\n'; p++)
|
||||
;
|
||||
if (!*p || *p == '\n')
|
||||
break;
|
||||
n = strcspn (p, "= \t\n");
|
||||
if (p[n] == '=')
|
||||
{
|
||||
log_error ("assigning a value to a flag is not yet supported; "
|
||||
"in `%s', line %d; flag ignored\n", fname, lnr);
|
||||
p++;
|
||||
}
|
||||
else if (n == 7 && !memcmp (p, "confirm", 7))
|
||||
{
|
||||
if (r_confirm)
|
||||
*r_confirm = 1;
|
||||
}
|
||||
else
|
||||
log_error ("invalid flag `%.*s' in `%s', line %d; ignored\n",
|
||||
n, p, fname, lnr);
|
||||
p += n;
|
||||
}
|
||||
|
||||
return 0; /* Okay: found it. */
|
||||
}
|
||||
@ -783,11 +816,12 @@ search_control_file (FILE *fp, const char *hexgrip,
|
||||
|
||||
/* Add an entry to the control file to mark the key with the keygrip
|
||||
HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
|
||||
for it. This function is in general used to add a key received
|
||||
through the ssh-add function. We can assume that the user wants to
|
||||
allow ssh using this key. */
|
||||
for it. FMTFPR is the fingerprint string. This function is in
|
||||
general used to add a key received through the ssh-add function.
|
||||
We can assume that the user wants to allow ssh using this key. */
|
||||
static gpg_error_t
|
||||
add_control_entry (ctrl_t ctrl, const char *hexgrip, int ttl)
|
||||
add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr,
|
||||
int ttl, int confirm)
|
||||
{
|
||||
gpg_error_t err;
|
||||
FILE *fp;
|
||||
@ -799,7 +833,7 @@ add_control_entry (ctrl_t ctrl, const char *hexgrip, int ttl)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = search_control_file (fp, hexgrip, &disabled, NULL);
|
||||
err = search_control_file (fp, hexgrip, &disabled, NULL, NULL);
|
||||
if (err && gpg_err_code(err) == GPG_ERR_EOF)
|
||||
{
|
||||
struct tm *tp;
|
||||
@ -808,10 +842,12 @@ add_control_entry (ctrl_t ctrl, const char *hexgrip, int ttl)
|
||||
/* Not yet in the file - add it. Because the file has been
|
||||
opened in append mode, we simply need to write to it. */
|
||||
tp = localtime (&atime);
|
||||
fprintf (fp, "# Key added on %04d-%02d-%02d %02d:%02d:%02d\n%s %d\n",
|
||||
fprintf (fp, ("# Key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
|
||||
"# Fingerprint: %s\n"
|
||||
"%s %d%s\n"),
|
||||
1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
|
||||
tp->tm_hour, tp->tm_min, tp->tm_sec,
|
||||
hexgrip, ttl);
|
||||
fmtfpr, hexgrip, ttl, confirm? " confirm":"");
|
||||
|
||||
}
|
||||
fclose (fp);
|
||||
@ -832,7 +868,7 @@ ttl_from_sshcontrol (const char *hexgrip)
|
||||
if (open_control_file (&fp, 0))
|
||||
return 0; /* Error: Use the global default TTL. */
|
||||
|
||||
if (search_control_file (fp, hexgrip, &disabled, &ttl)
|
||||
if (search_control_file (fp, hexgrip, &disabled, &ttl, NULL)
|
||||
|| disabled)
|
||||
ttl = 0; /* Use the global default if not found or disabled. */
|
||||
|
||||
@ -842,6 +878,30 @@ ttl_from_sshcontrol (const char *hexgrip)
|
||||
}
|
||||
|
||||
|
||||
/* Scan the sshcontrol file and return the confirm flag. */
|
||||
static int
|
||||
confirm_flag_from_sshcontrol (const char *hexgrip)
|
||||
{
|
||||
FILE *fp;
|
||||
int disabled, confirm;
|
||||
|
||||
if (!hexgrip || strlen (hexgrip) != 40)
|
||||
return 1; /* Wrong input: Better ask for confirmation. */
|
||||
|
||||
if (open_control_file (&fp, 0))
|
||||
return 1; /* Error: Better ask for confirmation. */
|
||||
|
||||
if (search_control_file (fp, hexgrip, &disabled, NULL, &confirm)
|
||||
|| disabled)
|
||||
confirm = 0; /* If not found or disabled, there is no reason to
|
||||
ask for confirmation. */
|
||||
|
||||
fclose (fp);
|
||||
|
||||
return confirm;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1588,6 +1648,7 @@ ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Converts the secret key KEY_SECRET into a public key, storing it in
|
||||
KEY_PUBLIC. SPEC is the according key specification. Returns zero
|
||||
on success or an error code. */
|
||||
@ -1909,7 +1970,7 @@ ssh_handler_request_identities (ctrl_t ctrl,
|
||||
hexgrip[40] = 0;
|
||||
if ( strlen (hexgrip) != 40 )
|
||||
continue;
|
||||
if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL)
|
||||
if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL, NULL)
|
||||
|| disabled)
|
||||
continue;
|
||||
|
||||
@ -2044,14 +2105,60 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder,
|
||||
const char *elems;
|
||||
size_t elems_n;
|
||||
gcry_mpi_t *mpis = NULL;
|
||||
char hexgrip[40+1];
|
||||
|
||||
*sig = NULL;
|
||||
*sig_n = 0;
|
||||
|
||||
/* Quick check to see whether we have a valid keygrip and convert it
|
||||
to hex. */
|
||||
if (!ctrl->have_keygrip)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_NO_SECKEY);
|
||||
goto out;
|
||||
}
|
||||
bin2hex (ctrl->keygrip, 20, hexgrip);
|
||||
|
||||
/* Ask for confirmation if needed. */
|
||||
if (confirm_flag_from_sshcontrol (hexgrip))
|
||||
{
|
||||
gcry_sexp_t key;
|
||||
char *fpr, *prompt;
|
||||
char *comment = NULL;
|
||||
|
||||
err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
|
||||
if (err)
|
||||
goto out;
|
||||
err = ssh_get_fingerprint_string (key, &fpr);
|
||||
if (!err)
|
||||
{
|
||||
gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
|
||||
if (tmpsxp)
|
||||
comment = gcry_sexp_nth_string (tmpsxp, 1);
|
||||
gcry_sexp_release (tmpsxp);
|
||||
}
|
||||
gcry_sexp_release (key);
|
||||
if (err)
|
||||
goto out;
|
||||
prompt = xtryasprintf (_("An ssh process requested the use of key%%0A"
|
||||
" %s%%0A"
|
||||
" (%s)%%0A"
|
||||
"Do you want to allow this?"),
|
||||
fpr, comment? comment:"");
|
||||
xfree (fpr);
|
||||
gcry_free (comment);
|
||||
err = agent_get_confirmation (ctrl, prompt, _("Allow"), _("Deny"), 0);
|
||||
xfree (prompt);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Create signature. */
|
||||
ctrl->use_auth_call = 1;
|
||||
err = agent_pksign_do (ctrl, NULL,
|
||||
_("Please enter the passphrase "
|
||||
"for the ssh key%0A %c"), &signature_sexp,
|
||||
"for the ssh key%%0A %F%%0A (%c)"),
|
||||
&signature_sexp,
|
||||
CACHE_MODE_SSH, ttl_from_sshcontrol);
|
||||
ctrl->use_auth_call = 0;
|
||||
if (err)
|
||||
@ -2370,7 +2477,7 @@ reenter_compare_cb (struct pin_entry_info_s *pi)
|
||||
our key storage, don't do anything. When entering a new key also
|
||||
add an entry to the sshcontrol file. */
|
||||
static gpg_error_t
|
||||
ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
|
||||
ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm)
|
||||
{
|
||||
gpg_error_t err;
|
||||
unsigned char key_grip_raw[20];
|
||||
@ -2380,6 +2487,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
|
||||
char *description = NULL;
|
||||
const char *description2 = _("Please re-enter this passphrase");
|
||||
char *comment = NULL;
|
||||
char *key_fpr = NULL;
|
||||
const char *initial_errtext = NULL;
|
||||
unsigned int i;
|
||||
struct pin_entry_info_s *pi = NULL, *pi2;
|
||||
@ -2393,6 +2501,9 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
|
||||
if ( !agent_key_available (key_grip_raw) )
|
||||
goto out; /* Yes, key is available. */
|
||||
|
||||
err = ssh_get_fingerprint_string (key, &key_fpr);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = ssh_key_extract_comment (key, &comment);
|
||||
if (err)
|
||||
@ -2402,8 +2513,9 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
|
||||
_("Please enter a passphrase to protect"
|
||||
" the received secret key%%0A"
|
||||
" %s%%0A"
|
||||
" %s%%0A"
|
||||
"within gpg-agent's key storage"),
|
||||
comment ? comment : "?") < 0)
|
||||
key_fpr, comment ? comment : "") < 0)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto out;
|
||||
@ -2460,7 +2572,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
|
||||
goto out;
|
||||
|
||||
/* And add an entry to the sshcontrol file. */
|
||||
err = add_control_entry (ctrl, key_grip, ttl);
|
||||
err = add_control_entry (ctrl, key_grip, key_fpr, ttl, confirm);
|
||||
|
||||
|
||||
out:
|
||||
@ -2469,6 +2581,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
|
||||
xfree (pi);
|
||||
xfree (buffer);
|
||||
xfree (comment);
|
||||
xfree (key_fpr);
|
||||
xfree (description);
|
||||
|
||||
return err;
|
||||
@ -2553,9 +2666,7 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
/* FIXME: are constraints used correctly? */
|
||||
|
||||
err = ssh_identity_register (ctrl, key, ttl);
|
||||
err = ssh_identity_register (ctrl, key, ttl, confirm);
|
||||
|
||||
out:
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* findkey.c - Locate the secret key
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
|
||||
* 2010 Free Software Foundation, Inc.
|
||||
* 2010, 2011 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -33,6 +33,7 @@
|
||||
|
||||
#include "agent.h"
|
||||
#include "i18n.h"
|
||||
#include "../common/ssh-utils.h"
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
@ -185,12 +186,14 @@ try_unprotect_cb (struct pin_entry_info_s *pi)
|
||||
|
||||
%% - Replaced by a single %
|
||||
%c - Replaced by the content of COMMENT.
|
||||
%F - Replaced by an ssh style fingerprint computed from KEY.
|
||||
|
||||
The functions returns 0 on success or an error code. On success a
|
||||
newly allocated string is stored at the address of RESULT.
|
||||
*/
|
||||
static gpg_error_t
|
||||
modify_description (const char *in, const char *comment, char **result)
|
||||
modify_description (const char *in, const char *comment, const gcry_sexp_t key,
|
||||
char **result)
|
||||
{
|
||||
size_t comment_length;
|
||||
size_t in_len;
|
||||
@ -198,6 +201,7 @@ modify_description (const char *in, const char *comment, char **result)
|
||||
char *out;
|
||||
size_t i;
|
||||
int special, pass;
|
||||
char *ssh_fpr = NULL;
|
||||
|
||||
comment_length = strlen (comment);
|
||||
in_len = strlen (in);
|
||||
@ -233,6 +237,18 @@ modify_description (const char *in, const char *comment, char **result)
|
||||
out_len += comment_length;
|
||||
break;
|
||||
|
||||
case 'F': /* SSH style fingerprint. */
|
||||
if (!ssh_fpr && key)
|
||||
ssh_get_fingerprint_string (key, &ssh_fpr);
|
||||
if (ssh_fpr)
|
||||
{
|
||||
if (out)
|
||||
out = stpcpy (out, ssh_fpr);
|
||||
else
|
||||
out_len += strlen (ssh_fpr);
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* Invalid special sequences are kept as they are. */
|
||||
if (out)
|
||||
{
|
||||
@ -259,12 +275,16 @@ modify_description (const char *in, const char *comment, char **result)
|
||||
{
|
||||
*result = out = xtrymalloc (out_len + 1);
|
||||
if (!out)
|
||||
{
|
||||
xfree (ssh_fpr);
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*out = 0;
|
||||
assert (*result + out_len == out);
|
||||
xfree (ssh_fpr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -564,45 +584,26 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
||||
break; /* no unprotection needed */
|
||||
case PRIVATE_KEY_PROTECTED:
|
||||
{
|
||||
gcry_sexp_t comment_sexp;
|
||||
size_t comment_length;
|
||||
char *desc_text_final;
|
||||
const char *comment = NULL;
|
||||
char *comment = NULL;
|
||||
|
||||
/* Note, that we will take the comment as a C string for
|
||||
display purposes; i.e. all stuff beyond a Nul character is
|
||||
ignored. */
|
||||
{
|
||||
gcry_sexp_t comment_sexp;
|
||||
|
||||
comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
|
||||
if (comment_sexp)
|
||||
comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
|
||||
if (!comment)
|
||||
{
|
||||
comment = "";
|
||||
comment_length = 0;
|
||||
comment = gcry_sexp_nth_string (comment_sexp, 1);
|
||||
gcry_sexp_release (comment_sexp);
|
||||
}
|
||||
|
||||
desc_text_final = NULL;
|
||||
if (desc_text)
|
||||
{
|
||||
if (comment[comment_length])
|
||||
{
|
||||
/* Not a C-string; create one. We might here allocate
|
||||
more than actually displayed but well, that
|
||||
shouldn't be a problem. */
|
||||
char *tmp = xtrymalloc (comment_length+1);
|
||||
if (!tmp)
|
||||
rc = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
memcpy (tmp, comment, comment_length);
|
||||
tmp[comment_length] = 0;
|
||||
rc = modify_description (desc_text, tmp, &desc_text_final);
|
||||
xfree (tmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
rc = modify_description (desc_text, comment, &desc_text_final);
|
||||
}
|
||||
rc = modify_description (desc_text, comment? comment:"", s_skey,
|
||||
&desc_text_final);
|
||||
gcry_free (comment);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
@ -613,7 +614,6 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
||||
gpg_strerror (rc));
|
||||
}
|
||||
|
||||
gcry_sexp_release (comment_sexp);
|
||||
xfree (desc_text_final);
|
||||
}
|
||||
break;
|
||||
@ -793,6 +793,28 @@ agent_is_dsa_key (gcry_sexp_t s_key)
|
||||
|
||||
|
||||
|
||||
/* Return the key for the keygrip GRIP. The result is stored at
|
||||
RESULT. This function extracts the key from the private key
|
||||
database and returns it as an S-expression object as it is. On
|
||||
failure an error code is returned and NULL stored at RESULT. */
|
||||
gpg_error_t
|
||||
agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip,
|
||||
gcry_sexp_t *result)
|
||||
{
|
||||
gpg_error_t err;
|
||||
gcry_sexp_t s_skey;
|
||||
|
||||
(void)ctrl;
|
||||
|
||||
*result = NULL;
|
||||
|
||||
err = read_key_file (grip, &s_skey);
|
||||
if (!err)
|
||||
*result = s_skey;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Return the public key for the keygrip GRIP. The result is stored
|
||||
at RESULT. This function extracts the public key from the private
|
||||
key database. On failure an error code is returned and NULL stored
|
||||
|
@ -27,13 +27,6 @@
|
||||
#include "util.h"
|
||||
#include "ssh-utils.h"
|
||||
|
||||
#define pass() do { ; } while(0)
|
||||
#define fail(a,e) \
|
||||
do { fprintf (stderr, "%s:%d: test %d failed (%s)\n", \
|
||||
__FILE__,__LINE__, (a), gpg_strerror (e)); \
|
||||
exit (1); \
|
||||
} while(0)
|
||||
|
||||
|
||||
static struct { const char *key; const char *fpr; } sample_keys[] = {
|
||||
{ "(protected-private-key "
|
||||
|
@ -646,6 +646,12 @@ digits, optionally followed by the caching TTL in seconds and another
|
||||
optional field for arbitrary flags. A non-zero TTL overrides the global
|
||||
default as set by @option{--default-cache-ttl-ssh}.
|
||||
|
||||
The only flag support is @code{confirm}. If this flag is found for a
|
||||
key, each use of the key will pop up a pinentry to confirm the use of
|
||||
that key. The flag is automatically set if a new key was loaded into
|
||||
@code{gpg-agent} using the option @option{-c} of the @code{ssh-add}
|
||||
command.
|
||||
|
||||
The keygrip may be prefixed with a @code{!} to disable an entry entry.
|
||||
|
||||
The following example lists exactly one key. Note that keys available
|
||||
@ -653,8 +659,9 @@ through a OpenPGP smartcard in the active smartcard reader are
|
||||
implicitly added to this list; i.e. there is no need to list them.
|
||||
|
||||
@example
|
||||
# Key added on 2005-02-25 15:08:29
|
||||
5A6592BF45DC73BD876874A28FD4639282E29B52 0
|
||||
# Key added on: 2011-07-20 20:38:46
|
||||
# Fingerprint: 5e:8d:c4:ad:e7:af:6e:27:8a:d6:13:e4:79:ad:0b:81
|
||||
34B62F25E277CF13D3C6BCEBFD3F85D08F0A864B 0 confirm
|
||||
@end example
|
||||
|
||||
@item private-keys-v1.d/
|
||||
|
Loading…
x
Reference in New Issue
Block a user