2009-11-10 Marcus Brinkmann <marcus@g10code.de>

* configure.ac: Activate UIServer if FD passing is enabled and
	Assuan is available.

m4/
2009-11-10  Marcus Brinkmann  <marcus@g10code.de>

	* libassuan.m4: Fix LIBASSUAN_VERSION.

src/
2009-11-10  Marcus Brinkmann  <marcus@g10code.de>

	* Makefile.am (uiserver_components): New variable.
	(main_sources): Add it.
	* ops.h, key.c (_gpgme_key_append_name): Take CONVERT argument,
	implement it.  Adjust callers.
	(gpgme_key_from_uid): New function.
	* gpgme.h.in (gpgme_protocol_t): Add GPGME_PROTOCOL_DEFAULT.
	(gpgme_encrypt_flags_t): Add GPGME_ENCRYPT_PREPARE,
	GPGME_ENCRYPT_EXPECT_SIGN.
	(gpgme_set_sub_protocol, gpgme_key_from_uid): New functions.
	* libgpgme.vers, gpgme.def: Add new functions.
	* gpgme.c (gpgme_set_protocol): Add UIServer protocol.
	(gpgme_set_sub_protocol): New function.
	(gpgme_get_protocol_name): Add UIServer and default protocol.
	* assuan-support.c: Return correct error values, implement
	socketpair for POSIX.
	* priv-io.h, posix-io.c, w32-io.c, w32-glib-io.c,
	w32-qt-io.cpp (_gpgme_io_spawn): Add ATFORK and ATFORKVALUE
	arguments.  Implement it for POSIX.  Adjust all callers.
	* engine.h, engine-backend.h (_gpgme_engine_set_protocol)
	(_gpgme_engine_op_decrypt_verify): New prototypes.  Adjust all
	users.
	* engine.c (engine_ops, gpgme_get_engine_info): Add UIServer
	engine.
	(_gpgme_engine_set_protocol, _gpgme_engine_op_decrypt_verify): New
	function.
	* decrypt-verify.c (decrypt_verify_start): Call
	_gpgme_engine_op_decrypt_verify.
	* util.h, posix-util.c,
	w32-util.c (_gpgme_get_uiserver_socket_path): New function.
	* engine-gpgsm.c (gpgsm_set_fd): Fix _gpgme_io_pipe invocation.
	* gpgme-tool.c: Some support for UIServer protocol.
	* engine-uiserver.c: New file.
This commit is contained in:
Marcus Brinkmann 2009-11-10 09:07:19 +00:00
parent 8435f18d96
commit 96cf17b159
37 changed files with 1721 additions and 69 deletions

View File

@ -1,3 +1,8 @@
2009-11-10 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Activate UIServer if FD passing is enabled and
Assuan is available.
2009-10-30 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Check for argp.h and error_t.

2
NEWS
View File

@ -8,6 +8,8 @@ Noteworthy changes in version 1.2.1 (unreleased)
* New engine GPGME_PROTOCOL_G13 to support the new g13 tool.
* New engine GPGME_PROTOCOL_UISERVER to support UI Servers.
* Interface changes relative to the 1.2.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GPGME_STATUS_INV_SGNR NEW

5
TODO
View File

@ -1,5 +1,10 @@
Hey Emacs, this is -*- org -*- mode!
* Document all the new stuff.
* Fix the remaining UI Server problems:
** VERIFY --silent support.
** ENCRYPT/DECRYPT/VERIFY/SIGN reset the engine, shouldn't be done with UISERVER?
* IMPORTANT
** When using descriptor passing, we need to set the fd to blocking before
issueing simple commands, because we are mixing synchronous

View File

