diff options
| author | Werner Koch <[email protected]> | 2018-03-23 14:27:32 +0000 | 
|---|---|---|
| committer | Werner Koch <[email protected]> | 2018-03-23 14:27:32 +0000 | 
| commit | b9000bc293164ff62efa7e91e5cf6d5fc19d482f (patch) | |
| tree | a664a1e81aa8041a86b2ae931255119d4af99089 | |
| parent | build: Allow building with released libgpg-error. (diff) | |
| download | gpgme-b9000bc293164ff62efa7e91e5cf6d5fc19d482f.tar.gz gpgme-b9000bc293164ff62efa7e91e5cf6d5fc19d482f.zip | |
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 <[email protected]>
Diffstat (limited to '')
| -rw-r--r-- | doc/gpgme.texi | 5 | ||||
| -rw-r--r-- | src/context.h | 3 | ||||
| -rw-r--r-- | src/engine-assuan.c | 35 | ||||
| -rw-r--r-- | src/engine-backend.h | 1 | ||||
| -rw-r--r-- | src/engine-g13.c | 1 | ||||
| -rw-r--r-- | src/engine-gpg.c | 34 | ||||
| -rw-r--r-- | src/engine-gpgconf.c | 1 | ||||
| -rw-r--r-- | src/engine-gpgsm.c | 35 | ||||
| -rw-r--r-- | src/engine-spawn.c | 1 | ||||
| -rw-r--r-- | src/engine-uiserver.c | 1 | ||||
| -rw-r--r-- | src/engine.c | 20 | ||||
| -rw-r--r-- | src/engine.h | 1 | ||||
| -rw-r--r-- | src/gpgme.c | 21 | ||||
| -rw-r--r-- | src/op-support.c | 2 | ||||
| -rw-r--r-- | tests/run-decrypt.c | 23 | 
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);          } | 
