2003-05-27  Marcus Brinkmann  <marcus@g10code.de>

	* gpgme.texi (Passphrase Callback): Document new prototype.

gpgme/
2003-05-26  Marcus Brinkmann  <marcus@g10code.de>

	* engine.h (EngineCommandHandler): Change last argument to int fd.
	* gpgme.h (gpgme_passphrase_cb_t): Rewritten to take parts of the
	description and fd.
	(gpgme_edit_cb_t): Change last argument to int fd.
	* ops.h (_gpgme_passphrase_command_handler_internal): New prototype.
	* passphrase.c: Include <assert.h>.
	(op_data_t): Rename userid_hint to uid_hint, remove last_pw_handle.
	(release_op_data): Check values before calling free.
	(_gpgme_passphrase_status_handler): Likewise.
	(_gpgme_passphrase_command_handler_internal): New function.
	(_gpgme_passphrase_command_handler): Rewritten.
	* edit.c (edit_status_handler): Pass -1 as fd argument.
	(command_handler): Update prototype.  New variable processed.  Use
	it to store return value of
	_gpgme_passphrase_command_handler_internal which is now used
	instead _gpgme_passphrase_command_handler.  Use it also to check
	if we should call the user's edit function.  Pass fd to user's
	edit function.
	* rungpg.c (struct gpg_object_s): Change type of cmd.cb_data to
	void *.
	(gpg_release): Check value before calling free.  Do not release
	cmd.cb_data.
	(command_cb): Function removed.
	(command_handler): New function.  Thus we don't use a data object
	for command handler stuff anymore, but handle it directly.  This
	allows proper error reporting (cancel of passphrase requests, for
	example).  Also all callbacks work via direct writes to the file
	descriptor (so that passphrases are not kept in insecure memory).
	(gpg_set_command_handler): Rewritten to use even more ugly hacks.
	(read_status): Check cmd.keyword before calling free.  Install
	command_handler as the I/O callback handler with GPG as private
	data.

tests/
2003-05-27  Marcus Brinkmann  <marcus@g10code.de>

	* (t-decrypt-verify.c, t-decrypt.c, t-edit.c, t-encrypt-sign.c,
	t-encrypt-sym.c, t-sign.c, t-signers.c): Include <unistd.h>.
	(passphrase_cb): Rewritten.
	* t-edit.c (edit_fnc): Rewritten.
This commit is contained in:
Marcus Brinkmann 2003-05-27 01:31:06 +00:00
parent 0f2763bbe3
commit 03bcb7f4c1
19 changed files with 208 additions and 218 deletions

14
NEWS
View File

@ -46,6 +46,18 @@ Noteworthy changes in version 0.4.1 (unreleased)
signatures, the progress callback is invoked for both the detached
signature and the plaintext message, though.
* gpgme_passphrase_cb_t has been changed to not return a complete
description, but the UID hint, passphrase info and a flag
indicating if this is a repeated attempt individually, so the user
can compose his own description from this information. Furthermore
it does not expect the user to return a string, but write the
passphrase followed by a newline character directly to a file
descriptor.
* gpgme_edit_cb_t has been changed to take a file descriptor argument.
The user is expected to write the response to the file descriptor,
followed by a newline.
* gpgme_op_verify and gpgme_op_decrypt_verify don't return a status
summary anymore. Use gpgme_get_sig_status to retrieve the individual
stati.
@ -226,6 +238,8 @@ gpgme_trust_item_t NEW
gpgme_status_code_t NEW
gpgme_io_cb_t CHANGED: Return type from void to GpgmeError.
gpgme_event_io_t CHANGED: New event type (all numbers changed).
gpgme_passphrase_cb_t CHANGED: Desc decomposed, write directly to FD.
gpgme_edit_cb_t CHANGED: Write directly to FD.
gpgme_key_get_string_attr CHANGED: Don't handle GPGME_ATTR_IS_SECRET.
gpgme_op_verify CHANGED: Drop R_STAT argument.
gpgme_op_decrypt_verify CHANGED: Drop R_STAT argument.

6
TODO
View File

@ -74,10 +74,8 @@ Hey Emacs, this is -*- outline -*- mode!
release all resources on error (for example to free assuan_cmd).
* Operations
** Passphrase callback should not copy password. !!!
*** If no passphrase cb is installed, status handler is not run even if
password is required by crypto engine. !!
*** Verify that passphrase callback beaves correctly with cancel etc.
** If no passphrase cb is installed, status handler is not run even if
password is required by crypto engine. !!
** Export status handler need much more work. !!!
** Import should return a useful error when one happened.
*** Import does not take notice of NODATA status report.