@ -338,7 +338,7 @@ AC_DEFINE_UNQUOTED(NEED_GPGSM_VERSION, "$NEED_GPGSM_VERSION",
AC_DEFINE_UNQUOTED(NEED_GPGCONF_VERSION, "$NEED_GPGCONF_VERSION",
[Min. needed GPGCONF version.])
AC_DEFINE_UNQUOTED(NEED_G13_VERSION, "$NEED_G13_VERSION",
[Min. needed G13 version.])
[Min. needed G13 version.])
NO_OVERRIDE=no
@ -634,13 +634,6 @@ AC_ARG_ENABLE(gpgconf-test,
run_gpgconf_test=$enableval)
AM_CONDITIONAL(RUN_GPGCONF_TESTS, test "$run_gpgconf_test" = "yes")
# Only build if supported.
AM_CONDITIONAL(BUILD_GPGCONF, test "$GPGCONF" != "no")
if test "$GPGCONF" != "no"; then
AC_DEFINE(HAVE_GPGCONF, 1,
[Defined if we are building with gpgconf support.])
fi
NO_OVERRIDE=no
AC_ARG_WITH(g13,
@ -737,13 +730,6 @@ AC_ARG_ENABLE(g13-test,
run_g13_test=$enableval)
AM_CONDITIONAL(RUN_G13_TESTS, test "$run_g13_test" = "yes")
# Only build if supported.
AM_CONDITIONAL(BUILD_G13, test "$G13" != "no")
if test "$G13" != "no"; then
AC_DEFINE(HAVE_G13, 1,
[Defined if we are building with g13 support.])
fi
# Check for funopen
AC_CHECK_FUNCS(funopen)
@ -803,6 +789,17 @@ fi
AM_CONDITIONAL(USE_DESCRIPTOR_PASSING, test "$use_descriptor_passing" = "yes")
uiserver=no
if test "$use_descriptor_passing" = "yes" && test "$have_libassuan" = "yes"; then
uiserver=yes
fi
if test "$uiserver" != "no"; then
AC_DEFINE(ENABLE_UISERVER, 1,
[Defined if we are building with uiserver support.])
fi
AM_CONDITIONAL(HAVE_UISERVER, test "$uiserver" != "no")
AM_CONDITIONAL(BUILD_COMPLUS, test "$component_system" = "COM+")
# Generate values for the DLL version info
@ -912,6 +909,9 @@ echo "
Assuan version: $LIBASSUAN_VERSION
UI Server: $uiserver
FD Passing: $use_descriptor_passing
GPGME Pthread: $have_pthread
GPGME Pth: $have_pth
"

View File

@ -1,3 +1,7 @@
2009-11-10 Marcus Brinkmann <marcus@g10code.de>
* libassuan.m4: Fix LIBASSUAN_VERSION.
2006-06-08 Marcus Brinkmann <marcus@g10code.de>
* pth.m4: Add --all to pth-config invocation.

View File

@ -63,7 +63,7 @@ AC_DEFUN([AM_PATH_LIBASSUAN],
if test $ok = yes; then
LIBASSUAN_CFLAGS=`$LIBASSUAN_CONFIG $libassuan_config_args --cflags`
LIBASSUAN_LIBS=`$LIBASSUAN_CONFIG $libassuan_config_args --libs`
LIBASSUAN_VERSION="$LIBASSUAN_CONFIG_VERSION"
LIBASSUAN_VERSION="$libassuan_config_version"
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else

View File

@ -1,3 +1,38 @@
2009-11-10 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (uiserver_components): New variable.
(main_sources): Add it.
* ops.h, key.c (_gpgme_key_append_name): Take CONVERT argument,
implement it. Adjust callers.
(gpgme_key_from_uid): New function.
* gpgme.h.in (gpgme_protocol_t): Add GPGME_PROTOCOL_DEFAULT.
(gpgme_encrypt_flags_t): Add GPGME_ENCRYPT_PREPARE,
GPGME_ENCRYPT_EXPECT_SIGN.
(gpgme_set_sub_protocol, gpgme_key_from_uid): New functions.
* libgpgme.vers, gpgme.def: Add new functions.
* gpgme.c (gpgme_set_protocol): Add UIServer protocol.
(gpgme_set_sub_protocol): New function.
(gpgme_get_protocol_name): Add UIServer and default protocol.
* assuan-support.c: Return correct error values, implement
socketpair for POSIX.
* priv-io.h, posix-io.c, w32-io.c, w32-glib-io.c,
w32-qt-io.cpp (_gpgme_io_spawn): Add ATFORK and ATFORKVALUE
arguments. Implement it for POSIX. Adjust all callers.
* engine.h, engine-backend.h (_gpgme_engine_set_protocol)
(_gpgme_engine_op_decrypt_verify): New prototypes. Adjust all
users.
* engine.c (engine_ops, gpgme_get_engine_info): Add UIServer
engine.
(_gpgme_engine_set_protocol, _gpgme_engine_op_decrypt_verify): New
function.
* decrypt-verify.c (decrypt_verify_start): Call
_gpgme_engine_op_decrypt_verify.
* util.h, posix-util.c,
w32-util.c (_gpgme_get_uiserver_socket_path): New function.
* engine-gpgsm.c (gpgsm_set_fd): Fix _gpgme_io_pipe invocation.
* gpgme-tool.c: Some support for UIServer protocol.
* engine-uiserver.c: New file.
2009-11-09 Marcus Brinkmann <marcus@g10code.de>
* engine-gpgsm.c (gpgsm_new): Close server side FDs.

View File

@ -92,6 +92,13 @@ else
g13_components =
endif
if HAVE_UISERVER
uiserver_components = engine-uiserver.c
else
uiserver_components =
endif
# These are the source files common to all library versions. We used
# to build a non-installed library for that, but that does not work
# correctly on all platforms (in particular, one can not specify the
@ -111,6 +118,7 @@ main_sources = \
opassuan.c \
engine.h engine-backend.h engine.c engine-gpg.c status-table.h \
$(gpgsm_components) $(assuan_components) $(gpgconf_components) \
$(uiserver_components) \
$(g13_components) vfs-mount.c vfs-create.c \
gpgconf.c \
sema.h priv-io.h $(system_components) dirinfo.c \

View File

@ -4,6 +4,7 @@
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
#include "assuan.h"
@ -76,7 +77,8 @@ my_recvmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg,
int flags)
{
#ifdef HAVE_W32_SYSTEM
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
errno = ENOSYS;
return -1;
#else
return _gpgme_io_recvmsg (fd, msg, flags);
#endif
@ -89,7 +91,8 @@ my_sendmsg (assuan_context_t ctx, assuan_fd_t fd, const assuan_msghdr_t msg,
int flags)
{
#ifdef HAVE_W32_SYSTEM
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
errno = ENOSYS;
return -1;
#else
return _gpgme_io_sendmsg (fd, msg, flags);
#endif
@ -107,14 +110,17 @@ my_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue, unsigned int flags)
{
gpg_error_t err;
int err;
struct spawn_fd_item_s *fd_items;
int i;
assert (name);
if (! name)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
{
errno = ENOSYS;
return -1;
}
i = 0;
if (fd_child_list)
@ -126,7 +132,7 @@ my_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
i += 3;
fd_items = malloc (sizeof (struct spawn_fd_item_s) * i);
if (! fd_items)
return gpg_error_from_syserror ();
return -1;
i = 0;
if (fd_child_list)
{
@ -152,7 +158,8 @@ my_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
fd_items[i].fd = -1;
fd_items[i].dup_to = -1;
err = _gpgme_io_spawn (name, argv, IOSPAWN_FLAG_NOCLOSE, fd_items, r_pid);
err = _gpgme_io_spawn (name, argv, IOSPAWN_FLAG_NOCLOSE, fd_items,
atfork, atforkvalue, r_pid);
if (! err)
{
i = 0;
@ -195,8 +202,13 @@ static int
my_socketpair (assuan_context_t ctx, int namespace, int style,
int protocol, assuan_fd_t filedes[2])
{
assert ("Should never happen.");
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
#ifdef HAVE_W32_SYSTEM
errno = ENOSYS;
return -1;
#else
/* FIXME: Debug output missing. */
return __assuan_socketpair (ctx, namespace, style, protocol, filedes);
#endif
}

View File

@ -77,7 +77,7 @@ decrypt_verify_start (gpgme_ctx_t ctx, int synchronous,
_gpgme_engine_set_status_handler (ctx->engine,
decrypt_verify_status_handler, ctx);
return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain);
return _gpgme_engine_op_decrypt_verify (ctx->engine, cipher, plain);
}

View File

@ -102,7 +102,7 @@ read_gpgconf_dirs (void)
cfd[0].fd = rp[1];
status = _gpgme_io_spawn (pgmname, argv, 0, cfd, NULL);
status = _gpgme_io_spawn (pgmname, argv, 0, cfd, NULL, NULL, NULL);
if (status < 0)
{
_gpgme_io_close (rp[0]);

View File

@ -743,7 +743,9 @@ struct engine_ops _gpgme_engine_ops_assuan =
NULL, /* set_command_handler */
NULL, /* set_colon_line_handler */
llass_set_locale,
NULL, /* set_protocol */
NULL, /* decrypt */
NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */

View File

@ -58,8 +58,11 @@ struct engine_ops
engine_colon_line_handler_t fnc,
void *fnc_value);
gpgme_error_t (*set_locale) (void *engine, int category, const char *value);
gpgme_error_t (*set_protocol) (void *engine, gpgme_protocol_t protocol);
gpgme_error_t (*decrypt) (void *engine, gpgme_data_t ciph,
gpgme_data_t plain);
gpgme_error_t (*decrypt_verify) (void *engine, gpgme_data_t ciph,
gpgme_data_t plain);
gpgme_error_t (*delete) (void *engine, gpgme_key_t key, int allow_secret);
gpgme_error_t (*edit) (void *engine, int type, gpgme_key_t key,
gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */);
@ -88,12 +91,11 @@ struct engine_ops
gpgme_keylist_mode_t mode);
gpgme_error_t (*sign) (void *engine, gpgme_data_t in, gpgme_data_t out,
gpgme_sig_mode_t mode, int use_armor,
int use_textmode,
int include_certs, gpgme_ctx_t ctx /* FIXME */);
int use_textmode, int include_certs,
gpgme_ctx_t ctx /* FIXME */);
gpgme_error_t (*trustlist) (void *engine, const char *pattern);
gpgme_error_t (*verify) (void *engine, gpgme_data_t sig,
gpgme_data_t signed_text,
gpgme_data_t plaintext);
gpgme_data_t signed_text, gpgme_data_t plaintext);
gpgme_error_t (*getauditlog) (void *engine, gpgme_data_t output,
unsigned int flags);
gpgme_error_t (*opassuan_transact) (void *engine,
@ -132,5 +134,8 @@ extern struct engine_ops _gpgme_engine_ops_assuan; /* Low-level Assuan. */
#ifdef ENABLE_G13
extern struct engine_ops _gpgme_engine_ops_g13; /* Crypto VFS. */
#endif
#ifdef ENABLE_UISERVER
extern struct engine_ops _gpgme_engine_ops_uiserver;
#endif
#endif /* ENGINE_BACKEND_H */

View File

@ -757,7 +757,9 @@ struct engine_ops _gpgme_engine_ops_g13 =
NULL, /* set_command_handler */
NULL, /* set_colon_line_handler */
g13_set_locale,
NULL, /* set_protocol */
NULL, /* decrypt */
NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */

View File

@ -1332,7 +1332,7 @@ start (engine_gpg_t gpg)
status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name :
_gpgme_get_gpg_path (), gpg->argv,
IOSPAWN_FLAG_ALLOW_SET_FG,
fd_list, &pid);
fd_list, NULL, NULL, &pid);
saved_errno = errno;
free (fd_list);
@ -2347,7 +2347,9 @@ struct engine_ops _gpgme_engine_ops_gpg =
gpg_set_command_handler,
gpg_set_colon_line_handler,
gpg_set_locale,
NULL, /* set_protocol */
gpg_decrypt,
gpg_decrypt, /* decrypt_verify */
gpg_delete,
gpg_edit,
gpg_encrypt,

