[git] GPGME - branch, master, updated. gpgme-1.6.0-306-g9ee1039

by Werner Koch cvs at cvs.gnupg.org
Thu Aug 25 11:41:33 CEST 2016


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 "GnuPG Made Easy".

The branch, master has been updated
       via  9ee103957e4136337b92d238283f8ef30fd4a7c5 (commit)
      from  38798fee5b539d6153a8a7856152959412ee59b5 (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 9ee103957e4136337b92d238283f8ef30fd4a7c5
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Aug 25 11:38:03 2016 +0200

    core: Add GPGME_KEYLIST_MODE_WITH_TOFU.
    
    * src/gpgme.h.in (GPGME_KEYLIST_MODE_WITH_TOFU): New.
    * src/engine-gpg.c (gpg_keylist_build_options): Use that.
    * src/keylist.c: Include limits.h.
    (parse_tfs_record): New.
    (keylist_colon_handler): Support TFS record.
    * tests/run-keylist.c: Include time.h.
    (isotimestr): New.
    (main): Add option --tofu.  Print TOFU info.
    * tests/run-verify.c: Include time.h.
    (isotimestr): New.
    (print_result): Use isotimestr for TOFU dates.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index 1294e0b..da331b4 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,7 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_]
  GPGME_STATUS_TOFU_STATS        NEW.
  GPGME_STATUS_TOFU_STATS_LONG   NEW.
  GPGME_STATUS_NOTATION_FLAGS    NEW.
+ GPGME_KEYLIST_MODE_WITH_TOFU   NEW.
  GPGME_DATA_TYPE_PGP_ENCRYPTED  NEW.
  GPGME_DATA_TYPE_PGP_SIGNATURE  NEW.
  GPGME_DATA_ENCODING_MIME       NEW.
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 02551d9..dfc9548 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -2683,6 +2683,11 @@ signature notations on key signatures should be included in the listed
 keys.  This only works if @code{GPGME_KEYLIST_MODE_SIGS} is also
 enabled.
 
+ at item GPGME_KEYLIST_MODE_WITH_TOFU
+The @code{GPGME_KEYLIST_MODE_WITH_TOFU} symbol specifies that
+information pertaining to the TOFU trust model should be included in
+the listed keys.
+
 @item GPGME_KEYLIST_MODE_WITH_SECRET
 The @code{GPGME_KEYLIST_MODE_WITH_SECRET} returns information about
 the presence of a corresponding secret key in a public key listing.  A
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 3edac6c..7036ee0 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -2338,8 +2338,13 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
         err = add_arg (gpg, "--with-fingerprint");
     }
 
+  if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU)
+      && have_gpg_version (gpg, "2.1.16"))
+    err = add_arg (gpg, "--with-tofu-info");
+
   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
     err = add_arg (gpg, "--with-secret");
+
   if (!err
       && (mode & GPGME_KEYLIST_MODE_SIGS)
       && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
@@ -2348,6 +2353,7 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
       if (!err)
 	err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
     }
+
   if (!err)
     {
       if ( (mode & GPGME_KEYLIST_MODE_EXTERN) )
@@ -2379,6 +2385,7 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
                             ? "--check-sigs" : "--list-keys"));
         }
     }
+
   if (!err)
     err = add_arg (gpg, "--");
 
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 79a7b9f..57f3446 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -411,6 +411,7 @@ gpgme_protocol_t;
 #define GPGME_KEYLIST_MODE_SIGS			4
 #define GPGME_KEYLIST_MODE_SIG_NOTATIONS	8
 #define GPGME_KEYLIST_MODE_WITH_SECRET       	16
+#define GPGME_KEYLIST_MODE_WITH_TOFU       	32
 #define GPGME_KEYLIST_MODE_EPHEMERAL            128
 #define GPGME_KEYLIST_MODE_VALIDATE		256
 
@@ -843,7 +844,7 @@ struct _gpgme_user_id
    * NULL is stored.  */
   char *address;
 
-  /* The malloced tofo information or NULL.  */
+  /* The malloced TOFU information or NULL.  */
   gpgme_tofu_info_t tofu;
 };
 typedef struct _gpgme_user_id *gpgme_user_id_t;
