aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcus Brinkmann <[email protected]>2006-12-17 21:12:40 +0000
committerMarcus Brinkmann <[email protected]>2006-12-17 21:12:40 +0000
commit13d2e5d1c769d82d05e47a3fe9733108fabd5f73 (patch)
tree043da58743ab799790f4260fb74cc6ee9bc5d9ec
parent2006-12-17 Marcus Brinkmann <[email protected]> (diff)
downloadgpgme-13d2e5d1c769d82d05e47a3fe9733108fabd5f73.tar.gz
gpgme-13d2e5d1c769d82d05e47a3fe9733108fabd5f73.zip
2006-12-17 Marcus Brinkmann <[email protected]>
* configure.ac: Fix two typos in last change. gpgme/ 2006-12-17 Marcus Brinkmann <[email protected]> * gpgme.c (gpgme_set_protocol): Shut down the engine when switching protocols. (gpgme_ctx_set_engine_info): Likewise for engine info. * engine.h (_gpgme_engine_reset): New function prototype. * engine.c (_gpgme_engine_reset): New function. * engine-backend.h (struct engine_ops): New member RESET. * rungpg.c (_gpgme_engine_ops_gpg): Add NULL for reset function. * engine-gpgsm.c (_gpgme_engine_ops_gpgsm) [USE_DESCRIPTOR_PASSING]: Add gpgsm_reset for reset. (_gpgme_engine_ops_gpgsm) [!USE_DESCRIPTOR_PASSING]: Add NULL for reset function. (gpgsm_reset) [USE_DESCRIPTOR_PASSING]: New function. * op-support.c (_gpgme_op_reset): Try to use the engine's reset function if available. * engine-gpgsm.c (gpgsm_new): Move code to dup status_fd to ... (start): ... here. * posix-io.c (_gpgme_io_recvmsg, _gpgme_io_sendmsg): New functions.
-rw-r--r--ChangeLog4
-rw-r--r--TODO2
-rw-r--r--assuan/assuan.h6
-rw-r--r--configure.ac2
-rw-r--r--gpgme/ChangeLog18
-rw-r--r--gpgme/engine-backend.h1
-rw-r--r--gpgme/engine-gpgsm.c94
-rw-r--r--gpgme/engine.c13
-rw-r--r--gpgme/engine.h1
-rw-r--r--gpgme/gpgme.c20
-rw-r--r--gpgme/gpgme.h2
-rw-r--r--gpgme/op-support.c37
-rw-r--r--gpgme/posix-io.c83
-rw-r--r--gpgme/rungpg.c1
14 files changed, 223 insertions, 61 deletions
diff --git a/ChangeLog b/ChangeLog
index 6899474d..83e47d49 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-12-17 Marcus Brinkmann <[email protected]>
+
+ * configure.ac: Fix two typos in last change.
+
2006-12-03 Marcus Brinkmann <[email protected]>
* configure.ac: Use descriptor passing only if --enable-fd-passing
diff --git a/TODO b/TODO
index c2255ca5..ddcf6b11 100644
--- a/TODO
+++ b/TODO
@@ -78,6 +78,8 @@ Hey Emacs, this is -*- outline -*- mode!
release everything properly at a reset and at an error. Think hard
about where to guarantee what (ie, what happens if start fails, are
the fds unregistered immediately - i think so?)
+ Note that we need support in gpgsm to set include-certs to default
+ as RESET does not reset it.
** Optimize the case where a data object has 0an underlying fd we can pass
directly to the engine. This will be automatic with socket I/O and
descriptor passing.
diff --git a/assuan/assuan.h b/assuan/assuan.h
index 4916d6fb..cdf0445a 100644
--- a/assuan/assuan.h
+++ b/assuan/assuan.h
@@ -75,6 +75,8 @@ int _gpgme_ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
int _gpgme_ath_connect (int s, struct sockaddr *addr, socklen_t length);
int _gpgme_ath_sendmsg (int s, const struct msghdr *msg, int flags);
int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
+int _gpgme_io_sendmsg (int sock, const struct msghdr *msg, int flags);
+int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
#endif /*!HAVE_W32_SYSTEM*/
#define read _gpgme_io_read
@@ -83,8 +85,8 @@ int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
#define select _gpgme_ath_select
#define accept _gpgme_ath_accept
#define connect _gpgme_ath_connect
-#define sendmsg _gpgme_ath_sendmsg
-#define recvmsg _gpgme_ath_recvmsg
+#define sendmsg _gpgme_io_sendmsg
+#define recvmsg _gpgme_io_recvmsg
#endif /*_ASSUAN_IN_GPGME_BUILD_ASSUAN*/
/**** End GPGME specific modifications. ******/
diff --git a/configure.ac b/configure.ac
index c03e42f3..581e0537 100644
--- a/configure.ac
+++ b/configure.ac
@@ -491,7 +491,7 @@ AC_CHECK_MEMBER(struct cmsghdr.cmsg_len,
AC_ARG_ENABLE(fd-passing,
AC_HELP_STRING([--enable-fd-passing], [use FD passing if supported]),
- use_desciptor_passing=$withval)
+ use_descriptor_passing=$enableval)
if test "$supports_descriptor_passing" != "yes"; then
use_descriptor_passing=no
diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog
index fea3b67d..6e6749d2 100644
--- a/gpgme/ChangeLog
+++ b/gpgme/ChangeLog
@@ -1,5 +1,23 @@
2006-12-17 Marcus Brinkmann <[email protected]>
+ * gpgme.c (gpgme_set_protocol): Shut down the engine when
+ switching protocols.
+ (gpgme_ctx_set_engine_info): Likewise for engine info.
+ * engine.h (_gpgme_engine_reset): New function prototype.
+ * engine.c (_gpgme_engine_reset): New function.
+ * engine-backend.h (struct engine_ops): New member RESET.
+ * rungpg.c (_gpgme_engine_ops_gpg): Add NULL for reset function.
+ * engine-gpgsm.c (_gpgme_engine_ops_gpgsm)
+ [USE_DESCRIPTOR_PASSING]: Add gpgsm_reset for reset.
+ (_gpgme_engine_ops_gpgsm) [!USE_DESCRIPTOR_PASSING]: Add NULL for
+ reset function.
+ (gpgsm_reset) [USE_DESCRIPTOR_PASSING]: New function.
+ * op-support.c (_gpgme_op_reset): Try to use the engine's reset
+ function if available.
+ * engine-gpgsm.c (gpgsm_new): Move code to dup status_fd to ...
+ (start): ... here.
+ * posix-io.c (_gpgme_io_recvmsg, _gpgme_io_sendmsg): New functions.
+
* engine.h (_gpgme_engine_new): Remove arguments lc_ctype and
lc_messages from prototype.
(_gpgme_engine_set_locale): New prototype.
diff --git a/gpgme/engine-backend.h b/gpgme/engine-backend.h
index eed8ffd9..052e724c 100644
--- a/gpgme/engine-backend.h
+++ b/gpgme/engine-backend.h
@@ -49,6 +49,7 @@ struct engine_ops
/* Member functions. */
void (*release) (void *engine);
+ gpgme_error_t (*reset) (void *engine);
void (*set_status_handler) (void *engine, engine_status_handler_t fnc,
void *fnc_value);
gpgme_error_t (*set_command_handler) (void *engine,
diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c
index 766323a4..23e49a67 100644
--- a/gpgme/engine-gpgsm.c
+++ b/gpgme/engine-gpgsm.c
@@ -334,15 +334,15 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
char dft_ttyname[64];
char *dft_ttytype = NULL;
char *optstr;
- int fdlist[5];
- int nfds;
gpgsm = calloc (1, sizeof *gpgsm);
if (!gpgsm)
return gpg_error_from_errno (errno);
gpgsm->status_cb.fd = -1;
+ gpgsm->status_cb.dir = 1;
gpgsm->status_cb.tag = 0;
+ gpgsm->status_cb.data = gpgsm;
gpgsm->input_cb.fd = -1;
gpgsm->input_cb.dir = 0;
@@ -423,30 +423,6 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
if (err)
goto leave;
- /* We need to know the fd used by assuan for reads. We do this by
- using the assumption that the first returned fd from
- assuan_get_active_fds() is always this one. */
- nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */,
- fdlist, DIM (fdlist));
- if (nfds < 1)
- {
- err = gpg_error (GPG_ERR_GENERAL); /* FIXME */
- goto leave;
- }
- /* We duplicate the file descriptor, so we can close it without
- disturbing assuan. Alternatively, we could special case
- status_fd and register/unregister it manually as needed, but this
- increases code duplication and is more complicated as we can not
- use the close notifications etc. */
- gpgsm->status_cb.fd = dup (fdlist[0]);
- if (gpgsm->status_cb.fd < 0)
- {
- err = gpg_error (GPG_ERR_GENERAL); /* FIXME */
- goto leave;
- }
- gpgsm->status_cb.dir = 1;
- gpgsm->status_cb.data = gpgsm;
-
err = _gpgme_getenv ("DISPLAY", &dft_display);
if (err)
goto leave;
@@ -518,14 +494,6 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
}
}
- if (!err
- && (_gpgme_io_set_close_notify (gpgsm->status_cb.fd,
- close_notify_handler, gpgsm)))
- {
- err = gpg_error (GPG_ERR_GENERAL);
- goto leave;
- }
-
#if !USE_DESCRIPTOR_PASSING
if (!err
&& (_gpgme_io_set_close_notify (gpgsm->input_cb.fd,
@@ -997,6 +965,33 @@ static gpgme_error_t
start (engine_gpgsm_t gpgsm, const char *command)
{
gpgme_error_t err;
+ int fdlist[5];
+ int nfds;
+
+ /* We need to know the fd used by assuan for reads. We do this by
+ using the assumption that the first returned fd from
+ assuan_get_active_fds() is always this one. */
+ nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */,
+ fdlist, DIM (fdlist));
+ if (nfds < 1)
+ return gpg_error (GPG_ERR_GENERAL); /* FIXME */
+
+ /* We duplicate the file descriptor, so we can close it without
+ disturbing assuan. Alternatively, we could special case
+ status_fd and register/unregister it manually as needed, but this
+ increases code duplication and is more complicated as we can not
+ use the close notifications etc. */
+ gpgsm->status_cb.fd = dup (fdlist[0]);
+ if (gpgsm->status_cb.fd < 0)
+ return gpg_error_from_syserror ();
+
+ if (_gpgme_io_set_close_notify (gpgsm->status_cb.fd,
+ close_notify_handler, gpgsm))
+ {
+ close (gpgsm->status_cb.fd);
+ gpgsm->status_cb.fd = -1;
+ return gpg_error (GPG_ERR_GENERAL);
+ }
err = add_io_cb (gpgsm, &gpgsm->status_cb, status_handler);
if (!err && gpgsm->input_cb.fd != -1)
@@ -1016,6 +1011,19 @@ start (engine_gpgsm_t gpgsm, const char *command)
}
+#if USE_DESCRIPTOR_PASSING
+static gpgme_error_t
+gpgsm_reset (void *engine)
+{
+ engine_gpgsm_t gpgsm = engine;
+
+ /* We must send a reset because we need to reset the list of
+ signers. Note that RESET does not reset OPTION commands. */
+ return gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "RESET", NULL, NULL);
+}
+#endif
+
+
static gpgme_error_t
gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
{
@@ -1385,6 +1393,7 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
if (!pattern)
pattern = "";
+ /* Always send list-mode option because RESET does not reset it. */
if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
return gpg_error_from_errno (errno);
err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
@@ -1393,6 +1402,8 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
return err;
+ /* Always send key validation because RESET does not reset it. */
+
/* Use the validation mode if required. We don't check for an error
yet because this is a pretty fresh gpgsm features. */
gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
@@ -1448,6 +1459,7 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
if (mode & GPGME_KEYLIST_MODE_EXTERN)
list_mode |= 2;
+ /* Always send list-mode option because RESET does not reset it. */
if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
return gpg_error_from_errno (errno);
err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
@@ -1455,6 +1467,7 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
if (err)
return err;
+ /* Always send key validation because RESET does not reset it. */
/* Use the validation mode if required. We don't check for an error
yet because this is a pretty fresh gpgsm features. */
gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
@@ -1561,12 +1574,8 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
- /* We must send a reset because we need to reset the list of
- signers. Note that RESET does not reset OPTION commands. */
- err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "RESET", NULL, NULL);
- if (err)
- return err;
-
+ /* FIXME: This does not work as RESET does not reset it so we can't
+ revert back to default. */
if (include_certs != GPGME_INCLUDE_CERTS_DEFAULT)
{
/* FIXME: Make sure that if we run multiple operations, that we
@@ -1704,6 +1713,11 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
/* Member functions. */
gpgsm_release,
+#if USE_DESCRIPTOR_PASSING
+ gpgsm_reset,
+#else
+ NULL, /* reset */
+#endif
gpgsm_set_status_handler,
NULL, /* set_command_handler */
gpgsm_set_colon_line_handler,
diff --git a/gpgme/engine.c b/gpgme/engine.c
index dd89c2d7..a64b4625 100644
--- a/gpgme/engine.c
+++ b/gpgme/engine.c
@@ -420,6 +420,19 @@ _gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine)
}
+gpgme_error_t
+_gpgme_engine_reset (engine_t engine)
+{
+ if (!engine)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ if (!engine->ops->reset)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+ return (*engine->ops->reset) (engine->engine);
+}
+
+
void
_gpgme_engine_release (engine_t engine)
{
diff --git a/gpgme/engine.h b/gpgme/engine.h
index 893e5914..1fe24f55 100644
--- a/gpgme/engine.h
+++ b/gpgme/engine.h
@@ -52,6 +52,7 @@ gpgme_error_t _gpgme_set_engine_info (gpgme_engine_info_t info,
gpgme_error_t _gpgme_engine_new (gpgme_engine_info_t info,
engine_t *r_engine);
+gpgme_error_t _gpgme_engine_reset (engine_t engine);
gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category,
const char *value);
diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c
index 85f377ff..6604cb08 100644
--- a/gpgme/gpgme.c
+++ b/gpgme/gpgme.c
@@ -159,7 +159,17 @@ gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
if (protocol != GPGME_PROTOCOL_OpenPGP && protocol != GPGME_PROTOCOL_CMS)
return gpg_error (GPG_ERR_INV_VALUE);
- ctx->protocol = protocol;
+ if (ctx->protocol != protocol)
+ {
+ /* Shut down the engine when switching protocols. */
+ if (ctx->engine)
+ {
+ _gpgme_engine_release (ctx->engine);
+ ctx->engine = NULL;
+ }
+
+ ctx->protocol = protocol;
+ }
return 0;
}
@@ -417,8 +427,12 @@ gpgme_error_t
gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
const char *file_name, const char *home_dir)
{
- /* FIXME: Make sure to reset the context if we are running in daemon
- mode. */
+ /* Shut down the engine when changing engine info. */
+ if (ctx->engine)
+ {
+ _gpgme_engine_release (ctx->engine);
+ ctx->engine = NULL;
+ }
return _gpgme_set_engine_info (ctx->engine_info, proto,
file_name, home_dir);
}
diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h
index 6251a2f7..bf69d87f 100644
--- a/gpgme/gpgme.h
+++ b/gpgme/gpgme.h
@@ -72,7 +72,7 @@ extern "C" {
AM_PATH_GPGME macro) check that this header matches the installed
library. Warning: Do not edit the next line. configure will do
that for you! */
-#define GPGME_VERSION "1.1.3-cvs1188"
+#define GPGME_VERSION "1.1.3-cvs1196"
diff --git a/gpgme/op-support.c b/gpgme/op-support.c
index 8a428512..4be7a018 100644
--- a/gpgme/op-support.c
+++ b/gpgme/op-support.c
@@ -68,28 +68,37 @@ gpgme_error_t
_gpgme_op_reset (gpgme_ctx_t ctx, int type)
{
gpgme_error_t err = 0;
- gpgme_engine_info_t info;
struct gpgme_io_cbs io_cbs;
- info = ctx->engine_info;
- while (info && info->protocol != ctx->protocol)
- info = info->next;
-
- if (!info)
- return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
-
_gpgme_release_result (ctx);
if (ctx->engine)
{
- _gpgme_engine_release (ctx->engine);
- ctx->engine = NULL;
+ /* Attempt to reset an existing engine. */
+
+ err = _gpgme_engine_reset (ctx->engine);
+ if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
+ {
+ _gpgme_engine_release (ctx->engine);
+ ctx->engine = NULL;
+ }
}
- /* Create an engine object. */
- err = _gpgme_engine_new (info, &ctx->engine);
- if (err)
- return err;
+ if (!ctx->engine)
+ {
+ gpgme_engine_info_t info;
+ info = ctx->engine_info;
+ while (info && info->protocol != ctx->protocol)
+ info = info->next;
+
+ if (!info)
+ return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
+
+ /* Create an engine object. */
+ err = _gpgme_engine_new (info, &ctx->engine);
+ if (err)
+ return err;
+ }
err = _gpgme_engine_set_locale (ctx->engine, LC_CTYPE, ctx->lc_ctype);
if (!err)
diff --git a/gpgme/posix-io.c b/gpgme/posix-io.c
index 0e26a91e..5cb71f9b 100644
--- a/gpgme/posix-io.c
+++ b/gpgme/posix-io.c
@@ -412,3 +412,86 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
}
return count;
}
+
+
+int
+_gpgme_io_recvmsg (int fd, struct msghdr *msg, int flags)
+{
+ int nread;
+ int saved_errno;
+ struct iovec *iov;
+
+ nread = 0;
+ iov = msg->msg_iov;
+ while (iov < msg->msg_iov + msg->msg_iovlen)
+ {
+ nread += iov->iov_len;
+ iov++;
+ }
+
+ DEBUG2 ("fd %d: about to receive %d bytes\n",
+ fd, (int) nread);
+ do
+ {
+ nread = _gpgme_ath_recvmsg (fd, msg, flags);
+ }
+ while (nread == -1 && errno == EINTR);
+ saved_errno = errno;
+ DEBUG2 ("fd %d: got %d bytes\n", fd, nread);
+ if (nread > 0)
+ {
+ int nr = nread;
+
+ iov = msg->msg_iov;
+ while (nr > 0)
+ {
+ int len = nr > iov->iov_len ? iov->iov_len : nr;
+ _gpgme_debug (2, "fd %d: got `%.*s'\n", fd, len,
+ msg->msg_iov->iov_base);
+ iov++;
+ nr -= len;
+ }
+ }
+ errno = saved_errno;
+ return nread;
+}
+
+
+int
+_gpgme_io_sendmsg (int fd, const struct msghdr *msg, int flags)
+{
+ int saved_errno;
+ int nwritten;
+ struct iovec *iov;
+
+ nwritten = 0;
+ iov = msg->msg_iov;
+ while (iov < msg->msg_iov + msg->msg_iovlen)
+ {
+ nwritten += iov->iov_len;
+ iov++;
+ }
+
+ DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int) nwritten);
+ iov = msg->msg_iov;
+ while (nwritten > 0)
+ {
+ int len = nwritten > iov->iov_len ? iov->iov_len : nwritten;
+ _gpgme_debug (2, "fd %d: write `%.*s'\n", fd, len,
+ msg->msg_iov->iov_base);
+ iov++;
+ nwritten -= len;
+ }
+
+ do
+ {
+ nwritten = _gpgme_ath_sendmsg (fd, msg, flags);
+ }
+ while (nwritten == -1 && errno == EINTR);
+ saved_errno = errno;
+ DEBUG2 ("fd %d: wrote %d bytes\n", fd, (int) nwritten);
+ errno = saved_errno;
+ return nwritten;
+}
+
+
diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c
index f3326b30..b81aca37 100644
--- a/gpgme/rungpg.c
+++ b/gpgme/rungpg.c
@@ -2078,6 +2078,7 @@ struct engine_ops _gpgme_engine_ops_gpg =
/* Member functions. */
gpg_release,
+ NULL, /* reset */
gpg_set_status_handler,
gpg_set_command_handler,
gpg_set_colon_line_handler,