diff options
| -rw-r--r-- | NEWS | 15 | ||||
| -rw-r--r-- | TODO | 10 | ||||
| -rw-r--r-- | doc/ChangeLog | 4 | ||||
| -rw-r--r-- | doc/gpgme.texi | 25 | ||||
| -rw-r--r-- | gpgme/ChangeLog | 10 | ||||
| -rw-r--r-- | gpgme/engine-gpgsm.c | 91 | ||||
| -rw-r--r-- | gpgme/engine-gpgsm.h | 4 | ||||
| -rw-r--r-- | gpgme/engine.c | 28 | ||||
| -rw-r--r-- | gpgme/engine.h | 5 | ||||
| -rw-r--r-- | gpgme/keylist.c | 67 | ||||
| -rw-r--r-- | gpgme/rungpg.c | 33 | ||||
| -rw-r--r-- | gpgme/rungpg.h | 3 | 
12 files changed, 281 insertions, 14 deletions
| @@ -1,4 +1,11 @@ + * gpgme_op_encrypt does now fail with GPGME_Invalid_Recipients if +   some recipients have been invalid, whereas earlier versions +   succeeded in this case.  The plaintext is still encrypted for all valid +   recipients, so the application might take this error as a hint that +   the ciphertext is not usable for all requested recipients. +   Information about invalid recipients is available with gpgme_get_op_info. +   * New interfaces gpgme_set_include_certs and gpgme_get_include_certs     to set and get the number of certifications to include in S/MIME     signed messages. @@ -6,12 +13,7 @@   * New interfaces gpgme_op_encrypt_sign and gpgme_op_encrypt_sign_start     to encrypt and sign a message in a combined operation. - * gpgme_op_encrypt does now fail with GPGME_Invalid_Recipients if -   some recipients have been invalid, whereas earlier versions -   succeeded in this case.  The plaintext is still encrypted for all valid -   recipients, so the application might take this error as a hint that -   the ciphertext is not usable for all requested recipients. -   Information about invalid recipients is available with gpgme_get_op_info. + * New interface gpgme_op_keylist_ext_start to search for multiple patterns.   * Interface changes relative to the 0.3.3 release:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -20,6 +22,7 @@ gpgme_set_include_certs		NEW  gpgme_get_include_certs		NEW  gpgme_op_encrypt_sign		NEW  gpgme_op_encrypt_sign_start	NEW +gpgme_op_keylist_ext_start	NEW  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  Noteworthy changes in version 0.3.3 (2002-02-12) @@ -44,10 +44,10 @@ Hey Emacs, this is -*- outline -*- mode!     get GPGME_No_Passphrase." Bug reported by Stephane Corthesy.  * Tests -  Write a fake gpg-agent so that we can supply known passphrases to -  gpgsm and setup the configuration files to use the agent.  Without -  this we are testing a currently running gpg-agent which is not a -  clever idea. +** Write a fake gpg-agent so that we can supply known passphrases to +   gpgsm and setup the configuration files to use the agent.  Without +   this we are testing a currently running gpg-agent which is not a +   clever idea.  ** t-data  *** Test gpgme_data_release_and_get_mem.  *** Test gpgme_data_rewind for invalid types. @@ -55,8 +55,6 @@ Hey Emacs, this is -*- outline -*- mode!  * Build suite  ** Make sure everything is cleaned correctly (esp. test area). -** There is a spurious 4/10 tests failed in some conditions. -   Rebuilding from scratch works around that.  * Architecture support  ** Implement posix-sema.c diff --git a/doc/ChangeLog b/doc/ChangeLog index 8ae8ae2b..56be6280 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,9 @@  2002-02-27  Marcus Brinkmann  <[email protected]> +	* gpgme.texi (Listing Keys): Document gpgme_op_keylist_ext_start. + +2002-02-27  Marcus Brinkmann  <[email protected]> +  	* gpgme.texi (Encrypting a Plaintext): Document  	GPGME_Invalid_Recipients.  	(Error Values): Likewise. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 5c2a084d..a012abb8 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -1261,6 +1261,31 @@ valid pointer, and passes through any errors that are reported by the  crypto engine support routines.  @end deftypefun +@deftypefun GpgmeError gpgme_op_keylist_ext_start (@w{GpgmeCtx @var{ctx}}, @w{const char *@var{pattern}[]}, @w{int @var{secret_only}}, @w{int @var{reserved}}) +The function @code{gpgme_op_keylist_ext_start} initiates an extended +key listing operation inside the context @var{ctx}.  It sets +everything up so that subsequent invocations of +@code{gpgme_op_keylist_next} return the keys in the list. + +If @var{pattern} or @var{*pattern} is @code{NULL}, all available keys +are returned.  Otherwise, @var{pattern} is a @code{NULL} terminated +array of strings that are used to limit the list to all keys matching +at least one of the patterns verbatim. + +If @var{secret_only} is not @code{0}, the list is restricted to secret +keys only. + +The value of @var{reserved} must be @code{0}. + +The context will be busy until either all keys are received (and +@code{gpgme_op_keylist_next} returns @code{GPGME_EOF}), or +@code{gpgme_op_keylist_end} is called to finish the operation. + +The function returns @code{GPGME_Invalid_Value} if @var{ctx} is not a +valid pointer, and passes through any errors that are reported by the +crypto engine support routines. +@end deftypefun +  @deftypefun GpgmeError gpgme_op_keylist_next (@w{GpgmeCtx @var{ctx}}, @w{GpgmeKey *@var{r_key}})  The function @code{gpgme_op_keylist_next} returns the next key in the  list created by a previous @code{gpgme_op_keylist_start} operation in diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 55358f70..58f09c62 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,5 +1,15 @@  2002-02-27  Marcus Brinkmann  <[email protected]> +	* rungpg.h (_gpgme_gpg_op_keylist_ext): New prototype. +	* rungpg.c (_gpgme_gpg_op_keylist_ext): New function. +	* engine-gpgsm.h (_gpgme_gpgsm_op_keylist_ext): New prototype. +	* engine-gpgsm.c (_gpgme_gpgsm_op_keylist_ext): New function. +	* engine.h (_gpgme_engine_op_keylist_ext): New prototype. +	* engine.c (_gpgme_engine_op_keylist_ext): New function. +	* keylist.c (gpgme_op_keylist_ext_start): New function. + +2002-02-27  Marcus Brinkmann  <[email protected]> +  	* gpgme.h: Add new error code GPGME_Invalid_Recipient.  	* encrypt.c (struct encrypt_result_s): New member invalid_recipients,  	rename no_recipients to no_valid_recipients. diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index a88d6384..32ee3a07 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -602,6 +602,97 @@ _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,  GpgmeError +_gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm, const char *pattern[], +			     int secret_only, int reserved, int keylist_mode) +{ +  char *line; +  /* Length is "LISTSECRETKEYS " + p + '\0'.  */ +  int length = 15 + 1; +  char *linep; + +  if (reserved) +    return mk_error (Invalid_Value); + +  if (pattern && *pattern) +    { +      const char **pat = pattern; + +      while (*pat) +	{ +	  const char *patlet = *pat; + +	  while (*patlet) +	    { +	      length++; +	      if (*patlet == '%' || *patlet == ' ' || *patlet == '+') +		length += 2; +	      patlet++; +	    } +	  pat++; +	  /* This will allocate one byte more than necessary.  */ +	  length++; +	} +    } +  line = xtrymalloc (length); +  if (!line) +    return mk_error (Out_Of_Core); +  if (secret_only) +    { +      strcpy (line, "LISTSECRETKEYS "); +      linep = &line[15]; +    } +  else +    { +      strcpy (line, "LISTKEYS "); +      linep = &line[9]; +    } + +  if (pattern && *pattern) +    { +      while (*pattern) +	{ +	  const char *patlet = *pattern; + +	  while (*patlet) +	    { +	      switch (*patlet) +		{ +		case '%': +		  *(linep++) = '%'; +		  *(linep++) = '2'; +		  *(linep++) = '5'; +		  break; +		case ' ': +		  *(linep++) = '%'; +		  *(linep++) = '2'; +		  *(linep++) = '0'; +		  break; +		case '+': +		  *(linep++) = '%'; +		  *(linep++) = '2'; +		  *(linep++) = 'B'; +		  break; +		default: +		  *(linep++) = *patlet; +		  break; +		} +	      patlet++; +	    } +	  pattern++; +	} +    } +  *linep = '\0'; + +  _gpgme_io_close (gpgsm->input_fd); +  _gpgme_io_close (gpgsm->output_fd); +  _gpgme_io_close (gpgsm->message_fd); + +  gpgsm->command = line; +  return 0; +} + + +GpgmeError  _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,  		      GpgmeSigMode mode, int use_armor,  		      int use_textmode, int include_certs, diff --git a/gpgme/engine-gpgsm.h b/gpgme/engine-gpgsm.h index b629ed6f..ecd80b40 100644 --- a/gpgme/engine-gpgsm.h +++ b/gpgme/engine-gpgsm.h @@ -50,6 +50,10 @@ GpgmeError _gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data,  GpgmeError _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata);  GpgmeError _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,  				    int secret_only, int keylist_mode); +GpgmeError _gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm, +					const char *pattern[], +					int secret_only, int reserved, +					int keylist_mode);  GpgmeError _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in,  				 GpgmeData out,  				 GpgmeSigMode mode, int use_armor, diff --git a/gpgme/engine.c b/gpgme/engine.c index 8841b20b..c1dd630e 100644 --- a/gpgme/engine.c +++ b/gpgme/engine.c @@ -438,9 +438,10 @@ _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata)    return 0;  } +  GpgmeError -_gpgme_engine_op_keylist (EngineObject engine, const char *pattern, int secret_only, -			  int keylist_mode) +_gpgme_engine_op_keylist (EngineObject engine, const char *pattern, +			  int secret_only, int keylist_mode)  {    if (!engine)      return mk_error (Invalid_Value); @@ -459,6 +460,29 @@ _gpgme_engine_op_keylist (EngineObject engine, const char *pattern, int secret_o    return 0;  } + +GpgmeError +_gpgme_engine_op_keylist_ext (EngineObject engine, const char *pattern[], +			      int secret_only, int reserved, int keylist_mode) +{ +  if (!engine) +    return mk_error (Invalid_Value); + +  switch (engine->protocol) +    { +    case GPGME_PROTOCOL_OpenPGP: +      return _gpgme_gpg_op_keylist_ext (engine->engine.gpg, pattern, +					secret_only, reserved, keylist_mode); +    case GPGME_PROTOCOL_CMS: +      return _gpgme_gpgsm_op_keylist_ext (engine->engine.gpgsm, pattern, +					  secret_only, reserved, keylist_mode); +    default: +      break; +    } +  return 0; +} + +  GpgmeError  _gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out,  		       GpgmeSigMode mode, int use_armor, diff --git a/gpgme/engine.h b/gpgme/engine.h index d8881a10..f6840217 100644 --- a/gpgme/engine.h +++ b/gpgme/engine.h @@ -60,6 +60,11 @@ GpgmeError _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata);  GpgmeError _gpgme_engine_op_keylist (EngineObject engine, const char *pattern,  				     int secret_only,  				     int keylist_mode); +GpgmeError _gpgme_engine_op_keylist_ext (EngineObject engine, +					 const char *pattern[], +					 int secret_only, +					 int reserved, +					 int keylist_mode);  GpgmeError _gpgme_engine_op_sign (EngineObject engine, GpgmeData in,  				  GpgmeData out, GpgmeSigMode mode,  				  int use_armor, int use_textmode, diff --git a/gpgme/keylist.c b/gpgme/keylist.c index 91bdbc35..55d427d2 100644 --- a/gpgme/keylist.c +++ b/gpgme/keylist.c @@ -506,6 +506,73 @@ gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)  /** + * gpgme_op_keylist_ext_start: + * @c: context  + * @pattern: a NULL terminated array of search patterns + * @secret_only: List only keys where the secret part is available + * @reserved: Should be 0. + *  + * Note that this function also cancels a pending key listing + * operaton. To actually retrieve the key, use + * gpgme_op_keylist_next(). + *  + * Return value:  0 on success or an errorcode.  + **/ +GpgmeError +gpgme_op_keylist_ext_start (GpgmeCtx ctx, const char *pattern[], +			    int secret_only, int reserved) +{ +  GpgmeError err = 0; + +  if (!ctx) +    return mk_error (Invalid_Value); +  ctx->pending = 1; + +  _gpgme_release_result (ctx); + +  if (ctx->engine) +    { +      _gpgme_engine_release (ctx->engine);  +      ctx->engine = NULL; +    } +  gpgme_key_release (ctx->tmp_key); +  ctx->tmp_key = NULL; +  /* Fixme: Release key_queue.  */ +     +  err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS +			   : GPGME_PROTOCOL_OpenPGP, &ctx->engine); +  if (err) +    goto leave; + +  _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx); +  err = _gpgme_engine_set_colon_line_handler (ctx->engine, +					      keylist_colon_handler, ctx); +  if (err) +    goto leave; + +  /* We don't want to use the verbose mode as this will also print  +     the key signatures which is in most cases not needed and furthermore we  +     just ignore those lines - This should speed up things */ +  _gpgme_engine_set_verbosity (ctx->engine, 0); + +  err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only, +				      reserved, ctx->keylist_mode); + +  if (!err)	/* And kick off the process.  */ +    err = _gpgme_engine_start (ctx->engine, ctx); + + leave: +  if (err) +    { +      ctx->pending = 0;  +      _gpgme_engine_release (ctx->engine); +      ctx->engine = NULL; +    } +  return err; +} + + +/**   * gpgme_op_keylist_next:   * @c: Context   * @r_key: Returned key object diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index 8738fc38..dc69acba 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -1441,6 +1441,7 @@ _gpgme_gpg_op_import (GpgObject gpg, GpgmeData keydata)    return err;  } +  GpgmeError  _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only,  		       int keylist_mode) @@ -1465,6 +1466,38 @@ _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only,    return err;  } + +GpgmeError +_gpgme_gpg_op_keylist_ext (GpgObject gpg, const char *pattern[], +			   int secret_only, int reserved, int keylist_mode) +{ +  GpgmeError err; + +  if (reserved) +    return mk_error (Invalid_Value); + +  err = _gpgme_gpg_add_arg (gpg, "--with-colons"); +  if (!err) +    err = _gpgme_gpg_add_arg (gpg, "--fixed-list-mode"); +  if (!err) +    err = _gpgme_gpg_add_arg (gpg, "--with-fingerprint"); +  if (!err) +    err = _gpgme_gpg_add_arg (gpg, secret_only ? "--list-secret-keys" +			      : "--list-keys"); +   +  /* Tell the gpg object about the data */ +  if (!err) +    err = _gpgme_gpg_add_arg (gpg, "--"); +  if (!err && pattern && *pattern) +    { +      while (*pattern) +	err = _gpgme_gpg_add_arg (gpg, *(pattern++)); +    } + +  return err; +} + +  GpgmeError  _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,  		    GpgmeSigMode mode, int use_armor, diff --git a/gpgme/rungpg.h b/gpgme/rungpg.h index ed65cf15..58afd8a8 100644 --- a/gpgme/rungpg.h +++ b/gpgme/rungpg.h @@ -137,6 +137,9 @@ GpgmeError _gpgme_gpg_op_genkey (GpgObject gpg, GpgmeData help_data,  GpgmeError _gpgme_gpg_op_import (GpgObject gpg, GpgmeData keydata);  GpgmeError _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern,  				  int secret_only, int keylist_mode); +GpgmeError _gpgme_gpg_op_keylist_ext (GpgObject gpg, const char *pattern[], +				      int secret_only, int reserved, +				      int keylist_mode);  GpgmeError _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,  			       GpgmeSigMode mode, int use_armor,  			       int use_textmode, GpgmeCtx ctx /* FIXME */); | 
