[git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-233-g50c98c7

by Werner Koch cvs at cvs.gnupg.org
Thu Aug 8 21:56:32 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, master has been updated
       via  50c98c7ed6b542857ee2f902eca36cda37407737 (commit)
      from  498b9a95dc65c43240835d64cc92d8fb43014d53 (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 50c98c7ed6b542857ee2f902eca36cda37407737
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>

diff --git a/agent/agent.h b/agent/agent.h
index 7445061..885e7fe 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -157,6 +157,10 @@ struct
 /* 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;
 
@@ -290,6 +294,16 @@ gpg_error_t pinentry_loopback(ctrl_t, const char *keyword,
 			      size_t max_length);
 
 /*-- 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 39435aa..f378ade 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.
  *
@@ -87,7 +88,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";
 
@@ -186,8 +187,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. */
@@ -200,8 +201,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.  */
@@ -730,10 +729,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)
@@ -795,7 +794,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;
@@ -804,7 +803,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;
@@ -818,7 +817,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];
@@ -921,7 +920,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;
@@ -965,7 +964,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;
@@ -1001,7 +1000,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)
@@ -1024,7 +1023,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)
@@ -1044,6 +1043,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;
+}
+
 
 

 
@@ -2185,7 +2265,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 0364868..5e955ab 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -998,13 +998,15 @@ 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> <cached> <protection> <fpr>\n"
   "\n"
@@ -1013,7 +1015,8 @@ static const char hlp_keyinfo[] =
   "TYPE is 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"
+  "    '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"
@@ -1031,13 +1034,21 @@ static const char hlp_keyinfo[] =
   "    '-' - Unknown protection.\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];
@@ -1050,24 +1061,55 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
   const char *cached;
   const char *protectionstr;
   char *pw;
+  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);
 
-  switch (keytype)
+  if (ttl > 0)
+    snprintf (ttlbuf, sizeof ttlbuf, "%d", ttl);
+  else
+    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)
     {
-    case PRIVATE_KEY_CLEAR: protectionstr = "C"; keytypestr = "D";
-      break;
-    case PRIVATE_KEY_PROTECTED: protectionstr = "P"; keytypestr = "D";
-      break;
-    case PRIVATE_KEY_SHADOWED: protectionstr = "-"; keytypestr = "T";
-      break;
-    default: protectionstr = "-"; keytypestr = "-";
-      break;
+      protectionstr = "-"; keytypestr = "-";
+    }
+  else
+    {
+      switch (keytype)
+        {
+        case PRIVATE_KEY_CLEAR: protectionstr = "C"; keytypestr = "D";
+          break;
+        case PRIVATE_KEY_PROTECTED: protectionstr = "P"; keytypestr = "D";
+          break;
+        case PRIVATE_KEY_SHADOWED: protectionstr = "-"; keytypestr = "T";
+          break;
+        default: protectionstr = "-"; keytypestr = "X";
+          break;
+        }
     }
 
   /* Compute the ssh fingerprint if requested.  */
@@ -1105,16 +1147,20 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
                               cached,
 			      protectionstr,
                               fpr? fpr : "-",
+                              ttlbuf,
+                              flagsbuf,
                               NULL);
   else
     {
       char *string;
 
-      string = xtryasprintf ("%s %s %s %s %s %s %s\n",
+      string = xtryasprintf ("%s %s %s %s %s %s %s %s %s\n",
                              hexgrip, keytypestr,
                              serialno? serialno : "-",
                              idstr? idstr : "-", cached, protectionstr,
-                             fpr? fpr : "-");
+                             fpr? fpr : "-",
+                             ttlbuf,
+                             flagsbuf);
       if (!string)
         err = gpg_error_from_syserror ();
       else
@@ -1141,18 +1187,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)
@@ -1180,7 +1252,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;
         }
@@ -1191,10 +1275,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       |   14 +++++
 agent/command-ssh.c |  110 +++++++++++++++++++++++++++++++++-----
 agent/command.c     |  147 ++++++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 231 insertions(+), 40 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list