diff --git a/doc/gpgme.texi b/doc/gpgme.texi --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -747,6 +747,23 @@ that directory is the installation directory. This flag has no effect on non-Windows platforms. +@item trust-model +@since{1.11.2} + +Change the default trust-model for all new contexts. 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. + +See @code{gpgme_set_ctx_flag} for a context local version of this +flag. + @end table This function returns @code{0} on success. In contrast to other @@ -2444,6 +2461,7 @@ * 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 +3048,10 @@ 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 +3153,23 @@ 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. + +See @code{gpgme_set_global_flag} for a global version of this +flag. + @end table This function returns @code{0} on success. diff --git a/src/context.h b/src/context.h --- a/src/context.h +++ b/src/context.h @@ -162,6 +162,9 @@ 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; diff --git a/src/engine-gpg.c b/src/engine-gpg.c --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -141,6 +141,7 @@ 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 @@ 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 @@ 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 @@ 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"); diff --git a/src/gpgme.c b/src/gpgme.c --- a/src/gpgme.c +++ b/src/gpgme.c @@ -47,6 +47,11 @@ static char *def_lc_messages; +/* The global default trust model. */ +DEFINE_STATIC_LOCK (def_trust_model_lock); +static char *def_trust_model; + + gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL; /* Protects all reference counters in result structures. All other @@ -80,6 +85,14 @@ return _gpgme_set_default_gpg_name (value); else if (!strcmp (name, "w32-inst-dir")) return _gpgme_set_override_inst_dir (value); + else if (!strcmp (name, "trust-model")) + { + LOCK (def_trust_model_lock); + free (def_trust_model); + def_trust_model = strdup (value); + UNLOCK (def_trust_model_lock); + return !def_trust_model; + } else return -1; } @@ -156,6 +169,13 @@ def_lc_messages = NULL; UNLOCK (def_lc_lock); + LOCK (def_trust_model_lock); + if (def_trust_model && strlen (def_trust_model)) + { + ctx->trust_model = strdup (def_trust_model); + } + UNLOCK (def_trust_model_lock); + *r_ctx = ctx; return TRACE_SUC1 ("ctx=%p", ctx); @@ -250,6 +270,7 @@ 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 +575,13 @@ 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); diff --git a/tests/run-keylist.c b/tests/run-keylist.c --- a/tests/run-keylist.c +++ b/tests/run-keylist.c @@ -60,6 +60,7 @@ " --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); } @@ -208,6 +209,14 @@ mode |= GPGME_KEYLIST_MODE_LOCATE; from_wkd = 1; } + else if (!strcmp (*argv, "--trust-model")) + { + argc--; argv++; + if (!argc) + show_usage (1); + gpgme_set_global_flag ("trust-model", *argv); + argc--; argv++; + } else if (!strncmp (*argv, "--", 2)) show_usage (1); }