core: Add trust-model flag
authorAndre Heinecke <aheinecke@intevation.de>
Wed, 12 Sep 2018 07:42:09 +0000 (09:42 +0200)
committerAndre Heinecke <aheinecke@intevation.de>
Tue, 9 Oct 2018 08:48:58 +0000 (10:48 +0200)
* src/context.h (gpgme_context): Extend with trust_model.
* src/engine-gpg.c (engine_gpg): Extend with trust_model.
(gpg_set_engine_flags): Take trust_model from context.
(build_argv): Handle trust_model.
(gpg_release): Free trust_model.
* src/gpgme.c (gpgme_set_ctx_flag): Handle trust-model flag.
(gpgme_release): Release trust-model.
* doc/gpgme.texi: Document new flag for gpgme_set_ctx_flag.
(Context Flags): New subsection for the context flags.
* tests/run-keylist.c (show_usage, main): Add new --trust-model
parameter.

--
This gives a GPGME user fine grained control over the
trust-model.

Changing the trust model for only a single application depends
on:
GnuPG-Bug-Id: T4134
Maniphest Tasks: T4134
Differential Revision: https://dev.gnupg.org/D466

doc/gpgme.texi
src/context.h
src/engine-gpg.c
src/gpgme.c
tests/run-keylist.c

index d99e9bb..fc4840e 100644 (file)
@@ -2444,6 +2444,7 @@ started.  In fact, these references are accessed through the
 * Passphrase Callback::           Getting the passphrase from the user.
 * Progress Meter Callback::       Being informed about the progress.
 * Status Message Callback::       Status messages received from gpg.
+* Context Flags::                 Additional flags for a context.
 * Locale::                        Setting the locale of a context.
 * Additional Logs::               Additional logs of a context.
 @end menu
@@ -3030,6 +3031,10 @@ or @var{ctx} is not a valid pointer, @code{NULL} is returned in both
 variables.
 @end deftypefun
 
+@node Context Flags
+@subsection Context Flags
+@cindex flags, of a context
+
 @deftypefun {gpgme_error_t} gpgme_set_ctx_flag  @
             (@w{gpgme_ctx_t @var{ctx}}, @
             @w{const char *@var{name}}, @
@@ -3131,6 +3136,20 @@ Requires at least GnuPG 2.1.18.
 Note: Keys retrieved through @code{auto-key-locate} are automatically
 imported in the keyring.
 
+@item trust-model
+@since{1.11.2}
+
+Change the trust-model for all GnuPG engine operations.  An empty
+string sets the trust-model back to the users default.  If the
+trust-model is not supported by GnuPG the behavior is undefined
+and will likely cause all operations to fail.  Example: "tofu+pgp".
+
+This options should be used carefully with a strict version
+requirement.  In some versions of GnuPG setting the
+trust-model changes the default trust-model for future operations.
+A change in the trust-model also can have unintended side effects, like
+rebuilding the trust-db.
+
 @end table
 
 This function returns @code{0} on success.
index 1c9379b..d65bf9b 100644 (file)
@@ -162,6 +162,9 @@ struct gpgme_context
   char *lc_ctype;
   char *lc_messages;
 
+  /* The optional trust-model override.  */
+  char *trust_model;
+
   /* The operation data hooked into the context.  */
   ctx_op_data_t op_data;
 
index 2833374..aed933e 100644 (file)
@@ -141,6 +141,7 @@ struct engine_gpg
   gpgme_pinentry_mode_t pinentry_mode;
   char request_origin[10];
   char *auto_key_locate;
+  char *trust_model;
 
   struct {
     unsigned int no_symkey_cache : 1;
@@ -455,6 +456,7 @@ gpg_release (void *engine)
   if (gpg->cmd.keyword)
     free (gpg->cmd.keyword);
   free (gpg->auto_key_locate);
+  free (gpg->trust_model);
 
   gpgme_data_release (gpg->override_session_key);
   gpgme_data_release (gpg->diagnostics);
@@ -669,6 +671,14 @@ gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
                                                ctx->auto_key_locate, NULL);
     }
 