View File

@ -221,7 +221,7 @@ gpgconf_read (void *engine, char *arg1, char *arg2,
cfd[0].fd = rp[1];
status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL);
status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL, NULL, NULL);
if (status < 0)
{
_gpgme_io_close (rp[0]);
@ -659,7 +659,7 @@ gpgconf_write (void *engine, char *arg1, char *arg2, gpgme_data_t conf)
cfd[0].fd = rp[0];
status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL);
status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL, NULL, NULL);
if (status < 0)
{
_gpgme_io_close (rp[0]);
@ -897,7 +897,9 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
NULL, /* set_command_handler */
NULL, /* set_colon_line_handler */
NULL, /* set_locale */
NULL, /* set_protocol */
NULL, /* decrypt */
NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */

View File

@ -38,6 +38,7 @@
#include "wait.h"
#include "priv-io.h"
#include "sema.h"
#include "data.h"
#include "assuan.h"
#include "status-table.h"
@ -657,7 +658,7 @@ gpgsm_set_fd (engine_gpgsm_t gpgsm, fd_type_t fd_type, const char *opt)
{
int fds[2];
if (_gpgme_io_pipe (fds, 0) < 0)
if (_gpgme_io_pipe (fds, dir) < 0)
return gpg_error_from_errno (errno);
iocb_data->fd = dir ? fds[0] : fds[1];
@ -1914,8 +1915,10 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
NULL, /* set_command_handler */
gpgsm_set_colon_line_handler,
gpgsm_set_locale,
NULL, /* set_protocol */
gpgsm_decrypt,
gpgsm_delete,
gpgsm_decrypt,
gpgsm_delete, /* decrypt_verify */
NULL, /* edit */
gpgsm_encrypt,
NULL, /* encrypt_sign */

1361
src/engine-uiserver.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -61,7 +61,12 @@ static struct engine_ops *engine_ops[] =
NULL,
#endif
#ifdef ENABLE_G13
&_gpgme_engine_ops_g13 /* Crypto VFS. */
&_gpgme_engine_ops_g13, /* Crypto VFS. */
#else
NULL,
#endif
#ifdef ENABLE_UISERVER
&_gpgme_engine_ops_uiserver /* Crypto VFS. */
#else
NULL
#endif
@ -200,7 +205,8 @@ gpgme_get_engine_info (gpgme_engine_info_t *info)
GPGME_PROTOCOL_CMS,
GPGME_PROTOCOL_GPGCONF,
GPGME_PROTOCOL_ASSUAN,
GPGME_PROTOCOL_G13 };
GPGME_PROTOCOL_G13,
GPGME_PROTOCOL_UISERVER };
unsigned int proto;
for (proto = 0; proto < DIM (proto_list); proto++)
@ -550,6 +556,20 @@ _gpgme_engine_set_locale (engine_t engine, int category,
return (*engine->ops->set_locale) (engine->engine, category, value);
}
gpgme_error_t
_gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->set_protocol)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->set_protocol) (engine->engine, protocol);
}
gpgme_error_t
_gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
gpgme_data_t plain)
@ -563,6 +583,21 @@ _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
return (*engine->ops->decrypt) (engine->engine, ciph, plain);
}
gpgme_error_t
_gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
gpgme_data_t plain)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->decrypt_verify)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain);
}
gpgme_error_t
_gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
int allow_secret)