diff --git a/src/keylist.c b/src/keylist.c
index 38ddd0c..9f1e68d 100644
--- a/src/keylist.c
+++ b/src/keylist.c
@@ -33,6 +33,7 @@
 #include <assert.h>
 #include <ctype.h>
 #include <errno.h>
+#include <limits.h>
 
 /* Suppress warning for accessing deprecated member "class".  */
 #define _GPGME_IN_GPGME
@@ -403,6 +404,84 @@ parse_sec_field15 (gpgme_key_t key, gpgme_subkey_t subkey, char *field)
 }
 
 
+/* Parse a tfs record.  */
+static gpg_error_t
+parse_tfs_record (gpgme_user_id_t uid, char **field, int nfield)
+{
+  gpg_error_t err;
+  gpgme_tofu_info_t ti;
+  unsigned long uval;
+
+  /* We add only the first TOFU record in case future versions emit
+   * several.  */
+  if (uid->tofu)
+    return 0;
+
+  /* Check that we have enough fields and that the version is supported.  */
+  if (nfield < 8 || atoi(field[1]) != 1)
+    return trace_gpg_error (GPG_ERR_INV_ENGINE);
+
+  ti = calloc (1, sizeof *ti);
+  if (!ti)
+    return gpg_error_from_syserror ();
+
+  /* Note that we allow a value of up to 7 which is what we can store
+   * in the ti->validity.  */
+  err = _gpgme_strtoul_field (field[2], &uval);
+  if (err || uval > 7)
+    goto inv_engine;
+  ti->validity = uval;
+
+  /* Parse the sign-count.  */
+  err = _gpgme_strtoul_field (field[3], &uval);
+  if (err)
+    goto inv_engine;
+  if (uval > USHRT_MAX)
+    uval = USHRT_MAX;
+  ti->signcount = uval;
+
+  /* Parse the encr-count.  */
+  err = _gpgme_strtoul_field (field[4], &uval);
+  if (err)
+    goto inv_engine;
+  if (uval > USHRT_MAX)
+    uval = USHRT_MAX;
+  ti->encrcount = uval;
+
+  /* Parse the policy.  */
+  if (!strcmp (field[5], "none"))
+    ti->policy = GPGME_TOFU_POLICY_NONE;
+  else if (!strcmp (field[5], "auto"))
+    ti->policy = GPGME_TOFU_POLICY_AUTO;
+  else if (!strcmp (field[5], "good"))
+    ti->policy = GPGME_TOFU_POLICY_GOOD;
+  else if (!strcmp (field[5], "bad"))
+    ti->policy = GPGME_TOFU_POLICY_BAD;
+  else if (!strcmp (field[5], "ask"))
+    ti->policy = GPGME_TOFU_POLICY_ASK;
+  else /* "unknown" and invalid policy strings.  */
+    ti->policy = GPGME_TOFU_POLICY_UNKNOWN;
+
+  /* Parse first and last seen timestamps.  */
+  err = _gpgme_strtoul_field (field[6], &uval);
+  if (err)
+    goto inv_engine;
+  ti->firstseen = uval;
+  err = _gpgme_strtoul_field (field[7], &uval);
+  if (err)
+    goto inv_engine;
+  ti->lastseen = uval;
+
+  /* Ready.  */
+  uid->tofu = ti;
+  return 0;
+
+ inv_engine:
+  free (ti);
+  return trace_gpg_error (GPG_ERR_INV_ENGINE);
+}
+
+
 /* We have read an entire key into tmp_key and should now finish it.
    It is assumed that this releases tmp_key.  */
 static void
@@ -426,7 +505,7 @@ keylist_colon_handler (void *priv, char *line)
   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
   enum
     {
-      RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR, RT_GRP,
+      RT_NONE, RT_SIG, RT_UID, RT_TFS, RT_SUB, RT_PUB, RT_FPR, RT_GRP,
       RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
     }
   rectype = RT_NONE;
@@ -483,6 +562,8 @@ keylist_colon_handler (void *priv, char *line)
     rectype = RT_GRP;
   else if (!strcmp (field[0], "uid") && key)
     rectype = RT_UID;