+  if (ctx->trust_model && strlen (ctx->trust_model))
+    {
+      if (gpg->trust_model)
+        free (gpg->trust_model);
+      gpg->trust_model = _gpgme_strconcat ("--trust-model=",
+                                           ctx->trust_model, NULL);
+    }
+
   gpg->flags.no_symkey_cache = (ctx->no_symkey_cache
                                 && have_gpg_version (gpg, "2.2.7"));
   gpg->flags.offline = (ctx->offline && have_gpg_version (gpg, "2.1.23"));
@@ -981,6 +991,19 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
       argc++;
     }
 
+  if (gpg->trust_model)
+    {
+      argv[argc] = strdup (gpg->trust_model);
+      if (!argv[argc])
+        {
+          int saved_err = gpg_error_from_syserror ();
+          free (fd_data_map);
+          free_argv (argv);
+          return saved_err;
+        }
+      argc++;
+    }
+
   if (gpg->flags.no_symkey_cache)
     {
       argv[argc] = strdup ("--no-symkey-cache");
index 2d829d9..3d72f69 100644 (file)
@@ -250,6 +250,7 @@ gpgme_release (gpgme_ctx_t ctx)
   free (ctx->override_session_key);
   free (ctx->request_origin);
   free (ctx->auto_key_locate);
+  free (ctx->trust_model);
   _gpgme_engine_info_release (ctx->engine_info);
   ctx->engine_info = NULL;
   DESTROY_LOCK (ctx->lock);
@@ -554,6 +555,13 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
       if (!ctx->auto_key_locate)
         err = gpg_error_from_syserror ();
     }
+  else if (!strcmp (name, "trust-model"))
+    {
+      free (ctx->trust_model);
+      ctx->trust_model = strdup (value);
+      if (!ctx->trust_model)
+        err = gpg_error_from_syserror ();
+    }
   else
     err = gpg_error (GPG_ERR_UNKNOWN_NAME);
 
index 9206b50..08b671d 100644 (file)
@@ -60,6 +60,7 @@ show_usage (int ex)
          "  --from-file      list all keys in the given file\n"
          "  --from-wkd       list key from a web key directory\n"
          "  --require-gnupg  required at least the given GnuPG version\n"
+         "  --trust-model    use the specified trust-model\n"
          , stderr);
   exit (ex);
 }
@@ -104,6 +105,7 @@ main (int argc, char **argv)
   int from_file = 0;
   int from_wkd = 0;
   gpgme_data_t data = NULL;
+  char *trust_model = NULL;
 
 
   if (argc)
@@ -208,6 +210,14 @@ main (int argc, char **argv)
           mode |= GPGME_KEYLIST_MODE_LOCATE;
           from_wkd = 1;
         }
+      else if (!strcmp (*argv, "--trust-model"))
+        {
+          argc--; argv++;
+          if (!argc)
+            show_usage (1);
+          trust_model = strdup (*argv);
+          argc--; argv++;
+        }
       else if (!strncmp (*argv, "--", 2))
         show_usage (1);
     }
@@ -227,6 +237,12 @@ main (int argc, char **argv)
 
   gpgme_set_offline (ctx, offline);
 
+  if (trust_model)
+    {
+      err = gpgme_set_ctx_flag (ctx, "trust-model", trust_model);
+      fail_if_err (err);
+    }
+
   if (from_wkd)
     {
       err = gpgme_set_ctx_flag (ctx, "auto-key-locate",
@@ -401,6 +417,8 @@ main (int argc, char **argv)
   for (keyidx=0; keyarray[keyidx]; keyidx++)
     gpgme_key_unref (keyarray[keyidx]);
 
+  free (trust_model);
+
   gpgme_release (ctx);
   return 0;
 }