View File

@ -59,7 +59,8 @@ gpgme_error_t _gpgme_engine_reset (engine_t engine);
gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category,
const char *value);
gpgme_error_t _gpgme_engine_set_protocol (engine_t engine,
gpgme_protocol_t protocol);
void _gpgme_engine_release (engine_t engine);
void _gpgme_engine_set_status_handler (engine_t engine,
engine_status_handler_t fnc,
@ -72,9 +73,11 @@ gpgme_error_t
_gpgme_engine_set_colon_line_handler (engine_t engine,
engine_colon_line_handler_t fnc,
void *fnc_value);
gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine,
gpgme_data_t ciph,
gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
gpgme_data_t plain);
gpgme_error_t _gpgme_engine_op_decrypt_verify (engine_t engine,
gpgme_data_t ciph,
gpgme_data_t plain);
gpgme_error_t _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
int allow_secret);
gpgme_error_t _gpgme_engine_op_edit (engine_t engine, int type,

View File

@ -669,7 +669,10 @@ gt_recipients_add (gpgme_tool_t gt, const char *pattern)
if (gt->recipients_nr >= MAX_RECIPIENTS)
return gpg_error_from_errno (ENOMEM);
err = gt_get_key (gt, pattern, &key);
if (gpgme_get_protocol (gt->ctx) == GPGME_PROTOCOL_UISERVER)
err = gpgme_key_from_uid (&key, pattern);
else
err = gt_get_key (gt, pattern, &key);
if (err)
return err;
@ -780,6 +783,10 @@ gt_protocol_from_name (const char *name)
return GPGME_PROTOCOL_ASSUAN;
if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_G13)))
return GPGME_PROTOCOL_G13;
if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_UISERVER)))
return GPGME_PROTOCOL_UISERVER;
if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_DEFAULT)))
return GPGME_PROTOCOL_DEFAULT;
return GPGME_PROTOCOL_UNKNOWN;
}
@ -791,6 +798,13 @@ gt_set_protocol (gpgme_tool_t gt, gpgme_protocol_t proto)
}
gpg_error_t
gt_set_sub_protocol (gpgme_tool_t gt, gpgme_protocol_t proto)
{
return gpgme_set_sub_protocol (gt->ctx, proto);
}
gpg_error_t
gt_get_protocol (gpgme_tool_t gt)
{
@ -1248,6 +1262,17 @@ cmd_protocol (assuan_context_t ctx, char *line)
}
static gpg_error_t
cmd_sub_protocol (assuan_context_t ctx, char *line)
{
struct server *server = assuan_get_pointer (ctx);
if (line && *line)
return gt_set_sub_protocol (server->gt, gt_protocol_from_name (line));
/* FIXME. */
return 0;
}
static gpg_error_t
cmd_armor (assuan_context_t ctx, char *line)
{
@ -1456,30 +1481,35 @@ _cmd_sign_encrypt (assuan_context_t ctx, char *line, int sign)
gpg_error_t err;
assuan_fd_t inp_fd;
assuan_fd_t out_fd;
gpgme_data_t inp_data;
gpgme_data_t out_data;
gpgme_data_t inp_data = NULL;
gpgme_data_t out_data = NULL;
gpgme_encrypt_flags_t flags = 0;
if (strstr (line, "--always-trust"))
flags |= GPGME_ENCRYPT_ALWAYS_TRUST;
if (strstr (line, "--no-encrypt-to"))
flags |= GPGME_ENCRYPT_NO_ENCRYPT_TO;
if (strstr (line, "--prepare"))
flags |= GPGME_ENCRYPT_PREPARE;
if (strstr (line, "--expect-sign"))
flags |= GPGME_ENCRYPT_EXPECT_SIGN;
inp_fd = assuan_get_input_fd (ctx);
if (inp_fd == ASSUAN_INVALID_FD)
return GPG_ERR_ASS_NO_INPUT;
out_fd = assuan_get_output_fd (ctx);
if (out_fd == ASSUAN_INVALID_FD)
return GPG_ERR_ASS_NO_OUTPUT;
err = server_data_obj (inp_fd, server->input_enc, &inp_data);
if (err)
return err;
err = server_data_obj (out_fd, server->output_enc, &out_data);
if (err)
if (inp_fd != ASSUAN_INVALID_FD)
{
gpgme_data_release (inp_data);
return err;
err = server_data_obj (inp_fd, server->input_enc, &inp_data);
if (err)
return err;
}
if (out_fd != ASSUAN_INVALID_FD)
{
err = server_data_obj (out_fd, server->output_enc, &out_data);
if (err)
{
gpgme_data_release (inp_data);
return err;
}
}
err = gt_sign_encrypt (server->gt, flags, inp_data, out_data, sign);
@ -1957,6 +1987,7 @@ register_commands (assuan_context_t ctx)
// TODO: Set engine info.
{ "ENGINE", cmd_engine },
{ "PROTOCOL", cmd_protocol, hlp_protocol },
{ "SUB_PROTOCOL", cmd_sub_protocol },
{ "ARMOR", cmd_armor },
{ "TEXTMODE", cmd_textmode },
{ "INCLUDE_CERTS", cmd_include_certs },

View File

@ -265,13 +265,14 @@ gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
{
TRACE_BEG2 (DEBUG_CTX, "gpgme_set_protocol", ctx, "protocol=%i (%s)",
protocol, gpgme_get_protocol_name (protocol)
? gpgme_get_protocol_name (protocol) : "unknown");
? gpgme_get_protocol_name (protocol) : "invalid");
if (protocol != GPGME_PROTOCOL_OpenPGP
&& protocol != GPGME_PROTOCOL_CMS
&& protocol != GPGME_PROTOCOL_GPGCONF
&& protocol != GPGME_PROTOCOL_ASSUAN
&& protocol != GPGME_PROTOCOL_G13)
&& protocol != GPGME_PROTOCOL_G13
&& protocol != GPGME_PROTOCOL_UISERVER)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
if (ctx->protocol != protocol)
@ -296,11 +297,24 @@ gpgme_get_protocol (gpgme_ctx_t ctx)
TRACE2 (DEBUG_CTX, "gpgme_get_protocol", ctx,
"ctx->protocol=%i (%s)", ctx->protocol,
gpgme_get_protocol_name (ctx->protocol)
? gpgme_get_protocol_name (ctx->protocol) : "unknown");
? gpgme_get_protocol_name (ctx->protocol) : "invalid");
return ctx->protocol;
}
gpgme_error_t
gpgme_set_sub_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
{
gpgme_error_t err;
TRACE_BEG2 (DEBUG_CTX, "gpgme_set_sub_protocol", ctx, "protocol=%i (%s)",
protocol, gpgme_get_protocol_name (protocol)
? gpgme_get_protocol_name (protocol) : "invalid");
err = _gpgme_engine_set_protocol (ctx->engine, protocol);
return TRACE_ERR (err);
}
const char *
gpgme_get_protocol_name (gpgme_protocol_t protocol)
{
@ -321,6 +335,12 @@ gpgme_get_protocol_name (gpgme_protocol_t protocol)
case GPGME_PROTOCOL_G13:
return "G13";
case GPGME_PROTOCOL_UISERVER:
return "UIServer";
case GPGME_PROTOCOL_DEFAULT:
return "default";
case GPGME_PROTOCOL_UNKNOWN:
return "unknown";

View File

@ -192,5 +192,8 @@ EXPORTS
gpgme_op_vfs_mount @147
gpgme_op_vfs_create @148
gpgme_key_from_uid @149
gpgme_set_sub_protocol @150
; END

View File

@ -326,6 +326,7 @@ typedef enum
GPGME_PROTOCOL_ASSUAN = 3, /* Low-level access to an Assuan server. */
GPGME_PROTOCOL_G13 = 4,
GPGME_PROTOCOL_UISERVER= 5,
GPGME_PROTOCOL_DEFAULT = 254,
GPGME_PROTOCOL_UNKNOWN = 255
}
gpgme_protocol_t;
@ -803,6 +804,15 @@ gpgme_error_t gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t proto);
/* Get the protocol used with CTX */
gpgme_protocol_t gpgme_get_protocol (gpgme_ctx_t ctx);
/* Set the crypto protocol to be used by CTX to PROTO.
gpgme_set_protocol actually sets the backend engine. This sets the
crypto protocol used in engines that support more than one crypto
prococol (for example, an UISERVER can support OpenPGP and CMS).
This is reset to the default with gpgme_set_protocol. */
gpgme_error_t gpgme_set_sub_protocol (gpgme_ctx_t ctx,
gpgme_protocol_t proto);
/* Get the string describing protocol PROTO, or NULL if invalid. */
const char *gpgme_get_protocol_name (gpgme_protocol_t proto);
@ -1209,7 +1219,9 @@ gpgme_encrypt_result_t gpgme_op_encrypt_result (gpgme_ctx_t ctx);
typedef enum
{
GPGME_ENCRYPT_ALWAYS_TRUST = 1,
GPGME_ENCRYPT_NO_ENCRYPT_TO = 2
GPGME_ENCRYPT_NO_ENCRYPT_TO = 2,
GPGME_ENCRYPT_PREPARE = 4,
GPGME_ENCRYPT_EXPECT_SIGN = 8
}
gpgme_encrypt_flags_t;
@ -1981,6 +1993,13 @@ gpgme_error_t gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p);
follow chained components! */
gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp);
/* UIServer support. */
/* Create a dummy key to specify an email address. */
gpgme_error_t gpgme_key_from_uid (gpgme_key_t *key, const char *name);
/* Various functions. */

