core: New gpgme_set_ctx_flag "request-origin".

* src/context.h (gpgme_context): Add 'request_origin'.
* src/gpgme.c (gpgme_release): Free that field.
(gpgme_set_ctx_flag, gpgme_get_ctx_flag): Add "request-origin".
* src/engine-backend.h (engine_ops): Add 'set_engine_ops' func ptr and
adjust all users.
* src/engine.c (_gpgme_engine_set_engine_flags): New.
* src/op-support.c (_gpgme_op_reset): Call that func.
* src/engine-gpg.c (struct engine_gpg): Add 'request_origin'.
(gpg_set_engine_flags): New.
(_gpgme_engine_ops_gpg): Hook it.
(build_argv): Use command line option --request-origin.
* src/engine-gpgsm.c (struct engine_gpgsm): Add 'request_origin'.
(gpgsm_set_engine_flags): New.
(_gpgme_engine_ops_gpgsm): Hook it.
(start): Send OPTION "request-origin".
* src/engine-assuan.c (struct engine_llass): Add 'request_origin'.
(gpgsm_set_engine_flags): New.
(_gpgme_engine_ops_assuan): Hook it.
(start): Send OPTION "pretend-request-origin".

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2018-03-23 15:27:32 +01:00
parent eee68c1b13
commit b9000bc293
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
15 changed files with 176 additions and 8 deletions

View File

@ -3065,6 +3065,11 @@ a message signed by a brand new key (which you naturally will not have
on your local keyring), the operator can tell both your IP address and
the time when you verified the signature.
@item "request-origin"
The string given in @var{value} is passed to the GnuPG engines to
request restrictions based on the origin of the request. Valid values
are documented in the GnuPG manual and the gpg man page under the
option ``--request-origin''.
@end table

View File

@ -145,6 +145,9 @@ struct gpgme_context
/* The gpg specific override session key or NULL. */
char *override_session_key;
/* The optional request origin. */
char *request_origin;
/* The locale for the pinentry. */
char *lc_ctype;
char *lc_messages;

View File