View File

@ -1,3 +1,7 @@
2003-05-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Passphrase Callback): Document new prototype.
2003-05-18 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Header): Remove Gpgme as namespace prefix. Add

View File

@ -1684,21 +1684,28 @@ current mode otherwise. Note that 0 is not a valid mode value.
@cindex callback, passphrase
@cindex passphrase callback
@deftp {Data type} {gpgme_error_t (*gpgme_passphrase_cb_t)(void *@var{hook}, const char *@var{desc}, void **@var{r_hd}, const char **@var{result})}
@deftp {Data type} {gpgme_error_t (*gpgme_passphrase_cb_t)(void *@var{hook}, const char *@var{uid_hint}, const char *@var{passphrase_info}, @w{int @var{prev_was_bad}}, @w{int @var{fd}})}
@tindex gpgme_passphrase_cb_t
The @code{gpgme_passphrase_cb_t} type is the type of functions usable as
passphrase callback function.
The string @var{desc} contains a text usable to be displayed to the
user of the application. The function should return a passphrase for
the context when invoked with @var{desc} not being @code{NULL} in
*@var{result}.
The argument @var{uid_hint} might contain a string that gives an
indication for which user ID the passphrase is required. If this is
not available, or not applicable (in the case of symmetric encryption,
for example), @var{uid_hint} will be @code{NULL}.
The user may store information about the resources associated with the
returned passphrase in @var{*r_hd}. When the passphrase is no longer
needed by @acronym{GPGME}, the passphrase callback function will be
called with @var{desc} being @var{NULL}, and @var{r_hd} being the same
as at the first invocation.
The argument @var{passphrase_info}, if not @code{NULL}, will give
further information about the context in which the passphrase is
required. This information is engine and operation specific.
If this is the repeated attempt to get the passphrase, because
previous attempts failed, then @var{prev_was_bad} is 1, otherwise it
will be 0.
The user must write the passphrase, followed by a newline character,
to the file descriptor @var{fd}. If the user does not return 0
indicating success, the user must at least write a newline character
before returning from the callback.
If an error occurs, return the corresponding @code{gpgme_error_t} value.
You can use @code{GPGME_Canceled} to abort the operation. Otherwise,

View File

@ -1,5 +1,38 @@
2003-05-26 Marcus Brinkmann <marcus@g10code.de>
* engine.h (EngineCommandHandler): Change last argument to int fd.
* gpgme.h (gpgme_passphrase_cb_t): Rewritten to take parts of the
description and fd.
(gpgme_edit_cb_t): Change last argument to int fd.
* ops.h (_gpgme_passphrase_command_handler_internal): New prototype.
* passphrase.c: Include <assert.h>.
(op_data_t): Rename userid_hint to uid_hint, remove last_pw_handle.
(release_op_data): Check values before calling free.
(_gpgme_passphrase_status_handler): Likewise.
(_gpgme_passphrase_command_handler_internal): New function.
(_gpgme_passphrase_command_handler): Rewritten.
* edit.c (edit_status_handler): Pass -1 as fd argument.
(command_handler): Update prototype. New variable processed. Use
it to store return value of
_gpgme_passphrase_command_handler_internal which is now used
instead _gpgme_passphrase_command_handler. Use it also to check
if we should call the user's edit function. Pass fd to user's
edit function.
* rungpg.c (struct gpg_object_s): Change type of cmd.cb_data to
void *.
(gpg_release): Check value before calling free. Do not release
cmd.cb_data.
(command_cb): Function removed.
(command_handler): New function. Thus we don't use a data object
for command handler stuff anymore, but handle it directly. This
allows proper error reporting (cancel of passphrase requests, for
example). Also all callbacks work via direct writes to the file
descriptor (so that passphrases are not kept in insecure memory).
(gpg_set_command_handler): Rewritten to use even more ugly hacks.
(read_status): Check cmd.keyword before calling free. Install
command_handler as the I/O callback handler with GPG as private
data.
* rungpg.c (gpg_new): Add --enable-progress-filter to gpg
invocation.
* decrypt-verify.c (_gpgme_op_decrypt_verify_start): Rename to

View File