View File

@ -202,7 +202,7 @@ parse_x509_user_id (char *src, char **name, char **email,
/* Take a name from the --with-colon listing, remove certain escape
sequences sequences and put it into the list of UIDs. */
gpgme_error_t
_gpgme_key_append_name (gpgme_key_t key, char *src)
_gpgme_key_append_name (gpgme_key_t key, char *src, int convert)
{
gpgme_user_id_t uid;
char *dst;
@ -219,7 +219,10 @@ _gpgme_key_append_name (gpgme_key_t key, char *src)
uid->uid = ((char *) uid) + sizeof (*uid);
dst = uid->uid;
_gpgme_decode_c_string (src, &dst, src_len + 1);
if (convert)
_gpgme_decode_c_string (src, &dst, src_len + 1);
else
memcpy (dst, src, src_len + 1);
dst += strlen (dst) + 1;
if (key->protocol == GPGME_PROTOCOL_CMS)
@ -370,6 +373,32 @@ gpgme_key_unref (gpgme_key_t key)
free (key);
}
/* Support functions. */
/* Create a dummy key to specify an email address. */
gpgme_error_t
gpgme_key_from_uid (gpgme_key_t *r_key, const char *name)
{
gpgme_error_t err;
gpgme_key_t key;
*r_key = NULL;
err = _gpgme_key_new (&key);
if (err)
return err;
/* Note: protocol doesn't matter if only email is provided. */
err = _gpgme_key_append_name (key, name, 0);
if (err)
gpgme_key_unref (key);
else
*r_key = key;
return err;
}
/* Compatibility interfaces. */

View File

@ -650,7 +650,7 @@ keylist_colon_handler (void *priv, char *line)
/* Field 2 has the trust info, and field 10 has the user ID. */
if (fields >= 10)
{
if (_gpgme_key_append_name (key, field[9]))
if (_gpgme_key_append_name (key, field[9], 1))
return gpg_error_from_errno (GPG_ERR_ENOMEM); /* FIXME */
else
{

View File

@ -73,6 +73,8 @@ GPGME_1.1 {
gpgme_op_vfs_mount;
gpgme_op_vfs_create;
gpgme_key_from_uid;
gpgme_set_sub_protocol;
};

View File

@ -128,7 +128,7 @@ gpgme_error_t _gpgme_progress_status_handler (void *priv,
gpgme_error_t _gpgme_key_new (gpgme_key_t *r_key);
gpgme_error_t _gpgme_key_add_subkey (gpgme_key_t key,
gpgme_subkey_t *r_subkey);
gpgme_error_t _gpgme_key_append_name (gpgme_key_t key, char *src);
gpgme_error_t _gpgme_key_append_name (gpgme_key_t key, char *src, int convert);
gpgme_key_sig_t _gpgme_key_add_sig (gpgme_key_t key, char *src);

View File

@ -305,7 +305,9 @@ _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal)
/* Returns 0 on success, -1 on error. */
int
_gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
struct spawn_fd_item_s *fd_list, pid_t *r_pid)
struct spawn_fd_item_s *fd_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue, pid_t *r_pid)
{
pid_t pid;
int i;
@ -344,6 +346,9 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
int seen_stdin = 0;
int seen_stderr = 0;
if (atfork)
atfork (atforkvalue, 0);
/* First close all fds which will not be inherited. */
for (fd = 0; fd < max_fds; fd++)
{

View File

@ -69,6 +69,30 @@ _gpgme_get_g13_path (void)
#endif
}
const char *
_gpgme_get_uiserver_socket_path (void)
{
static char *socket_path;
char *homedir;
const char name[] = "S.uiserver";
if (socket_path)
return socket_path;
homedir = _gpgme_get_default_homedir ();
if (! homedir)
return NULL;
socket_path = malloc (strlen (homedir) + 1 + strlen (name) + 1);
if (! socket_path)
return NULL;
strcpy (stpcpy (stpcpy (socket_path, homedir), "/"), name);
return socket_path;
}
/* See w32-util.c */
int
_gpgme_get_conf_int (const char *key, int *value)

View File

@ -76,7 +76,9 @@ int _gpgme_io_set_nonblocking (int fd);
optionally dup() the child fds. Finally, all fds in the list are
closed in the parent. */
int _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
struct spawn_fd_item_s *fd_list, pid_t *r_pid);
struct spawn_fd_item_s *fd_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue, pid_t *r_pid);
int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock);

