mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-28 22:49:59 +01:00
agent: Extend cmd KEYINFO to return data from sshcontrol.
* agent/command-ssh.c (struct control_file_s): Rename to ssh_control_file_s. (ssh_open_control_file, ssh_close_control_file) (ssh_read_control_file, ssh_search_control_file): New. (control_file_t): Rename and move to ... * agent/agent.h (ssh_control_file_t): here. * agent/command.c (do_one_keyinfo): Add args is_ssh, ttl, disabled, and confirm. Rename unknown keytype indicator from '-' to 'X'. Extend output. (cmd_keyinfo): Add options --ssh-list and --with-ssh. -- This extension allows the development of frontends to manage the sshcontrol file. Signed-off-by: Werner Koch <wk@gnupg.org> (cherry picked from commit 50c98c7ed6b542857ee2f902eca36cda37407737) Conflicts in agent/command.c (due to less information printed by keyinfo) solved.
This commit is contained in:
parent
110b52fffa
commit
88914a9e24
@ -126,7 +126,14 @@ struct
|
|||||||
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
|
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
|
||||||
#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE)
|
#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE)
|
||||||
|
|
||||||
|
/* Forward reference for local definitions in command.c. */
|
||||||
struct server_local_s;
|
struct server_local_s;
|
||||||
|
|
||||||
|
/* Declaration of objects from command-ssh.c. */
|
||||||
|
struct ssh_control_file_s;
|
||||||
|
typedef struct ssh_control_file_s *ssh_control_file_t;
|
||||||
|
|
||||||
|
/* Forward reference for local definitions in call-scd.c. */
|
||||||
struct scd_local_s;
|
struct scd_local_s;
|
||||||
|
|
||||||
/* Collection of data per session (aka connection). */
|
/* Collection of data per session (aka connection). */
|
||||||
@ -226,6 +233,16 @@ int serve_mmapped_ssh_request (ctrl_t ctrl,
|
|||||||
#endif /*HAVE_W32_SYSTEM*/
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
/*-- command-ssh.c --*/
|
/*-- command-ssh.c --*/
|
||||||
|
ssh_control_file_t ssh_open_control_file (void);
|
||||||
|
void ssh_close_control_file (ssh_control_file_t cf);
|
||||||
|
gpg_error_t ssh_read_control_file (ssh_control_file_t cf,
|
||||||
|
char *r_hexgrip, int *r_disabled,
|
||||||
|
int *r_ttl, int *r_confirm);
|
||||||
|
gpg_error_t ssh_search_control_file (ssh_control_file_t cf,
|
||||||
|
const char *hexgrip,
|
||||||
|
int *r_disabled,
|
||||||
|
int *r_ttl, int *r_confirm);
|
||||||
|
|
||||||
void start_command_handler_ssh (ctrl_t, gnupg_fd_t);
|
void start_command_handler_ssh (ctrl_t, gnupg_fd_t);
|
||||||
|
|
||||||
/*-- findkey.c --*/
|
/*-- findkey.c --*/
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* command-ssh.c - gpg-agent's ssh-agent emulation layer
|
/* command-ssh.c - gpg-agent's ssh-agent emulation layer
|
||||||
* Copyright (C) 2004, 2005, 2006, 2009, 2012 Free Software Foundation, Inc.
|
* Copyright (C) 2004, 2005, 2006, 2009, 2012 Free Software Foundation, Inc.
|
||||||
|
* Copyright (C) 2013 Werner Koch
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -88,7 +89,7 @@ static const char sshcontrolblurb[] =
|
|||||||
"# the format of the entries is fixed and checked by gpg-agent. A\n"
|
"# the format of the entries is fixed and checked by gpg-agent. A\n"
|
||||||
"# non-comment line starts with optional white spaces, followed by the\n"
|
"# non-comment line starts with optional white spaces, followed by the\n"
|
||||||
"# keygrip of the key given as 40 hex digits, optionally followed by a\n"
|
"# keygrip of the key given as 40 hex digits, optionally followed by a\n"
|
||||||
"# the caching TTL in seconds and another optional field for arbitrary\n"
|
"# caching TTL in seconds, and another optional field for arbitrary\n"
|
||||||
"# flags. Prepend the keygrip with an '!' mark to disable it.\n"
|
"# flags. Prepend the keygrip with an '!' mark to disable it.\n"
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
@ -187,8 +188,8 @@ struct ssh_key_type_spec
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* An object used to access the sshcontrol file. */
|
/* Definition of an object to access the sshcontrol file. */
|
||||||
struct control_file_s
|
struct ssh_control_file_s
|
||||||
{
|
{
|
||||||
char *fname; /* Name of the file. */
|
char *fname; /* Name of the file. */
|
||||||
FILE *fp; /* This is never NULL. */
|
FILE *fp; /* This is never NULL. */
|
||||||
@ -201,8 +202,6 @@ struct control_file_s
|
|||||||
char hexgrip[40+1]; /* The hexgrip of the item (uppercase). */
|
char hexgrip[40+1]; /* The hexgrip of the item (uppercase). */
|
||||||
} item;
|
} item;
|
||||||
};
|
};
|
||||||
typedef struct control_file_s *control_file_t;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
@ -731,10 +730,10 @@ file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n)
|
|||||||
control file object stored at R_CF. On error an error code is
|
control file object stored at R_CF. On error an error code is
|
||||||
returned and NULL is stored at R_CF. */
|
returned and NULL is stored at R_CF. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
open_control_file (control_file_t *r_cf, int append)
|
open_control_file (ssh_control_file_t *r_cf, int append)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
control_file_t cf;
|
ssh_control_file_t cf;
|
||||||
|
|
||||||
cf = xtrycalloc (1, sizeof *cf);
|
cf = xtrycalloc (1, sizeof *cf);
|
||||||
if (!cf)
|
if (!cf)
|
||||||
@ -796,7 +795,7 @@ open_control_file (control_file_t *r_cf, int append)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rewind_control_file (control_file_t cf)
|
rewind_control_file (ssh_control_file_t cf)
|
||||||
{
|
{
|
||||||
fseek (cf->fp, 0, SEEK_SET);
|
fseek (cf->fp, 0, SEEK_SET);
|
||||||
cf->lnr = 0;
|
cf->lnr = 0;
|
||||||
@ -805,7 +804,7 @@ rewind_control_file (control_file_t cf)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
close_control_file (control_file_t cf)
|
close_control_file (ssh_control_file_t cf)
|
||||||
{
|
{
|
||||||
if (!cf)
|
if (!cf)
|
||||||
return;
|
return;
|
||||||
@ -819,7 +818,7 @@ close_control_file (control_file_t cf)
|
|||||||
/* Read the next line from the control file and store the data in CF.
|
/* Read the next line from the control file and store the data in CF.
|
||||||
Returns 0 on success, GPG_ERR_EOF on EOF, or other error codes. */
|
Returns 0 on success, GPG_ERR_EOF on EOF, or other error codes. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
read_control_file_item (control_file_t cf)
|
read_control_file_item (ssh_control_file_t cf)
|
||||||
{
|
{
|
||||||
int c, i, n;
|
int c, i, n;
|
||||||
char *p, *pend, line[256];
|
char *p, *pend, line[256];
|
||||||
@ -922,7 +921,7 @@ read_control_file_item (control_file_t cf)
|
|||||||
a specified TTL for that key is stored there. If R_CONFIRM is not
|
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. */
|
NULL it is set to 1 if the key has the confirm flag set. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
search_control_file (control_file_t cf, const char *hexgrip,
|
search_control_file (ssh_control_file_t cf, const char *hexgrip,
|
||||||
int *r_disabled, int *r_ttl, int *r_confirm)
|
int *r_disabled, int *r_ttl, int *r_confirm)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
@ -966,7 +965,7 @@ add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr,
|
|||||||
int ttl, int confirm)
|
int ttl, int confirm)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
control_file_t cf;
|
ssh_control_file_t cf;
|
||||||
int disabled;
|
int disabled;
|
||||||
|
|
||||||
(void)ctrl;
|
(void)ctrl;
|
||||||
@ -1002,7 +1001,7 @@ add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr,
|
|||||||
static int
|
static int
|
||||||
ttl_from_sshcontrol (const char *hexgrip)
|
ttl_from_sshcontrol (const char *hexgrip)
|
||||||
{
|
{
|
||||||
control_file_t cf;
|
ssh_control_file_t cf;
|
||||||
int disabled, ttl;
|
int disabled, ttl;
|
||||||
|
|
||||||
if (!hexgrip || strlen (hexgrip) != 40)
|
if (!hexgrip || strlen (hexgrip) != 40)
|
||||||
@ -1025,7 +1024,7 @@ ttl_from_sshcontrol (const char *hexgrip)
|
|||||||
static int
|
static int
|
||||||
confirm_flag_from_sshcontrol (const char *hexgrip)
|
confirm_flag_from_sshcontrol (const char *hexgrip)
|
||||||
{
|
{
|
||||||
control_file_t cf;
|
ssh_control_file_t cf;
|
||||||
int disabled, confirm;
|
int disabled, confirm;
|
||||||
|
|
||||||
if (!hexgrip || strlen (hexgrip) != 40)
|
if (!hexgrip || strlen (hexgrip) != 40)
|
||||||
@ -1045,6 +1044,87 @@ confirm_flag_from_sshcontrol (const char *hexgrip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Open the ssh control file for reading. This is a public version of
|
||||||
|
open_control_file. The caller must use ssh_close_control_file to
|
||||||
|
release the retruned handle. */
|
||||||
|
ssh_control_file_t
|
||||||
|
ssh_open_control_file (void)
|
||||||
|
{
|
||||||
|
ssh_control_file_t cf;
|
||||||
|
|
||||||
|
/* Then look at all the registered and non-disabled keys. */
|
||||||
|
if (open_control_file (&cf, 0))
|
||||||
|
return NULL;
|
||||||
|
return cf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close an ssh control file handle. This is the public version of
|
||||||
|
close_control_file. CF may be NULL. */
|
||||||
|
void
|
||||||
|
ssh_close_control_file (ssh_control_file_t cf)
|
||||||
|
{
|
||||||
|
close_control_file (cf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the next item from the ssh control file. The function returns
|
||||||
|
0 if a item was read, GPG_ERR_EOF on eof or another error value.
|
||||||
|
R_HEXGRIP shall either be null or a BUFFER of at least 41 byte.
|
||||||
|
R_DISABLED, R_TTLm and R_CONFIRM return flags from the control
|
||||||
|
file; they are only set on success. */
|
||||||
|
gpg_error_t
|
||||||
|
ssh_read_control_file (ssh_control_file_t cf,
|
||||||
|
char *r_hexgrip,
|
||||||
|
int *r_disabled, int *r_ttl, int *r_confirm)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
|
do
|
||||||
|
err = read_control_file_item (cf);
|
||||||
|
while (!err && !cf->item.valid);
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
if (r_hexgrip)
|
||||||
|
strcpy (r_hexgrip, cf->item.hexgrip);
|
||||||
|
if (r_disabled)
|
||||||
|
*r_disabled = cf->item.disabled;
|
||||||
|
if (r_ttl)
|
||||||
|
*r_ttl = cf->item.ttl;
|
||||||
|
if (r_confirm)
|
||||||
|
*r_confirm = cf->item.confirm;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Search for a key with HEXGRIP in sshcontrol and return all
|
||||||
|
info. */
|
||||||
|
gpg_error_t
|
||||||
|
ssh_search_control_file (ssh_control_file_t cf,
|
||||||
|
const char *hexgrip,
|
||||||
|
int *r_disabled, int *r_ttl, int *r_confirm)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
int i;
|
||||||
|
const char *s;
|
||||||
|
char uphexgrip[41];
|
||||||
|
|
||||||
|
/* We need to make sure that HEXGRIP is all uppercase. The easiest
|
||||||
|
way to do this and also check its length is by copying to a
|
||||||
|
second buffer. */
|
||||||
|
for (i=0, s=hexgrip; i < 40; s++, i++)
|
||||||
|
uphexgrip[i] = *s >= 'a'? (*s & 0xdf): *s;
|
||||||
|
uphexgrip[i] = 0;
|
||||||
|
if (i != 40)
|
||||||
|
err = gpg_error (GPG_ERR_INV_LENGTH);
|
||||||
|
else
|
||||||
|
err = search_control_file (cf, uphexgrip, r_disabled, r_ttl, r_confirm);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_EOF)
|
||||||
|
err = gpg_error (GPG_ERR_NOT_FOUND);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2187,7 +2267,7 @@ ssh_handler_request_identities (ctrl_t ctrl,
|
|||||||
gcry_sexp_t key_public;
|
gcry_sexp_t key_public;
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
int ret;
|
int ret;
|
||||||
control_file_t cf = NULL;
|
ssh_control_file_t cf = NULL;
|
||||||
char *cardsn;
|
char *cardsn;
|
||||||
gpg_error_t ret_err;
|
gpg_error_t ret_err;
|
||||||
|
|
||||||
|
153
agent/command.c
153
agent/command.c
@ -1,6 +1,7 @@
|
|||||||
/* command.c - gpg-agent command handler
|
/* command.c - gpg-agent command handler
|
||||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
|
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
|
||||||
* 2006, 2008, 2009 Free Software Foundation, Inc.
|
* 2006, 2008, 2009 Free Software Foundation, Inc.
|
||||||
|
* Copyright (C) 2013 Werner Koch
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -833,22 +834,25 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
static const char hlp_keyinfo[] =
|
static const char hlp_keyinfo[] =
|
||||||
"KEYINFO [--list] [--data] [--ssh-fpr] <keygrip>\n"
|
"KEYINFO [--[ssh-]list] [--data] [--ssh-fpr] [--with-ssh] <keygrip>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Return information about the key specified by the KEYGRIP. If the\n"
|
"Return information about the key specified by the KEYGRIP. If the\n"
|
||||||
"key is not available GPG_ERR_NOT_FOUND is returned. If the option\n"
|
"key is not available GPG_ERR_NOT_FOUND is returned. If the option\n"
|
||||||
"--list is given the keygrip is ignored and information about all\n"
|
"--list is given the keygrip is ignored and information about all\n"
|
||||||
"available keys are returned. The information is returned as a\n"
|
"available keys are returned. If --ssh-list is given information\n"
|
||||||
"status line unless --data was specified, with this format:\n"
|
"about all keys listed in the sshcontrol are returned. With --with-ssh\n"
|
||||||
|
"information from sshcontrol is always added to the info. Unless --data\n"
|
||||||
|
"is given, the information is returned as a status line using the format:\n"
|
||||||
"\n"
|
"\n"
|
||||||
" KEYINFO <keygrip> <type> <serialno> <idstr> - - <fpr>\n"
|
" KEYINFO <keygrip> <type> <serialno> <idstr> - - <fpr> <ttl> <flags>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"KEYGRIP is the keygrip.\n"
|
"KEYGRIP is the keygrip.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"TYPE is describes the type of the key:\n"
|
"TYPE describes the type of the key:\n"
|
||||||
" 'D' - Regular key stored on disk,\n"
|
" 'D' - Regular key stored on disk,\n"
|
||||||
" 'T' - Key is stored on a smartcard (token).\n"
|
" 'T' - Key is stored on a smartcard (token),\n"
|
||||||
" '-' - Unknown type.\n"
|
" 'X' - Unknown type,\n"
|
||||||
|
" '-' - Key is missing.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"SERIALNO is an ASCII string with the serial number of the\n"
|
"SERIALNO is an ASCII string with the serial number of the\n"
|
||||||
" smartcard. If the serial number is not known a single\n"
|
" smartcard. If the serial number is not known a single\n"
|
||||||
@ -858,13 +862,21 @@ static const char hlp_keyinfo[] =
|
|||||||
" is not known a dash is used instead.\n"
|
" is not known a dash is used instead.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"FPR returns the formatted ssh-style fingerprint of the key. It is only\n"
|
"FPR returns the formatted ssh-style fingerprint of the key. It is only\n"
|
||||||
" print if the option --ssh-fpr has been used. '-' is printed if the\n"
|
" printed if the option --ssh-fpr has been used. It defaults to '-'.\n"
|
||||||
" fingerprint is not available.\n"
|
"\n"
|
||||||
|
"TTL is the TTL in seconds for that key or '-' if n/a.\n"
|
||||||
|
"\n"
|
||||||
|
"FLAGS is a word consisting of one-letter flags:\n"
|
||||||
|
" 'D' - The key has been disabled,\n"
|
||||||
|
" 'S' - The key is listed in sshcontrol (requires --with-ssh),\n"
|
||||||
|
" 'c' - Use of the key needs to be confirmed,\n"
|
||||||
|
" '-' - No flags given.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"More information may be added in the future.";
|
"More information may be added in the future.";
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
|
do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
|
||||||
int data, int with_ssh_fpr)
|
int data, int with_ssh_fpr, int in_ssh,
|
||||||
|
int ttl, int disabled, int confirm)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
char hexgrip[40+1];
|
char hexgrip[40+1];
|
||||||
@ -874,21 +886,56 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
|
|||||||
char *serialno = NULL;
|
char *serialno = NULL;
|
||||||
char *idstr = NULL;
|
char *idstr = NULL;
|
||||||
const char *keytypestr;
|
const char *keytypestr;
|
||||||
|
int missing_key = 0;
|
||||||
|
char ttlbuf[20];
|
||||||
|
char flagsbuf[5];
|
||||||
|
|
||||||
err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
|
err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
{
|
||||||
|
if (in_ssh && gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||||
|
missing_key = 1;
|
||||||
|
else
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reformat the grip so that we use uppercase as good style. */
|
/* Reformat the grip so that we use uppercase as good style. */
|
||||||
bin2hex (grip, 20, hexgrip);
|
bin2hex (grip, 20, hexgrip);
|
||||||
|
|
||||||
if (keytype == PRIVATE_KEY_CLEAR
|
if (ttl > 0)
|
||||||
|| keytype == PRIVATE_KEY_PROTECTED)
|
snprintf (ttlbuf, sizeof ttlbuf, "%d", ttl);
|
||||||
keytypestr = "D";
|
|
||||||
else if (keytype == PRIVATE_KEY_SHADOWED)
|
|
||||||
keytypestr = "T";
|
|
||||||
else
|
else
|
||||||
keytypestr = "-";
|
strcpy (ttlbuf, "-");
|
||||||
|
|
||||||
|
*flagsbuf = 0;
|
||||||
|
if (disabled)
|
||||||
|
strcat (flagsbuf, "D");
|
||||||
|
if (in_ssh)
|
||||||
|
strcat (flagsbuf, "S");
|
||||||
|
if (confirm)
|
||||||
|
strcat (flagsbuf, "c");
|
||||||
|
if (!*flagsbuf)
|
||||||
|
strcpy (flagsbuf, "-");
|
||||||
|
|
||||||
|
|
||||||
|
if (missing_key)
|
||||||
|
{
|
||||||
|
keytypestr = "-";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (keytype)
|
||||||
|
{
|
||||||
|
case PRIVATE_KEY_CLEAR: keytypestr = "D";
|
||||||
|
break;
|
||||||
|
case PRIVATE_KEY_PROTECTED: keytypestr = "D";
|
||||||
|
break;
|
||||||
|
case PRIVATE_KEY_SHADOWED: keytypestr = "T";
|
||||||
|
break;
|
||||||
|
default: keytypestr = "X";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute the ssh fingerprint if requested. */
|
/* Compute the ssh fingerprint if requested. */
|
||||||
if (with_ssh_fpr)
|
if (with_ssh_fpr)
|
||||||
@ -921,16 +968,21 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
|
|||||||
"-",
|
"-",
|
||||||
"-",
|
"-",
|
||||||
fpr? fpr : "-",
|
fpr? fpr : "-",
|
||||||
|
ttlbuf,
|
||||||
|
flagsbuf,
|
||||||
NULL);
|
NULL);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *string;
|
char *string;
|
||||||
|
|
||||||
string = xtryasprintf ("%s %s %s %s - - %s\n",
|
string = xtryasprintf ("%s %s %s %s - - %s %s %s\n",
|
||||||
hexgrip, keytypestr,
|
hexgrip, keytypestr,
|
||||||
serialno? serialno : "-",
|
serialno? serialno : "-",
|
||||||
idstr? idstr : "-",
|
idstr? idstr : "-",
|
||||||
fpr? fpr : "-");
|
fpr? fpr : "-",
|
||||||
|
ttlbuf,
|
||||||
|
flagsbuf);
|
||||||
|
|
||||||
if (!string)
|
if (!string)
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
else
|
else
|
||||||
@ -955,18 +1007,44 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
|
|||||||
unsigned char grip[20];
|
unsigned char grip[20];
|
||||||
DIR *dir = NULL;
|
DIR *dir = NULL;
|
||||||
int list_mode;
|
int list_mode;
|
||||||
int opt_data, opt_ssh_fpr;
|
int opt_data, opt_ssh_fpr, opt_with_ssh;
|
||||||
|
ssh_control_file_t cf = NULL;
|
||||||
|
char hexgrip[41];
|
||||||
|
int disabled, ttl, confirm, is_ssh;
|
||||||
|
|
||||||
list_mode = has_option (line, "--list");
|
if (has_option (line, "--ssh-list"))
|
||||||
|
list_mode = 2;
|
||||||
|
else
|
||||||
|
list_mode = has_option (line, "--list");
|
||||||
opt_data = has_option (line, "--data");
|
opt_data = has_option (line, "--data");
|
||||||
opt_ssh_fpr = has_option (line, "--ssh-fpr");
|
opt_ssh_fpr = has_option (line, "--ssh-fpr");
|
||||||
|
opt_with_ssh = has_option (line, "--with-ssh");
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
|
|
||||||
if (list_mode)
|
if (opt_with_ssh || list_mode == 2)
|
||||||
|
cf = ssh_open_control_file ();
|
||||||
|
|
||||||
|
if (list_mode == 2)
|
||||||
|
{
|
||||||
|
if (cf)
|
||||||
|
{
|
||||||
|
while (!ssh_read_control_file (cf, hexgrip,
|
||||||
|
&disabled, &ttl, &confirm))
|
||||||
|
{
|
||||||
|
if (hex2bin (hexgrip, grip, 20) < 0 )
|
||||||
|
continue; /* Bad hex string. */
|
||||||
|
err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, 1,
|
||||||
|
ttl, disabled, confirm);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
else if (list_mode)
|
||||||
{
|
{
|
||||||
char *dirname;
|
char *dirname;
|
||||||
struct dirent *dir_entry;
|
struct dirent *dir_entry;
|
||||||
char hexgrip[41];
|
|
||||||
|
|
||||||
dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
|
dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
|
||||||
if (!dirname)
|
if (!dirname)
|
||||||
@ -994,7 +1072,19 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
|
|||||||
if ( hex2bin (hexgrip, grip, 20) < 0 )
|
if ( hex2bin (hexgrip, grip, 20) < 0 )
|
||||||
continue; /* Bad hex string. */
|
continue; /* Bad hex string. */
|
||||||
|
|
||||||
err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr);
|
disabled = ttl = confirm = is_ssh = 0;
|
||||||
|
if (opt_with_ssh)
|
||||||
|
{
|
||||||
|
err = ssh_search_control_file (cf, hexgrip,
|
||||||
|
&disabled, &ttl, &confirm);
|
||||||
|
if (!err)
|
||||||
|
is_ssh = 1;
|
||||||
|
else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, is_ssh,
|
||||||
|
ttl, disabled, confirm);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -1005,10 +1095,23 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
|
|||||||
err = parse_keygrip (ctx, line, grip);
|
err = parse_keygrip (ctx, line, grip);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr);
|
disabled = ttl = confirm = is_ssh = 0;
|
||||||
|
if (opt_with_ssh)
|
||||||
|
{
|
||||||
|
err = ssh_search_control_file (cf, line,
|
||||||
|
&disabled, &ttl, &confirm);
|
||||||
|
if (!err)
|
||||||
|
is_ssh = 1;
|
||||||
|
else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, is_ssh,
|
||||||
|
ttl, disabled, confirm);
|
||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
ssh_close_control_file (cf);
|
||||||
if (dir)
|
if (dir)
|
||||||
closedir (dir);
|
closedir (dir);
|
||||||
if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
|
if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user