summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2018-03-23 15:27:32 +0100
committerWerner Koch <wk@gnupg.org>2018-03-23 15:27:32 +0100
commitb9000bc293164ff62efa7e91e5cf6d5fc19d482f (patch)
treea664a1e81aa8041a86b2ae931255119d4af99089
parenteee68c1b13fbe21c123f469712817e0c81f16383 (diff)
downloadgpgme-b9000bc293164ff62efa7e91e5cf6d5fc19d482f.tar.gz
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>
-rw-r--r--doc/gpgme.texi5
-rw-r--r--src/context.h3
-rw-r--r--src/engine-assuan.c35
-rw-r--r--src/engine-backend.h1
-rw-r--r--src/engine-g13.c1
-rw-r--r--src/engine-gpg.c34
-rw-r--r--src/engine-gpgconf.c1
-rw-r--r--src/engine-gpgsm.c35
-rw-r--r--src/engine-spawn.c1
-rw-r--r--src/engine-uiserver.c1
-rw-r--r--src/engine.c20
-rw-r--r--src/engine.h1
-rw-r--r--src/gpgme.c21
-rw-r--r--src/op-support.c2
-rw-r--r--tests/run-decrypt.c23
15 files changed, 176 insertions, 8 deletions
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 37cf16ac..ab554d86 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -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
diff --git a/src/context.h b/src/context.h
index 1e763d2a..202cf168 100644
--- a/src/context.h
+++ b/src/context.h
@@ -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;
diff --git a/src/engine-assuan.c b/src/engine-assuan.c
index bb2290ac..6e603d9d 100644
--- a/src/engine-assuan.c
+++ b/src/engine-assuan.c
@@ -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 */
diff --git a/src/engine-backend.h b/src/engine-backend.h
index 421eb166..97cf6a10 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -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,
diff --git a/src/engine-g13.c b/src/engine-g13.c
index f8f31780..ec2f7af4 100644
--- a/src/engine-g13.c
+++ b/src/engine-g13.c
@@ -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 */
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index bfe7d131..22d327e0 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -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,
diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c
index 94ae67f0..24867c74 100644
--- a/src/engine-gpgconf.c
+++ b/src/engine-gpgconf.c
@@ -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 */
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index e337fedd..b8e44e7c 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -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 */
diff --git a/src/engine-spawn.c b/src/engine-spawn.c
index 7f78bb50..7b7a9cdf 100644
--- a/src/engine-spawn.c
+++ b/src/engine-spawn.c
@@ -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 */
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index bc3f3fbd..fd5ac174 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -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 */
diff --git a/src/engine.c b/src/engine.c
index 28ba9fdf..e51384f0 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -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,
diff --git a/src/engine.h b/src/engine.h
index 0bf1bb27..34bf8e90 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -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);
diff --git a/src/gpgme.c b/src/gpgme.c
index d0a5afee..9e65c50a 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -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;
}
diff --git a/src/op-support.c b/src/op-support.c
index 817c5691..43cb1c76 100644
--- a/src/op-support.c
+++ b/src/op-support.c
@@ -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,
diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c
index e961293a..f4c47544 100644
--- a/tests/run-decrypt.c
+++ b/tests/run-decrypt.c
@@ -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);
}