diff options
| author | Werner Koch <[email protected]> | 2016-10-25 15:27:49 +0000 | 
|---|---|---|
| committer | Werner Koch <[email protected]> | 2016-10-25 15:28:01 +0000 | 
| commit | b8159eadb5636cd9d93ee60c41e75d5978927870 (patch) | |
| tree | 5b9c857eba89d45fca40f136abb85d95d15f70ee | |
| parent | qt: Improve WKSPublishJob apidoc (diff) | |
| download | gpgme-b8159eadb5636cd9d93ee60c41e75d5978927870.tar.gz gpgme-b8159eadb5636cd9d93ee60c41e75d5978927870.zip | |
core: New API functions gpgme_set_sender, gpgme_get_sender.
* src/context.h (struct gpgme_context): Add field 'sender'.
* src/gpgme.c: Include mbox-util.h.
(gpgme_release): Free SENDER.
(gpgme_set_sender): New.
(gpgme_get_sender): New.
* src/gpgme.def, src/libgpgme.vers: Add new functions.
* src/engine-gpg.c (append_args_from_sender): New.
(gpg_encrypt_sign, gpg_sign): Call append_args_from_sender.
(gpg_verify): Add arg CTX.  Call append_args_from_sender/
* src/engine-gpgsm.c (gpgsm_verify): Add dummy arg CTX.
* src/engine-uiserver.c (uiserver_verify): Ditto.
* src/engine.c (_gpgme_engine_op_verify): Add arg CTX.
* src/verify.c (verify_start): Pass CTX to engine function.
* tests/gpg/t-verify.c (main): Add some checks for new functions.
* tests/run-sign.c (main): Add option --sender.
* tests/run-verify.c (main): Ditto.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to '')
| -rw-r--r-- | NEWS | 6 | ||||
| -rw-r--r-- | doc/gpgme.texi | 43 | ||||
| -rw-r--r-- | src/context.h | 8 | ||||
| -rw-r--r-- | src/engine-backend.h | 3 | ||||
| -rw-r--r-- | src/engine-gpg.c | 31 | ||||
| -rw-r--r-- | src/engine-gpgsm.c | 4 | ||||
| -rw-r--r-- | src/engine-uiserver.c | 7 | ||||
| -rw-r--r-- | src/engine.c | 6 | ||||
| -rw-r--r-- | src/engine.h | 3 | ||||
| -rw-r--r-- | src/gpgme.c | 47 | ||||
| -rw-r--r-- | src/gpgme.def | 3 | ||||
| -rw-r--r-- | src/gpgme.h.in | 6 | ||||
| -rw-r--r-- | src/libgpgme.vers | 3 | ||||
| -rw-r--r-- | src/verify.c | 3 | ||||
| -rw-r--r-- | tests/gpg/t-verify.c | 49 | ||||
| -rw-r--r-- | tests/run-sign.c | 16 | ||||
| -rw-r--r-- | tests/run-verify.c | 16 | 
17 files changed, 234 insertions, 20 deletions
| @@ -2,6 +2,12 @@ Noteworthy changes in version 1.7.2 (unreleased)  ------------------------------------------------ + * Interface changes relative to the 1.7.1 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gpgme_set_sender                NEW. + gpgme_get_sender                NEW. + +  Noteworthy changes in version 1.7.1 (2016-10-18)  ------------------------------------------------ diff --git a/doc/gpgme.texi b/doc/gpgme.texi index cc598887..9fae9aaf 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -186,6 +186,7 @@ Context Attributes  * Protocol Selection::            Selecting the protocol used by a context.  * Crypto Engine::                 Configuring the crypto engine. +* Setting the Sender::            How to tell the engine the sender.  * ASCII Armor::                   Requesting @acronym{ASCII} armored output.  * Text Mode::                     Choosing canonical text mode.  * Offline Mode::                  Choosing offline mode. @@ -2366,6 +2367,7 @@ started.  In fact, these references are accessed through the  @menu  * Protocol Selection::            Selecting the protocol used by a context.  * Crypto Engine::                 Configuring the crypto engine. +* Setting the Sender::            How to tell the engine the sender.  * ASCII Armor::                   Requesting @acronym{ASCII} armored output.  * Text Mode::                     Choosing canonical text mode.  * Offline Mode::                  Choosing offline mode. @@ -2448,6 +2450,47 @@ successful, or an eror code on failure.  @end deftypefun +@node Setting the Sender +@subsection How to tell the engine the sender. +@cindex context, sender +@cindex sender +@cindex From: + +Some engines can make use of the sender’s address, for example to +figure out the best user id in certain trust models.  For verification +and signing of mails, it is thus suggested to let the engine know the +sender ("From:") address.  @acronym{GPGME} provides two functions to +accomplish that.  Note that the esoteric use of multiple "From:" +addresses is not supported. + +@deftypefun gpgme_error_t gpgme_set_sender @ +      (@w{gpgme_ctx_t @var{ctx}}, @ +       @w{int @var{address}}) + +The function @code{gpgme_set_sender} specifies the sender address for +use in sign and verify operations.  @var{address} is expected to be +the ``addr-spec'' part of an address but my also be a complete mailbox +address, in which case this function extracts the ``addr-spec'' from +it.  Using @code{NULL} for @var{address} clears the sender address. + +The function returns 0 on success or an error code on failure.  The +most likely failure is that no valid ``addr-spec'' was found in +@var{address}. + +@end deftypefun + +@deftypefun @w{const char *} gpgme_get_sender @ +      (@w{gpgme_ctx_t @var{ctx}}) + +The function @code{gpgme_get_sender} returns the current sender +address from the context, or NULL if none was set.  The returned +value is valid as long as the @var{ctx} is valid and +@code{gpgme_set_sender} has not been called again. + +@end deftypefun + + +  @c FIXME: Unfortunately, using @acronym here breaks texi2dvi.  @node ASCII Armor  @subsection @acronym{ASCII} Armor diff --git a/src/context.h b/src/context.h index 4b12c3bd..f6c1ad1e 100644 --- a/src/context.h +++ b/src/context.h @@ -119,16 +119,18 @@ struct gpgme_context    /* Number of certs to be included.  */    unsigned int include_certs; -  /* The number of keys in signers.  */ +  /* The actual number of keys in SIGNERS, the allocated size of the +   * array, and the array with the signing keys.  */    unsigned int signers_len; - -  /* Size of the following array.  */    unsigned int signers_size;    gpgme_key_t *signers;    /* The signature notations for this context.  */    gpgme_sig_notation_t sig_notations; +  /* The sender's addr-spec or NULL.  */ +  char *sender; +    /* The locale for the pinentry.  */    char *lc_ctype;    char *lc_messages; diff --git a/src/engine-backend.h b/src/engine-backend.h index ccab0e3e..e02c7157 100644 --- a/src/engine-backend.h +++ b/src/engine-backend.h @@ -111,7 +111,8 @@ struct engine_ops  			 gpgme_ctx_t ctx /* FIXME */);    gpgme_error_t (*trustlist) (void *engine, const char *pattern);    gpgme_error_t (*verify) (void *engine, gpgme_data_t sig, -			   gpgme_data_t signed_text, gpgme_data_t plaintext); +			   gpgme_data_t signed_text, gpgme_data_t plaintext, +                           gpgme_ctx_t ctx);    gpgme_error_t  (*getauditlog) (void *engine, gpgme_data_t output,                                   unsigned int flags);    gpgme_error_t  (*opassuan_transact) (void *engine, diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 4415c946..cb52dea7 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -1646,6 +1646,23 @@ append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)  static gpgme_error_t +append_args_from_sender (engine_gpg_t gpg, gpgme_ctx_t ctx) +{ +  gpgme_error_t err; + +  if (ctx->sender && have_gpg_version (gpg, "2.1.15")) +    { +      err = add_arg (gpg, "--sender"); +      if (!err) +        err = add_arg (gpg, ctx->sender); +    } +  else +    err = 0; +  return err; +} + + +static gpgme_error_t  append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)  {    gpgme_error_t err = 0; @@ -1893,6 +1910,9 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],      err = append_args_from_signers (gpg, ctx);    if (!err) +    err = append_args_from_sender (gpg, ctx); + +  if (!err)      err = append_args_from_sig_notations (gpg, ctx);    /* Tell the gpg object about the data.  */ @@ -2794,6 +2814,8 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,    if (!err)      err = append_args_from_signers (gpg, ctx);    if (!err) +    err = append_args_from_sender (gpg, ctx); +  if (!err)      err = append_args_from_sig_notations (gpg, ctx);    if (gpgme_data_get_file_name (in)) @@ -2845,12 +2867,15 @@ gpg_trustlist (void *engine, const char *pattern)  static gpgme_error_t  gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, -	    gpgme_data_t plaintext) +	    gpgme_data_t plaintext, gpgme_ctx_t ctx)  {    engine_gpg_t gpg = engine; -  gpgme_error_t err = 0; +  gpgme_error_t err; -  if (plaintext) +  err = append_args_from_sender (gpg, ctx); +  if (err) +    ; +  else if (plaintext)      {        /* Normal or cleartext signature.  */        err = add_arg (gpg, "--output"); diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index e7e2a20d..0ce4a6d1 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -1901,11 +1901,13 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,  static gpgme_error_t  gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, -	      gpgme_data_t plaintext) +	      gpgme_data_t plaintext, gpgme_ctx_t ctx)  {    engine_gpgsm_t gpgsm = engine;    gpgme_error_t err; +  (void)ctx; +    if (!gpgsm)      return gpg_error (GPG_ERR_INV_VALUE); diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c index 63e77de6..76fa4d79 100644 --- a/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -1243,13 +1243,16 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,  /* FIXME: Missing a way to specify --silent.  */  static gpgme_error_t  uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, -	      gpgme_data_t plaintext) +                 gpgme_data_t plaintext, gpgme_ctx_t ctx)  {    engine_uiserver_t uiserver = engine;    gpgme_error_t err;    const char *protocol;    char *cmd; +  (void)ctx; /* FIXME: We should to add a --sender option to the +              * UISever protocol.  */ +    if (!uiserver)      return gpg_error (GPG_ERR_INV_VALUE);    if (uiserver->protocol == GPGME_PROTOCOL_DEFAULT) @@ -1395,6 +1398,6 @@ struct engine_ops _gpgme_engine_ops_uiserver =      uiserver_cancel,      NULL,		/* cancel_op */      NULL,               /* passwd */ -    NULL,                /* set_pinentry_mode */ +    NULL,               /* set_pinentry_mode */      NULL                /* opspawn */    }; diff --git a/src/engine.c b/src/engine.c index a1173a07..f5dfe51f 100644 --- a/src/engine.c +++ b/src/engine.c @@ -902,7 +902,8 @@ _gpgme_engine_op_trustlist (engine_t engine, const char *pattern)  gpgme_error_t  _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig, -			 gpgme_data_t signed_text, gpgme_data_t plaintext) +			 gpgme_data_t signed_text, gpgme_data_t plaintext, +                         gpgme_ctx_t ctx)  {    if (!engine)      return gpg_error (GPG_ERR_INV_VALUE); @@ -910,7 +911,8 @@ _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,    if (!engine->ops->verify)      return gpg_error (GPG_ERR_NOT_IMPLEMENTED); -  return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext); +  return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext, +                                 ctx);  } diff --git a/src/engine.h b/src/engine.h index 4ce2bed1..2999ab64 100644 --- a/src/engine.h +++ b/src/engine.h @@ -152,7 +152,8 @@ gpgme_error_t _gpgme_engine_op_trustlist (engine_t engine,  					  const char *pattern);  gpgme_error_t _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,  				       gpgme_data_t signed_text, -				       gpgme_data_t plaintext); +				       gpgme_data_t plaintext, +                                       gpgme_ctx_t ctx);  gpgme_error_t _gpgme_engine_op_getauditlog (engine_t engine,                                              gpgme_data_t output, diff --git a/src/gpgme.c b/src/gpgme.c index d59f8080..6d0dbffa 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -38,6 +38,7 @@  #include "debug.h"  #include "priv-io.h"  #include "sys-util.h" +#include "mbox-util.h"  /* The default locale.  */ @@ -275,12 +276,10 @@ gpgme_release (gpgme_ctx_t ctx)    _gpgme_release_result (ctx);    _gpgme_signers_clear (ctx);    _gpgme_sig_notation_clear (ctx); -  if (ctx->signers) -    free (ctx->signers); -  if (ctx->lc_ctype) -    free (ctx->lc_ctype); -  if (ctx->lc_messages) -    free (ctx->lc_messages); +  free (ctx->sender); +  free (ctx->signers); +  free (ctx->lc_ctype); +  free (ctx->lc_messages);    _gpgme_engine_info_release (ctx->engine_info);    ctx->engine_info = NULL;    DESTROY_LOCK (ctx->lock); @@ -459,6 +458,42 @@ gpgme_get_protocol_name (gpgme_protocol_t protocol)      }  } + +/* Store the sender's address in the context.  ADDRESS is addr-spec of + * mailbox but my also be a complete mailbox, in which case this + * function extracts the addr-spec from it.  Returns 0 on success or + * an error code if no valid addr-spec could be extracted from + * ADDRESS.  */ +gpgme_error_t +gpgme_set_sender (gpgme_ctx_t ctx, const char *address) +{ +  char *p = NULL; + +  TRACE_BEG1 (DEBUG_CTX, "gpgme_set_sender", ctx, "sender='%s'", +              address?address:"(null)"); + +  if (!ctx || (address && !(p = _gpgme_mailbox_from_userid (address)))) +    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); + +  free (ctx->sender); +  ctx->sender = p; +  return TRACE_ERR (0); +} + + +/* Return the sender's address (addr-spec part) from the context or + * NULL if none was set.  The returned value is valid as long as the + * CTX is valid and gpgme_set_sender has not been used.  */ +const char * +gpgme_get_sender (gpgme_ctx_t ctx) +{ +  TRACE1 (DEBUG_CTX, "gpgme_get_sender", ctx, "sender='%s'", +          ctx?ctx->sender:""); + +  return ctx->sender; +} + +  /* Enable or disable the use of an ascii armor for all output.  */  void  gpgme_set_armor (gpgme_ctx_t ctx, int use_armor) diff --git a/src/gpgme.def b/src/gpgme.def index c94c9607..d633df57 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -246,5 +246,8 @@ EXPORTS      gpgme_addrspec_from_uid               @186 +    gpgme_set_sender                      @187 +    gpgme_get_sender                      @188 +  ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 5c914ae7..94ef51de 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1161,6 +1161,12 @@ gpgme_error_t gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,  /* Get the sig notations for this context.  */  gpgme_sig_notation_t gpgme_sig_notation_get (gpgme_ctx_t ctx); +/* Store a sender address in the context.  */ +gpgme_error_t gpgme_set_sender (gpgme_ctx_t ctx, const char *address); + +/* Get the sender address from the context.  */ +const char *gpgme_get_sender (gpgme_ctx_t ctx); +  /* diff --git a/src/libgpgme.vers b/src/libgpgme.vers index d3962db0..42f00d5a 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -119,6 +119,9 @@ GPGME_1.1 {      gpgme_op_interact;      gpgme_addrspec_from_uid; + +    gpgme_set_sender; +    gpgme_get_sender;  }; diff --git a/src/verify.c b/src/verify.c index eb1cc108..faa8deb9 100644 --- a/src/verify.c +++ b/src/verify.c @@ -1104,7 +1104,8 @@ verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t sig,    if (!sig)      return gpg_error (GPG_ERR_NO_DATA); -  return _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext); +  return _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext, +                                  ctx);  } diff --git a/tests/gpg/t-verify.c b/tests/gpg/t-verify.c index 9842d3af..f955cc9d 100644 --- a/tests/gpg/t-verify.c +++ b/tests/gpg/t-verify.c @@ -209,6 +209,7 @@ main (int argc, char *argv[])    gpgme_error_t err;    gpgme_data_t sig, text;    gpgme_verify_result_t result; +  const char *s;    (void)argc;    (void)argv; @@ -270,6 +271,54 @@ main (int argc, char *argv[])        exit (1);      } +  /* Checking that set/get_sernder works.  */ +  err = gpgme_set_sender (ctx, "[email protected]"); +  fail_if_err (err); +  s = gpgme_get_sender (ctx); +  if (!s || strcmp (s, "[email protected]")) +    { +      fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n", +               __FILE__, __LINE__); +      exit (1); +    } + +  err = gpgme_set_sender (ctx, "<[email protected]>"); +  fail_if_err (err); +  s = gpgme_get_sender (ctx); +  if (!s || strcmp (s, "[email protected]")) +    { +      fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n", +               __FILE__, __LINE__); +      exit (1); +    } + +  err = gpgme_set_sender (ctx, "Foo bar (comment) <[email protected]>"); +  fail_if_err (err); +  s = gpgme_get_sender (ctx); +  if (!s || strcmp (s, "[email protected]")) +    { +      fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n", +               __FILE__, __LINE__); +      exit (1); +    } + +  err = gpgme_set_sender (ctx, "foo"); +  if (gpgme_err_code (err) != GPG_ERR_INV_VALUE) +    { +      fprintf (stderr, "%s:%i: gpgme_set_sender didn't detect bogus address\n", +               __FILE__, __LINE__); +      exit (1); +    } +  /* (the former address should still be there.)  */ +  s = gpgme_get_sender (ctx); +  if (!s || strcmp (s, "[email protected]")) +    { +      fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n", +               __FILE__, __LINE__); +      exit (1); +    } + +    gpgme_data_release (sig);    gpgme_data_release (text);    gpgme_release (ctx); diff --git a/tests/run-sign.c b/tests/run-sign.c index 70853ed6..f790cb64 100644 --- a/tests/run-sign.c +++ b/tests/run-sign.c @@ -83,6 +83,7 @@ show_usage (int ex)           "  --uiserver       use the UI server\n"           "  --loopback       use a loopback pinentry\n"           "  --key NAME       use key NAME for signing\n" +         "  --sender MBOX    use MBOX as sender address\n"           , stderr);    exit (ex);  } @@ -101,6 +102,7 @@ main (int argc, char **argv)    gpgme_sign_result_t result;    int print_status = 0;    int use_loopback = 0; +  const char *sender = NULL;    if (argc)      { argc--; argv++; } @@ -148,6 +150,14 @@ main (int argc, char **argv)            key_string = *argv;            argc--; argv++;          } +      else if (!strcmp (*argv, "--sender")) +        { +          argc--; argv++; +          if (!argc) +            show_usage (1); +          sender = *argv; +          argc--; argv++; +        }        else if (!strcmp (*argv, "--loopback"))          {            use_loopback = 1; @@ -192,6 +202,12 @@ main (int argc, char **argv)        gpgme_key_unref (akey);      } +  if (sender) +    { +      err = gpgme_set_sender (ctx, sender); +      fail_if_err (err); +    } +    err = gpgme_data_new_from_file (&in, *argv, 1);    if (err)      { diff --git a/tests/run-verify.c b/tests/run-verify.c index ebc20d97..22242c00 100644 --- a/tests/run-verify.c +++ b/tests/run-verify.c @@ -221,6 +221,7 @@ show_usage (int ex)           "  --status         print status lines from the backend\n"           "  --openpgp        use the OpenPGP protocol (default)\n"           "  --cms            use the CMS protocol\n" +         "  --sender MBOX    use MBOX as sender address\n"           , stderr);    exit (ex);  } @@ -239,6 +240,7 @@ main (int argc, char **argv)    gpgme_data_t msg = NULL;    gpgme_verify_result_t result;    int print_status = 0; +  const char *sender = NULL;    if (argc)      { argc--; argv++; } @@ -273,6 +275,14 @@ main (int argc, char **argv)            protocol = GPGME_PROTOCOL_CMS;            argc--; argv++;          } +      else if (!strcmp (*argv, "--sender")) +        { +          argc--; argv++; +          if (!argc) +            show_usage (1); +          sender = *argv; +          argc--; argv++; +        }        else if (!strncmp (*argv, "--", 2))          show_usage (1); @@ -313,6 +323,12 @@ main (int argc, char **argv)      }    /* gpgme_set_ctx_flag (ctx, "raw-description", "1"); */ +  if (sender) +    { +      err = gpgme_set_sender (ctx, sender); +      fail_if_err (err); +    } +    err = gpgme_data_new_from_stream (&sig, fp_sig);    if (err)      { | 
