[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