@ -44,33 +44,34 @@ edit_status_handler (void *priv, gpgme_status_code_t status, char *args)
return _gpgme_passphrase_status_handler (priv, status, args)
|| _gpgme_progress_status_handler (priv, status, args)
|| _gpgme_op_data_lookup (ctx, OPDATA_EDIT, (void **) &opd, -1, NULL)
|| (*opd->fnc) (opd->fnc_value, status, args, NULL);
|| (*opd->fnc) (opd->fnc_value, status, args, -1);
}
static gpgme_error_t
command_handler (void *priv, gpgme_status_code_t status, const char *args,
const char **result)
int fd)
{
gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
gpgme_error_t err;
op_data_t opd;
int processed = 0;
*result = NULL;
if (ctx->passphrase_cb)
{
err = _gpgme_passphrase_command_handler (ctx, status, args, result);
err = _gpgme_passphrase_command_handler_internal (ctx, status, args,
fd, &processed);
if (err)
return err;
}
if (!*result)
if (!processed)
{
err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, (void **) &opd, -1, NULL);
if (err)
return err;
return (*opd->fnc) (opd->fnc_value, status, args, result);
return (*opd->fnc) (opd->fnc_value, status, args, fd);
}
return 0;
}

View File

@ -33,7 +33,7 @@ typedef gpgme_error_t (*EngineColonLineHandler) (void *priv, char *line);
typedef gpgme_error_t (*EngineCommandHandler) (void *priv,
gpgme_status_code_t code,
const char *keyword,
const char **result);
int fd);
gpgme_error_t _gpgme_engine_new (gpgme_protocol_t proto,
EngineObject *r_engine);

View File

@ -614,9 +614,10 @@ typedef struct _gpgme_key *gpgme_key_t;
/* Types for callback functions. */
/* Request a passphrase from the user. */
typedef gpgme_error_t (*gpgme_passphrase_cb_t) (void *hook, const char *desc,
void **r_hd,
const char **result);
typedef gpgme_error_t (*gpgme_passphrase_cb_t) (void *hook,
const char *uid_hint,
const char *passphrase_info,
int prev_was_bad, int fd);
/* Inform the user about progress made. */
typedef void (*gpgme_progress_cb_t) (void *opaque, const char *what,
@ -625,8 +626,7 @@ typedef void (*gpgme_progress_cb_t) (void *opaque, const char *what,
/* Interact with the user about an edit operation. */
typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque,
gpgme_status_code_t status,
const char *args,
const char **reply);
const char *args, int fd);
/* Context management functions. */

View File

@ -102,8 +102,11 @@ gpgme_error_t _gpgme_passphrase_status_handler (void *priv,
char *args);
gpgme_error_t _gpgme_passphrase_command_handler (void *opaque,
gpgme_status_code_t code,
const char *key,
const char **result);
const char *key, int fd);
gpgme_error_t _gpgme_passphrase_command_handler_internal (void *opaque,
gpgme_status_code_t code,
const char *key, int fd,
int *processed);
/* From progress.c. */

View File