+  else if (!strcmp (field[0], "tfs") && key)
+    rectype = RT_TFS;
   else if (!strcmp (field[0], "sub") && key)
     rectype = RT_SUB;
   else if (!strcmp (field[0], "ssb") && key)
@@ -492,10 +573,10 @@ keylist_colon_handler (void *priv, char *line)
   else
     rectype = RT_NONE;
 
-  /* Only look at signatures immediately following a user ID.  For
-     this, clear the user ID pointer when encountering anything but a
-     signature.  */
-  if (rectype != RT_SIG && rectype != RT_REV)
+  /* Only look at signature and trust info records immediately
+     following a user ID.  For this, clear the user ID pointer when
+     encountering anything but a signature or trust record.  */
+  if (rectype != RT_SIG && rectype != RT_REV && rectype != RT_TFS)
     opd->tmp_uid = NULL;
 
   /* Only look at subpackets immediately following a signature.  For
@@ -695,6 +776,15 @@ keylist_colon_handler (void *priv, char *line)
 	}
       break;
 
+    case RT_TFS:
+      if (opd->tmp_uid)
+	{
+          err = parse_tfs_record (opd->tmp_uid, field, fields);
+          if (err)
+            return err;
+        }
+      break;
+
     case RT_FPR:
       /* Field 10 has the fingerprint (take only the first one).  */
       if (fields >= 10 && field[9] && *field[9])
diff --git a/tests/run-keylist.c b/tests/run-keylist.c
index bae2dbb..00f874d 100644
--- a/tests/run-keylist.c
+++ b/tests/run-keylist.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <time.h>
 
 #include <gpgme.h>
 
@@ -49,6 +50,7 @@ show_usage (int ex)
          "  --local          use GPGME_KEYLIST_MODE_LOCAL\n"
          "  --extern         use GPGME_KEYLIST_MODE_EXTERN\n"
          "  --sigs           use GPGME_KEYLIST_MODE_SIGS\n"
+         "  --tofu           use GPGME_KEYLIST_MODE_TOFU\n"
          "  --sig-notations  use GPGME_KEYLIST_MODE_SIG_NOTATIONS\n"
          "  --ephemeral      use GPGME_KEYLIST_MODE_EPHEMERAL\n"
          "  --validate       use GPGME_KEYLIST_MODE_VALIDATE\n"
@@ -60,6 +62,26 @@ show_usage (int ex)
 }
 
 
