core: New function gpgme_op_setownertrust
* src/Makefile.am (main_sources): Add new file. * src/context.h (ctx_op_data_id_t): Add OPDATA_SETOWNERTRUST. * src/engine.c, src/engine.h (_gpgme_engine_op_setownertrust): New. * src/engine-backend.h (engine_ops): Add 'setownertrust' and adjust all engine initializers. * src/engine-gpg.c (gpg_setownertrust): New. (_gpgme_engine_ops_gpg): Set setownertrust to gpg_setownertrust. * src/gpgme.h.in (gpgme_op_setownertrust_start, gpgme_op_setownertrust): New. * src/gpgme.def, src/libgpgme.vers: Add new functions. * src/setownertrust.c: New. * doc/gpgme.texi: Document new functions. * tests/Makefile.am (noinst_PROGRAMS): Add new test program. * tests/run-setownertrust.c: New. * tests/gpg/Makefile.am (c_tests): Add new file. (LDADD): Add @GPG_ERROR_LIBS@. * tests/gpg/t-setownertrust.c: New. * tests/gpg/t-support.h (have_gpg_version): New. -- This extends GPGME to support the --quick-set-ownertrust command added by GnuPG 2.4.6. This allows changing the owner trust of keys and enabling/disabling keys without using the editinteractor interface. GnuPG-bug-id: 7239
This commit is contained in:
parent
9272b0fb6e
commit
d804a7a4bc
6
NEWS
6
NEWS
@ -11,6 +11,10 @@ Noteworthy changes in version 1.24.0 (unrelease)
|
||||
|
||||
* New context flag "import-options". [T7152]
|
||||
|
||||
* New function gpgme_op_setownertrust to make changing the owner trust
|
||||
easier and to allow enabling/disabling of keys (requires GnuPG 2.4.6).
|
||||
[T7239]
|
||||
|
||||
* cpp: Provide information about designated revocation keys for a Key.
|
||||
[T7118]
|
||||
|
||||
@ -38,6 +42,8 @@ Noteworthy changes in version 1.24.0 (unrelease)
|
||||
gpgme_key_t EXTENDED: New field 'revkeys'.
|
||||
gpgme_revocation_key_t NEW.
|
||||
gpgme_set_ctx_flag EXTENDED: New flag 'import-options'.
|
||||
gpgme_op_setownertrust_start NEW.
|
||||
gpgme_op_setownertrust NEW.
|
||||
cpp: Context::EncryptFile NEW.
|
||||
cpp: SignatureMode::SignFile NEW.
|
||||
cpp: RevocationKey NEW.
|
||||
|
@ -4277,6 +4277,53 @@ be completed by calling @code{gpgme_wait} on the context.
|
||||
|
||||
@end deftypefun
|
||||
|
||||
@c
|
||||
@c gpgme_op_setownertrust
|
||||
@c
|
||||
@deftypefun gpgme_error_t gpgme_op_setownertrust @
|
||||
(@w{gpgme_ctx_t @var{ctx}}, @
|
||||
@w{gpgme_key_t @var{key}}, @
|
||||
@w{const char *@var{value}});
|
||||
|
||||
@since{1.24.0}
|
||||
|
||||
The function @code{gpgme_op_setownertrust} sets the owner trust of the
|
||||
key @var{key} or it sets the disable flag of the key @var{key}.
|
||||
This function only works for OpenPGP and requires at least version 2.4.6
|
||||
of GnuPG.
|
||||
|
||||
@var{key} specifies the key to operate on.
|
||||
|
||||
@var{value} specifies the owner trust value to set. Valid values are
|
||||
"undefined", "never", "marginal", "full", "ultimate". If @var{value} is
|
||||
the string "disable" then the key @var{key} is disabled. If @var{value}
|
||||
is the string "enable" then the key @var{key} is re-enabled.
|
||||
|
||||
The function returns the error code @code{GPG_ERR_NO_ERROR} if the
|
||||
operation was completed successfully, @code{GPG_ERR_NOT_SUPPORTED} if
|
||||
the engine does not support the command, and @code{GPG_ERR_INV_VALUE} if
|
||||
@var{key} is not a valid pointer or not a valid key or if @var{value} is
|
||||
not a valid pointer or the empty string.
|
||||
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@deftypefun gpgme_error_t gpgme_op_setownertrust_start @
|
||||
(@w{gpgme_ctx_t @var{ctx}}, @
|
||||
@w{gpgme_key_t @var{key}}, @
|
||||
@w{const char *@var{value}});
|
||||
|
||||
@since{1.24.0}
|
||||
|
||||
The function @code{gpgme_op_setownertrust_start} initiates a
|
||||
@code{gpgme_op_setownertrust} operation; see there for details. It must
|
||||
be completed by calling @code{gpgme_wait} on the context.
|
||||
@xref{Waiting For Completion}.
|
||||
|
||||
The function returns the same error codes as @code{gpgme_op_setownertrust}.
|
||||
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Generating Keys
|
||||
@subsection Generating Keys
|
||||
|
@ -85,7 +85,7 @@ main_sources = \
|
||||
key.c keylist.c keysign.c trust-item.c trustlist.c tofupolicy.c \
|
||||
revsig.c \
|
||||
import.c export.c genkey.c delete.c edit.c getauditlog.c \
|
||||
setexpire.c \
|
||||
setexpire.c setownertrust.c \
|
||||
opassuan.c passwd.c spawn.c assuan-support.c \
|
||||
engine.h engine-backend.h engine.c engine-gpg.c status-table.c \
|
||||
engine-gpgsm.c engine-assuan.c engine-gpgconf.c \
|
||||
|
@ -39,7 +39,7 @@ typedef enum
|
||||
OPDATA_IMPORT, OPDATA_GENKEY, OPDATA_KEYLIST, OPDATA_EDIT,
|
||||
OPDATA_VERIFY, OPDATA_TRUSTLIST, OPDATA_ASSUAN, OPDATA_VFS_MOUNT,
|
||||
OPDATA_PASSWD, OPDATA_EXPORT, OPDATA_KEYSIGN, OPDATA_TOFU_POLICY,
|
||||
OPDATA_QUERY_SWDB, OPDATA_SETEXPIRE, OPDATA_REVSIG
|
||||
OPDATA_QUERY_SWDB, OPDATA_SETEXPIRE, OPDATA_REVSIG, OPDATA_SETOWNERTRUST
|
||||
} ctx_op_data_id_t;
|
||||
|
||||
|
||||
|
@ -839,6 +839,7 @@ struct engine_ops _gpgme_engine_ops_assuan =
|
||||
NULL, /* verify */
|
||||
NULL, /* getauditlog */
|
||||
NULL, /* setexpire */
|
||||
NULL, /* setownertrust */
|
||||
llass_transact, /* opassuan_transact */
|
||||
NULL, /* conf_load */
|
||||
NULL, /* conf_save */
|
||||
|
@ -129,6 +129,8 @@ struct engine_ops
|
||||
gpgme_error_t (*setexpire) (void *engine, gpgme_key_t key,
|
||||
unsigned long expires, const char *subfprs,
|
||||
unsigned int reserved);
|
||||
gpgme_error_t (*setownertrust) (void *engine, gpgme_key_t key,
|
||||
const char *value);
|
||||
gpgme_error_t (*opassuan_transact) (void *engine,
|
||||
const char *command,
|
||||
gpgme_assuan_data_cb_t data_cb,
|
||||
|
@ -810,6 +810,7 @@ struct engine_ops _gpgme_engine_ops_g13 =
|
||||
NULL, /* verify */
|
||||
NULL, /* getauditlog */
|
||||
NULL, /* setexpire */
|
||||
NULL, /* setownertrust */
|
||||
g13_transact,
|
||||
NULL, /* conf_load */
|
||||
NULL, /* conf_save */
|
||||
|
@ -4017,6 +4017,38 @@ gpg_setexpire (void *engine, gpgme_key_t key, unsigned long expires,
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
gpg_setownertrust (void *engine, gpgme_key_t key, const char *value)
|
||||
{
|
||||
engine_gpg_t gpg = engine;
|
||||
gpgme_error_t err;
|
||||
|
||||
if (!have_gpg_version (gpg, "2.4.6"))
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
|
||||
if (!key || !key->fpr)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
if (!value || !*value)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
err = add_arg (gpg, "--quick-set-ownertrust");
|
||||
|
||||
if (!err)
|
||||
err = add_arg (gpg, "--");
|
||||
|
||||
if (!err)
|
||||
err = add_arg (gpg, key->fpr);
|
||||
|
||||
if (!err)
|
||||
err = add_arg (gpg, value);
|
||||
|
||||
if (!err)
|
||||
err = start (gpg);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct engine_ops _gpgme_engine_ops_gpg =
|
||||
{
|
||||
@ -4056,6 +4088,7 @@ struct engine_ops _gpgme_engine_ops_gpg =
|
||||
gpg_verify,
|
||||
gpg_getauditlog,
|
||||
gpg_setexpire,
|
||||
gpg_setownertrust,
|
||||
NULL, /* opassuan_transact */
|
||||
NULL, /* conf_load */
|
||||
NULL, /* conf_save */
|
||||
|
@ -1310,6 +1310,7 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
|
||||
NULL, /* verify */
|
||||
NULL, /* getauditlog */
|
||||
NULL, /* setexpire */
|
||||
NULL, /* setownertrust */
|
||||
NULL, /* opassuan_transact */
|
||||
gpgconf_conf_load,
|
||||
gpgconf_conf_save,
|
||||
|
@ -2444,6 +2444,7 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
|
||||
gpgsm_verify,
|
||||
gpgsm_getauditlog,
|
||||
NULL, /* setexpire */
|
||||
NULL, /* setownertrust */
|
||||
NULL, /* opassuan_transact */
|
||||
NULL, /* conf_load */
|
||||
NULL, /* conf_save */
|
||||
|
@ -470,6 +470,7 @@ struct engine_ops _gpgme_engine_ops_spawn =
|
||||
NULL, /* verify */
|
||||
NULL, /* getauditlog */
|
||||
NULL, /* setexpire */
|
||||
NULL, /* setownertrust */
|
||||
NULL, /* opassuan_transact */
|
||||
NULL, /* conf_load */
|
||||
NULL, /* conf_save */
|
||||
|
@ -1453,6 +1453,7 @@ struct engine_ops _gpgme_engine_ops_uiserver =
|
||||
uiserver_verify,
|
||||
NULL, /* getauditlog */
|
||||
NULL, /* setexpire */
|
||||
NULL, /* setownertrust */
|
||||
NULL, /* opassuan_transact */
|
||||
NULL, /* conf_load */
|
||||
NULL, /* conf_save */
|
||||
|
13
src/engine.c
13
src/engine.c
@ -1161,3 +1161,16 @@ _gpgme_engine_op_setexpire (engine_t engine, gpgme_key_t key,
|
||||
|
||||
return (*engine->ops->setexpire) (engine->engine, key, expires, subfprs, reserved);
|
||||
}
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_engine_op_setownertrust (engine_t engine, gpgme_key_t key,
|
||||
const char *value)
|
||||
{
|
||||
if (!engine)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if (!engine->ops->setownertrust)
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
||||
return (*engine->ops->setownertrust) (engine->engine, key, value);
|
||||
}
|
||||
|
@ -225,6 +225,8 @@ gpgme_error_t _gpgme_engine_op_setexpire (engine_t engine,
|
||||
unsigned long expires,
|
||||
const char *subfprs,
|
||||
unsigned int reserved);
|
||||
|
||||
gpgme_error_t _gpgme_engine_op_setownertrust (engine_t engine,
|
||||
gpgme_key_t key,
|
||||
const char *value);
|
||||
|
||||
#endif /* ENGINE_H */
|
||||
|
@ -285,5 +285,8 @@ EXPORTS
|
||||
|
||||
gpgme_op_verify_ext @211
|
||||
gpgme_op_verify_ext_start @212
|
||||
|
||||
gpgme_op_setownertrust @213
|
||||
gpgme_op_setownertrust_start @214
|
||||
; END
|
||||
|
||||
|
@ -1969,6 +1969,12 @@ gpgme_error_t gpgme_op_setexpire (gpgme_ctx_t ctx,
|
||||
gpgme_key_t key, unsigned long expires,
|
||||
const char *subfprs, unsigned int reserved);
|
||||
|
||||
/* Change the ownertrust of a key. */
|
||||
gpgme_error_t gpgme_op_setownertrust_start (gpgme_ctx_t ctx,
|
||||
gpgme_key_t key, const char *value);
|
||||
gpgme_error_t gpgme_op_setownertrust (gpgme_ctx_t ctx,
|
||||
gpgme_key_t key, const char *value);
|
||||
|
||||
/* Retrieve a pointer to the result of a genkey, createkey, or
|
||||
* createsubkey operation. */
|
||||
gpgme_genkey_result_t gpgme_op_genkey_result (gpgme_ctx_t ctx);
|
||||
|
@ -285,6 +285,9 @@ GPGME_1.0 {
|
||||
gpgme_op_verify_ext;
|
||||
gpgme_op_verify_ext_start;
|
||||
|
||||
gpgme_op_setownertrust;
|
||||
gpgme_op_setownertrust_start;
|
||||
|
||||
local:
|
||||
*;
|
||||
|
||||
|
181
src/setownertrust.c
Normal file
181
src/setownertrust.c
Normal file
@ -0,0 +1,181 @@
|
||||
/* setownertrust.c - Set ownertrust helpers.
|
||||
* Copyright (C) 2024 g10 Code GmbH
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
* GPGME is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* GPGME is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <https://gnu.org/licenses/>.
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gpgme.h"
|
||||
#include "debug.h"
|
||||
#include "context.h"
|
||||
#include "ops.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* The error code from a FAILURE status line or 0. */
|
||||
gpg_error_t failure_code;
|
||||
|
||||
/* The error code from an ERROR status line or 0. */
|
||||
gpg_error_t error_code;
|
||||
|
||||
} *op_data_t;
|
||||
|
||||
|
||||
/* Parse an error status line. Return the error location and the
|
||||
error code. The function may modify ARGS. */
|
||||
static char *
|
||||
parse_error (char *args, gpg_error_t *r_err)
|
||||
{
|
||||
char *where = strchr (args, ' ');
|
||||
char *which;
|
||||
|
||||
if (where)
|
||||
{
|
||||
*where = '\0';
|
||||
which = where + 1;
|
||||
|
||||
where = strchr (which, ' ');
|
||||
if (where)
|
||||
*where = '\0';
|
||||
|
||||
where = args;
|
||||
}
|
||||
else
|
||||
{
|
||||
*r_err = trace_gpg_error (GPG_ERR_INV_ENGINE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*r_err = atoi (which);
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
setownertrust_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
||||
{
|
||||
gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
|
||||
gpgme_error_t err;
|
||||
void *hook;
|
||||
op_data_t opd;
|
||||
char *loc;
|
||||
|
||||
err = _gpgme_op_data_lookup (ctx, OPDATA_SETOWNERTRUST, &hook, -1, NULL);
|
||||
opd = hook;
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case GPGME_STATUS_ERROR:
|
||||
loc = parse_error (args, &err);
|
||||
if (!loc)
|
||||
return err;
|
||||
if (!opd->error_code)
|
||||
opd->error_code = err;
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_FAILURE:
|
||||
if (!opd->failure_code
|
||||
|| gpg_err_code (opd->failure_code) == GPG_ERR_GENERAL)
|
||||
opd->failure_code = _gpgme_parse_failure (args);
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_EOF:
|
||||
if (opd->error_code)
|
||||
err = opd->error_code;
|
||||
else if (opd->failure_code)
|
||||
err = opd->failure_code;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Set the ownertrust of a key or enable/disable a key. See
|
||||
--quick-set-ownertrust in the gnupg documentation. */
|
||||
static gpg_error_t
|
||||
setownertrust (gpgme_ctx_t ctx, int synchronous,
|
||||
gpgme_key_t key,
|
||||
const char *value)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
void *hook;
|
||||
op_data_t opd;
|
||||
|
||||
TRACE_BEG (DEBUG_CTX, "gpgme_op_setownertrust", ctx,
|
||||
"%d key=%p value: %s",
|
||||
synchronous, key, value);
|
||||
|
||||
if (!ctx)
|
||||
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
||||
|
||||
if (ctx->protocol != GPGME_PROTOCOL_OPENPGP)
|
||||
return TRACE_ERR (gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL));
|
||||
|
||||
if (!key)
|
||||
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
||||
|
||||
err = _gpgme_op_reset (ctx, synchronous);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = _gpgme_op_data_lookup (ctx, OPDATA_SETOWNERTRUST, &hook, sizeof (*opd),
|
||||
NULL);
|
||||
opd = hook;
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
_gpgme_engine_set_status_handler (ctx->engine, setownertrust_status_handler,
|
||||
ctx);
|
||||
|
||||
err = _gpgme_engine_op_setownertrust (ctx->engine, key, value);
|
||||
|
||||
if (synchronous && !err)
|
||||
err = _gpgme_wait_one (ctx);
|
||||
return TRACE_ERR (err);
|
||||
}
|
||||
|
||||
|
||||
/* See setownertrust. */
|
||||
gpgme_error_t
|
||||
gpgme_op_setownertrust_start (gpgme_ctx_t ctx,
|
||||
gpgme_key_t key,
|
||||
const char *value)
|
||||
{
|
||||
return setownertrust (ctx, 0, key, value);
|
||||
}
|
||||
|
||||
|
||||
/* See setownertrust. This is the synchronous variant. */
|
||||
gpgme_error_t
|
||||
gpgme_op_setownertrust (gpgme_ctx_t ctx,
|
||||
gpgme_key_t key,
|
||||
const char *value)
|
||||
{
|
||||
return setownertrust (ctx, 1, key, value);
|
||||
}
|
@ -42,7 +42,7 @@ noinst_HEADERS = run-support.h
|
||||
noinst_PROGRAMS = $(TESTS) run-keylist run-export run-import run-sign \
|
||||
run-verify run-encrypt run-identify run-decrypt run-genkey \
|
||||
run-keysign run-tofu run-swdb run-threaded \
|
||||
run-receive-keys
|
||||
run-receive-keys run-setownertrust
|
||||
|
||||
run_threaded_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_MT_CFLAGS@
|
||||
run_threaded_LDADD = ../src/libgpgme.la \
|
||||
|
@ -40,6 +40,7 @@ c_tests = \
|
||||
t-decrypt t-verify t-decrypt-verify t-sig-notation t-export \
|
||||
t-import t-edit t-keylist t-keylist-sig t-keylist-secret-sig t-wait \
|
||||
t-encrypt-large t-file-name t-gpgconf t-encrypt-mixed t-edit-sign \
|
||||
t-setownertrust \
|
||||
$(tests_unix)
|
||||
|
||||
TESTS = initial.test $(c_tests) final.test
|
||||
@ -67,7 +68,7 @@ BUILT_SOURCES = gpg.conf gpg-agent.conf pubring-stamp \
|
||||
gpg-sample.stamp
|
||||
AM_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_CFLAGS@
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = ../../src/libgpgme.la @LDADD_FOR_TESTS_KLUDGE@
|
||||
LDADD = ../../src/libgpgme.la @GPG_ERROR_LIBS@ @LDADD_FOR_TESTS_KLUDGE@
|
||||
|
||||
WITH_THREAD_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_MT_CFLAGS@
|
||||
WITH_THREAD_LDADD = ../../src/libgpgme.la \
|
||||
|
132
tests/gpg/t-setownertrust.c
Normal file
132
tests/gpg/t-setownertrust.c
Normal file
@ -0,0 +1,132 @@
|
||||
/* t-setownertrust.c - Regression test.
|
||||
* Copyright (C) 2024 g10 Code GmbH
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
* GPGME is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* GPGME is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <https://gnu.org/licenses/>.
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
/* We need to include config.h so that we know whether we are building
|
||||
with large file system (LFS) support. */
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define PGM "t-setownertrust"
|
||||
#include "t-support.h"
|
||||
|
||||
#include <gpgme.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
static gpgme_key_t
|
||||
list_one_key (gpgme_ctx_t ctx, const char *pattern, int secret_only)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
gpgme_key_t key = NULL;
|
||||
|
||||
err = gpgme_op_keylist_start (ctx, pattern, secret_only);
|
||||
fail_if_err (err);
|
||||
err = gpgme_op_keylist_next (ctx, &key);
|
||||
fail_if_err (err);
|
||||
err = gpgme_op_keylist_end (ctx);
|
||||
fail_if_err (err);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
gpgme_ctx_t ctx;
|
||||
gpgme_error_t err;
|
||||
gpgme_key_t key = NULL;
|
||||
const char *pattern = "Alpha";
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
if (!have_gpg_version ("2.4.6"))
|
||||
{
|
||||
printf ("Testsuite skipped. Minimum GnuPG version (2.4.6) "
|
||||
"not found.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
init_gpgme (GPGME_PROTOCOL_OpenPGP);
|
||||
|
||||
err = gpgme_new (&ctx);
|
||||
fail_if_err (err);
|
||||
|
||||
key = list_one_key (ctx, pattern, 0);
|
||||
err = gpgme_op_setownertrust (ctx, key, "disable");
|
||||
fail_if_err (err);
|
||||
gpgme_key_unref (key);
|
||||
|
||||
key = list_one_key (ctx, pattern, 0);
|
||||
if (!key->disabled)
|
||||
{
|
||||
fprintf (stderr, "%s:%i: Key is unexpectedly not disabled\n",
|
||||
PGM, __LINE__);
|
||||
exit (1);
|
||||
}
|
||||
gpgme_key_unref (key);
|
||||
|
||||
key = list_one_key (ctx, pattern, 0);
|
||||
err = gpgme_op_setownertrust (ctx, key, "enable");
|
||||
fail_if_err (err);
|
||||
gpgme_key_unref (key);
|
||||
|
||||
key = list_one_key (ctx, pattern, 0);
|
||||
if (key->disabled)
|
||||
{
|
||||
fprintf (stderr, "%s:%i: Key is unexpectedly disabled\n",
|
||||
PGM, __LINE__);
|
||||
exit (1);
|
||||
}
|
||||
gpgme_key_unref (key);
|
||||
|
||||
/* Check error handling */
|
||||
err = gpgme_op_setownertrust (ctx, NULL, "ultimate");
|
||||
if (gpgme_err_code (err) != GPG_ERR_INV_VALUE)
|
||||
{
|
||||
fprintf (stderr, "%s:%i: Unexpected error code: %s\n",
|
||||
PGM, __LINE__, gpgme_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
key = list_one_key (ctx, pattern, 0);
|
||||
err = gpgme_op_setownertrust (ctx, key, NULL);
|
||||
if (gpgme_err_code (err) != GPG_ERR_INV_VALUE)
|
||||
{
|
||||
fprintf (stderr, "%s:%i: Unexpected error code: %s\n",
|
||||
PGM, __LINE__, gpgme_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
err = gpgme_op_setownertrust (ctx, key, "");
|
||||
if (gpgme_err_code (err) != GPG_ERR_INV_VALUE)
|
||||
{
|
||||
fprintf (stderr, "%s:%i: Unexpected error code: %s\n",
|
||||
PGM, __LINE__, gpgme_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
gpgme_key_unref (key);
|
||||
|
||||
gpgme_release (ctx);
|
||||
|
||||
return 0;
|
||||
}
|
@ -19,19 +19,21 @@
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include <gpgme.h>
|
||||
#include <gpg-error.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <gpgme.h>
|
||||
|
||||
#ifndef PGM
|
||||
#define PGM "unknown program; define PGM before including t-support.h"
|
||||
#endif
|
||||
@ -271,3 +273,21 @@ print_import_result (gpgme_import_result_t r)
|
||||
r->not_imported,
|
||||
r->skipped_v3_keys);
|
||||
}
|
||||
|
||||
|
||||
/* Return true if the gpg engine's version is at least REQ_VERSION. */
|
||||
int
|
||||
have_gpg_version (const char *req_version)
|
||||
{
|
||||
gpgme_engine_info_t engine_info;
|
||||
init_gpgme (GPGME_PROTOCOL_OpenPGP);
|
||||
|
||||
fail_if_err (gpgme_get_engine_info (&engine_info));
|
||||
for (; engine_info; engine_info = engine_info->next)
|
||||
if (engine_info->protocol == GPGME_PROTOCOL_OpenPGP)
|
||||
break;
|
||||
|
||||
test (engine_info);
|
||||
|
||||
return gpgrt_cmp_version (engine_info->version, req_version, 3) >= 0;
|
||||
}
|
||||
|
127
tests/run-setownertrust.c
Normal file
127
tests/run-setownertrust.c
Normal file
@ -0,0 +1,127 @@
|
||||
/* run-setownertrust.c - Test tool to perform ownertrust changes
|
||||
* Copyright (C) 2024 g10 Code GmbH
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
* GPGME is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* GPGME is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <https://gnu.org/licenses/>.
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
/* We need to include config.h so that we know whether we are building
|
||||
with large file system (LFS) support. */
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gpgme.h>
|
||||
|
||||
#define PGM "run-setownertrust"
|
||||
|
||||
#include "run-support.h"
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
status_cb (void *opaque, const char *keyword, const char *value)
|
||||
{
|
||||
(void)opaque;
|
||||
fprintf (stderr, "status_cb: %s %s\n", nonnull(keyword), nonnull(value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
show_usage (int ex)
|
||||
{
|
||||
fputs ("usage: " PGM " [options] USERID VALUE\n"
|
||||
"Options:\n"
|
||||
" --status print status lines from the backend\n"
|
||||
, stderr);
|
||||
exit (ex);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int last_argc = -1;
|
||||
gpgme_error_t err;
|
||||
gpgme_ctx_t ctx;
|
||||
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
|
||||
int print_status = 0;
|
||||
const char *userid;
|
||||
const char *value;
|
||||
gpgme_key_t key;
|
||||
|
||||
if (argc)
|
||||
{ argc--; argv++; }
|
||||
|
||||
while (argc && last_argc != argc )
|
||||
{
|
||||
last_argc = argc;
|
||||
if (!strcmp (*argv, "--"))
|
||||
{
|
||||
argc--; argv++;
|
||||
break;
|
||||
}
|
||||
else if (!strcmp (*argv, "--help"))
|
||||
show_usage (0);
|
||||
else if (!strcmp (*argv, "--status"))
|
||||
{
|
||||
print_status = 1;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strncmp (*argv, "--", 2))
|
||||
show_usage (1);
|
||||
}
|
||||
|
||||
if (argc != 2)
|
||||
show_usage (1);
|
||||
userid = argv[0];
|
||||
value = argv[1];
|
||||
|
||||
init_gpgme (protocol);
|
||||
|
||||
err = gpgme_new (&ctx);
|
||||
fail_if_err (err);
|
||||
gpgme_set_protocol (ctx, protocol);
|
||||
gpgme_set_armor (ctx, 1);
|
||||
if (print_status)
|
||||
{
|
||||
gpgme_set_status_cb (ctx, status_cb, NULL);
|
||||
gpgme_set_ctx_flag (ctx, "full-status", "1");
|
||||
}
|
||||
|
||||
err = gpgme_get_key (ctx, userid, &key, 0);
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr, PGM ": error getting public key for '%s': %s\n",
|
||||
userid, gpg_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
err = gpgme_op_setownertrust (ctx, key, value);
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr, PGM ": gpgme_op_setownertrust failed: %s\n",
|
||||
gpg_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
gpgme_key_unref (key);
|
||||
|
||||
gpgme_release (ctx);
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user