@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "gpgme.h"
#include "context.h"
@ -33,8 +34,7 @@
typedef struct
{
int no_passphrase;
void *last_pw_handle;
char *userid_hint;
char *uid_hint;
char *passphrase_info;
int bad_passphrase;
} *op_data_t;
@ -45,8 +45,10 @@ release_op_data (void *hook)
{
op_data_t opd = (op_data_t) hook;
free (opd->passphrase_info);
free (opd->userid_hint);
if (opd->passphrase_info)
free (opd->passphrase_info);
if (opd->uid_hint)
free (opd->uid_hint);
}
@ -69,9 +71,9 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
switch (code)
{
case GPGME_STATUS_USERID_HINT:
if (opd->userid_hint)
free (opd->userid_hint);
if (!(opd->userid_hint = strdup (args)))
if (opd->uid_hint)
free (opd->uid_hint);
if (!(opd->uid_hint = strdup (args)))
return GPGME_Out_Of_Core;
break;
@ -112,64 +114,45 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
gpgme_error_t
_gpgme_passphrase_command_handler (void *priv, gpgme_status_code_t code,
const char *key, const char **result)
_gpgme_passphrase_command_handler_internal (void *priv,
gpgme_status_code_t code,
const char *key, int fd,
int *processed)
{
gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
gpgme_error_t err;
op_data_t opd;
if (!ctx->passphrase_cb)
return 0;
assert (ctx->passphrase_cb);
err = _gpgme_op_data_lookup (ctx, OPDATA_PASSPHRASE, (void **) &opd,
sizeof (*opd), release_op_data);
if (err)
return err;
if (!code)
{
/* We have been called for cleanup. */
if (ctx->passphrase_cb)
/* FIXME: Take the key in account. */
err = ctx->passphrase_cb (ctx->passphrase_cb_value, NULL,
&opd->last_pw_handle, NULL);
*result = NULL;
return err;
}
if (!key || !ctx->passphrase_cb)
{
*result = NULL;
return 0;
}
if (code == GPGME_STATUS_GET_HIDDEN && !strcmp (key, "passphrase.enter"))
{
const char *userid_hint = opd->userid_hint;
const char *passphrase_info = opd->passphrase_info;
int bad_passphrase = opd->bad_passphrase;
char *buf;
if (processed)
processed = 1;
err = ctx->passphrase_cb (ctx->passphrase_cb_value,
opd->uid_hint, opd->passphrase_info,
opd->bad_passphrase, fd);
/* Reset bad passphrase flag, in case it is correct now. */
opd->bad_passphrase = 0;
if (!userid_hint)
userid_hint = "[User ID hint missing]";
if (!passphrase_info)
passphrase_info = "[passphrase info missing]";
buf = malloc (20 + strlen (userid_hint)
+ strlen (passphrase_info) + 3);
if (!buf)
return GPGME_Out_Of_Core;
sprintf (buf, "%s\n%s\n%s",
bad_passphrase ? "TRY_AGAIN":"ENTER",
userid_hint, passphrase_info);
err = ctx->passphrase_cb (ctx->passphrase_cb_value, buf,
&opd->last_pw_handle, result);
free (buf);
return err;
}
*result = NULL;
return 0;
}
gpgme_error_t
_gpgme_passphrase_command_handler (void *priv, gpgme_status_code_t code,
const char *key, int fd)
{
return _gpgme_passphrase_command_handler_internal (priv, code, key, fd,
NULL);
}

View File

@ -109,8 +109,8 @@ struct gpg_object_s
{
int used;
int fd;
void *cb_data;
int idx; /* Index in fd_data_map */
gpgme_data_t cb_data; /* hack to get init the above idx later */
gpgme_status_code_t code; /* last code */
char *keyword; /* what has been requested (malloced) */
EngineCommandHandler fnc;
@ -301,16 +301,19 @@ gpg_release (void *engine)
{
struct arg_and_data_s *next = gpg->arglist->next;
free (gpg->arglist);
if (gpg->arglist)
free (gpg->arglist);
gpg->arglist = next;
}
free (gpg->status.buffer);
free (gpg->colon.buffer);
if (gpg->status.buffer)
free (gpg->status.buffer);
if (gpg->colon.buffer)
free (gpg->colon.buffer);
if (gpg->argv)
free_argv (gpg->argv);
gpgme_data_release (gpg->cmd.cb_data);
free (gpg->cmd.keyword);
if (gpg->cmd.keyword)
free (gpg->cmd.keyword);
if (gpg->status.fd[0] != -1)
_gpgme_io_close (gpg->status.fd[0]);
@ -320,7 +323,8 @@ gpg_release (void *engine)
_gpgme_io_close (gpg->colon.fd[0]);
if (gpg->colon.fd[1] != -1)
_gpgme_io_close (gpg->colon.fd[1]);
free_fd_data_map (gpg->fd_data_map);
if (gpg->fd_data_map)
free_fd_data_map (gpg->fd_data_map);
if (gpg->cmd.fd != -1)
_gpgme_io_close (gpg->cmd.fd);
free (gpg);
@ -436,60 +440,20 @@ gpg_set_colon_line_handler (void *engine, EngineColonLineHandler fnc,
}
/* Here we handle --command-fd. This works closely together with the
status handler. */
static gpgme_error_t
command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
command_handler (void *opaque, int fd)
{
gpgme_error_t err;
GpgObject gpg = opaque;
const char *value;
int value_len;
GpgObject gpg = (GpgObject) opaque;
DEBUG0 ("command_cb: enter\n");
assert (gpg->cmd.used);
if (!buffer || !length || !nread)
return 0; /* These values are reserved for extensions. */
*nread = 0;
if (!gpg->cmd.code)
{
DEBUG0 ("command_cb: no code\n");
return -1;
}
if (!gpg->cmd.fnc)
{
DEBUG0 ("command_cb: no user cb\n");
return -1;
}
assert (gpg->cmd.code);
assert (gpg->cmd.fnc);
/* FIXME catch error */
err = gpg->cmd.fnc (gpg->cmd.fnc_value,
gpg->cmd.code, gpg->cmd.keyword, &value);
err = gpg->cmd.fnc (gpg->cmd.fnc_value, gpg->cmd.code, gpg->cmd.keyword, fd);
if (err)
return err;
if (!value)
{
DEBUG0 ("command_cb: no data from user cb\n");
gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value, &value);
return -1;
}
value_len = strlen (value);
if (value_len + 1 > length)
{
DEBUG0 ("command_cb: too much data from user cb\n");
gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value, &value);
return -1;
}
memcpy (buffer, value, value_len);
if (!value_len || (value_len && value[value_len-1] != '\n'))
buffer[value_len++] = '\n';
*nread = value_len;
gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value, &value);
gpg->cmd.code = 0;
/* And sleep again until read_status will wake us up again. */
/* XXX We must check if there are any more fds active after removing
@ -502,6 +466,7 @@ command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
}
/* The Fnc will be called to get a value for one of the commands with
a key KEY. If the Code pssed to FNC is 0, the function may release
resources associated with the returned value from another call. To
@ -512,17 +477,14 @@ gpg_set_command_handler (void *engine, EngineCommandHandler fnc,
void *fnc_value, gpgme_data_t linked_data)
{
GpgObject gpg = engine;
gpgme_data_t tmp;
gpgme_error_t err;
err = gpgme_data_new_with_read_cb (&tmp, command_cb, gpg);
if (err)
return err;
add_arg (gpg, "--command-fd");
add_data (gpg, tmp, -2, 0);
gpg->cmd.cb_data = tmp;
/* This is a hack. We don't have a real data object. The only
thing that matters is that we use something unique, so we use the
address of the cmd structure in the gpg object. */
add_data (gpg, (void *) &gpg->cmd, -2, 0);
gpg->cmd.fnc = fnc;
gpg->cmd.cb_data = (void *) &gpg->cmd;
gpg->cmd.fnc_value = fnc_value;
gpg->cmd.linked_data = linked_data;
gpg->cmd.used = 1;
@ -579,7 +541,7 @@ build_argv (GpgObject gpg)
if (use_agent)
argc++;
if (!gpg->cmd.used)
argc++;
argc++; /* --batch */
argc += 2; /* --comment */
argv = calloc (argc + 1, sizeof *argv);
@ -843,7 +805,8 @@ read_status (GpgObject gpg)
|| r->code == GPGME_STATUS_GET_HIDDEN))
{
gpg->cmd.code = r->code;
free (gpg->cmd.keyword);
if (gpg->cmd.keyword)
free (gpg->cmd.keyword);
gpg->cmd.keyword = strdup (rest);
if (!gpg->cmd.keyword)
return GPGME_Out_Of_Core;
@ -877,8 +840,7 @@ read_status (GpgObject gpg)
}
add_io_cb (gpg, gpg->cmd.fd, 0,
_gpgme_data_outbound_handler,
gpg->fd_data_map[gpg->cmd.idx].data,
command_handler, gpg,
&gpg->fd_data_map[gpg->cmd.idx].tag);
gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd;
gpg->cmd.fd = -1;

