2001-11-22 Marcus Brinkmann <marcus@g10code.de>
* rungpg.c (gpg_inbound_handler, write_mem_data, write_cb_data, gpg_outbound_handler): Moved to ... * data.c (_gpgme_data_inbound_handler, write_mem_data, write_cb_data, _gpgme_data_outbound_handler): ... here. Make the _gpgme_* ones non-static. * data.c: Include io.h. * ops.h (_gpgme_data_inbound_handler): New prototype. (_gpgme_data_outbound_handler): Likewise. (_gpgme_gpg_spawn): Use these new functions. * engine-gpgsm.h (_gpgme_gpgsm_op_decrypt, _gpgme_gpgsm_op_delete, _gpgme_gpgsm_op_encrypt, _gpgme_gpgsm_op_export, _gpgme_gpgsm_op_genkey, _gpgme_gpgsm_op_import, _gpgme_gpgsm_op_keylist, _gpgme_gpgsm_op_sign, _gpgme_gpgsm_op_trustlist, _gpgme_gpgsm_op_verify, _gpgme_gpgsm_start, _gpgme_gpgsm_set_status_handler): New prototype. Include <rungpg.h> for status handler function. * engine-gpgsm.c (struct gpgsm_object_s): New members input_fd, input_data, output_fd, output_data, message_fd, message_data, command and status. (_gpgme_gpgsm_new): Open input, output and message pipes before connecting to the client. Close server's ends afterwards. (_gpgme_gpgsm_release): Close open file descriptors. Remove server process from wait queue. (_gpgme_gpgsm_op_verify, _gpgme_gpgsm_start, _gpgme_gpgsm_set_status_handler, gpgms_status_handler): New function. * engine.c (_gpgme_engine_start): Implement for GPGME_PROTOCOL_CMS. (_gpgme_engine_set_status_handler): Likewise. (_gpgme_engine_op_verify): Likewise.
This commit is contained in:
parent
3f1c299866
commit
679d5c2b49
@ -1,3 +1,38 @@
|
|||||||
|
2001-11-22 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* rungpg.c (gpg_inbound_handler, write_mem_data, write_cb_data,
|
||||||
|
gpg_outbound_handler): Moved to ...
|
||||||
|
* data.c (_gpgme_data_inbound_handler, write_mem_data,
|
||||||
|
write_cb_data, _gpgme_data_outbound_handler): ... here. Make the
|
||||||
|
_gpgme_* ones non-static.
|
||||||
|
* data.c: Include io.h.
|
||||||
|
|
||||||
|
* ops.h (_gpgme_data_inbound_handler): New prototype.
|
||||||
|
(_gpgme_data_outbound_handler): Likewise.
|
||||||
|
(_gpgme_gpg_spawn): Use these new functions.
|
||||||
|
|
||||||
|
* engine-gpgsm.h (_gpgme_gpgsm_op_decrypt, _gpgme_gpgsm_op_delete,
|
||||||
|
_gpgme_gpgsm_op_encrypt, _gpgme_gpgsm_op_export,
|
||||||
|
_gpgme_gpgsm_op_genkey, _gpgme_gpgsm_op_import,
|
||||||
|
_gpgme_gpgsm_op_keylist, _gpgme_gpgsm_op_sign,
|
||||||
|
_gpgme_gpgsm_op_trustlist, _gpgme_gpgsm_op_verify,
|
||||||
|
_gpgme_gpgsm_start, _gpgme_gpgsm_set_status_handler): New prototype.
|
||||||
|
Include <rungpg.h> for status handler function.
|
||||||
|
|
||||||
|
* engine-gpgsm.c (struct gpgsm_object_s): New members input_fd,
|
||||||
|
input_data, output_fd, output_data, message_fd, message_data, command
|
||||||
|
and status.
|
||||||
|
(_gpgme_gpgsm_new): Open input, output and message pipes before
|
||||||
|
connecting to the client. Close server's ends afterwards.
|
||||||
|
(_gpgme_gpgsm_release): Close open file descriptors. Remove
|
||||||
|
server process from wait queue.
|
||||||
|
(_gpgme_gpgsm_op_verify, _gpgme_gpgsm_start,
|
||||||
|
_gpgme_gpgsm_set_status_handler, gpgms_status_handler): New function.
|
||||||
|
|
||||||
|
* engine.c (_gpgme_engine_start): Implement for GPGME_PROTOCOL_CMS.
|
||||||
|
(_gpgme_engine_set_status_handler): Likewise.
|
||||||
|
(_gpgme_engine_op_verify): Likewise.
|
||||||
|
|
||||||
2001-11-21 Marcus Brinkmann <marcus@g10code.de>
|
2001-11-21 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* context.h: Do not include rungpg.h, but engine.h.
|
* context.h: Do not include rungpg.h, but engine.h.
|
||||||
|
139
gpgme/data.c
139
gpgme/data.c
@ -32,6 +32,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "ops.h"
|
#include "ops.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
#define ALLOC_CHUNK 1024
|
#define ALLOC_CHUNK 1024
|
||||||
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' )
|
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' )
|
||||||
@ -757,9 +758,6 @@ hextobyte( const byte *s )
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Append a string with percent style (%XX) escape characters as XML
|
* Append a string with percent style (%XX) escape characters as XML
|
||||||
*/
|
*/
|
||||||
@ -785,3 +783,138 @@ _gpgme_data_append_percentstring_for_xml ( GpgmeData dh, const char *string )
|
|||||||
xfree (buf);
|
xfree (buf);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Functions to support the wait interface. */
|
||||||
|
|
||||||
|
int
|
||||||
|
_gpgme_data_inbound_handler (void *opaque, int pid, int fd)
|
||||||
|
{
|
||||||
|
GpgmeData dh = opaque;
|
||||||
|
GpgmeError err;
|
||||||
|
int nread;
|
||||||
|
char buf[200];
|
||||||
|
|
||||||
|
assert (_gpgme_data_get_mode (dh) == GPGME_DATA_MODE_IN);
|
||||||
|
|
||||||
|
nread = _gpgme_io_read (fd, buf, 200);
|
||||||
|
if (nread < 0)
|
||||||
|
{
|
||||||
|
DEBUG3 ("read_mem_data: read failed on fd %d (n=%d): %s",
|
||||||
|
fd, nread, strerror (errno) );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (!nread)
|
||||||
|
return 1; /* eof */
|
||||||
|
|
||||||
|
/* We could improve this with a GpgmeData function which takes
|
||||||
|
* the read function or provides a memory area for writing to it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
err = _gpgme_data_append (dh, buf, nread);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
DEBUG1 ("_gpgme_append_data failed: %s\n",
|
||||||
|
gpgme_strerror(err));
|
||||||
|
/* Fixme: we should close the pipe or read it to /dev/null in
|
||||||
|
* this case. Returnin EOF is not sufficient */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
write_mem_data (GpgmeData dh, int fd)
|
||||||
|
{
|
||||||
|
size_t nbytes;
|
||||||
|
int nwritten;
|
||||||
|
|
||||||
|
nbytes = dh->len - dh->readpos;
|
||||||
|
if (!nbytes)
|
||||||
|
{
|
||||||
|
_gpgme_io_close (fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Arggg, the pipe blocks on large write request, although
|
||||||
|
* select told us that it is okay to write - need to figure out
|
||||||
|
* why this happens? Stevens says nothing about this problem (or
|
||||||
|
* is it my Linux kernel 2.4.0test1)
|
||||||
|
* To avoid that we have set the pipe to nonblocking.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nwritten = _gpgme_io_write (fd, dh->data+dh->readpos, nbytes);
|
||||||
|
if (nwritten == -1 && errno == EAGAIN)
|
||||||
|
return 0;
|
||||||
|
if (nwritten < 1)
|
||||||
|
{
|
||||||
|
DEBUG3 ("write_mem_data(%d): write failed (n=%d): %s",
|
||||||
|
fd, nwritten, strerror (errno));
|
||||||
|
_gpgme_io_close (fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dh->readpos += nwritten;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
write_cb_data (GpgmeData dh, int fd)
|
||||||
|
{
|
||||||
|
size_t nbytes;
|
||||||
|
int err, nwritten;
|
||||||
|
char buffer[512];
|
||||||
|
|
||||||
|
err = gpgme_data_read (dh, buffer, DIM(buffer), &nbytes);
|
||||||
|
if (err == GPGME_EOF)
|
||||||
|
{
|
||||||
|
_gpgme_io_close (fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nwritten = _gpgme_io_write (fd, buffer, nbytes);
|
||||||
|
if (nwritten == -1 && errno == EAGAIN )
|
||||||
|
return 0;
|
||||||
|
if (nwritten < 1)
|
||||||
|
{
|
||||||
|
DEBUG3 ("write_cb_data(%d): write failed (n=%d): %s",
|
||||||
|
fd, nwritten, strerror (errno));
|
||||||
|
_gpgme_io_close (fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nwritten < nbytes)
|
||||||
|
{
|
||||||
|
/* ugly, ugly: It does currently only for for MEM type data */
|
||||||
|
if (_gpgme_data_unread (dh, buffer + nwritten, nbytes - nwritten))
|
||||||
|
DEBUG1 ("wite_cb_data: unread of %d bytes failed\n",
|
||||||
|
nbytes - nwritten);
|
||||||
|
_gpgme_io_close (fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_gpgme_data_outbound_handler (void *opaque, int pid, int fd)
|
||||||
|
{
|
||||||
|
GpgmeData dh = opaque;
|
||||||
|
|
||||||
|
assert (_gpgme_data_get_mode (dh) == GPGME_DATA_MODE_OUT);
|
||||||
|
switch (gpgme_data_get_type (dh))
|
||||||
|
{
|
||||||
|
case GPGME_DATA_TYPE_MEM:
|
||||||
|
if (write_mem_data (dh, fd))
|
||||||
|
return 1; /* ready */
|
||||||
|
break;
|
||||||
|
case GPGME_DATA_TYPE_CB:
|
||||||
|
if (write_cb_data (dh, fd))
|
||||||
|
return 1; /* ready */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -23,13 +23,6 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gpgme.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "ops.h"
|
|
||||||
|
|
||||||
#include "engine-gpgsm.h"
|
|
||||||
|
|
||||||
/* FIXME: Correct check? */
|
/* FIXME: Correct check? */
|
||||||
#ifdef GPGSM_PATH
|
#ifdef GPGSM_PATH
|
||||||
#define ENABLE_GPGSM 1
|
#define ENABLE_GPGSM 1
|
||||||
@ -37,11 +30,50 @@
|
|||||||
|
|
||||||
#ifdef ENABLE_GPGSM
|
#ifdef ENABLE_GPGSM
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
#include "../assuan/assuan-defs.h"
|
||||||
|
#undef xtrymalloc
|
||||||
|
#undef xtrycalloc
|
||||||
|
#undef xtryrealloc
|
||||||
|
#undef xfree
|
||||||
|
|
||||||
|
#include "gpgme.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "ops.h"
|
||||||
|
#include "wait.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
#include "engine-gpgsm.h"
|
||||||
|
|
||||||
#include "assuan.h"
|
#include "assuan.h"
|
||||||
|
|
||||||
struct gpgsm_object_s
|
struct gpgsm_object_s
|
||||||
{
|
{
|
||||||
ASSUAN_CONTEXT assuan_ctx;
|
ASSUAN_CONTEXT assuan_ctx;
|
||||||
|
|
||||||
|
/* Input, output etc are from the servers perspective. */
|
||||||
|
int input_fd;
|
||||||
|
int input_fd_server;
|
||||||
|
GpgmeData input_data;
|
||||||
|
int output_fd;
|
||||||
|
int output_fd_server;
|
||||||
|
GpgmeData output_data;
|
||||||
|
int message_fd;
|
||||||
|
int message_fd_server;
|
||||||
|
GpgmeData message_data;
|
||||||
|
|
||||||
|
char *command;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
GpgStatusHandler fnc;
|
||||||
|
void *fnc_value;
|
||||||
|
} status;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
@ -70,6 +102,9 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
GpgsmObject gpgsm;
|
GpgsmObject gpgsm;
|
||||||
char *argv[] = { "gpgsm", "--server", NULL };
|
char *argv[] = { "gpgsm", "--server", NULL };
|
||||||
|
int ip[2] = { -1, -1 };
|
||||||
|
int op[2] = { -1, -1 };
|
||||||
|
int mp[2] = { -1, -1 };
|
||||||
|
|
||||||
*r_gpgsm = NULL;
|
*r_gpgsm = NULL;
|
||||||
gpgsm = xtrycalloc (1, sizeof *gpgsm);
|
gpgsm = xtrycalloc (1, sizeof *gpgsm);
|
||||||
@ -79,10 +114,39 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_gpgme_io_pipe (ip, 0) < 0)
|
||||||
|
{
|
||||||
|
err = mk_error (General_Error);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
gpgsm->input_fd = ip[1];
|
||||||
|
gpgsm->input_fd_server = ip[0];
|
||||||
|
if (_gpgme_io_pipe (op, 1) < 0)
|
||||||
|
{
|
||||||
|
err = mk_error (General_Error);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
gpgsm->output_fd = op[0];
|
||||||
|
gpgsm->output_fd_server = op[1];
|
||||||
|
if (_gpgme_io_pipe (mp, 0) < 0)
|
||||||
|
{
|
||||||
|
err = mk_error (General_Error);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
gpgsm->message_fd = mp[1];
|
||||||
|
gpgsm->message_fd_server = mp[0];
|
||||||
|
|
||||||
err = assuan_pipe_connect (&gpgsm->assuan_ctx,
|
err = assuan_pipe_connect (&gpgsm->assuan_ctx,
|
||||||
_gpgme_get_gpgsm_path (), argv);
|
_gpgme_get_gpgsm_path (), argv);
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
if (ip[0] != -1)
|
||||||
|
_gpgme_io_close (ip[0]);
|
||||||
|
if (op[1] != -1)
|
||||||
|
_gpgme_io_close (op[1]);
|
||||||
|
if (mp[0] != -1)
|
||||||
|
_gpgme_io_close (mp[0]);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
_gpgme_gpgsm_release (gpgsm);
|
_gpgme_gpgsm_release (gpgsm);
|
||||||
else
|
else
|
||||||
@ -94,13 +158,156 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
void
|
void
|
||||||
_gpgme_gpgsm_release (GpgsmObject gpgsm)
|
_gpgme_gpgsm_release (GpgsmObject gpgsm)
|
||||||
{
|
{
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
if (!gpgsm)
|
if (!gpgsm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
pid = assuan_get_pid (gpgsm->assuan_ctx);
|
||||||
|
if (pid != -1)
|
||||||
|
_gpgme_remove_proc_from_wait_queue (pid);
|
||||||
|
|
||||||
|
if (gpgsm->input_fd != -1)
|
||||||
|
_gpgme_io_close (gpgsm->input_fd);
|
||||||
|
if (gpgsm->output_fd != -1)
|
||||||
|
_gpgme_io_close (gpgsm->output_fd);
|
||||||
|
if (gpgsm->message_fd != -1)
|
||||||
|
_gpgme_io_close (gpgsm->message_fd);
|
||||||
|
|
||||||
assuan_pipe_disconnect (gpgsm->assuan_ctx);
|
assuan_pipe_disconnect (gpgsm->assuan_ctx);
|
||||||
xfree (gpgsm);
|
xfree (gpgsm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COMMANDLINELEN 40
|
||||||
|
static AssuanError
|
||||||
|
gpgsm_set_fd (ASSUAN_CONTEXT ctx, const char *which, int fd)
|
||||||
|
{
|
||||||
|
AssuanError err;
|
||||||
|
char line[COMMANDLINELEN];
|
||||||
|
|
||||||
|
snprintf (line, COMMANDLINELEN, "%s FD=%i", which, fd);
|
||||||
|
err = _assuan_write_line (ctx, line);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
err = _assuan_read_line (ctx);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
while (*ctx->inbound.line == '#' || !ctx->inbound.linelen);
|
||||||
|
|
||||||
|
if (ctx->inbound.linelen >= 2
|
||||||
|
&& ctx->inbound.line[0] == 'O' && ctx->inbound.line[1] == 'K'
|
||||||
|
&& (ctx->inbound.line[2] == '\0' || ctx->inbound.line[2] == ' '))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return ASSUAN_General_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
GpgmeError
|
||||||
|
_gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text)
|
||||||
|
{
|
||||||
|
AssuanError err;
|
||||||
|
|
||||||
|
if (!gpgsm)
|
||||||
|
return mk_error (Invalid_Value);
|
||||||
|
|
||||||
|
gpgsm->input_data = sig;
|
||||||
|
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server);
|
||||||
|
if (err)
|
||||||
|
return mk_error (General_Error); /* FIXME */
|
||||||
|
gpgsm->message_data = sig;
|
||||||
|
err = gpgsm_set_fd (gpgsm->assuan_ctx, "MESSAGE", gpgsm->message_fd_server);
|
||||||
|
if (err)
|
||||||
|
return mk_error (General_Error); /* FIXME */
|
||||||
|
_gpgme_io_close (gpgsm->output_fd);
|
||||||
|
gpgsm->output_fd = -1;
|
||||||
|
|
||||||
|
gpgsm->command = "VERIFY";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gpgsm_status_handler (void *opaque, int pid, int fd)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
GpgsmObject gpgsm = opaque;
|
||||||
|
ASSUAN_CONTEXT actx = gpgsm->assuan_ctx;
|
||||||
|
|
||||||
|
assert (fd == gpgsm->assuan_ctx->inbound.fd);
|
||||||
|
|
||||||
|
err = _assuan_read_line (gpgsm->assuan_ctx);
|
||||||
|
|
||||||
|
if (actx->inbound.line[0] == '#' || !actx->inbound.linelen)
|
||||||
|
return 0; /* FIXME */
|
||||||
|
|
||||||
|
if (actx->inbound.linelen >= 2
|
||||||
|
&& actx->inbound.line[0] == 'O' && actx->inbound.line[1] == 'K'
|
||||||
|
&& (actx->inbound.line[2] == '\0' || actx->inbound.line[2] == ' '))
|
||||||
|
{
|
||||||
|
if (gpgsm->status.fnc)
|
||||||
|
gpgsm->status.fnc (gpgsm->status.fnc_value, STATUS_EOF, "");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* FIXME: Parse the status and call the handler. */
|
||||||
|
|
||||||
|
fprintf (stderr, "[UNCAUGHT STATUS]%s", actx->inbound.line);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gpgme_gpgsm_set_status_handler (GpgsmObject gpgsm,
|
||||||
|
GpgStatusHandler fnc, void *fnc_value)
|
||||||
|
{
|
||||||
|
assert (gpgsm);
|
||||||
|
|
||||||
|
gpgsm->status.fnc = fnc;
|
||||||
|
gpgsm->status.fnc_value = fnc_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
GpgmeError
|
||||||
|
_gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque)
|
||||||
|
{
|
||||||
|
GpgmeError err = 0;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (!gpgsm)
|
||||||
|
return mk_error (Invalid_Value);
|
||||||
|
|
||||||
|
pid = assuan_get_pid (gpgsm->assuan_ctx);
|
||||||
|
|
||||||
|
err = _gpgme_register_pipe_handler (opaque, gpgsm_status_handler, gpgsm, pid,
|
||||||
|
gpgsm->assuan_ctx->inbound.fd, 1);
|
||||||
|
|
||||||
|
if (gpgsm->input_fd != -1)
|
||||||
|
{
|
||||||
|
err = _gpgme_register_pipe_handler (opaque, _gpgme_data_outbound_handler,
|
||||||
|
gpgsm->input_data, pid,
|
||||||
|
gpgsm->input_fd, 0);
|
||||||
|
if (!err) /* FIXME Kludge around poll() problem. */
|
||||||
|
err = _gpgme_io_set_nonblocking (gpgsm->input_fd);
|
||||||
|
}
|
||||||
|
if (!err && gpgsm->output_fd != -1)
|
||||||
|
err = _gpgme_register_pipe_handler (opaque, _gpgme_data_inbound_handler,
|
||||||
|
gpgsm->output_data, pid,
|
||||||
|
gpgsm->output_fd, 1);
|
||||||
|
if (!err && gpgsm->message_fd != -1)
|
||||||
|
{
|
||||||
|
err = _gpgme_register_pipe_handler (opaque, _gpgme_data_outbound_handler,
|
||||||
|
gpgsm->message_data, pid,
|
||||||
|
gpgsm->message_fd, 0);
|
||||||
|
if (!err) /* FIXME Kludge around poll() problem. */
|
||||||
|
err = _gpgme_io_set_nonblocking (gpgsm->message_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
err = _assuan_write_line (gpgsm->assuan_ctx, gpgsm->command);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
#else /* ENABLE_GPGSM */
|
#else /* ENABLE_GPGSM */
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
@ -127,4 +334,16 @@ _gpgme_gpgsm_release (GpgsmObject gpgsm)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GpgmeError
|
||||||
|
_gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text)
|
||||||
|
{
|
||||||
|
return mk_error (Invalid_Engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
GpgmeError
|
||||||
|
_gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque)
|
||||||
|
{
|
||||||
|
return mk_error (Invalid_Engine);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* ! ENABLE_GPGSM */
|
#endif /* ! ENABLE_GPGSM */
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#define ENGINE_GPGSM_H
|
#define ENGINE_GPGSM_H
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "rungpg.h" /* FIXME statusHandler */
|
||||||
|
|
||||||
const char *_gpgme_gpgsm_get_version (void);
|
const char *_gpgme_gpgsm_get_version (void);
|
||||||
GpgmeError _gpgme_gpgsm_check_version (void);
|
GpgmeError _gpgme_gpgsm_check_version (void);
|
||||||
@ -30,4 +31,26 @@ GpgmeError _gpgme_gpgsm_check_version (void);
|
|||||||
GpgmeError _gpgme_gpgsm_new (GpgsmObject *r_gpg);
|
GpgmeError _gpgme_gpgsm_new (GpgsmObject *r_gpg);
|
||||||
void _gpgme_gpgsm_release (GpgsmObject gpg);
|
void _gpgme_gpgsm_release (GpgsmObject gpg);
|
||||||
|
|
||||||
|
void _gpgme_gpgsm_set_status_handler (GpgsmObject gpgsm,
|
||||||
|
GpgStatusHandler fnc, void *fnc_value);
|
||||||
|
GpgmeError _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph,
|
||||||
|
GpgmeData plain);
|
||||||
|
GpgmeError _gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, int allow_secret);
|
||||||
|
GpgmeError _gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp,
|
||||||
|
GpgmeData plain, GpgmeData ciph,
|
||||||
|
int use_armor);
|
||||||
|
GpgmeError _gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp,
|
||||||
|
GpgmeData keydata, int use_armor);
|
||||||
|
GpgmeError _gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data,
|
||||||
|
int use_armor);
|
||||||
|
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_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,
|
||||||
|
GpgmeSigMode mode, int use_armor,
|
||||||
|
int use_textmode, GpgmeCtx ctx /* FIXME */);
|
||||||
|
GpgmeError _gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern);
|
||||||
|
GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text);
|
||||||
|
GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque);
|
||||||
|
|
||||||
#endif /* ENGINE_GPGSM_H */
|
#endif /* ENGINE_GPGSM_H */
|
||||||
|
@ -189,7 +189,7 @@ _gpgme_engine_set_status_handler (EngineObject engine,
|
|||||||
_gpgme_gpg_set_status_handler (engine->engine.gpg, fnc, fnc_value);
|
_gpgme_gpg_set_status_handler (engine->engine.gpg, fnc, fnc_value);
|
||||||
break;
|
break;
|
||||||
case GPGME_PROTOCOL_CMS:
|
case GPGME_PROTOCOL_CMS:
|
||||||
/* FIXME */
|
_gpgme_gpgsm_set_status_handler (engine->engine.gpgsm, fnc, fnc_value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -428,8 +428,7 @@ _gpgme_engine_op_verify (EngineObject engine, GpgmeData sig, GpgmeData text)
|
|||||||
case GPGME_PROTOCOL_OpenPGP:
|
case GPGME_PROTOCOL_OpenPGP:
|
||||||
return _gpgme_gpg_op_verify (engine->engine.gpg, sig, text);
|
return _gpgme_gpg_op_verify (engine->engine.gpg, sig, text);
|
||||||
case GPGME_PROTOCOL_CMS:
|
case GPGME_PROTOCOL_CMS:
|
||||||
/* FIXME */
|
return _gpgme_gpgsm_op_verify (engine->engine.gpgsm, sig, text);
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -446,8 +445,7 @@ GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque)
|
|||||||
case GPGME_PROTOCOL_OpenPGP:
|
case GPGME_PROTOCOL_OpenPGP:
|
||||||
return _gpgme_gpg_spawn (engine->engine.gpg, opaque);
|
return _gpgme_gpg_spawn (engine->engine.gpg, opaque);
|
||||||
case GPGME_PROTOCOL_CMS:
|
case GPGME_PROTOCOL_CMS:
|
||||||
/* FIXME */
|
return _gpgme_gpgsm_start (engine->engine.gpgsm, opaque);
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,9 @@ GpgmeError _gpgme_data_append_percentstring_for_xml ( GpgmeData dh,
|
|||||||
GpgmeError _gpgme_data_unread (GpgmeData dh,
|
GpgmeError _gpgme_data_unread (GpgmeData dh,
|
||||||
const char *buffer, size_t length );
|
const char *buffer, size_t length );
|
||||||
|
|
||||||
|
int _gpgme_data_inbound_handler (void *opaque, int pid, int fd);
|
||||||
|
int _gpgme_data_outbound_handler (void *opaque, int pid, int fd);
|
||||||
|
|
||||||
|
|
||||||
/*-- key.c --*/
|
/*-- key.c --*/
|
||||||
GpgmeError _gpgme_key_new ( GpgmeKey *r_key );
|
GpgmeError _gpgme_key_new ( GpgmeKey *r_key );
|
||||||
|
134
gpgme/rungpg.c
134
gpgme/rungpg.c
@ -132,9 +132,6 @@ DEFINE_STATIC_LOCK (reap_list_lock);
|
|||||||
static void free_argv ( char **argv );
|
static void free_argv ( char **argv );
|
||||||
static void free_fd_data_map ( struct fd_data_map_s *fd_data_map );
|
static void free_fd_data_map ( struct fd_data_map_s *fd_data_map );
|
||||||
|
|
||||||
static int gpg_inbound_handler ( void *opaque, int pid, int fd );
|
|
||||||
static int gpg_outbound_handler ( void *opaque, int pid, int fd );
|
|
||||||
|
|
||||||
static int gpg_status_handler ( void *opaque, int pid, int fd );
|
static int gpg_status_handler ( void *opaque, int pid, int fd );
|
||||||
static GpgmeError read_status ( GpgObject gpg );
|
static GpgmeError read_status ( GpgObject gpg );
|
||||||
|
|
||||||
@ -919,7 +916,7 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
|||||||
if ( _gpgme_register_pipe_handler (
|
if ( _gpgme_register_pipe_handler (
|
||||||
opaque,
|
opaque,
|
||||||
gpg->fd_data_map[i].inbound?
|
gpg->fd_data_map[i].inbound?
|
||||||
gpg_inbound_handler:gpg_outbound_handler,
|
_gpgme_data_inbound_handler:_gpgme_data_outbound_handler,
|
||||||
gpg->fd_data_map[i].data,
|
gpg->fd_data_map[i].data,
|
||||||
pid, gpg->fd_data_map[i].fd,
|
pid, gpg->fd_data_map[i].fd,
|
||||||
gpg->fd_data_map[i].inbound )
|
gpg->fd_data_map[i].inbound )
|
||||||
@ -939,135 +936,6 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
gpg_inbound_handler ( void *opaque, int pid, int fd )
|
|
||||||
{
|
|
||||||
GpgmeData dh = opaque;
|
|
||||||
GpgmeError err;
|
|
||||||
int nread;
|
|
||||||
char buf[200];
|
|
||||||
|
|
||||||
assert ( _gpgme_data_get_mode (dh) == GPGME_DATA_MODE_IN );
|
|
||||||
|
|
||||||
nread = _gpgme_io_read (fd, buf, 200 );
|
|
||||||
if ( nread < 0 ) {
|
|
||||||
DEBUG3 ("read_mem_data: read failed on fd %d (n=%d): %s",
|
|
||||||
fd, nread, strerror (errno) );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (!nread)
|
|
||||||
return 1; /* eof */
|
|
||||||
|
|
||||||
/* We could improve this with a GpgmeData function which takes
|
|
||||||
* the read function or provides a memory area for writing to it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
err = _gpgme_data_append ( dh, buf, nread );
|
|
||||||
if ( err ) {
|
|
||||||
DEBUG1 ("_gpgme_append_data failed: %s\n",
|
|
||||||
gpgme_strerror(err));
|
|
||||||
/* Fixme: we should close the pipe or read it to /dev/null in
|
|
||||||
* this case. Returnin EOF is not sufficient */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
write_mem_data ( GpgmeData dh, int fd )
|
|
||||||
{
|
|
||||||
size_t nbytes;
|
|
||||||
int nwritten;
|
|
||||||
|
|
||||||
nbytes = dh->len - dh->readpos;
|
|
||||||
if ( !nbytes ) {
|
|
||||||
_gpgme_io_close (fd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Arggg, the pipe blocks on large write request, although
|
|
||||||
* select told us that it is okay to write - need to figure out
|
|
||||||
* why this happens? Stevens says nothing about this problem (or
|
|
||||||
* is it my Linux kernel 2.4.0test1)
|
|
||||||
* To avoid that we have set the pipe to nonblocking.
|
|
||||||
*/
|
|
||||||
|
|
||||||
nwritten = _gpgme_io_write ( fd, dh->data+dh->readpos, nbytes );
|
|
||||||
if (nwritten == -1 && errno == EAGAIN )
|
|
||||||
return 0;
|
|
||||||
if ( nwritten < 1 ) {
|
|
||||||
DEBUG3 ("write_mem_data(%d): write failed (n=%d): %s",
|
|
||||||
fd, nwritten, strerror (errno) );
|
|
||||||
_gpgme_io_close (fd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dh->readpos += nwritten;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
write_cb_data ( GpgmeData dh, int fd )
|
|
||||||
{
|
|
||||||
size_t nbytes;
|
|
||||||
int err, nwritten;
|
|
||||||
char buffer[512];
|
|
||||||
|
|
||||||
err = gpgme_data_read ( dh, buffer, DIM(buffer), &nbytes );
|
|
||||||
if (err == GPGME_EOF) {
|
|
||||||
_gpgme_io_close (fd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
nwritten = _gpgme_io_write ( fd, buffer, nbytes );
|
|
||||||
if (nwritten == -1 && errno == EAGAIN )
|
|
||||||
return 0;
|
|
||||||
if ( nwritten < 1 ) {
|
|
||||||
DEBUG3 ("write_cb_data(%d): write failed (n=%d): %s",
|
|
||||||
fd, nwritten, strerror (errno) );
|
|
||||||
_gpgme_io_close (fd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( nwritten < nbytes ) {
|
|
||||||
/* ugly, ugly: It does currently only for for MEM type data */
|
|
||||||
if ( _gpgme_data_unread (dh, buffer + nwritten, nbytes - nwritten ) )
|
|
||||||
DEBUG1 ("wite_cb_data: unread of %d bytes failed\n",
|
|
||||||
nbytes - nwritten );
|
|
||||||
_gpgme_io_close (fd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
gpg_outbound_handler ( void *opaque, int pid, int fd )
|
|
||||||
{
|
|
||||||
GpgmeData dh = opaque;
|
|
||||||
|
|
||||||
assert ( _gpgme_data_get_mode (dh) == GPGME_DATA_MODE_OUT );
|
|
||||||
switch ( gpgme_data_get_type (dh) ) {
|
|
||||||
case GPGME_DATA_TYPE_MEM:
|
|
||||||
if ( write_mem_data ( dh, fd ) )
|
|
||||||
return 1; /* ready */
|
|
||||||
break;
|
|
||||||
case GPGME_DATA_TYPE_CB:
|
|
||||||
if (write_cb_data (dh, fd))
|
|
||||||
return 1; /* ready */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gpg_status_handler ( void *opaque, int pid, int fd )
|
gpg_status_handler ( void *opaque, int pid, int fd )
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user