[git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.20-27-g88914a9
by Werner Koch
cvs at cvs.gnupg.org
Thu Aug 8 22:23:22 CEST 2013
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".
The branch, STABLE-BRANCH-2-0 has been updated
via 88914a9e24a8a116508d5b7d52b76b947e4d21a6 (commit)
from 110b52fffa77b339e6d59eba939408f7e87e7138 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 88914a9e24a8a116508d5b7d52b76b947e4d21a6
Author: Werner Koch <wk at gnupg.org>
Date: Thu Aug 8 21:22:38 2013 +0200
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 at gnupg.org>
(cherry picked from commit 50c98c7ed6b542857ee2f902eca36cda37407737)
Conflicts in agent/command.c (due to less information printed by
keyinfo) solved.
diff --git a/agent/agent.h b/agent/agent.h
index 4afe6e9..938a9aa 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -126,7 +126,14 @@ struct
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE)
+/* Forward reference for local definitions in command.c. */
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;
/* Collection of data per session (aka connection). */
@@ -226,6 +233,16 @@ int serve_mmapped_ssh_request (ctrl_t ctrl,
#endif /*HAVE_W32_SYSTEM*/
/*-- 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);
/*-- findkey.c --*/
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 6533730..a767697 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -1,5 +1,6 @@
/* command-ssh.c - gpg-agent's ssh-agent emulation layer
* Copyright (C) 2004, 2005, 2006, 2009, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2013 Werner Koch
*
* 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"
"# 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"
-"# 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"
"\n";
@@ -187,8 +188,8 @@ struct ssh_key_type_spec
};
-/* An object used to access the sshcontrol file. */
-struct control_file_s
+/* Definition of an object to access the sshcontrol file. */
+struct ssh_control_file_s
{
char *fname; /* Name of the file. */
FILE *fp; /* This is never NULL. */
@@ -201,8 +202,6 @@ struct control_file_s
char hexgrip[40+1]; /* The hexgrip of the item (uppercase). */
} item;
};
-typedef struct control_file_s *control_file_t;
-
/* 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
returned and NULL is stored at R_CF. */
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;
- control_file_t cf;
+ ssh_control_file_t cf;
cf = xtrycalloc (1, sizeof *cf);
if (!cf)
@@ -796,7 +795,7 @@ open_control_file (control_file_t *r_cf, int append)
static void
-rewind_control_file (control_file_t cf)
+rewind_control_file (ssh_control_file_t cf)
{
fseek (cf->fp, 0, SEEK_SET);
cf->lnr = 0;
@@ -805,7 +804,7 @@ rewind_control_file (control_file_t cf)
static void
-close_control_file (control_file_t cf)
+close_control_file (ssh_control_file_t cf)
{
if (!cf)
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.
Returns 0 on success, GPG_ERR_EOF on EOF, or other error codes. */
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;
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
NULL it is set to 1 if the key has the confirm flag set. */
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)
{
gpg_error_t err;
@@ -966,7 +965,7 @@ add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr,
int ttl, int confirm)
{
gpg_error_t err;
- control_file_t cf;
+ ssh_control_file_t cf;
int disabled;
(void)ctrl;
@@ -1002,7 +1001,7 @@ add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr,
static int
ttl_from_sshcontrol (const char *hexgrip)
{
- control_file_t cf;
+ ssh_control_file_t cf;
int disabled, ttl;
if (!hexgrip || strlen (hexgrip) != 40)
@@ -1025,7 +1024,7 @@ ttl_from_sshcontrol (const char *hexgrip)
static int
confirm_flag_from_sshcontrol (const char *hexgrip)
{
- control_file_t cf;
+ ssh_control_file_t cf;
int disabled, confirm;
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;
gpg_error_t err;
int ret;
- control_file_t cf = NULL;
+ ssh_control_file_t cf = NULL;
char *cardsn;
gpg_error_t ret_err;
diff --git a/agent/command.c b/agent/command.c
index 97cf507..2405c54 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -1,6 +1,7 @@
/* command.c - gpg-agent command handler
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
* 2006, 2008, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2013 Werner Koch
*
* This file is part of GnuPG.
*
@@ -833,22 +834,25 @@ cmd_readkey (assuan_context_t ctx, char *line)
static const char hlp_keyinfo[] =
- "KEYINFO [--list] [--data] [--ssh-fpr] <keygrip>\n"
+ "KEYINFO [--[ssh-]list] [--data] [--ssh-fpr] [--with-ssh] <keygrip>\n"
"\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"
"--list is given the keygrip is ignored and information about all\n"
- "available keys are returned. The information is returned as a\n"
- "status line unless --data was specified, with this format:\n"
+ "available keys are returned. If --ssh-list is given information\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"
- " KEYINFO <keygrip> <type> <serialno> <idstr> - - <fpr>\n"
+ " KEYINFO <keygrip> <type> <serialno> <idstr> - - <fpr> <ttl> <flags>\n"
"\n"
"KEYGRIP is the keygrip.\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"
- " 'T' - Key is stored on a smartcard (token).\n"
- " '-' - Unknown type.\n"
+ " 'T' - Key is stored on a smartcard (token),\n"
+ " 'X' - Unknown type,\n"
+ " '-' - Key is missing.\n"
"\n"
"SERIALNO is an ASCII string with the serial number of the\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"
"\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"
- " fingerprint is not available.\n"
+ " printed if the option --ssh-fpr has been used. It defaults to '-'.\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"
"More information may be added in the future.";
static gpg_error_t
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;
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 *idstr = NULL;
const char *keytypestr;
+ int missing_key = 0;
+ char ttlbuf[20];
+ char flagsbuf[5];
err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
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. */
bin2hex (grip, 20, hexgrip);
- if (keytype == PRIVATE_KEY_CLEAR
- || keytype == PRIVATE_KEY_PROTECTED)
- keytypestr = "D";
- else if (keytype == PRIVATE_KEY_SHADOWED)
- keytypestr = "T";
+ if (ttl > 0)
+ snprintf (ttlbuf, sizeof ttlbuf, "%d", ttl);
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. */
if (with_ssh_fpr)
@@ -921,16 +968,21 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
"-",
"-",
fpr? fpr : "-",
+ ttlbuf,
+ flagsbuf,
NULL);
else
{
char *string;
- string = xtryasprintf ("%s %s %s %s - - %s\n",
+ string = xtryasprintf ("%s %s %s %s - - %s %s %s\n",
hexgrip, keytypestr,
serialno? serialno : "-",
idstr? idstr : "-",
- fpr? fpr : "-");
+ fpr? fpr : "-",
+ ttlbuf,
+ flagsbuf);
+
if (!string)
err = gpg_error_from_syserror ();
else
@@ -955,18 +1007,44 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
unsigned char grip[20];
DIR *dir = NULL;
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_ssh_fpr = has_option (line, "--ssh-fpr");
+ opt_with_ssh = has_option (line, "--with-ssh");
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;
struct dirent *dir_entry;
- char hexgrip[41];
dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
if (!dirname)
@@ -994,7 +1072,19 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
if ( hex2bin (hexgrip, grip, 20) < 0 )
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)
goto leave;
}
@@ -1005,10 +1095,23 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
err = parse_keygrip (ctx, line, grip);
if (err)
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:
+ ssh_close_control_file (cf);
if (dir)
closedir (dir);
if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
-----------------------------------------------------------------------
Summary of changes:
agent/agent.h | 17 ++++++
agent/command-ssh.c | 110 +++++++++++++++++++++++++++++++-----
agent/command.c | 153 ++++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 240 insertions(+), 40 deletions(-)
hooks/post-receive
--
The GNU Privacy Guard
http://git.gnupg.org
More information about the Gnupg-commits
mailing list