View File

@ -1,3 +1,10 @@
2003-05-27 Marcus Brinkmann <marcus@g10code.de>
* (t-decrypt-verify.c, t-decrypt.c, t-edit.c, t-encrypt-sign.c,
t-encrypt-sym.c, t-sign.c, t-signers.c): Include <unistd.h>.
(passphrase_cb): Rewritten.
* t-edit.c (edit_fnc): Rewritten.
2003-05-04 Marcus Brinkmann <marcus@g10code.de>
* gpg/t-keylist-sig.c (main): Remove timestamp check.

View File

@ -22,6 +22,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <gpgme.h>
@ -57,13 +58,10 @@ print_data (gpgme_data_t dh)
static gpgme_error_t
passphrase_cb (void *opaque, const char *desc, void **hd, const char **result)
passphrase_cb (void *opaque, const char *uid_hint, const char *passphrase_info,
int last_was_bad, int fd)
{
/* Cleanup by looking at *hd. */
if (!desc)
return 0;
*result = "abc";
write (fd, "abc\n", 4);
return 0;
}

View File

@ -22,6 +22,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <gpgme.h>
@ -56,13 +57,10 @@ print_data (gpgme_data_t dh)
static gpgme_error_t
passphrase_cb (void *opaque, const char *desc, void **hd, const char **result)
passphrase_cb (void *opaque, const char *uid_hint, const char *passphrase_info,
int last_was_bad, int fd)
{
/* Cleanup by looking at *hd. */
if (!desc)
return 0;
*result = "abc";
write (fd, "abc\n", 4);
return 0;
}