@ -96,6 +96,7 @@ struct engine_llass
int gpg_agent:1; /* Assume this is a gpg-agent connection. */
} opt;
char request_origin[10]; /* Copy from the CTX. */
};
typedef struct engine_llass *engine_llass_t;
@ -365,6 +366,24 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
}
/* Copy flags from CTX into the engine object. */
static void
llass_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
{
engine_llass_t llass = engine;
if (ctx->request_origin)
{
if (strlen (ctx->request_origin) + 1 > sizeof llass->request_origin)
strcpy (llass->request_origin, "xxx"); /* Too long - force error */
else
strcpy (llass->request_origin, ctx->request_origin);
}
else
*llass->request_origin = 0;
}
static gpgme_error_t
llass_set_locale (void *engine, int category, const char *value)
{
@ -660,6 +679,21 @@ start (engine_llass_t llass, const char *command)
int nfds;
int i;
if (*llass->request_origin && llass->opt.gpg_agent)
{
char *cmd;
cmd = _gpgme_strconcat ("OPTION pretend-request-origin=",
llass->request_origin, NULL);
if (!cmd)
return gpg_error_from_syserror ();
err = assuan_transact (llass->assuan_ctx, cmd, NULL, NULL, NULL,
NULL, NULL, NULL);
free (cmd);
if (err && gpg_err_code (err) != GPG_ERR_UNKNOWN_OPTION)
return err;
}
/* We need to know the fd used by assuan for reads. We do this by
using the assumption that the first returned fd from
assuan_get_active_fds() is always this one. */
@ -775,6 +809,7 @@ struct engine_ops _gpgme_engine_ops_assuan =
NULL, /* set_colon_line_handler */
llass_set_locale,
NULL, /* set_protocol */
llass_set_engine_flags,
NULL, /* decrypt */
NULL, /* delete */
NULL, /* edit */

View File

@ -61,6 +61,7 @@ struct engine_ops
void *fnc_value);
gpgme_error_t (*set_locale) (void *engine, int category, const char *value);
gpgme_error_t (*set_protocol) (void *engine, gpgme_protocol_t protocol);
void (*set_engine_flags) (void *engine, gpgme_ctx_t ctx);
gpgme_error_t (*decrypt) (void *engine,
gpgme_decrypt_flags_t flags,
gpgme_data_t ciph,

View File

@ -790,6 +790,7 @@ struct engine_ops _gpgme_engine_ops_g13 =
NULL, /* set_colon_line_handler */
g13_set_locale,
NULL, /* set_protocol */
NULL, /* set_engine_flags */
NULL, /* decrypt */
NULL, /* delete */
NULL, /* edit */

View File

@ -143,6 +143,7 @@ struct engine_gpg
struct gpgme_io_cbs io_cbs;
gpgme_pinentry_mode_t pinentry_mode;
char request_origin[10];
/* NULL or the data object fed to --override_session_key-fd. */
gpgme_data_t override_session_key;
@ -628,6 +629,24 @@ gpg_new (void **engine, const char *file_name, const char *home_dir,
}
/* Copy flags from CTX into the engine object. */
static void
gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
{
engine_gpg_t gpg = engine;
if (ctx->request_origin && have_gpg_version (gpg, "2.2.6"))
{
if (strlen (ctx->request_origin) + 1 > sizeof gpg->request_origin)
strcpy (gpg->request_origin, "xxx"); /* Too long - force error */
else
strcpy (gpg->request_origin, ctx->request_origin);
}
else
*gpg->request_origin = 0;
}
static gpgme_error_t
gpg_set_locale (void *engine, int category, const char *value)
{
@ -904,6 +923,20 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argc++;
}
if (*gpg->request_origin)
{
argv[argc] = _gpgme_strconcat ("--request-origin=",
gpg->request_origin, NULL);
if (!argv[argc])
{
int saved_err = gpg_error_from_syserror ();
free (fd_data_map);
free_argv (argv);
return saved_err;
}
argc++;
}
if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0"))
{
const char *s = NULL;
@ -3090,6 +3123,7 @@ struct engine_ops _gpgme_engine_ops_gpg =
gpg_set_colon_line_handler,
gpg_set_locale,
NULL, /* set_protocol */
gpg_set_engine_flags, /* set_engine_flags */
gpg_decrypt,
gpg_delete,
gpg_edit,

View File

@ -1287,6 +1287,7 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
NULL, /* set_colon_line_handler */
NULL, /* set_locale */
NULL, /* set_protocol */
NULL, /* set_engine_flags */
NULL, /* decrypt */
NULL, /* delete */
NULL, /* edit */

View File

@ -107,6 +107,8 @@ struct engine_gpgsm
gpgme_data_t inline_data; /* Used to collect D lines. */
char request_origin[10];
struct gpgme_io_cbs io_cbs;
};
@ -521,6 +523,24 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
}
/* Copy flags from CTX into the engine object. */
static void
gpgsm_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
{
engine_gpgsm_t gpgsm = engine;
if (ctx->request_origin)
{
if (strlen (ctx->request_origin) + 1 > sizeof gpgsm->request_origin)
strcpy (gpgsm->request_origin, "xxx"); /* Too long - force error */
else
strcpy (gpgsm->request_origin, ctx->request_origin);
}
else
*gpgsm->request_origin = 0;
}
static gpgme_error_t
gpgsm_set_locale (void *engine, int category, const char *value)
{
@ -1058,6 +1078,20 @@ start (engine_gpgsm_t gpgsm, const char *command)
int nfds;
int i;
if (*gpgsm->request_origin)
{
char *cmd;
cmd = _gpgme_strconcat ("OPTION request-origin=",
gpgsm->request_origin, NULL);
if (!cmd)
return gpg_error_from_syserror ();
err = gpgsm_assuan_simple_command (gpgsm, cmd, NULL, NULL);
free (cmd);
if (err && gpg_err_code (err) != GPG_ERR_UNKNOWN_OPTION)
return err;
}
/* We need to know the fd used by assuan for reads. We do this by
using the assumption that the first returned fd from
assuan_get_active_fds() is always this one. */
@ -2102,6 +2136,7 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
gpgsm_set_colon_line_handler,
gpgsm_set_locale,
NULL, /* set_protocol */
gpgsm_set_engine_flags,
gpgsm_decrypt,
gpgsm_delete, /* decrypt_verify */
NULL, /* edit */

View File

@ -449,6 +449,7 @@ struct engine_ops _gpgme_engine_ops_spawn =
NULL, /* set_colon_line_handler */
NULL, /* set_locale */
NULL, /* set_protocol */
NULL, /* set_engine_flags */
NULL, /* decrypt */
NULL, /* delete */
NULL, /* edit */

View File

@ -1368,6 +1368,7 @@ struct engine_ops _gpgme_engine_ops_uiserver =
uiserver_set_colon_line_handler,
uiserver_set_locale,
uiserver_set_protocol,
NULL, /* set_engine_flags */
uiserver_decrypt,
NULL, /* delete */
NULL, /* edit */

View File

@ -651,6 +651,26 @@ _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
}
/* Pass information about the current context to the engine. The
* engine may use this context to retrieve context specific flags.
* Important: The engine is required to immediately copy the required
* flags to its own context!
*
* This function will eventually be used to reduce the number of
* explicit passed flags. */
void
_gpgme_engine_set_engine_flags (engine_t engine, gpgme_ctx_t ctx)
{
if (!engine)
return;
if (!engine->ops->set_engine_flags)
return;
(*engine->ops->set_engine_flags) (engine->engine, ctx);
}
gpgme_error_t
_gpgme_engine_op_decrypt (engine_t engine,
gpgme_decrypt_flags_t flags,

View File

@ -69,6 +69,7 @@ gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category,
const char *value);
gpgme_error_t _gpgme_engine_set_protocol (engine_t engine,
gpgme_protocol_t protocol);
void _gpgme_engine_set_engine_flags (engine_t engine, gpgme_ctx_t ctx);
void _gpgme_engine_release (engine_t engine);
void _gpgme_engine_set_status_cb (engine_t engine,
gpgme_status_cb_t cb, void *cb_value);