+static const char *
+isotimestr (unsigned long value)
+{
+  time_t t;
+  static char buffer[25+5];
+  struct tm *tp;
+
+  if (!value)
+    return "none";
+  t = value;
+
+  tp = gmtime (&t);
+  snprintf (buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d",
+            1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+            tp->tm_hour, tp->tm_min, tp->tm_sec);
+  return buffer;
+}
+
+
+
 int
 main (int argc, char **argv)
 {
@@ -120,6 +142,11 @@ main (int argc, char **argv)
           mode |= GPGME_KEYLIST_MODE_EXTERN;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--tofu"))
+        {
+          mode |= GPGME_KEYLIST_MODE_WITH_TOFU;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--sigs"))
         {
           mode |= GPGME_KEYLIST_MODE_SIGS;
@@ -181,6 +208,7 @@ main (int argc, char **argv)
   while (!(err = gpgme_op_keylist_next (ctx, &key)))
     {
       gpgme_user_id_t uid;
+      gpgme_tofu_info_t ti;
       int nuids;
       int nsub;
 
@@ -233,24 +261,42 @@ main (int argc, char **argv)
       for (nuids=0, uid=key->uids; uid; uid = uid->next, nuids++)
         {
           printf ("userid %d: %s\n", nuids, nonnull(uid->uid));
-          printf ("  mbox %d: %s\n", nuids, nonnull(uid->address));
+          printf ("    mbox: %s\n", nonnull(uid->address));
           if (uid->email && uid->email != uid->address)
-            printf (" email %d: %s\n", nuids, uid->email);
+            printf ("   email: %s\n", uid->email);
           if (uid->name)
-            printf ("  name %d: %s\n", nuids, uid->name);
+            printf ("    name: %s\n", uid->name);
           if (uid->comment)
-            printf (" cmmnt %d: %s\n", nuids, uid->comment);
-          printf (" valid %d: %s\n", nuids,
+            printf ("   cmmnt: %s\n", uid->comment);
+          printf ("   valid: %s\n",
                   uid->validity == GPGME_VALIDITY_UNKNOWN? "unknown":
                   uid->validity == GPGME_VALIDITY_UNDEFINED? "undefined":
                   uid->validity == GPGME_VALIDITY_NEVER? "never":
                   uid->validity == GPGME_VALIDITY_MARGINAL? "marginal":
                   uid->validity == GPGME_VALIDITY_FULL? "full":
                   uid->validity == GPGME_VALIDITY_ULTIMATE? "ultimate": "[?]");
+          if ((ti = uid->tofu))
+            {
+              printf ("    tofu: %u (%s)\n", ti->validity,
+                      ti->validity == 0? "conflict" :
+                      ti->validity == 1? "no history" :
+                      ti->validity == 2? "little history" :
+                      ti->validity == 3? "enough history" :
+                      ti->validity == 4? "lot of history" : "?");
+              printf ("  policy: %u (%s)\n", ti->policy,
+                      ti->policy == GPGME_TOFU_POLICY_NONE? "none" :
+                      ti->policy == GPGME_TOFU_POLICY_AUTO? "auto" :
+                      ti->policy == GPGME_TOFU_POLICY_GOOD? "good" :
+                      ti->policy == GPGME_TOFU_POLICY_UNKNOWN? "unknown" :
+                      ti->policy == GPGME_TOFU_POLICY_BAD? "bad" :
+                      ti->policy == GPGME_TOFU_POLICY_ASK? "ask" : "?");
+              printf ("   nsigs: %hu\n", ti->signcount);
+              printf ("   nencr: %hu\n", ti->encrcount);
+              printf ("   first: %s\n", isotimestr (ti->firstseen));
+              printf ("    last: %s\n", isotimestr (ti->lastseen));
+            }
         }
 
-
-
       putchar ('\n');
 
       if (import)
diff --git a/tests/run-verify.c b/tests/run-verify.c
index ef4dd32..3c18d3b 100644
--- a/tests/run-verify.c
+++ b/tests/run-verify.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <time.h>
 
 #include <gpgme.h>
 
@@ -36,6 +37,26 @@
 
 static int verbose;
 
+
+static const char *
+isotimestr (unsigned long value)
+{
+  time_t t;
+  static char buffer[25+5];
+  struct tm *tp;
+
+  if (!value)
+    return "none";
+  t = value;
+
+  tp = gmtime (&t);
+  snprintf (buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d",
+            1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+            tp->tm_hour, tp->tm_min, tp->tm_sec);
+  return buffer;
+}
+
+
 static gpg_error_t
 status_cb (void *opaque, const char *keyword, const char *value)
 {
@@ -177,8 +198,8 @@ print_result (gpgme_verify_result_t result)
                       ti->policy == GPGME_TOFU_POLICY_BAD? "bad" :
                       ti->policy == GPGME_TOFU_POLICY_ASK? "ask" : "?");
               printf ("    sigcount : %hu\n", ti->signcount);
-              printf ("    firstseen: %u\n", ti->firstseen);
-              printf ("    lastseen : %u\n", ti->lastseen);
+              printf ("    firstseen: %s\n", isotimestr (ti->firstseen));
+              printf ("    lastseen : %s\n", isotimestr (ti->lastseen));
               printf ("    desc ....: ");
               print_description (nonnull (ti->description), 15);
             }

-----------------------------------------------------------------------

Summary of changes:
 NEWS                |   1 +
 doc/gpgme.texi      |   5 +++
 src/engine-gpg.c    |   7 ++++
 src/gpgme.h.in      |   3 +-
 src/keylist.c       | 100 +++++++++++++++++++++++++++++++++++++++++++++++++---
 tests/run-keylist.c |  60 +++++++++++++++++++++++++++----
 tests/run-verify.c  |  25 +++++++++++--
 7 files changed, 186 insertions(+), 15 deletions(-)


hooks/post-receive
-- 
GnuPG Made Easy
http://git.gnupg.org




More information about the Gnupg-commits mailing list