View File

@ -24,6 +24,7 @@
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <gpgme.h>
@ -58,24 +59,18 @@ flush_data (gpgme_data_t dh)
static gpgme_error_t
passphrase_cb (void *opaque, const char *desc,
void **r_hd, const char **result)
passphrase_cb (void *opaque, const char *uid_hint, const char *passphrase_info,
int last_was_bad, int fd)
{
if (!desc)
/* Cleanup by looking at *r_hd. */
return 0;
*result = "abc";
fprintf (stderr, "%% requesting passphrase for `%s': ", desc);
fprintf (stderr, "sending `%s'\n", *result);
write (fd, "abc\n", 4);
return 0;
}
gpgme_error_t
edit_fnc (void *opaque, gpgme_status_code_t status, const char *args, const char **result)
edit_fnc (void *opaque, gpgme_status_code_t status, const char *args, int fd)
{
char *result = NULL;
gpgme_data_t out = (gpgme_data_t) opaque;
fputs ("[-- Response --]\n", stdout);
@ -83,36 +78,34 @@ edit_fnc (void *opaque, gpgme_status_code_t status, const char *args, const char
fprintf (stdout, "[-- Code: %i, %s --]\n", status, args);
if (!strcmp (args, "keyedit.prompt"))
{
static int step = 0;
switch (step)
{
case 0:
result = "fpr";
break;
case 1:
result = "expire";
break;
default:
result = "quit";
break;
}
step++;
}
else if (!strcmp (args, "keyedit.save.okay"))
result = "Y";
else if (!strcmp (args, "keygen.valid"))
result = "0";
if (result)
{
if (!strcmp (args, "keyedit.prompt"))
{
static int step = 0;
switch (step)
{
case 0:
*result = "fpr";
break;
case 1:
*result = "expire";
break;
default:
*result = "quit";
break;
}
step++;
}
else if (!strcmp (args, "keyedit.save.okay"))
{
*result = "Y";
}
else if (!strcmp (args, "keygen.valid"))
{
*result = "0";
}
write (fd, result, strlen (result));
write (fd, "\n", 1);
}
return 0;
}

View File

@ -21,6 +21,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <gpgme.h>
@ -55,13 +56,10 @@ print_data (gpgme_data_t dh)
static gpgme_error_t
passphrase_cb (void *opaque, const char *desc, void **hd, const char **result)
passphrase_cb (void *opaque, const char *uid_hint, const char *passphrase_info,
int last_was_bad, int fd)
{
/* Cleanup by looking at *hd. */
if (!desc)
return 0;
*result = "abc";
write (fd, "abc\n", 4);
return 0;
}

View File

@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <gpgme.h>
@ -47,18 +48,12 @@ print_data (gpgme_data_t dh)
fail_if_err (GPGME_File_Error);
}
static gpgme_error_t
passphrase_cb (void *opaque, const char *desc,
void **r_hd, const char **result)
{
if (!desc)
/* Cleanup by looking at *r_hd. */
return 0;
*result = "abc";
fprintf (stderr, "%% requesting passphrase for `%s': ", desc);
fprintf (stderr, "sending `%s'\n", *result);
static gpgme_error_t
passphrase_cb (void *opaque, const char *uid_hint, const char *passphrase_info,
int last_was_bad, int fd)
{
write (fd, "abc\n", 4);
return 0;
}

View File

@ -21,6 +21,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <gpgme.h>
@ -55,13 +56,10 @@ print_data (gpgme_data_t dh)
static gpgme_error_t
passphrase_cb (void *opaque, const char *desc, void **hd, const char **result)
passphrase_cb (void *opaque, const char *uid_hint, const char *passphrase_info,
int last_was_bad, int fd)
{
/* Cleanup by looking at *hd. */
if (!desc)
return 0;
*result = "abc";
write (fd, "abc\n", 4);
return 0;
}

View File

@ -21,6 +21,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <gpgme.h>
@ -55,13 +56,10 @@ print_data (gpgme_data_t dh)
static gpgme_error_t
passphrase_cb (void *opaque, const char *desc, void **hd, const char **result)
passphrase_cb (void *opaque, const char *uid_hint, const char *passphrase_info,
int last_was_bad, int fd)
{
/* Cleanup by looking at *hd. */
if (!desc)
return 0;
*result = "abc";
write (fd, "abc\n", 4);
return 0;
}