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
some recipients have been invalid, whereas earlier versions
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.
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:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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_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)

4
TODO
View File

@ -44,7 +44,7 @@ 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
** 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.
@ -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

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>
* 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.
@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

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>
* 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
_gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,
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_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,

View File

@ -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,

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,
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,

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:
* @c: Context

View File

@ -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,

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_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 */);