View File

@ -33,6 +33,8 @@ const char *_gpgme_get_gpg_path (void);
const char *_gpgme_get_gpgsm_path (void);
const char *_gpgme_get_gpgconf_path (void);
const char *_gpgme_get_g13_path (void);
const char *_gpgme_get_uiserver_socket_path (void);
int _gpgme_get_conf_int (const char *key, int *value);
void _gpgme_allow_set_foreground_window (pid_t pid);

View File

@ -309,7 +309,7 @@ _gpgme_get_program_version (const char *const file_name)
cfd[0].fd = rp[1];
status = _gpgme_io_spawn (file_name, argv, 0, cfd, NULL);
status = _gpgme_io_spawn (file_name, argv, 0, cfd, NULL, NULL, NULL);
if (status < 0)
{
_gpgme_io_close (rp[0]);

View File

@ -585,7 +585,9 @@ build_commandline (char **argv)
int
_gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
struct spawn_fd_item_s *fd_list, pid_t *r_pid)
struct spawn_fd_item_s *fd_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue, pid_t *r_pid)
{
SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi =

View File

@ -1042,7 +1042,9 @@ build_commandline (char **argv)
int
_gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
struct spawn_fd_item_s *fd_list, pid_t *r_pid)
struct spawn_fd_item_s *fd_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue, pid_t *r_pid)
{
SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi =

View File

@ -398,7 +398,9 @@ build_commandline (char **argv)
int
_gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
struct spawn_fd_item_s *fd_list, pid_t *r_pid)
struct spawn_fd_item_s *fd_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue, pid_t *r_pid)
{
SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi =

View File

@ -380,6 +380,29 @@ _gpgme_get_g13_path (void)
}
const char *
_gpgme_get_uiserver_socket_path (void)
{
static char *socket_path;
char *homedir;
const char name[] = "S.uiserver";
if (socket_path)
return socket_path;
homedir = _gpgme_get_default_homedir ();
if (! homedir)
return NULL;
socket_path = malloc (strlen (homedir) + 1 + strlen (name) + 1);
if (! socket_path)
return NULL;
strcpy (stpcpy (stpcpy (socket_path, homedir), "\\"), name);
return socket_path;
}
const char *
_gpgme_get_w32spawn_path (void)
{