View File

@ -248,6 +248,7 @@ gpgme_release (gpgme_ctx_t ctx)
free (ctx->lc_ctype);
free (ctx->lc_messages);
free (ctx->override_session_key);
free (ctx->request_origin);
_gpgme_engine_info_release (ctx->engine_info);
ctx->engine_info = NULL;
DESTROY_LOCK (ctx->lock);
@ -486,13 +487,8 @@ gpgme_get_armor (gpgme_ctx_t ctx)
}
/* Set the flag NAME for CTX to VALUE. The supported flags are:
*
* - full-status :: With a value of "1" the status callback set by
* gpgme_set_status_cb returns all status lines
* except for PROGRESS lines. With the default of
* "0" the status callback is only called in certain
* situations.
/* Set the flag NAME for CTX to VALUE. Please consult the manual for
* a description of the flags.
*/
gpgme_error_t
gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
@ -535,6 +531,13 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
{
ctx->auto_key_retrieve = abool;
}
else if (!strcmp (name, "request-origin"))
{
free (ctx->request_origin);
ctx->request_origin = strdup (value);
if (!ctx->request_origin)
err = gpg_error_from_syserror ();
}
else
err = gpg_error (GPG_ERR_UNKNOWN_NAME);
@ -576,6 +579,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
{
return ctx->auto_key_retrieve? "1":"";
}
else if (!strcmp (name, "request-origin"))
{
return ctx->request_origin? ctx->request_origin : "";
}
else
return NULL;
}

View File

@ -141,6 +141,8 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
err = 0;
_gpgme_engine_set_engine_flags (ctx->engine, ctx);
if (!err)
{
err = _gpgme_engine_set_pinentry_mode (ctx->engine,

View File

@ -81,6 +81,7 @@ show_usage (int ex)
" --cms use the CMS protocol\n"
" --export-session-key show the session key\n"
" --override-session-key STRING use STRING as session key\n"
" --request-origin STRING use STRING as request origin\n"
" --unwrap remove only the encryption layer\n"
, stderr);
exit (ex);
@ -102,6 +103,7 @@ main (int argc, char **argv)
int print_status = 0;
int export_session_key = 0;
const char *override_session_key = NULL;
const char *request_origin = NULL;
int raw_output = 0;
if (argc)
@ -150,6 +152,14 @@ main (int argc, char **argv)
override_session_key = *argv;
argc--; argv++;
}
else if (!strcmp (*argv, "--request-origin"))
{
argc--; argv++;
if (!argc)
show_usage (1);
request_origin = *argv;
argc--; argv++;
}
else if (!strcmp (*argv, "--unwrap"))
{
flags |= GPGME_DECRYPT_UNWRAP;
@ -199,7 +209,18 @@ main (int argc, char **argv)
override_session_key);
if (err)
{
fprintf (stderr, PGM ": error overriding session key: %s\n",
fprintf (stderr, PGM ": error setting overriding session key: %s\n",
gpgme_strerror (err));
exit (1);
}
}
if (request_origin)
{
err = gpgme_set_ctx_flag (ctx, "request-origin", request_origin);
if (err)
{
fprintf (stderr, PGM ": error setting request_origin: %s\n",
gpgme_strerror (err));
exit (1);
}