2002-02-27  Marcus Brinkmann  <marcus@g10code.de>

	* gpgme.texi (Listing Keys): Document gpgme_op_keylist_ext_start.

gpgme/
2002-02-27  Marcus Brinkmann  <marcus@g10code.de>

	* 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.
This commit is contained in:
Marcus Brinkmann 2002-02-27 00:59:31 +00:00
parent 31b2a458ff
commit da2cd9aa44
12 changed files with 282 additions and 15 deletions

17
NEWS
View File

@ -1,11 +1,4 @@
* 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.
* 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 * gpgme_op_encrypt does now fail with GPGME_Invalid_Recipients if
some recipients have been invalid, whereas earlier versions some recipients have been invalid, whereas earlier versions
succeeded in this case. The plaintext is still encrypted for all valid succeeded in this case. The plaintext is still encrypted for all valid
@ -13,6 +6,15 @@
the ciphertext is not usable for all requested recipients. the ciphertext is not usable for all requested recipients.
Information about invalid recipients is available with gpgme_get_op_info. 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.
* New interfaces gpgme_op_encrypt_sign and gpgme_op_encrypt_sign_start
to encrypt and sign a message in a combined operation.
* New interface gpgme_op_keylist_ext_start to search for multiple patterns.
* Interface changes relative to the 0.3.3 release: * Interface changes relative to the 0.3.3 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_op_encrypt CHANGED: Can fail with GPGME_Invalid_Recipients gpgme_op_encrypt CHANGED: Can fail with GPGME_Invalid_Recipients
@ -20,6 +22,7 @@ gpgme_set_include_certs NEW
gpgme_get_include_certs NEW gpgme_get_include_certs NEW
gpgme_op_encrypt_sign NEW gpgme_op_encrypt_sign NEW
gpgme_op_encrypt_sign_start NEW gpgme_op_encrypt_sign_start NEW
gpgme_op_keylist_ext_start NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.3.3 (2002-02-12) Noteworthy changes in version 0.3.3 (2002-02-12)

10
TODO
View File

@ -44,10 +44,10 @@ Hey Emacs, this is -*- outline -*- mode!
get GPGME_No_Passphrase." Bug reported by Stephane Corthesy. get GPGME_No_Passphrase." Bug reported by Stephane Corthesy.
* Tests * Tests
Write a fake gpg-agent so that we can supply known passphrases to ** Write a fake gpg-agent so that we can supply known passphrases to
gpgsm and setup the configuration files to use the agent. Without gpgsm and setup the configuration files to use the agent. Without
this we are testing a currently running gpg-agent which is not a this we are testing a currently running gpg-agent which is not a
clever idea. clever idea.
** t-data ** t-data
*** Test gpgme_data_release_and_get_mem. *** Test gpgme_data_release_and_get_mem.
*** Test gpgme_data_rewind for invalid types. *** Test gpgme_data_rewind for invalid types.
@ -55,8 +55,6 @@ Hey Emacs, this is -*- outline -*- mode!
* Build suite * Build suite
** Make sure everything is cleaned correctly (esp. test area). ** 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 * Architecture support
** Implement posix-sema.c ** Implement posix-sema.c

View File

@ -1,3 +1,7 @@
2002-02-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Listing Keys): Document gpgme_op_keylist_ext_start.
2002-02-27 Marcus Brinkmann <marcus@g10code.de> 2002-02-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Encrypting a Plaintext): Document * gpgme.texi (Encrypting a Plaintext): Document

View File

@ -1261,6 +1261,31 @@ valid pointer, and passes through any errors that are reported by the
crypto engine support routines. crypto engine support routines.
@end deftypefun @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}}) @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 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 list created by a previous @code{gpgme_op_keylist_start} operation in

View File

@ -1,3 +1,13 @@
2002-02-27 Marcus Brinkmann <marcus@g10code.de>
* 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 <marcus@g10code.de> 2002-02-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.h: Add new error code GPGME_Invalid_Recipient. * gpgme.h: Add new error code GPGME_Invalid_Recipient.

View File

@ -601,6 +601,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 GpgmeError
_gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out, _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,
GpgmeSigMode mode, int use_armor, GpgmeSigMode mode, int use_armor,

View File

@ -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_import (GpgsmObject gpgsm, GpgmeData keydata);
GpgmeError _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern, GpgmeError _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,
int secret_only, int keylist_mode); 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, GpgmeError _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in,
GpgmeData out, GpgmeData out,
GpgmeSigMode mode, int use_armor, GpgmeSigMode mode, int use_armor,

View File

@ -438,9 +438,10 @@ _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata)
return 0; return 0;
} }
GpgmeError GpgmeError
_gpgme_engine_op_keylist (EngineObject engine, const char *pattern, int secret_only, _gpgme_engine_op_keylist (EngineObject engine, const char *pattern,
int keylist_mode) int secret_only, int keylist_mode)
{ {
if (!engine) if (!engine)
return mk_error (Invalid_Value); return mk_error (Invalid_Value);
@ -459,6 +460,29 @@ _gpgme_engine_op_keylist (EngineObject engine, const char *pattern, int secret_o
return 0; 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 GpgmeError
_gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out, _gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out,
GpgmeSigMode mode, int use_armor, GpgmeSigMode mode, int use_armor,

View File

@ -60,6 +60,11 @@ GpgmeError _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata);
GpgmeError _gpgme_engine_op_keylist (EngineObject engine, const char *pattern, GpgmeError _gpgme_engine_op_keylist (EngineObject engine, const char *pattern,
int secret_only, int secret_only,
int keylist_mode); 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, GpgmeError _gpgme_engine_op_sign (EngineObject engine, GpgmeData in,
GpgmeData out, GpgmeSigMode mode, GpgmeData out, GpgmeSigMode mode,
int use_armor, int use_textmode, int use_armor, int use_textmode,

View File

@ -505,6 +505,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: * gpgme_op_keylist_next:
* @c: Context * @c: Context

View File

@ -1441,6 +1441,7 @@ _gpgme_gpg_op_import (GpgObject gpg, GpgmeData keydata)
return err; return err;
} }
GpgmeError GpgmeError
_gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only, _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only,
int keylist_mode) int keylist_mode)
@ -1465,6 +1466,38 @@ _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only,
return err; 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 GpgmeError
_gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out, _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,
GpgmeSigMode mode, int use_armor, GpgmeSigMode mode, int use_armor,

View File

@ -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_import (GpgObject gpg, GpgmeData keydata);
GpgmeError _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, GpgmeError _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern,
int secret_only, int keylist_mode); 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, GpgmeError _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,
GpgmeSigMode mode, int use_armor, GpgmeSigMode mode, int use_armor,
int use_textmode, GpgmeCtx ctx /* FIXME */); int use_textmode, GpgmeCtx ctx /* FIXME */);