diff options
| author | Marcus Brinkmann <[email protected]> | 2006-12-17 21:12:40 +0000 | 
|---|---|---|
| committer | Marcus Brinkmann <[email protected]> | 2006-12-17 21:12:40 +0000 | 
| commit | 13d2e5d1c769d82d05e47a3fe9733108fabd5f73 (patch) | |
| tree | 043da58743ab799790f4260fb74cc6ee9bc5d9ec | |
| parent | 2006-12-17 Marcus Brinkmann <[email protected]> (diff) | |
| download | gpgme-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-- | ChangeLog | 4 | ||||
| -rw-r--r-- | TODO | 2 | ||||
| -rw-r--r-- | assuan/assuan.h | 6 | ||||
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | gpgme/ChangeLog | 18 | ||||
| -rw-r--r-- | gpgme/engine-backend.h | 1 | ||||
| -rw-r--r-- | gpgme/engine-gpgsm.c | 94 | ||||
| -rw-r--r-- | gpgme/engine.c | 13 | ||||
| -rw-r--r-- | gpgme/engine.h | 1 | ||||
| -rw-r--r-- | gpgme/gpgme.c | 20 | ||||
| -rw-r--r-- | gpgme/gpgme.h | 2 | ||||
| -rw-r--r-- | gpgme/op-support.c | 37 | ||||
| -rw-r--r-- | gpgme/posix-io.c | 83 | ||||
| -rw-r--r-- | gpgme/rungpg.c | 1 | 
14 files changed, 223 insertions, 61 deletions
| @@ -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 @@ -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, | 
