summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJinWang An <jinwang.an@samsung.com>2021-12-01 16:54:36 +0900
committerJinWang An <jinwang.an@samsung.com>2021-12-01 16:54:36 +0900
commit214479142a766516e8770c3e1a3b0b0cc37c239e (patch)
tree43ff2d595b2e19d2f3e35ce6cf74a9e4a63ab3e7 /src
parent3a4efa5aa27f73c93a1b020b8b30f07f0b4e46c7 (diff)
downloadgpgme-214479142a766516e8770c3e1a3b0b0cc37c239e.tar.gz
gpgme-214479142a766516e8770c3e1a3b0b0cc37c239e.tar.bz2
gpgme-214479142a766516e8770c3e1a3b0b0cc37c239e.zip
Imported Upstream version 1.9.0upstream/1.9.0
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in10
-rw-r--r--src/context.h6
-rw-r--r--src/conversion.c19
-rw-r--r--src/data-compat.c13
-rw-r--r--src/data.c14
-rw-r--r--src/debug.c14
-rw-r--r--src/decrypt-verify.c67
-rw-r--r--src/decrypt.c18
-rw-r--r--src/dirinfo.c12
-rw-r--r--src/engine-assuan.c18
-rw-r--r--src/engine-backend.h8
-rw-r--r--src/engine-g13.c18
-rw-r--r--src/engine-gpg.c108
-rw-r--r--src/engine-gpgconf.c71
-rw-r--r--src/engine-gpgsm.c52
-rw-r--r--src/engine-spawn.c2
-rw-r--r--src/engine-uiserver.c87
-rw-r--r--src/engine.c36
-rw-r--r--src/engine.h17
-rw-r--r--src/funopen.c63
-rw-r--r--src/genkey.c62
-rw-r--r--src/gpgme.c8
-rw-r--r--src/gpgme.def13
-rw-r--r--src/gpgme.h.in785
-rw-r--r--src/import.c4
-rw-r--r--src/key.c39
-rw-r--r--src/keylist.c84
-rw-r--r--src/libgpgme.vers7
-rw-r--r--src/op-support.c1
-rw-r--r--src/ops.h3
-rw-r--r--src/posix-io.c116
-rw-r--r--src/progress.c8
-rw-r--r--src/util.h14
-rw-r--r--src/vasprintf.c206
-rw-r--r--src/verify.c39
-rw-r--r--src/versioninfo.rc.in2
-rw-r--r--src/vfs-create.c8
-rw-r--r--src/vfs-mount.c10
-rw-r--r--src/w32-io.c14
-rw-r--r--src/w32-util.c5
40 files changed, 1178 insertions, 903 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 3f0da74..5f153a8 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -107,8 +107,8 @@ subdir = src
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/build-aux/mkinstalldirs \
$(srcdir)/versioninfo.rc.in $(srcdir)/gpgme.h.in \
- $(srcdir)/gpgme-config.in stpcpy.c funopen.c ttyname_r.c \
- vasprintf.c setenv.c $(top_srcdir)/build-aux/depcomp
+ $(srcdir)/gpgme-config.in stpcpy.c ttyname_r.c setenv.c \
+ $(top_srcdir)/build-aux/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
@@ -119,8 +119,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
@@ -818,11 +818,9 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/funopen.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/setenv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/stpcpy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ttyname_r.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/vasprintf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argparse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assuan-support.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ath.Plo@am__quote@
diff --git a/src/context.h b/src/context.h
index 1a8698c..d0542d9 100644
--- a/src/context.h
+++ b/src/context.h
@@ -114,10 +114,14 @@ struct gpgme_context
/* True if session keys should be exported upon decryption. */
unsigned int export_session_keys : 1;
+ /* True if a Pinentry was launched during the last operation. This
+ * flag is cleared with each operation. */
+ unsigned int redraw_suggested : 1;
+
/* Flags for keylist mode. */
gpgme_keylist_mode_t keylist_mode;
- /* The current pinnetry mode. */
+ /* The current pinentry mode. */
gpgme_pinentry_mode_t pinentry_mode;
/* Number of certs to be included. */
diff --git a/src/conversion.c b/src/conversion.c
index 6dfabe7..92dd214 100644
--- a/src/conversion.c
+++ b/src/conversion.c
@@ -536,6 +536,25 @@ _gpgme_parse_timestamp (const char *timestamp, char **endp)
}
+/* This function is similar to _gpgme_parse_timestamp but returns an
+ * unsigned long and 0 on error. */
+unsigned long
+_gpgme_parse_timestamp_ul (const char *timestamp)
+{
+ time_t tim;
+ char *tail;
+
+ if (!*timestamp)
+ return 0; /* Shortcut empty strings. */
+
+ tim = _gpgme_parse_timestamp (timestamp, &tail);
+ if (tim == -1 || timestamp == tail || (*tail && *tail != ' '))
+ tim = 0; /* No time given or invalid engine. */
+
+ return (unsigned long)tim;
+}
+
+
/* The GPG backend uses OpenPGP algorithm numbers which we need to map
to our algorithm numbers. This function MUST not change ERRNO. */
int
diff --git a/src/data-compat.c b/src/data-compat.c
index 5c7d543..87eaeef 100644
--- a/src/data-compat.c
+++ b/src/data-compat.c
@@ -239,16 +239,3 @@ gpgme_data_new_with_read_cb (gpgme_data_t *r_dh,
(*r_dh)->data.old_user.handle = read_cb_value;
return TRACE_ERR (0);
}
-
-
-gpgme_error_t
-gpgme_data_rewind (gpgme_data_t dh)
-{
- gpgme_error_t err;
- TRACE_BEG (DEBUG_DATA, "gpgme_data_rewind", dh);
-
- err = ((gpgme_data_seek (dh, 0, SEEK_SET) == -1)
- ? gpg_error_from_syserror () : 0);
-
- return TRACE_ERR (err);
-}
diff --git a/src/data.c b/src/data.c
index 6964246..e4e9ee3 100644
--- a/src/data.c
+++ b/src/data.c
@@ -158,6 +158,20 @@ gpgme_data_seek (gpgme_data_t dh, gpgme_off_t offset, int whence)
}
+/* Convenience function to do a gpgme_data_seek (dh, 0, SEEK_SET). */
+gpgme_error_t
+gpgme_data_rewind (gpgme_data_t dh)
+{
+ gpgme_error_t err;
+ TRACE_BEG (DEBUG_DATA, "gpgme_data_rewind", dh);
+
+ err = ((gpgme_data_seek (dh, 0, SEEK_SET) == -1)
+ ? gpg_error_from_syserror () : 0);
+
+ return TRACE_ERR (err);
+}
+
+
/* Release the data object with the handle DH. */
void
gpgme_data_release (gpgme_data_t dh)
diff --git a/src/debug.c b/src/debug.c
index 1dd3723..e9bfc40 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -313,7 +313,7 @@ _gpgme_debug_begin (void **line, int level, const char *format, ...)
}
va_start (arg_ptr, format);
- res = vasprintf ((char **) line, format, arg_ptr);
+ res = gpgrt_vasprintf ((char **) line, format, arg_ptr);
va_end (arg_ptr);
if (res < 0)
*line = NULL;
@@ -333,16 +333,16 @@ _gpgme_debug_add (void **line, const char *format, ...)
return;
va_start (arg_ptr, format);
- res = vasprintf (&toadd, format, arg_ptr);
+ res = gpgrt_vasprintf (&toadd, format, arg_ptr);
va_end (arg_ptr);
if (res < 0)
{
- free (*line);
+ gpgrt_free (*line);
*line = NULL;
}
- res = asprintf (&result, "%s%s", *(char **) line, toadd);
- free (toadd);
- free (*line);
+ res = gpgrt_asprintf (&result, "%s%s", *(char **) line, toadd);
+ gpgrt_free (toadd);
+ gpgrt_free (*line);
if (res < 0)
*line = NULL;
else
@@ -361,7 +361,7 @@ _gpgme_debug_end (void **line)
/* The smallest possible level is 1, so force logging here by
using that. */
_gpgme_debug (1, "%s", *line);
- free (*line);
+ gpgrt_free (*line);
*line = NULL;
}
diff --git a/src/decrypt-verify.c b/src/decrypt-verify.c
index e0aa8ea..66cfe94 100644
--- a/src/decrypt-verify.c
+++ b/src/decrypt-verify.c
@@ -23,6 +23,8 @@
#include <config.h>
#endif
+#include <assert.h>
+
#include "debug.h"
#include "gpgme.h"
#include "ops.h"
@@ -45,10 +47,13 @@ decrypt_verify_status_handler (void *priv, gpgme_status_code_t code,
static gpgme_error_t
decrypt_verify_start (gpgme_ctx_t ctx, int synchronous,
+ gpgme_decrypt_flags_t flags,
gpgme_data_t cipher, gpgme_data_t plain)
{
gpgme_error_t err;
+ assert ((flags & GPGME_DECRYPT_VERIFY));
+
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
@@ -77,9 +82,11 @@ 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_verify (ctx->engine, cipher, plain,
- ctx->export_session_keys,
- ctx->override_session_key);
+ return _gpgme_engine_op_decrypt (ctx->engine,
+ flags,
+ cipher, plain,
+ ctx->export_session_keys,
+ ctx->override_session_key);
}
@@ -97,7 +104,7 @@ gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = decrypt_verify_start (ctx, 0, cipher, plain);
+ err = decrypt_verify_start (ctx, 0, GPGME_DECRYPT_VERIFY, cipher, plain);
return TRACE_ERR (err);
}
@@ -116,7 +123,57 @@ gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = decrypt_verify_start (ctx, 1, cipher, plain);
+ err = decrypt_verify_start (ctx, 1, GPGME_DECRYPT_VERIFY, cipher, plain);
+ if (!err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}
+
+
+/* Decrypt ciphertext CIPHER within CTX and store the resulting
+ plaintext in PLAIN. */
+gpgme_error_t
+gpgme_op_decrypt_ext_start (gpgme_ctx_t ctx,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher,
+ gpgme_data_t plain)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_ext_start", ctx,
+ "cipher=%p, plain=%p", cipher, plain);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ if ((flags & GPGME_DECRYPT_VERIFY))
+ err = decrypt_verify_start (ctx, 0, flags, cipher, plain);
+ else
+ err = _gpgme_decrypt_start (ctx, 0, flags, cipher, plain);
+ return TRACE_ERR (err);
+}
+
+
+/* Decrypt ciphertext CIPHER within CTX and store the resulting
+ plaintext in PLAIN. */
+gpgme_error_t
+gpgme_op_decrypt_ext (gpgme_ctx_t ctx,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher,
+ gpgme_data_t plain)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_ext", ctx,
+ "cipher=%p, plain=%p", cipher, plain);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ if ((flags & GPGME_DECRYPT_VERIFY))
+ err = decrypt_verify_start (ctx, 1, flags, cipher, plain);
+ else
+ err = _gpgme_decrypt_start (ctx, 1, flags, cipher, plain);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
diff --git a/src/decrypt.c b/src/decrypt.c
index 43717c0..f30f80f 100644
--- a/src/decrypt.c
+++ b/src/decrypt.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <assert.h>
#include "debug.h"
#include "gpgme.h"
@@ -358,12 +359,15 @@ _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
}
-static gpgme_error_t
-decrypt_start (gpgme_ctx_t ctx, int synchronous,
- gpgme_data_t cipher, gpgme_data_t plain)
+gpgme_error_t
+_gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher, gpgme_data_t plain)
{
gpgme_error_t err;
+ assert (!(flags & GPGME_DECRYPT_VERIFY));
+
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
@@ -390,7 +394,9 @@ decrypt_start (gpgme_ctx_t ctx, int synchronous,
_gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
- return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain,
+ return _gpgme_engine_op_decrypt (ctx->engine,
+ flags,
+ cipher, plain,
ctx->export_session_keys,
ctx->override_session_key);
}
@@ -408,7 +414,7 @@ gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = decrypt_start (ctx, 0, cipher, plain);
+ err = _gpgme_decrypt_start (ctx, 0, 0, cipher, plain);
return TRACE_ERR (err);
}
@@ -426,7 +432,7 @@ gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = decrypt_start (ctx, 1, cipher, plain);
+ err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
diff --git a/src/dirinfo.c b/src/dirinfo.c
index a0cbc03..7374412 100644
--- a/src/dirinfo.c
+++ b/src/dirinfo.c
@@ -51,6 +51,7 @@ enum
WANT_GPG_NAME,
WANT_GPGSM_NAME,
WANT_G13_NAME,
+ WANT_GPG_WKS_CLIENT_NAME,
WANT_GPG_ONE_MODE
};
@@ -73,6 +74,7 @@ static struct {
char *gpg_name;
char *gpgsm_name;
char *g13_name;
+ char *gpg_wks_client_name;
int gpg_one_mode; /* System is in gpg1 mode. */
} dirinfo;
@@ -333,6 +335,14 @@ get_gpgconf_item (int what)
case WANT_G13_NAME: result = dirinfo.g13_name; break;
case WANT_UISRV_SOCKET: result = dirinfo.uisrv_socket; break;
case WANT_GPG_ONE_MODE: result = dirinfo.gpg_one_mode? "1":NULL; break;
+ case WANT_GPG_WKS_CLIENT_NAME:
+ if (!dirinfo.gpg_wks_client_name && dirinfo.libexecdir)
+ dirinfo.gpg_wks_client_name = _gpgme_strconcat (dirinfo.libexecdir,
+ "/",
+ "gpg-wks-client",
+ NULL);
+ result = dirinfo.gpg_wks_client_name;
+ break;
}
UNLOCK (dirinfo_lock);
return result;
@@ -438,6 +448,8 @@ gpgme_get_dirinfo (const char *what)
return get_gpgconf_item (WANT_GPGSM_NAME);
else if (!strcmp (what, "g13-name"))
return get_gpgconf_item (WANT_G13_NAME);
+ else if (!strcmp (what, "gpg-wks-client-name"))
+ return get_gpgconf_item (WANT_GPG_WKS_CLIENT_NAME);
else if (!strcmp (what, "agent-ssh-socket"))
return get_gpgconf_item (WANT_AGENT_SSH_SOCKET);
else if (!strcmp (what, "dirmngr-socket"))
diff --git a/src/engine-assuan.c b/src/engine-assuan.c
index 3e3b89f..68bdaa6 100644
--- a/src/engine-assuan.c
+++ b/src/engine-assuan.c
@@ -265,7 +265,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_display)
{
- if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
{
err = gpg_error_from_syserror ();
free (dft_display);
@@ -275,7 +275,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -304,14 +304,14 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
- if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{
err = gpg_error_from_syserror ();
goto leave;
}
err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
@@ -320,7 +320,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_ttytype)
{
- if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0)
{
err = gpg_error_from_syserror ();
free (dft_ttytype);
@@ -330,7 +330,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -408,13 +408,13 @@ llass_set_locale (void *engine, int category, const char *value)
if (!value)
return 0;
- if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
err = gpg_error_from_syserror ();
else
{
err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
}
return err;
}
@@ -776,7 +776,6 @@ struct engine_ops _gpgme_engine_ops_assuan =
llass_set_locale,
NULL, /* set_protocol */
NULL, /* decrypt */
- NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */
@@ -787,6 +786,7 @@ struct engine_ops _gpgme_engine_ops_assuan =
NULL, /* import */
NULL, /* keylist */
NULL, /* keylist_ext */
+ NULL, /* keylist_data */
NULL, /* keysign */
NULL, /* tofu_policy */
NULL, /* sign */
diff --git a/src/engine-backend.h b/src/engine-backend.h
index a8457af..53af662 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -61,12 +61,11 @@ struct engine_ops
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_error_t (*decrypt) (void *engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph,
gpgme_data_t plain, int export_session_key,
const char *override_session_key);
- gpgme_error_t (*decrypt_verify) (void *engine, gpgme_data_t ciph,
- gpgme_data_t plain, int export_session_key,
- const char *override_session_key);
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 */);
@@ -100,6 +99,7 @@ struct engine_ops
int secret_only, int reserved,
gpgme_keylist_mode_t mode,
int engine_flags);
+ gpgme_error_t (*keylist_data) (void *engine, gpgme_data_t data);
gpgme_error_t (*keysign) (void *engine,
gpgme_key_t key, const char *userid,
unsigned long expires, unsigned int flags,
diff --git a/src/engine-g13.c b/src/engine-g13.c
index 972c3a8..02951e8 100644
--- a/src/engine-g13.c
+++ b/src/engine-g13.c
@@ -270,7 +270,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_display)
{
- if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
{
free (dft_display);
err = gpg_error_from_syserror ();
@@ -280,7 +280,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -304,14 +304,14 @@ g13_new (void **engine, const char *file_name, const char *home_dir,
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
- if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{
err = gpg_error_from_syserror ();
goto leave;
}
err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
@@ -320,7 +320,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_ttytype)
{
- if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0)
{
free (dft_ttytype);
err = gpg_error_from_syserror ();
@@ -330,7 +330,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -400,13 +400,13 @@ g13_set_locale (void *engine, int category, const char *value)
if (!value)
return 0;
- if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
err = gpg_error_from_syserror ();
else
{
err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
}
return err;
@@ -791,7 +791,6 @@ struct engine_ops _gpgme_engine_ops_g13 =
g13_set_locale,
NULL, /* set_protocol */
NULL, /* decrypt */
- NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */
@@ -802,6 +801,7 @@ struct engine_ops _gpgme_engine_ops_g13 =
NULL, /* import */
NULL, /* keylist */
NULL, /* keylist_ext */
+ NULL, /* keylist_data */
NULL, /* keysign */
NULL, /* tofu_policy */
NULL, /* sign */
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 3ddaa07..0c3a63e 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -74,6 +74,10 @@ struct fd_data_map_s
};
+/* NB.: R_LINE is allocated an gpgrt function and thus gpgrt_free
+ * shall be used to release it. This takes care of custom memory
+ * allocators and avoids problems on Windows with different runtimes
+ * used for libgpg-error/gpgrt and gpgme. */
typedef gpgme_error_t (*colon_preprocessor_t) (char *line, char **rline);
struct engine_gpg
@@ -1346,7 +1350,7 @@ read_colon_line (engine_gpg_t gpg)
}
while (linep && *linep);
- free (line);
+ gpgrt_free (line);
}
else
gpg->colon.fnc (gpg->colon.fnc_value, buffer);
@@ -1555,7 +1559,9 @@ add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data)
static gpgme_error_t
-gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
+gpg_decrypt (void *engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key, const char *override_session_key)
{
engine_gpg_t gpg = engine;
@@ -1563,6 +1569,14 @@ gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
err = add_arg (gpg, "--decrypt");
+ if (!err && (flags & GPGME_DECRYPT_UNWRAP))
+ {
+ if (!have_gpg_version (gpg, "2.1.12"))
+ err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+ else
+ err = add_arg (gpg, "--unwrap");
+ }
+
if (!err && export_session_key)
err = add_arg (gpg, "--show-session-key");
@@ -1853,9 +1867,23 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
if (!err && use_armor)
err = add_arg (gpg, "--armor");
+ if (!err && (flags & GPGME_ENCRYPT_WRAP))
+ {
+ /* gpg is current not abale to detect already compressed
+ * packets. Thus when using
+ * gpg --unwrap -d | gpg --no-literal -e
+ * the encryption would add an additional compression layer.
+ * We better suppress that. */
+ flags |= GPGME_ENCRYPT_NO_COMPRESS;
+ err = add_arg (gpg, "--no-literal");
+ }
+
if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
err = add_arg (gpg, "--compress-algo=none");
+ if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
+ err = add_arg (gpg, "--throw-keyids");
+
if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
&& have_gpg_version (gpg, "2.1.14"))
err = add_arg (gpg, "--mimemode");
@@ -1925,6 +1953,9 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
err = add_arg (gpg, "--compress-algo=none");
+ if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
+ err = add_arg (gpg, "--throw-keyids");
+
if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
&& have_gpg_version (gpg, "2.1.14"))
err = add_arg (gpg, "--mimemode");
@@ -2072,7 +2103,8 @@ gpg_add_algo_usage_expire (engine_gpg_t gpg,
/* This condition is only required to allow the use of gpg < 2.1.16 */
if (algo
|| (flags & (GPGME_CREATE_SIGN | GPGME_CREATE_ENCR
- | GPGME_CREATE_CERT | GPGME_CREATE_AUTH))
+ | GPGME_CREATE_CERT | GPGME_CREATE_AUTH
+ | GPGME_CREATE_NOEXPIRE))
|| expires)
{
err = add_arg (gpg, algo? algo : "default");
@@ -2086,11 +2118,18 @@ gpg_add_algo_usage_expire (engine_gpg_t gpg,
(flags & GPGME_CREATE_AUTH)? " auth":"");
err = add_arg (gpg, *tmpbuf? tmpbuf : "default");
}
- if (!err && expires)
+ if (!err)
{
- char tmpbuf[8+20];
- snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
- err = add_arg (gpg, tmpbuf);
+ if ((flags & GPGME_CREATE_NOEXPIRE))
+ err = add_arg (gpg, "never");
+ else if (expires == 0)
+ err = add_arg (gpg, "-");
+ else
+ {
+ char tmpbuf[8+20];
+ snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
+ err = add_arg (gpg, tmpbuf);
+ }
}
}
else
@@ -2136,6 +2175,8 @@ gpg_createkey (engine_gpg_t gpg,
err = add_arg (gpg, "--passphrase");
if (!err)
err = add_arg (gpg, "");
+ if (!err)
+ err = add_arg (gpg, "--batch");
}
if (!err && (flags & GPGME_CREATE_FORCE))
err = add_arg (gpg, "--yes");
@@ -2174,6 +2215,8 @@ gpg_addkey (engine_gpg_t gpg,
err = add_arg (gpg, "--passphrase");
if (!err)
err = add_arg (gpg, "");
+ if (!err)
+ err = add_arg (gpg, "--batch");
}
if (!err)
err = add_arg (gpg, "--");
@@ -2200,7 +2243,14 @@ gpg_adduid (engine_gpg_t gpg,
if (!key || !key->fpr || !userid)
return gpg_error (GPG_ERR_INV_ARG);
- if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
+ if ((extraflags & GENKEY_EXTRAFLAG_SETPRIMARY))
+ {
+ if (!have_gpg_version (gpg, "2.1.20"))
+ err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+ else
+ err = add_arg (gpg, "--quick-set-primary-uid");
+ }
+ else if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
err = add_arg (gpg, "--quick-revuid");
else
err = add_arg (gpg, "--quick-adduid");
@@ -2240,7 +2290,7 @@ gpg_genkey (void *engine,
* USERID && !KEY - Create a new keyblock.
* !USERID && KEY - Add a new subkey to KEY (gpg >= 2.1.14)
* USERID && KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14).
- *
+ * or set a flag on a user id.
*/
if (help_data)
{
@@ -2509,7 +2559,7 @@ gpg_keylist_preprocess (char *line, char **r_line)
n = strlen (field[1]);
if (n > 16)
{
- if (asprintf (r_line,
+ if (gpgrt_asprintf (r_line,
"pub:o%s:%s:%s:%s:%s:%s::::::::\n"
"fpr:::::::::%s:",
field[6], field[3], field[2], field[1] + n - 16,
@@ -2518,7 +2568,7 @@ gpg_keylist_preprocess (char *line, char **r_line)
}
else
{
- if (asprintf (r_line,
+ if (gpgrt_asprintf (r_line,
"pub:o%s:%s:%s:%s:%s:%s::::::::",
field[6], field[3], field[2], field[1],
field[4], field[5]) < 0)
@@ -2576,7 +2626,7 @@ gpg_keylist_preprocess (char *line, char **r_line)
}
*dst = '\0';
- if (asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
+ if (gpgrt_asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
field[4], field[2], field[3], uid) < 0)
return gpg_error_from_syserror ();
}
@@ -2715,6 +2765,38 @@ gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
static gpgme_error_t
+gpg_keylist_data (void *engine, gpgme_data_t data)
+{
+ engine_gpg_t gpg = engine;
+ gpgme_error_t err;
+
+ if (!have_gpg_version (gpg, "2.1.14"))
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ err = add_arg (gpg, "--with-colons");
+ if (!err)
+ err = add_arg (gpg, "--with-fingerprint");
+ if (!err)
+ err = add_arg (gpg, "--import-options");
+ if (!err)
+ err = add_arg (gpg, "import-show");
+ if (!err)
+ err = add_arg (gpg, "--dry-run");
+ if (!err)
+ err = add_arg (gpg, "--import");
+ if (!err)
+ err = add_arg (gpg, "--");
+ if (!err)
+ err = add_data (gpg, data, -1, 0);
+
+ if (!err)
+ err = start (gpg);
+
+ return err;
+}
+
+
+static gpgme_error_t
gpg_keysign (void *engine, gpgme_key_t key, const char *userid,
unsigned long expire, unsigned int flags,
gpgme_ctx_t ctx)
@@ -2986,7 +3068,6 @@ struct engine_ops _gpgme_engine_ops_gpg =
gpg_set_locale,
NULL, /* set_protocol */
gpg_decrypt,
- gpg_decrypt, /* decrypt_verify */
gpg_delete,
gpg_edit,
gpg_encrypt,
@@ -2997,6 +3078,7 @@ struct engine_ops _gpgme_engine_ops_gpg =
gpg_import,
gpg_keylist,
gpg_keylist_ext,
+ gpg_keylist_data,
gpg_keysign,
gpg_tofu_policy, /* tofu_policy */
gpg_sign,
diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c
index 2ea8673..6f7c8ac 100644
--- a/src/engine-gpgconf.c
+++ b/src/engine-gpgconf.c
@@ -708,10 +708,13 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf)
#define BUFLEN 1024
char buf[BUFLEN];
int buflen = 0;
- char *argv[6];
+ char *argv[7];
int argc = 0;
- int rp[2];
- struct spawn_fd_item_s cfd[] = { {-1, 0 /* STDIN_FILENO */}, {-1, -1} };
+ int rp[2] = { -1, -1 };
+ int errp[2] = { -1, -1 };
+ struct spawn_fd_item_s cfd[] = { {-1, 0 /* STDIN_FILENO */},
+ {-1, 2 /* STDERR_FILENO */, -1},
+ {-1, -1} };
int status;
int nwrite;
@@ -724,25 +727,38 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf)
argv[argc++] = gpgconf->home_dir;
}
+ argv[argc++] = (char*)"--runtime";
argv[argc++] = (char*)arg1;
argv[argc++] = arg2;
argv[argc] = NULL;
assert (argc < DIM (argv));
if (_gpgme_io_pipe (rp, 0) < 0)
- return gpg_error_from_syserror ();
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ if (_gpgme_io_pipe (errp, 1) < 0)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
cfd[0].fd = rp[0];
+ cfd[1].fd = errp[1];
status = _gpgme_io_spawn (gpgconf->file_name, argv,
IOSPAWN_FLAG_DETACHED, cfd, NULL, NULL, NULL);
if (status < 0)
{
- _gpgme_io_close (rp[0]);
- _gpgme_io_close (rp[1]);
- return gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
+ goto leave;
}
+ rp[0] = -1;
+ errp[1] = -1;
+
for (;;)
{
if (buflen == 0)
@@ -756,14 +772,29 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf)
if (buflen < 0)
{
err = gpg_error_from_syserror ();
- _gpgme_io_close (rp[1]);
- return err;
+ goto leave;
}
else if (buflen == 0)
{
/* All is written. */
_gpgme_io_close (rp[1]);
- return 0;
+ rp[1] = -1;
+
+ for (;;)
+ {
+ do
+ {
+ buflen = _gpgme_io_read (errp[0], buf, BUFLEN);
+ }
+ while (buflen < 0 && errno == EAGAIN);
+
+ if (buflen == 0)
+ {
+ err = 0;
+ goto leave;
+ }
+ /* XXX: Do something useful with BUF. */
+ }
}
}
@@ -781,12 +812,24 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf)
}
else if (nwrite < 0)
{
- _gpgme_io_close (rp[1]);
- return gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
+ goto leave;
}
}
- return 0;
+ assert (! "reached");
+
+ leave:
+ if (rp[0] != -1)
+ _gpgme_io_close (rp[0]);
+ if (rp[1] != -1)
+ _gpgme_io_close (rp[1]);
+ if (errp[0] != -1)
+ _gpgme_io_close (errp[0]);
+ if (errp[1] != -1)
+ _gpgme_io_close (errp[1]);
+
+ return err;
}
@@ -1190,7 +1233,6 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
NULL, /* set_locale */
NULL, /* set_protocol */
NULL, /* decrypt */
- NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */
@@ -1201,6 +1243,7 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
NULL, /* import */
NULL, /* keylist */
NULL, /* keylist_ext */
+ NULL, /* keylist_data */
NULL, /* keysign */
NULL, /* tofu_policy */
NULL, /* sign */
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index d1be049..c3d5427 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -396,7 +396,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_display)
{
- if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
{
free (dft_display);
err = gpg_error_from_syserror ();
@@ -406,7 +406,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -430,14 +430,14 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
- if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{
err = gpg_error_from_syserror ();
goto leave;
}
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
@@ -446,7 +446,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_ttytype)
{
- if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0)
{
free (dft_ttytype);
err = gpg_error_from_syserror ();
@@ -456,7 +456,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -561,13 +561,13 @@ gpgsm_set_locale (void *engine, int category, const char *value)
if (!value)
return 0;
- if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
err = gpg_error_from_syserror ();
else
{
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
}
return err;
@@ -593,7 +593,7 @@ gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, const char *cmd,
{
err = assuan_read_line (ctx, &line, &linelen);
if (err)
- return err;
+ break;
if (*line == '#' || !linelen)
continue;
@@ -601,7 +601,7 @@ gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, const char *cmd,
if (linelen >= 2
&& line[0] == 'O' && line[1] == 'K'
&& (line[2] == '\0' || line[2] == ' '))
- return cb_err;
+ break;
else if (linelen >= 4
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
&& line[3] == ' ')
@@ -610,6 +610,7 @@ gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, const char *cmd,
more related to gpgme and thus probably more important
than the error returned by the engine. */
err = cb_err? cb_err : atoi (&line[4]);
+ cb_err = 0;
}
else if (linelen >= 2
&& line[0] == 'S' && line[1] == ' ')
@@ -646,10 +647,16 @@ gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, const char *cmd,
to stop. As with ERR we prefer a status callback
generated error code, though. */
err = cb_err ? cb_err : gpg_error (GPG_ERR_GENERAL);
+ cb_err = 0;
}
}
while (!err);
+ /* We only want the first error from the status handler, thus we
+ * take the one saved in CB_ERR. */
+ if (!err && cb_err)
+ err = cb_err;
+
return err;
}
@@ -1120,12 +1127,16 @@ gpgsm_reset (void *engine)
static gpgme_error_t
-gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
+gpgsm_decrypt (void *engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key, const char *override_session_key)
{
engine_gpgsm_t gpgsm = engine;
gpgme_error_t err;
+ (void)flags;
+
/* gpgsm is not capable of exporting session keys right now, so we
* will ignore this if requested. */
(void)export_session_key;
@@ -1642,10 +1653,10 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
gpgsm_assuan_simple_command (gpgsm, "GETINFO agent-check", NULL, NULL);
/* Always send list-mode option because RESET does not reset it. */
- if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
+ if (gpgrt_asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
return gpg_error_from_syserror ();
err = gpgsm_assuan_simple_command (gpgsm, line, NULL, NULL);
- free (line);
+ gpgrt_free (line);
if (err)
return err;
@@ -1726,10 +1737,10 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
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)
+ if (gpgrt_asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
return gpg_error_from_syserror ();
err = gpgsm_assuan_simple_command (gpgsm, line, NULL, NULL);
- free (line);
+ gpgrt_free (line);
if (err)
return err;
@@ -1860,10 +1871,11 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
can reset any previously set value in case the default is
requested. */
- if (asprintf (&assuan_cmd, "OPTION include-certs %i", include_certs) < 0)
+ if (gpgrt_asprintf (&assuan_cmd,
+ "OPTION include-certs %i", include_certs) < 0)
return gpg_error_from_syserror ();
err = gpgsm_assuan_simple_command (gpgsm, assuan_cmd, NULL, NULL);
- free (assuan_cmd);
+ gpgrt_free (assuan_cmd);
if (err)
return err;
}
@@ -2048,7 +2060,7 @@ gpgsm_passwd (void *engine, gpgme_key_t key, unsigned int flags)
if (!key || !key->subkeys || !key->subkeys->fpr)
return gpg_error (GPG_ERR_INV_CERT_OBJ);
- if (asprintf (&line, "PASSWD -- %s", key->subkeys->fpr) < 0)
+ if (gpgrt_asprintf (&line, "PASSWD -- %s", key->subkeys->fpr) < 0)
return gpg_error_from_syserror ();
gpgsm_clear_fd (gpgsm, OUTPUT_FD);
@@ -2057,7 +2069,7 @@ gpgsm_passwd (void *engine, gpgme_key_t key, unsigned int flags)
gpgsm->inline_data = NULL;
err = start (gpgsm, line);
- free (line);
+ gpgrt_free (line);
return err;
}
@@ -2087,7 +2099,6 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
gpgsm_set_locale,
NULL, /* set_protocol */
gpgsm_decrypt,
- gpgsm_decrypt,
gpgsm_delete, /* decrypt_verify */
NULL, /* edit */
gpgsm_encrypt,
@@ -2098,6 +2109,7 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
gpgsm_import,
gpgsm_keylist,
gpgsm_keylist_ext,
+ NULL, /* keylist_data */
NULL, /* keysign */
NULL, /* tofu_policy */
gpgsm_sign,
diff --git a/src/engine-spawn.c b/src/engine-spawn.c
index 1cd4421..9d587cc 100644
--- a/src/engine-spawn.c
+++ b/src/engine-spawn.c
@@ -449,7 +449,6 @@ struct engine_ops _gpgme_engine_ops_spawn =
NULL, /* set_locale */
NULL, /* set_protocol */
NULL, /* decrypt */
- NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */
@@ -460,6 +459,7 @@ struct engine_ops _gpgme_engine_ops_spawn =
NULL, /* import */
NULL, /* keylist */
NULL, /* keylist_ext */
+ NULL, /* keylist_data */
NULL, /* keysign */
NULL, /* tofu_policy */
NULL, /* sign */
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index ee7b1d2..20a8abf 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -316,7 +316,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_display)
{
- if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
{
err = gpg_error_from_syserror ();
free (dft_display);
@@ -326,7 +326,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -350,14 +350,14 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir,
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
- if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{
err = gpg_error_from_syserror ();
goto leave;
}
err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
@@ -366,7 +366,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_ttytype)
{
- if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0)
{
err = gpg_error_from_syserror ();
free (dft_ttytype);
@@ -376,7 +376,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -441,13 +441,13 @@ uiserver_set_locale (void *engine, int category, const char *value)
if (!value)
return 0;
- if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
err = gpg_error_from_syserror ();
else
{
err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
}
return err;
@@ -959,14 +959,16 @@ uiserver_reset (void *engine)
static gpgme_error_t
-_uiserver_decrypt (void *engine, int verify,
- gpgme_data_t ciph, gpgme_data_t plain,
- int export_session_key, const char *override_session_key)
+uiserver_decrypt (void *engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph, gpgme_data_t plain,
+ int export_session_key, const char *override_session_key)
{
engine_uiserver_t uiserver = engine;
gpgme_error_t err;
const char *protocol;
char *cmd;
+ int verify = !!(flags & GPGME_DECRYPT_VERIFY);
(void)override_session_key; /* Fixme: We need to see now to add this
* to the UI server protocol */
@@ -982,7 +984,7 @@ _uiserver_decrypt (void *engine, int verify,
else
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
- if (asprintf (&cmd, "DECRYPT%s%s%s", protocol,
+ if (gpgrt_asprintf (&cmd, "DECRYPT%s%s%s", protocol,
verify ? "" : " --no-verify",
export_session_key ? " --export-session-key" : "") < 0)
return gpg_error_from_syserror ();
@@ -992,44 +994,25 @@ _uiserver_decrypt (void *engine, int verify,
map_data_enc (uiserver->input_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return gpg_error (GPG_ERR_GENERAL); /* FIXME */
}
uiserver->output_cb.data = plain;
err = uiserver_set_fd (uiserver, OUTPUT_FD, 0);
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return gpg_error (GPG_ERR_GENERAL); /* FIXME */
}
uiserver->inline_data = NULL;
err = start (engine, cmd);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
static gpgme_error_t
-uiserver_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
- int export_session_key, const char *override_session_key)
-{
- return _uiserver_decrypt (engine, 0, ciph, plain,
- export_session_key, override_session_key);
-}
-
-
-static gpgme_error_t
-uiserver_decrypt_verify (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
- int export_session_key,
- const char *override_session_key)
-{
- return _uiserver_decrypt (engine, 1, ciph, plain,
- export_session_key, override_session_key);
-}
-
-
-static gpgme_error_t
set_recipients (engine_uiserver_t uiserver, gpgme_key_t recp[])
{
gpgme_error_t err = 0;
@@ -1114,7 +1097,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
if (!recp || plain || ciph)
return gpg_error (GPG_ERR_INV_VALUE);
- if (asprintf (&cmd, "PREP_ENCRYPT%s%s", protocol,
+ if (gpgrt_asprintf (&cmd, "PREP_ENCRYPT%s%s", protocol,
(flags & GPGME_ENCRYPT_EXPECT_SIGN)
? " --expect-sign" : "") < 0)
return gpg_error_from_syserror ();
@@ -1124,7 +1107,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
if (!plain || !ciph)
return gpg_error (GPG_ERR_INV_VALUE);
- if (asprintf (&cmd, "ENCRYPT%s", protocol) < 0)
+ if (gpgrt_asprintf (&cmd, "ENCRYPT%s", protocol) < 0)
return gpg_error_from_syserror ();
}
@@ -1135,7 +1118,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
map_data_enc (uiserver->input_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
}
@@ -1147,7 +1130,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
: map_data_enc (uiserver->output_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
}
@@ -1159,13 +1142,13 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
err = set_recipients (uiserver, recp);
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
}
err = start (uiserver, cmd);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
@@ -1195,7 +1178,7 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
else
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
- if (asprintf (&cmd, "SIGN%s%s", protocol,
+ if (gpgrt_asprintf (&cmd, "SIGN%s%s", protocol,
(mode == GPGME_SIG_MODE_DETACH) ? " --detached" : "") < 0)
return gpg_error_from_syserror ();
@@ -1220,10 +1203,10 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
err = gpg_error (GPG_ERR_INV_VALUE);
gpgme_key_unref (key);
if (err)
- {
- free (cmd);
- return err;
- }
+ {
+ gpgrt_free (cmd);
+ return err;
+ }
}
uiserver->input_cb.data = in;
@@ -1231,7 +1214,7 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
map_data_enc (uiserver->input_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
uiserver->output_cb.data = out;
@@ -1239,13 +1222,13 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
: map_data_enc (uiserver->output_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
uiserver->inline_data = NULL;
err = start (uiserver, cmd);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
@@ -1274,7 +1257,7 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
else
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
- if (asprintf (&cmd, "VERIFY%s", protocol) < 0)
+ if (gpgrt_asprintf (&cmd, "VERIFY%s", protocol) < 0)
return gpg_error_from_syserror ();
uiserver->input_cb.data = sig;
@@ -1282,7 +1265,7 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
map_data_enc (uiserver->input_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
if (plaintext)
@@ -1302,7 +1285,7 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
if (!err)
err = start (uiserver, cmd);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
@@ -1383,7 +1366,6 @@ struct engine_ops _gpgme_engine_ops_uiserver =
uiserver_set_locale,
uiserver_set_protocol,
uiserver_decrypt,
- uiserver_decrypt_verify,
NULL, /* delete */
NULL, /* edit */
uiserver_encrypt,
@@ -1394,6 +1376,7 @@ struct engine_ops _gpgme_engine_ops_uiserver =
NULL, /* import */
NULL, /* keylist */
NULL, /* keylist_ext */
+ NULL, /* keylist_data */
NULL, /* keysign */
NULL, /* tofu_policy */
uiserver_sign,
diff --git a/src/engine.c b/src/engine.c
index 75d9ff7..278916d 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -652,7 +652,9 @@ _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
gpgme_error_t
-_gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
+_gpgme_engine_op_decrypt (engine_t engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph,
gpgme_data_t plain, int export_session_key,
const char *override_session_key)
{
@@ -662,29 +664,12 @@ _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
if (!engine->ops->decrypt)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- return (*engine->ops->decrypt) (engine->engine, ciph, plain,
+ return (*engine->ops->decrypt) (engine->engine, flags, ciph, plain,
export_session_key, override_session_key);
}
gpgme_error_t
-_gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
- gpgme_data_t plain, int export_session_key,
- const char *override_session_key)
-{
- 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,
- export_session_key,
- override_session_key);
-}
-
-
-gpgme_error_t
_gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
int allow_secret)
{
@@ -876,6 +861,19 @@ _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
gpgme_error_t
+_gpgme_engine_op_keylist_data (engine_t engine, gpgme_data_t data)
+{
+ if (!engine)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ if (!engine->ops->keylist_data)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+ return (*engine->ops->keylist_data) (engine->engine, data);
+}
+
+
+gpgme_error_t
_gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,
gpgme_sig_mode_t mode, int use_armor,
int use_textmode, int include_certs,
diff --git a/src/engine.h b/src/engine.h
index 29d2f25..dd0ef9c 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -25,8 +25,9 @@
#include "gpgme.h"
/* Flags used by the EXTRAFLAGS arg of _gpgme_engine_op_genkey. */
-#define GENKEY_EXTRAFLAG_ARMOR 1
-#define GENKEY_EXTRAFLAG_REVOKE 2
+#define GENKEY_EXTRAFLAG_ARMOR 1
+#define GENKEY_EXTRAFLAG_REVOKE 2
+#define GENKEY_EXTRAFLAG_SETPRIMARY 4
struct engine;
@@ -82,16 +83,12 @@ 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_decrypt_flags_t flags,
+ gpgme_data_t ciph,
gpgme_data_t plain,
int export_session_key,
const char *override_session_key);
-gpgme_error_t _gpgme_engine_op_decrypt_verify (engine_t engine,
- gpgme_data_t ciph,
- gpgme_data_t plain,
- int export_session_key,
- const char *override_session_key
- );
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,
@@ -148,6 +145,8 @@ gpgme_error_t _gpgme_engine_op_keylist_ext (engine_t engine,
int reserved,
gpgme_keylist_mode_t mode,
int engine_flags);
+gpgme_error_t _gpgme_engine_op_keylist_data (engine_t engine,
+ gpgme_data_t data);
gpgme_error_t _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in,
gpgme_data_t out, gpgme_sig_mode_t mode,
int use_armor, int use_textmode,
diff --git a/src/funopen.c b/src/funopen.c
deleted file mode 100644
index b722020..0000000
--- a/src/funopen.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* funopen.c - Replacement for funopen.
- Copyright (C) 2004 g10 Code GmbH
-
- This file is part of GPGME
-
- GPGME is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of
- the License, or (at your option) any later version.
-
- GPGME is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-
-
-/* Replacement for the *BSD function:
-
- FILE *funopen (void *cookie,
- int (*readfn)(void *, char *, int),
- int (*writefn)(void *, const char *, int),
- fpos_t (*seekfn)(void *, fpos_t, int),
- int (*closefn)(void *));
-
- The functions to provide my either be NULL if not required or
- similar to the unistd function with the exception of using the
- cookie instead of the file descriptor.
-*/
-
-
-#ifdef HAVE_FOPENCOOKIE
-FILE *
-_gpgme_funopen(void *cookie,
- cookie_read_function_t *readfn,
- cookie_write_function_t *writefn,
- cookie_seek_function_t *seekfn,
- cookie_close_function_t *closefn)
-{
- cookie_io_functions_t io = { NULL };
-
- io.read = readfn;
- io.write = writefn;
- io.seek = seekfn;
- io.close = closefn;
-
- return fopencookie (cookie,
- readfn ? ( writefn ? "rw" : "r" )
- : ( writefn ? "w" : ""), io);
-}
-#else
-#error No known way to implement funopen.
-#endif
diff --git a/src/genkey.c b/src/genkey.c
index ea3f1ea..710b58f 100644
--- a/src/genkey.c
+++ b/src/genkey.c
@@ -489,7 +489,7 @@ gpgme_op_createsubkey (gpgme_ctx_t ctx, gpgme_key_t key, const char *algo,
static gpgme_error_t
-addrevuid_start (gpgme_ctx_t ctx, int synchronous, int revoke,
+addrevuid_start (gpgme_ctx_t ctx, int synchronous, int extraflags,
gpgme_key_t key, const char *userid, unsigned int flags)
{
gpgme_error_t err;
@@ -512,7 +512,7 @@ addrevuid_start (gpgme_ctx_t ctx, int synchronous, int revoke,
if (err)
return err;
- opd->uidmode = revoke? 2 : 1;
+ opd->uidmode = extraflags? 2 : 1;
_gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
@@ -528,7 +528,7 @@ addrevuid_start (gpgme_ctx_t ctx, int synchronous, int revoke,
userid, NULL, 0, 0,
key, flags,
NULL,
- revoke? GENKEY_EXTRAFLAG_REVOKE : 0,
+ extraflags,
NULL, NULL);
}
@@ -584,7 +584,7 @@ gpgme_op_revuid_start (gpgme_ctx_t ctx,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
- err = addrevuid_start (ctx, 0, 1, key, userid, flags);
+ err = addrevuid_start (ctx, 0, GENKEY_EXTRAFLAG_REVOKE, key, userid, flags);
return TRACE_ERR (err);
}
@@ -601,8 +601,60 @@ gpgme_op_revuid (gpgme_ctx_t ctx,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
- err = addrevuid_start (ctx, 1, 1, key, userid, flags);
+ err = addrevuid_start (ctx, 1, GENKEY_EXTRAFLAG_REVOKE, key, userid, flags);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
}
+
+
+/* Set a flag on the USERID of KEY. The only supported flag right now
+ * is "primary" to mark the primary key. */
+static gpg_error_t
+set_uid_flag (gpgme_ctx_t ctx, int synchronous,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG4 (DEBUG_CTX, "gpgme_op_set_uid_flag", ctx,
+ "%d uid='%s' '%s'='%s'", synchronous, userid, name, value);
+
+ if (!ctx || !name || !key || !userid)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
+
+ if (!strcmp (name, "primary"))
+ {
+ if (value)
+ err = gpg_error (GPG_ERR_INV_ARG);
+ else
+ err = addrevuid_start (ctx, synchronous,
+ GENKEY_EXTRAFLAG_SETPRIMARY, key, userid, 0);
+ }
+ else
+ return err = gpg_error (GPG_ERR_UNKNOWN_NAME);
+
+ if (synchronous && !err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}
+
+
+/* See set_uid_flag. */
+gpgme_error_t
+gpgme_op_set_uid_flag_start (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value)
+{
+ return set_uid_flag (ctx, 0, key, userid, name, value);
+}
+
+
+/* See set_uid_flag. Thsi is the synchronous variant. */
+gpgme_error_t
+gpgme_op_set_uid_flag (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value)
+{
+ return set_uid_flag (ctx, 1, key, userid, name, value);
+}
diff --git a/src/gpgme.c b/src/gpgme.c
index cf767c7..2b196a2 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -508,6 +508,10 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
if (!ctx || !name || !value)
err = gpg_error (GPG_ERR_INV_VALUE);
+ else if (!strcmp (name, "redraw"))
+ {
+ ctx->redraw_suggested = abool;
+ }
else if (!strcmp (name, "full-status"))
{
ctx->full_status = abool;
@@ -544,6 +548,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
{
if (!ctx || !name)
return NULL;
+ else if (!strcmp (name, "redraw"))
+ {
+ return ctx->redraw_suggested? "1":"";
+ }
else if (!strcmp (name, "full-status"))
{
return ctx->full_status? "1":"";
diff --git a/src/gpgme.def b/src/gpgme.def
index 0d3ce74..51053cd 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -177,8 +177,8 @@ EXPORTS
gpgme_io_read @136
gpgme_io_write @137
- gpgme_result_ref @138
- gpgme_result_unref @139
+ gpgme_result_ref @138
+ gpgme_result_unref @139
gpgme_op_import_keys @140
gpgme_op_import_keys_start @141
@@ -253,5 +253,14 @@ EXPORTS
gpgme_op_query_swdb_result @190
gpgme_get_ctx_flag @191
+
+ gpgme_op_keylist_from_data_start @192
+
+ gpgme_op_set_uid_flag_start @193
+ gpgme_op_set_uid_flag @194
+
+ gpgme_op_decrypt_ext @195
+ gpgme_op_decrypt_ext_start @196
+
; END
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 7cfe8f6..24b21e7 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1,6 +1,6 @@
/* gpgme.h - Public interface to GnuPG Made Easy. -*- c -*-
* Copyright (C) 2000 Werner Koch (dd9jn)
- * Copyright (C) 2001-2016 g10 Code GmbH
+ * Copyright (C) 2001-2017 g10 Code GmbH
*
* This file is part of GPGME.
*
@@ -294,24 +294,6 @@ typedef enum
gpgme_hash_algo_t;
-/* The possible signature stati. Deprecated, use error value in sig
- status. */
-typedef enum
- {
- GPGME_SIG_STAT_NONE = 0,
- GPGME_SIG_STAT_GOOD = 1,
- GPGME_SIG_STAT_BAD = 2,
- GPGME_SIG_STAT_NOKEY = 3,
- GPGME_SIG_STAT_NOSIG = 4,
- GPGME_SIG_STAT_ERROR = 5,
- GPGME_SIG_STAT_DIFF = 6,
- GPGME_SIG_STAT_GOOD_EXP = 7,
- GPGME_SIG_STAT_GOOD_EXPKEY = 8
- }
-_gpgme_sig_stat_t;
-typedef _gpgme_sig_stat_t gpgme_sig_stat_t _GPGME_DEPRECATED(0,4);
-
-
/* The available signature modes. */
typedef enum
{
@@ -322,47 +304,6 @@ typedef enum
gpgme_sig_mode_t;
-/* The available key and signature attributes. Deprecated, use the
- individual result structures instead. */
-typedef enum
- {
- GPGME_ATTR_KEYID = 1,
- GPGME_ATTR_FPR = 2,
- GPGME_ATTR_ALGO = 3,
- GPGME_ATTR_LEN = 4,
- GPGME_ATTR_CREATED = 5,
- GPGME_ATTR_EXPIRE = 6,
- GPGME_ATTR_OTRUST = 7,
- GPGME_ATTR_USERID = 8,
- GPGME_ATTR_NAME = 9,
- GPGME_ATTR_EMAIL = 10,
- GPGME_ATTR_COMMENT = 11,
- GPGME_ATTR_VALIDITY = 12,
- GPGME_ATTR_LEVEL = 13,
- GPGME_ATTR_TYPE = 14,
- GPGME_ATTR_IS_SECRET = 15,
- GPGME_ATTR_KEY_REVOKED = 16,
- GPGME_ATTR_KEY_INVALID = 17,
- GPGME_ATTR_UID_REVOKED = 18,
- GPGME_ATTR_UID_INVALID = 19,
- GPGME_ATTR_KEY_CAPS = 20,
- GPGME_ATTR_CAN_ENCRYPT = 21,
- GPGME_ATTR_CAN_SIGN = 22,
- GPGME_ATTR_CAN_CERTIFY = 23,
- GPGME_ATTR_KEY_EXPIRED = 24,
- GPGME_ATTR_KEY_DISABLED = 25,
- GPGME_ATTR_SERIAL = 26,
- GPGME_ATTR_ISSUER = 27,
- GPGME_ATTR_CHAINID = 28,
- GPGME_ATTR_SIG_STATUS = 29,
- GPGME_ATTR_ERRTOK = 30,
- GPGME_ATTR_SIG_SUMMARY = 31,
- GPGME_ATTR_SIG_CLASS = 32
- }
-_gpgme_attr_t;
-typedef _gpgme_attr_t gpgme_attr_t _GPGME_DEPRECATED(0,4);
-
-
/* The available validities for a trust item or key. */
typedef enum
{
@@ -447,128 +388,15 @@ typedef unsigned int gpgme_export_mode_t;
#define GPGME_AUDITLOG_WITH_HELP 128
-/* The possible stati for gpgme_op_edit. The use of that function and
- * these status codes are deprecated in favor of gpgme_op_interact. */
-typedef enum
- {
- GPGME_STATUS_EOF = 0,
- /* mkstatus processing starts here */
- GPGME_STATUS_ENTER = 1,
- GPGME_STATUS_LEAVE = 2,
- GPGME_STATUS_ABORT = 3,
-
- GPGME_STATUS_GOODSIG = 4,
- GPGME_STATUS_BADSIG = 5,
- GPGME_STATUS_ERRSIG = 6,
-
- GPGME_STATUS_BADARMOR = 7,
-
- GPGME_STATUS_RSA_OR_IDEA = 8, /* (legacy) */
- GPGME_STATUS_KEYEXPIRED = 9,
- GPGME_STATUS_KEYREVOKED = 10,
-
- GPGME_STATUS_TRUST_UNDEFINED = 11,
- GPGME_STATUS_TRUST_NEVER = 12,
- GPGME_STATUS_TRUST_MARGINAL = 13,
- GPGME_STATUS_TRUST_FULLY = 14,
- GPGME_STATUS_TRUST_ULTIMATE = 15,
-
- GPGME_STATUS_SHM_INFO = 16, /* (legacy) */
- GPGME_STATUS_SHM_GET = 17, /* (legacy) */
- GPGME_STATUS_SHM_GET_BOOL = 18, /* (legacy) */
- GPGME_STATUS_SHM_GET_HIDDEN = 19, /* (legacy) */
-
- GPGME_STATUS_NEED_PASSPHRASE = 20,
- GPGME_STATUS_VALIDSIG = 21,
- GPGME_STATUS_SIG_ID = 22,
- GPGME_STATUS_ENC_TO = 23,
- GPGME_STATUS_NODATA = 24,
- GPGME_STATUS_BAD_PASSPHRASE = 25,
- GPGME_STATUS_NO_PUBKEY = 26,
- GPGME_STATUS_NO_SECKEY = 27,
- GPGME_STATUS_NEED_PASSPHRASE_SYM = 28,
- GPGME_STATUS_DECRYPTION_FAILED = 29,
- GPGME_STATUS_DECRYPTION_OKAY = 30,
- GPGME_STATUS_MISSING_PASSPHRASE = 31,
- GPGME_STATUS_GOOD_PASSPHRASE = 32,
- GPGME_STATUS_GOODMDC = 33,
- GPGME_STATUS_BADMDC = 34,
- GPGME_STATUS_ERRMDC = 35,
- GPGME_STATUS_IMPORTED = 36,
- GPGME_STATUS_IMPORT_OK = 37,
- GPGME_STATUS_IMPORT_PROBLEM = 38,
- GPGME_STATUS_IMPORT_RES = 39,
- GPGME_STATUS_FILE_START = 40,
- GPGME_STATUS_FILE_DONE = 41,
- GPGME_STATUS_FILE_ERROR = 42,
-
- GPGME_STATUS_BEGIN_DECRYPTION = 43,
- GPGME_STATUS_END_DECRYPTION = 44,
- GPGME_STATUS_BEGIN_ENCRYPTION = 45,
- GPGME_STATUS_END_ENCRYPTION = 46,
-
- GPGME_STATUS_DELETE_PROBLEM = 47,
- GPGME_STATUS_GET_BOOL = 48,
- GPGME_STATUS_GET_LINE = 49,
- GPGME_STATUS_GET_HIDDEN = 50,
- GPGME_STATUS_GOT_IT = 51,
- GPGME_STATUS_PROGRESS = 52,
- GPGME_STATUS_SIG_CREATED = 53,
- GPGME_STATUS_SESSION_KEY = 54,
- GPGME_STATUS_NOTATION_NAME = 55,
- GPGME_STATUS_NOTATION_DATA = 56,
- GPGME_STATUS_POLICY_URL = 57,
- GPGME_STATUS_BEGIN_STREAM = 58, /* (legacy) */
- GPGME_STATUS_END_STREAM = 59, /* (legacy) */
- GPGME_STATUS_KEY_CREATED = 60,
- GPGME_STATUS_USERID_HINT = 61,
- GPGME_STATUS_UNEXPECTED = 62,
- GPGME_STATUS_INV_RECP = 63,
- GPGME_STATUS_NO_RECP = 64,
- GPGME_STATUS_ALREADY_SIGNED = 65,
- GPGME_STATUS_SIGEXPIRED = 66, /* (legacy) */
- GPGME_STATUS_EXPSIG = 67,
- GPGME_STATUS_EXPKEYSIG = 68,
- GPGME_STATUS_TRUNCATED = 69,
- GPGME_STATUS_ERROR = 70,
- GPGME_STATUS_NEWSIG = 71,
- GPGME_STATUS_REVKEYSIG = 72,
- GPGME_STATUS_SIG_SUBPACKET = 73,
- GPGME_STATUS_NEED_PASSPHRASE_PIN = 74,
- GPGME_STATUS_SC_OP_FAILURE = 75,
- GPGME_STATUS_SC_OP_SUCCESS = 76,
- GPGME_STATUS_CARDCTRL = 77,
- GPGME_STATUS_BACKUP_KEY_CREATED = 78,
- GPGME_STATUS_PKA_TRUST_BAD = 79,
- GPGME_STATUS_PKA_TRUST_GOOD = 80,
- GPGME_STATUS_PLAINTEXT = 81,
- GPGME_STATUS_INV_SGNR = 82,
- GPGME_STATUS_NO_SGNR = 83,
- GPGME_STATUS_SUCCESS = 84,
- GPGME_STATUS_DECRYPTION_INFO = 85,
- GPGME_STATUS_PLAINTEXT_LENGTH = 86,
- GPGME_STATUS_MOUNTPOINT = 87,
- GPGME_STATUS_PINENTRY_LAUNCHED = 88,
- GPGME_STATUS_ATTRIBUTE = 89,
- GPGME_STATUS_BEGIN_SIGNING = 90,
- GPGME_STATUS_KEY_NOT_CREATED = 91,
- GPGME_STATUS_INQUIRE_MAXLEN = 92,
- GPGME_STATUS_FAILURE = 93,
- GPGME_STATUS_KEY_CONSIDERED = 94,
- GPGME_STATUS_TOFU_USER = 95,
- GPGME_STATUS_TOFU_STATS = 96,
- GPGME_STATUS_TOFU_STATS_LONG = 97,
- GPGME_STATUS_NOTATION_FLAGS = 98
- }
-gpgme_status_code_t;
-
-
/* The available signature notation flags. */
#define GPGME_SIG_NOTATION_HUMAN_READABLE 1
#define GPGME_SIG_NOTATION_CRITICAL 2
typedef unsigned int gpgme_sig_notation_flags_t;
+/* An object to hold information about notation data. This structure
+ * shall be considered read-only and an application must not allocate
+ * such a structure on its own. */
struct _gpgme_sig_notation
{
struct _gpgme_sig_notation *next;
@@ -606,7 +434,9 @@ typedef struct _gpgme_sig_notation *gpgme_sig_notation_t;
* Public structures.
*/
-/* The engine information structure. */
+/* The engine information structure.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_engine_info
{
struct _gpgme_engine_info *next;
@@ -629,7 +459,9 @@ struct _gpgme_engine_info
typedef struct _gpgme_engine_info *gpgme_engine_info_t;
-/* An object with TOFU information. */
+/* An object with TOFU information.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_tofu_info
{
struct _gpgme_tofu_info *next;
@@ -666,7 +498,9 @@ struct _gpgme_tofu_info
typedef struct _gpgme_tofu_info *gpgme_tofu_info_t;
-/* A subkey from a key. */
+/* A subkey from a key.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_subkey
{
struct _gpgme_subkey *next;
@@ -704,8 +538,11 @@ struct _gpgme_subkey
/* True if the secret key is stored on a smart card. */
unsigned int is_cardkey : 1;
+ /* True if the key is compliant to the de-vs mode. */
+ unsigned int is_de_vs : 1;
+
/* Internal to GPGME, do not use. */
- unsigned int _unused : 21;
+ unsigned int _unused : 20;
/* Public key algorithm supported by this subkey. */
gpgme_pubkey_algo_t pubkey_algo;
@@ -740,7 +577,9 @@ struct _gpgme_subkey
typedef struct _gpgme_subkey *gpgme_subkey_t;
-/* A signature on a user ID. */
+/* A signature on a user ID.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_key_sig
{
struct _gpgme_key_sig *next;
@@ -809,7 +648,9 @@ struct _gpgme_key_sig
typedef struct _gpgme_key_sig *gpgme_key_sig_t;
-/* An user ID from a key. */
+/* An user ID from a key.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_user_id
{
struct _gpgme_user_id *next;
@@ -821,7 +662,10 @@ struct _gpgme_user_id
unsigned int invalid : 1;
/* Internal to GPGME, do not use. */
- unsigned int _unused : 30;
+ unsigned int _unused : 25;
+
+ /* Origin of this user ID. */
+ unsigned int origin : 5;
/* The validity of the user ID. */
gpgme_validity_t validity;
@@ -852,11 +696,16 @@ struct _gpgme_user_id
/* The malloced TOFU information or NULL. */
gpgme_tofu_info_t tofu;
+
+ /* Time of the last refresh of thsi user id. 0 if unknown. */
+ unsigned long last_update;
};
typedef struct _gpgme_user_id *gpgme_user_id_t;
-/* A key from the keyring. */
+/* A key from the keyring.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_key
{
/* Internal to GPGME, do not use. */
@@ -893,7 +742,10 @@ struct _gpgme_key
unsigned int is_qualified : 1;
/* Internal to GPGME, do not use. */
- unsigned int _unused : 22;
+ unsigned int _unused : 17;
+
+ /* Origin of this key. */
+ unsigned int origin : 5;
/* This is the protocol supported by this key. */
gpgme_protocol_t protocol;
@@ -933,11 +785,16 @@ struct _gpgme_key
* this is a copy of the FPR of the first subkey. We need it here
* to allow for an incomplete key object. */
char *fpr;
+
+ /* Time of the last refresh of the entire key. 0 if unknown. */
+ unsigned long last_update;
};
typedef struct _gpgme_key *gpgme_key_t;
-/* An invalid key object. */
+/* An invalid key object.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_invalid_key
{
struct _gpgme_invalid_key *next;
@@ -976,13 +833,6 @@ typedef gpgme_error_t (*gpgme_interact_cb_t) (void *opaque,
const char *keyword,
const char *args, int fd);
-/* The callback type used by the deprecated functions gpgme_op_edit
- * and gpgme_op_card_edit. */
-typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque,
- gpgme_status_code_t status,
- const char *args, int fd);
-
-
/*
@@ -1122,33 +972,6 @@ unsigned int gpgme_signers_count (const gpgme_ctx_t ctx);
/* Return the SEQth signer's key in CTX. */
gpgme_key_t gpgme_signers_enum (const gpgme_ctx_t ctx, int seq);
-/* Retrieve the signature status of signature IDX in CTX after a
- successful verify operation in R_STAT (if non-null). The creation
- time stamp of the signature is returned in R_CREATED (if non-null).
- The function returns a string containing the fingerprint.
- Deprecated, use verify result directly. */
-const char *gpgme_get_sig_status (gpgme_ctx_t ctx, int idx,
- _gpgme_sig_stat_t *r_stat,
- time_t *r_created) _GPGME_DEPRECATED(0,4);
-
-/* Retrieve certain attributes of a signature. IDX is the index
- number of the signature after a successful verify operation. WHAT
- is an attribute where GPGME_ATTR_EXPIRE is probably the most useful
- one. WHATIDX is to be passed as 0 for most attributes . */
-unsigned long gpgme_get_sig_ulong_attr (gpgme_ctx_t c, int idx,
- _gpgme_attr_t what, int whatidx)
- _GPGME_DEPRECATED(0,4);
-const char *gpgme_get_sig_string_attr (gpgme_ctx_t c, int idx,
- _gpgme_attr_t what, int whatidx)
- _GPGME_DEPRECATED(0,4);
-
-
-/* Get the key used to create signature IDX in CTX and return it in
- R_KEY. */
-gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key)
- _GPGME_DEPRECATED(0,4);
-
-
/* Clear all notation data from the context. */
void gpgme_sig_notation_clear (gpgme_ctx_t ctx);
@@ -1360,15 +1183,6 @@ gpg_error_t gpgme_data_set_flag (gpgme_data_t dh,
gpgme_data_type_t gpgme_data_identify (gpgme_data_t dh, int reserved);
-/* Create a new data buffer which retrieves the data from the callback
- function READ_CB. Deprecated, please use gpgme_data_new_from_cbs
- instead. */
-gpgme_error_t gpgme_data_new_with_read_cb (gpgme_data_t *r_dh,
- int (*read_cb) (void*,char *,
- size_t,size_t*),
- void *read_cb_value)
- _GPGME_DEPRECATED(0,4);
-
/* Create a new data buffer filled with the content of file FNAME.
COPY must be non-zero. For delayed read, please use
gpgme_data_new_from_fd or gpgme_data_new_from_stream instead. */
@@ -1383,9 +1197,8 @@ gpgme_error_t gpgme_data_new_from_filepart (gpgme_data_t *r_dh,
const char *fname, FILE *fp,
@API__OFF_T@ offset, size_t length);
-/* Reset the read pointer in DH. Deprecated, please use
- gpgme_data_seek instead. */
-gpgme_error_t gpgme_data_rewind (gpgme_data_t dh) _GPGME_DEPRECATED(0,4);
+/* Convenience function to do a gpgme_data_seek (dh, 0, SEEK_SET). */
+gpgme_error_t gpgme_data_rewind (gpgme_data_t dh);
@@ -1409,46 +1222,15 @@ void gpgme_key_ref (gpgme_key_t key);
void gpgme_key_unref (gpgme_key_t key);
void gpgme_key_release (gpgme_key_t key);
-/* Return the value of the attribute WHAT of KEY, which has to be
- representable by a string. IDX specifies the sub key or user ID
- for attributes related to sub keys or user IDs. Deprecated, use
- key structure directly instead. */
-const char *gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
-/* Return the value of the attribute WHAT of KEY, which has to be
- representable by an unsigned integer. IDX specifies the sub key or
- user ID for attributes related to sub keys or user IDs.
- Deprecated, use key structure directly instead. */
-unsigned long gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
-/* Return the value of the attribute WHAT of a signature on user ID
- UID_IDX in KEY, which has to be representable by a string. IDX
- specifies the signature. Deprecated, use key structure directly
- instead. */
-const char *gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx,
- _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
-/* Return the value of the attribute WHAT of a signature on user ID
- UID_IDX in KEY, which has to be representable by an unsigned
- integer string. IDX specifies the signature. Deprecated, use key
- structure directly instead. */
-unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx,
- _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
/*
* Encryption.
*/
+/* An object to return results from an encryption operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_encrypt_result
{
/* The list of invalid recipients. */
@@ -1467,7 +1249,9 @@ typedef enum
GPGME_ENCRYPT_PREPARE = 4,
GPGME_ENCRYPT_EXPECT_SIGN = 8,
GPGME_ENCRYPT_NO_COMPRESS = 16,
- GPGME_ENCRYPT_SYMMETRIC = 32
+ GPGME_ENCRYPT_SYMMETRIC = 32,
+ GPGME_ENCRYPT_THROW_KEYIDS = 64,
+ GPGME_ENCRYPT_WRAP = 128
}
gpgme_encrypt_flags_t;
@@ -1497,6 +1281,9 @@ gpgme_error_t gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
* Decryption.
*/
+/* An object to hold information about a recipient.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_recipient
{
struct _gpgme_recipient *next;
@@ -1515,6 +1302,9 @@ struct _gpgme_recipient
};
typedef struct _gpgme_recipient *gpgme_recipient_t;
+/* An object to return results from a decryption operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_decrypt_result
{
char *unsupported_algorithm;
@@ -1540,6 +1330,14 @@ typedef struct _gpgme_op_decrypt_result *gpgme_decrypt_result_t;
/* Retrieve a pointer to the result of the decrypt operation. */
gpgme_decrypt_result_t gpgme_op_decrypt_result (gpgme_ctx_t ctx);
+/* The valid decryption flags. */
+typedef enum
+ {
+ GPGME_DECRYPT_VERIFY = 1,
+ GPGME_DECRYPT_UNWRAP = 128
+ }
+gpgme_decrypt_flags_t;
+
/* Decrypt ciphertext CIPHER within CTX and store the resulting
plaintext in PLAIN. */
gpgme_error_t gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
@@ -1555,11 +1353,27 @@ gpgme_error_t gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx,
gpgme_error_t gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
gpgme_data_t plain);
+/* Decrypt ciphertext CIPHER within CTX and store the resulting
+ * plaintext in PLAIN. With the flag GPGME_DECRYPT_VERIFY also do a
+ * signature verification pn the plaintext. */
+gpgme_error_t gpgme_op_decrypt_ext_start (gpgme_ctx_t ctx,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher,
+ gpgme_data_t plain);
+gpgme_error_t gpgme_op_decrypt_ext (gpgme_ctx_t ctx,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher,
+ gpgme_data_t plain);
+
+
/*
* Signing.
*/
+/* An object with signatures data.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_new_signature
{
struct _gpgme_new_signature *next;
@@ -1595,6 +1409,10 @@ struct _gpgme_new_signature
};
typedef struct _gpgme_new_signature *gpgme_new_signature_t;
+
+/* An object to return results from a signing operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_sign_result
{
/* The list of invalid signers. */
@@ -1638,6 +1456,9 @@ typedef enum
gpgme_sigsum_t;
+/* An object to hold the verification status of a signature.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_signature
{
struct _gpgme_signature *next;
@@ -1690,6 +1511,9 @@ struct _gpgme_signature
};
typedef struct _gpgme_signature *gpgme_signature_t;
+/* An object to return the results of a verify operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_verify_result
{
gpgme_signature_t signatures;
@@ -1723,6 +1547,9 @@ gpgme_error_t gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig,
#define GPGME_IMPORT_SECRET 16 /* The key contained a secret key. */
+/* An object to hold results for one imported key.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_import_status
{
struct _gpgme_import_status *next;
@@ -1741,7 +1568,9 @@ struct _gpgme_import_status
};
typedef struct _gpgme_import_status *gpgme_import_status_t;
-/* Import result object. */
+/* Import result object.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_import_result
{
/* Number of considered keys. */
@@ -1797,8 +1626,6 @@ gpgme_import_result_t gpgme_op_import_result (gpgme_ctx_t ctx);
/* Import the key in KEYDATA into the keyring. */
gpgme_error_t gpgme_op_import_start (gpgme_ctx_t ctx, gpgme_data_t keydata);
gpgme_error_t gpgme_op_import (gpgme_ctx_t ctx, gpgme_data_t keydata);
-gpgme_error_t gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata,
- int *nr) _GPGME_DEPRECATED(0,4);
/* Import the keys from the array KEYS into the keyring. */
gpgme_error_t gpgme_op_import_keys_start (gpgme_ctx_t ctx, gpgme_key_t keys[]);
@@ -1848,7 +1675,11 @@ gpgme_error_t gpgme_op_export_keys (gpgme_ctx_t ctx,
#define GPGME_CREATE_WANTPUB (1 << 10) /* Return the public key. */
#define GPGME_CREATE_WANTSEC (1 << 11) /* Return the secret key. */
#define GPGME_CREATE_FORCE (1 << 12) /* Force creation. */
+#define GPGME_CREATE_NOEXPIRE (1 << 13) /* Create w/o expiration. */
+/* An object to return result from a key generation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_genkey_result
{
/* A primary key was generated. */
@@ -1929,6 +1760,13 @@ gpgme_error_t gpgme_op_revuid (gpgme_ctx_t ctx,
gpgme_key_t key, const char *userid,
unsigned int reserved);
+/* Set a flag on the USERID of KEY. See the manual for supported flags. */
+gpgme_error_t gpgme_op_set_uid_flag_start (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value);
+gpgme_error_t gpgme_op_set_uid_flag (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value);
/* Retrieve a pointer to the result of a genkey, createkey, or
@@ -1989,21 +1827,6 @@ gpgme_error_t gpgme_op_interact (gpgme_ctx_t ctx, gpgme_key_t key,
void *fnc_value,
gpgme_data_t out);
-gpgme_error_t gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
- gpgme_edit_cb_t fnc, void *fnc_value,
- gpgme_data_t out) _GPGME_DEPRECATED(1,7);
-gpgme_error_t gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
- gpgme_edit_cb_t fnc, void *fnc_value,
- gpgme_data_t out) _GPGME_DEPRECATED(1,7);
-gpgme_error_t gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
- gpgme_edit_cb_t fnc, void *fnc_value,
- gpgme_data_t out)
- _GPGME_DEPRECATED(1,7);
-gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
- gpgme_edit_cb_t fnc, void *fnc_value,
- gpgme_data_t out)
- _GPGME_DEPRECATED(1,7);
-
/* Set the Tofu policy of KEY to POLCIY. */
gpgme_error_t gpgme_op_tofu_policy_start (gpgme_ctx_t ctx,
@@ -2020,6 +1843,9 @@ gpgme_error_t gpgme_op_tofu_policy (gpgme_ctx_t ctx,
* Key listing
*/
+/* An object to return results from a key listing operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_keylist_result
{
unsigned int truncated : 1;
@@ -2033,20 +1859,31 @@ typedef struct _gpgme_op_keylist_result *gpgme_keylist_result_t;
gpgme_keylist_result_t gpgme_op_keylist_result (gpgme_ctx_t ctx);
/* Start a keylist operation within CTX, searching for keys which
- match PATTERN. If SECRET_ONLY is true, only secret keys are
- returned. */
+ * match PATTERN. If SECRET_ONLY is true, only secret keys are
+ * returned. */
gpgme_error_t gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern,
int secret_only);
gpgme_error_t gpgme_op_keylist_ext_start (gpgme_ctx_t ctx,
const char *pattern[],
int secret_only, int reserved);
+/* List the keys contained in DATA. */
+gpgme_error_t gpgme_op_keylist_from_data_start (gpgme_ctx_t ctx,
+ gpgme_data_t data,
+ int reserved);
+
/* Return the next key from the keylist in R_KEY. */
gpgme_error_t gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key);
/* Terminate a pending keylist operation within CTX. */
gpgme_error_t gpgme_op_keylist_end (gpgme_ctx_t ctx);
+
+
+/*
+ * Protecting keys
+ */
+
/* Change the passphrase for KEY. FLAGS is reserved for future use
and must be passed as 0. */
gpgme_error_t gpgme_op_passwd_start (gpgme_ctx_t ctx, gpgme_key_t key,
@@ -2060,6 +1897,9 @@ gpgme_error_t gpgme_op_passwd (gpgme_ctx_t ctx, gpgme_key_t key,
* Trust items and operations.
*/
+/* An object to hold data of a trust item.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_trust_item
{
/* Internal to GPGME, do not use. */
@@ -2113,26 +1953,6 @@ void gpgme_trust_item_ref (gpgme_trust_item_t item);
item is destroyed. */
void gpgme_trust_item_unref (gpgme_trust_item_t item);
-/* Release the trust item ITEM. Deprecated, use
- gpgme_trust_item_unref. */
-void gpgme_trust_item_release (gpgme_trust_item_t item) _GPGME_DEPRECATED(0,4);
-
-/* Return the value of the attribute WHAT of ITEM, which has to be
- representable by a string. Deprecated, use trust item structure
- directly. */
-const char *gpgme_trust_item_get_string_attr (gpgme_trust_item_t item,
- _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
-/* Return the value of the attribute WHAT of KEY, which has to be
- representable by an integer. IDX specifies a running index if the
- attribute appears more than once in the key. Deprecated, use trust
- item structure directly. */
-int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
/*
@@ -2209,35 +2029,14 @@ gpgme_error_t gpgme_op_assuan_transact_ext (gpgme_ctx_t ctx,
void *stat_cb_value,
gpgme_error_t *op_err);
-/* Compat. */
-struct _gpgme_op_assuan_result
-{
- /* Deprecated. Use the second value in a DONE event or the
- synchronous variant gpgme_op_assuan_transact_ext. */
- gpgme_error_t err _GPGME_DEPRECATED_OUTSIDE_GPGME(1,2);
-};
-typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t;
-
-
-/* Return the result of the last Assuan command. */
-gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx)
- _GPGME_DEPRECATED(1,2);
-
-gpgme_error_t
-gpgme_op_assuan_transact (gpgme_ctx_t ctx,
- const char *command,
- gpgme_assuan_data_cb_t data_cb,
- void *data_cb_value,
- gpgme_assuan_inquire_cb_t inq_cb,
- void *inq_cb_value,
- gpgme_assuan_status_cb_t status_cb,
- void *status_cb_value) _GPGME_DEPRECATED(1,2);
-
/*
* Crypto container support.
*/
+/* An object to return results from a VFS mount operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_vfs_mount_result
{
char *mount_dir;
@@ -2410,7 +2209,8 @@ void gpgme_conf_arg_release (gpgme_conf_arg_t arg, gpgme_conf_type_t type);
/* Register a change for the value of OPT to ARG. If RESET is 1 (do
not use any values but 0 or 1), ARG is ignored and the option is
not changed (reverting a previous change). Otherwise, if ARG is
- NULL, the option is cleared or reset to its default. */
+ NULL, the option is cleared or reset to its default. The change
+ is done with gpgconf's --runtime option to immediately take effect. */
gpgme_error_t gpgme_conf_opt_change (gpgme_conf_opt_t opt, int reset,
gpgme_conf_arg_t arg);
@@ -2425,7 +2225,9 @@ gpgme_error_t gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p);
gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp);
-/* Information about software versions. */
+/* Information about software versions.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
typedef struct _gpgme_op_query_swdb_result
{
/* RFU */
@@ -2552,8 +2354,323 @@ char *gpgme_addrspec_from_uid (const char *uid);
/*
- * Deprecated types.
+ * Deprecated types, constants and functions.
*/
+
+/* The possible stati for gpgme_op_edit. The use of that function and
+ * these status codes are deprecated in favor of gpgme_op_interact. */
+typedef enum
+ {
+ GPGME_STATUS_EOF = 0,
+ /* mkstatus processing starts here */
+ GPGME_STATUS_ENTER = 1,
+ GPGME_STATUS_LEAVE = 2,
+ GPGME_STATUS_ABORT = 3,
+
+ GPGME_STATUS_GOODSIG = 4,
+ GPGME_STATUS_BADSIG = 5,
+ GPGME_STATUS_ERRSIG = 6,
+
+ GPGME_STATUS_BADARMOR = 7,
+
+ GPGME_STATUS_RSA_OR_IDEA = 8, /* (legacy) */
+ GPGME_STATUS_KEYEXPIRED = 9,
+ GPGME_STATUS_KEYREVOKED = 10,
+
+ GPGME_STATUS_TRUST_UNDEFINED = 11,
+ GPGME_STATUS_TRUST_NEVER = 12,
+ GPGME_STATUS_TRUST_MARGINAL = 13,
+ GPGME_STATUS_TRUST_FULLY = 14,
+ GPGME_STATUS_TRUST_ULTIMATE = 15,
+
+ GPGME_STATUS_SHM_INFO = 16, /* (legacy) */
+ GPGME_STATUS_SHM_GET = 17, /* (legacy) */
+ GPGME_STATUS_SHM_GET_BOOL = 18, /* (legacy) */
+ GPGME_STATUS_SHM_GET_HIDDEN = 19, /* (legacy) */
+
+ GPGME_STATUS_NEED_PASSPHRASE = 20,
+ GPGME_STATUS_VALIDSIG = 21,
+ GPGME_STATUS_SIG_ID = 22,
+ GPGME_STATUS_ENC_TO = 23,
+ GPGME_STATUS_NODATA = 24,
+ GPGME_STATUS_BAD_PASSPHRASE = 25,
+ GPGME_STATUS_NO_PUBKEY = 26,
+ GPGME_STATUS_NO_SECKEY = 27,
+ GPGME_STATUS_NEED_PASSPHRASE_SYM = 28,
+ GPGME_STATUS_DECRYPTION_FAILED = 29,
+ GPGME_STATUS_DECRYPTION_OKAY = 30,
+ GPGME_STATUS_MISSING_PASSPHRASE = 31,
+ GPGME_STATUS_GOOD_PASSPHRASE = 32,
+ GPGME_STATUS_GOODMDC = 33,
+ GPGME_STATUS_BADMDC = 34,
+ GPGME_STATUS_ERRMDC = 35,
+ GPGME_STATUS_IMPORTED = 36,
+ GPGME_STATUS_IMPORT_OK = 37,
+ GPGME_STATUS_IMPORT_PROBLEM = 38,
+ GPGME_STATUS_IMPORT_RES = 39,
+ GPGME_STATUS_FILE_START = 40,
+ GPGME_STATUS_FILE_DONE = 41,
+ GPGME_STATUS_FILE_ERROR = 42,
+
+ GPGME_STATUS_BEGIN_DECRYPTION = 43,
+ GPGME_STATUS_END_DECRYPTION = 44,
+ GPGME_STATUS_BEGIN_ENCRYPTION = 45,
+ GPGME_STATUS_END_ENCRYPTION = 46,
+
+ GPGME_STATUS_DELETE_PROBLEM = 47,
+ GPGME_STATUS_GET_BOOL = 48,
+ GPGME_STATUS_GET_LINE = 49,
+ GPGME_STATUS_GET_HIDDEN = 50,
+ GPGME_STATUS_GOT_IT = 51,
+ GPGME_STATUS_PROGRESS = 52,
+ GPGME_STATUS_SIG_CREATED = 53,
+ GPGME_STATUS_SESSION_KEY = 54,
+ GPGME_STATUS_NOTATION_NAME = 55,
+ GPGME_STATUS_NOTATION_DATA = 56,
+ GPGME_STATUS_POLICY_URL = 57,
+ GPGME_STATUS_BEGIN_STREAM = 58, /* (legacy) */
+ GPGME_STATUS_END_STREAM = 59, /* (legacy) */
+ GPGME_STATUS_KEY_CREATED = 60,
+ GPGME_STATUS_USERID_HINT = 61,
+ GPGME_STATUS_UNEXPECTED = 62,
+ GPGME_STATUS_INV_RECP = 63,
+ GPGME_STATUS_NO_RECP = 64,
+ GPGME_STATUS_ALREADY_SIGNED = 65,
+ GPGME_STATUS_SIGEXPIRED = 66, /* (legacy) */
+ GPGME_STATUS_EXPSIG = 67,
+ GPGME_STATUS_EXPKEYSIG = 68,
+ GPGME_STATUS_TRUNCATED = 69,
+ GPGME_STATUS_ERROR = 70,
+ GPGME_STATUS_NEWSIG = 71,
+ GPGME_STATUS_REVKEYSIG = 72,
+ GPGME_STATUS_SIG_SUBPACKET = 73,
+ GPGME_STATUS_NEED_PASSPHRASE_PIN = 74,
+ GPGME_STATUS_SC_OP_FAILURE = 75,
+ GPGME_STATUS_SC_OP_SUCCESS = 76,
+ GPGME_STATUS_CARDCTRL = 77,
+ GPGME_STATUS_BACKUP_KEY_CREATED = 78,
+ GPGME_STATUS_PKA_TRUST_BAD = 79,
+ GPGME_STATUS_PKA_TRUST_GOOD = 80,
+ GPGME_STATUS_PLAINTEXT = 81,
+ GPGME_STATUS_INV_SGNR = 82,
+ GPGME_STATUS_NO_SGNR = 83,
+ GPGME_STATUS_SUCCESS = 84,
+ GPGME_STATUS_DECRYPTION_INFO = 85,
+ GPGME_STATUS_PLAINTEXT_LENGTH = 86,
+ GPGME_STATUS_MOUNTPOINT = 87,
+ GPGME_STATUS_PINENTRY_LAUNCHED = 88,
+ GPGME_STATUS_ATTRIBUTE = 89,
+ GPGME_STATUS_BEGIN_SIGNING = 90,
+ GPGME_STATUS_KEY_NOT_CREATED = 91,
+ GPGME_STATUS_INQUIRE_MAXLEN = 92,
+ GPGME_STATUS_FAILURE = 93,
+ GPGME_STATUS_KEY_CONSIDERED = 94,
+ GPGME_STATUS_TOFU_USER = 95,
+ GPGME_STATUS_TOFU_STATS = 96,
+ GPGME_STATUS_TOFU_STATS_LONG = 97,
+ GPGME_STATUS_NOTATION_FLAGS = 98
+ }
+gpgme_status_code_t;
+
+/* The callback type used by the deprecated functions gpgme_op_edit
+ * and gpgme_op_card_edit. */
+typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque,
+ gpgme_status_code_t status,
+ const char *args, int fd);
+
+gpgme_error_t gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
+ gpgme_edit_cb_t fnc, void *fnc_value,
+ gpgme_data_t out) _GPGME_DEPRECATED(1,7);
+gpgme_error_t gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
+ gpgme_edit_cb_t fnc, void *fnc_value,
+ gpgme_data_t out) _GPGME_DEPRECATED(1,7);
+gpgme_error_t gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
+ gpgme_edit_cb_t fnc, void *fnc_value,
+ gpgme_data_t out)
+ _GPGME_DEPRECATED(1,7);
+gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
+ gpgme_edit_cb_t fnc, void *fnc_value,
+ gpgme_data_t out)
+ _GPGME_DEPRECATED(1,7);
+
+/* The possible signature stati. Deprecated, use error value in sig
+ status. */
+typedef enum
+ {
+ GPGME_SIG_STAT_NONE = 0,
+ GPGME_SIG_STAT_GOOD = 1,
+ GPGME_SIG_STAT_BAD = 2,
+ GPGME_SIG_STAT_NOKEY = 3,
+ GPGME_SIG_STAT_NOSIG = 4,
+ GPGME_SIG_STAT_ERROR = 5,
+ GPGME_SIG_STAT_DIFF = 6,
+ GPGME_SIG_STAT_GOOD_EXP = 7,
+ GPGME_SIG_STAT_GOOD_EXPKEY = 8
+ }
+_gpgme_sig_stat_t;
+typedef _gpgme_sig_stat_t gpgme_sig_stat_t _GPGME_DEPRECATED(0,4);
+
+/* The available key and signature attributes. Deprecated, use the
+ individual result structures instead. */
+typedef enum
+ {
+ GPGME_ATTR_KEYID = 1,
+ GPGME_ATTR_FPR = 2,
+ GPGME_ATTR_ALGO = 3,
+ GPGME_ATTR_LEN = 4,
+ GPGME_ATTR_CREATED = 5,
+ GPGME_ATTR_EXPIRE = 6,
+ GPGME_ATTR_OTRUST = 7,
+ GPGME_ATTR_USERID = 8,
+ GPGME_ATTR_NAME = 9,
+ GPGME_ATTR_EMAIL = 10,
+ GPGME_ATTR_COMMENT = 11,
+ GPGME_ATTR_VALIDITY = 12,
+ GPGME_ATTR_LEVEL = 13,
+ GPGME_ATTR_TYPE = 14,
+ GPGME_ATTR_IS_SECRET = 15,
+ GPGME_ATTR_KEY_REVOKED = 16,
+ GPGME_ATTR_KEY_INVALID = 17,
+ GPGME_ATTR_UID_REVOKED = 18,
+ GPGME_ATTR_UID_INVALID = 19,
+ GPGME_ATTR_KEY_CAPS = 20,
+ GPGME_ATTR_CAN_ENCRYPT = 21,
+ GPGME_ATTR_CAN_SIGN = 22,
+ GPGME_ATTR_CAN_CERTIFY = 23,
+ GPGME_ATTR_KEY_EXPIRED = 24,
+ GPGME_ATTR_KEY_DISABLED = 25,
+ GPGME_ATTR_SERIAL = 26,
+ GPGME_ATTR_ISSUER = 27,
+ GPGME_ATTR_CHAINID = 28,
+ GPGME_ATTR_SIG_STATUS = 29,
+ GPGME_ATTR_ERRTOK = 30,
+ GPGME_ATTR_SIG_SUMMARY = 31,
+ GPGME_ATTR_SIG_CLASS = 32
+ }
+_gpgme_attr_t;
+typedef _gpgme_attr_t gpgme_attr_t _GPGME_DEPRECATED(0,4);
+
+/* Retrieve the signature status of signature IDX in CTX after a
+ successful verify operation in R_STAT (if non-null). The creation
+ time stamp of the signature is returned in R_CREATED (if non-null).
+ The function returns a string containing the fingerprint.
+ Deprecated, use verify result directly. */
+const char *gpgme_get_sig_status (gpgme_ctx_t ctx, int idx,
+ _gpgme_sig_stat_t *r_stat,
+ time_t *r_created) _GPGME_DEPRECATED(0,4);
+
+/* Retrieve certain attributes of a signature. IDX is the index
+ number of the signature after a successful verify operation. WHAT
+ is an attribute where GPGME_ATTR_EXPIRE is probably the most useful
+ one. WHATIDX is to be passed as 0 for most attributes . */
+unsigned long gpgme_get_sig_ulong_attr (gpgme_ctx_t c, int idx,
+ _gpgme_attr_t what, int whatidx)
+ _GPGME_DEPRECATED(0,4);
+const char *gpgme_get_sig_string_attr (gpgme_ctx_t c, int idx,
+ _gpgme_attr_t what, int whatidx)
+ _GPGME_DEPRECATED(0,4);
+
+
+/* Get the key used to create signature IDX in CTX and return it in
+ R_KEY. */
+gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key)
+ _GPGME_DEPRECATED(0,4);
+
+/* Create a new data buffer which retrieves the data from the callback
+ function READ_CB. Deprecated, please use gpgme_data_new_from_cbs
+ instead. */
+gpgme_error_t gpgme_data_new_with_read_cb (gpgme_data_t *r_dh,
+ int (*read_cb) (void*,char *,
+ size_t,size_t*),
+ void *read_cb_value)
+ _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of KEY, which has to be
+ representable by a string. IDX specifies the sub key or user ID
+ for attributes related to sub keys or user IDs. Deprecated, use
+ key structure directly instead. */
+const char *gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of KEY, which has to be
+ representable by an unsigned integer. IDX specifies the sub key or
+ user ID for attributes related to sub keys or user IDs.
+ Deprecated, use key structure directly instead. */
+unsigned long gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of a signature on user ID
+ UID_IDX in KEY, which has to be representable by a string. IDX
+ specifies the signature. Deprecated, use key structure directly
+ instead. */
+const char *gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx,
+ _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of a signature on user ID
+ UID_IDX in KEY, which has to be representable by an unsigned
+ integer string. IDX specifies the signature. Deprecated, use key
+ structure directly instead. */
+unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx,
+ _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+
+gpgme_error_t gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata,
+ int *nr) _GPGME_DEPRECATED(0,4);
+
+/* Release the trust item ITEM. Deprecated, use
+ gpgme_trust_item_unref. */
+void gpgme_trust_item_release (gpgme_trust_item_t item) _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of ITEM, which has to be
+ representable by a string. Deprecated, use trust item structure
+ directly. */
+const char *gpgme_trust_item_get_string_attr (gpgme_trust_item_t item,
+ _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of KEY, which has to be
+ representable by an integer. IDX specifies a running index if the
+ attribute appears more than once in the key. Deprecated, use trust
+ item structure directly. */
+int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+/* Compat.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
+struct _gpgme_op_assuan_result
+{
+ /* Deprecated. Use the second value in a DONE event or the
+ synchronous variant gpgme_op_assuan_transact_ext. */
+ gpgme_error_t err _GPGME_DEPRECATED_OUTSIDE_GPGME(1,2);
+};
+typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t;
+
+
+/* Return the result of the last Assuan command. */
+gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx)
+ _GPGME_DEPRECATED(1,2);
+
+gpgme_error_t
+gpgme_op_assuan_transact (gpgme_ctx_t ctx,
+ const char *command,
+ gpgme_assuan_data_cb_t data_cb,
+ void *data_cb_value,
+ gpgme_assuan_inquire_cb_t inq_cb,
+ void *inq_cb_value,
+ gpgme_assuan_status_cb_t status_cb,
+ void *status_cb_value) _GPGME_DEPRECATED(1,2);
+
+
+
typedef gpgme_ctx_t GpgmeCtx _GPGME_DEPRECATED(0,4);
typedef gpgme_data_t GpgmeData _GPGME_DEPRECATED(0,4);
typedef gpgme_error_t GpgmeError _GPGME_DEPRECATED(0,4);
diff --git a/src/import.c b/src/import.c
index 6233a15..4173fe9 100644
--- a/src/import.c
+++ b/src/import.c
@@ -193,7 +193,7 @@ parse_import_res (char *args, gpgme_import_result_t result)
#define PARSE_NEXT(x) \
(x) = strtol (args, &tail, 0); \
- if (errno || args == tail || *tail != ' ') \
+ if (errno || args == tail || !(*tail == ' ' || !*tail)) \
/* The crypto backend does not behave. */ \
return trace_gpg_error (GPG_ERR_INV_ENGINE); \
args = tail;
@@ -249,7 +249,7 @@ import_status_handler (void *priv, gpgme_status_code_t code, char *args)
default:
break;
}
- return 0;
+ return err;
}
diff --git a/src/key.c b/src/key.c
index 38acc71..e2e30db 100644
--- a/src/key.c
+++ b/src/key.c
@@ -236,11 +236,13 @@ _gpgme_key_append_name (gpgme_key_t key, const char *src, int convert)
&uid->comment, dst);
uid->address = _gpgme_mailbox_from_userid (uid->uid);
- if (uid->address && uid->email && !strcmp (uid->address, uid->email))
+ if ((!uid->email || !*uid->email) && uid->address && uid->name
+ && !strcmp (uid->name, uid->address))
{
- /* The ADDRESS is the same as EMAIL: Save some space. */
- free (uid->address);
- uid->address = uid->email;
+ /* Name and address are the same. This is a mailbox only key.
+ Use address as email and remove name. */
+ *uid->name = '\0';
+ uid->email = uid->address;
}
if (!key->uids)
@@ -339,14 +341,10 @@ gpgme_key_unref (gpgme_key_t key)
while (subkey)
{
gpgme_subkey_t next = subkey->next;
- if (subkey->fpr)
- free (subkey->fpr);
- if (subkey->curve)
- free (subkey->curve);
- if (subkey->keygrip)
- free (subkey->keygrip);
- if (subkey->card_number)
- free (subkey->card_number);
+ free (subkey->fpr);
+ free (subkey->curve);
+ free (subkey->keygrip);
+ free (subkey->card_number);
free (subkey);
subkey = next;
}
@@ -386,22 +384,15 @@ gpgme_key_unref (gpgme_key_t key)
tofu = tofu_next;
}
- if (uid->address && uid->address != uid->email)
- free (uid->address);
-
+ free (uid->address);
free (uid);
uid = next_uid;
}
- if (key->issuer_serial)
- free (key->issuer_serial);
- if (key->issuer_name)
- free (key->issuer_name);
-
- if (key->chain_id)
- free (key->chain_id);
- if (key->fpr)
- free (key->fpr);
+ free (key->issuer_serial);
+ free (key->issuer_name);
+ free (key->chain_id);
+ free (key->fpr);
free (key);
}
diff --git a/src/keylist.c b/src/keylist.c
index 2ce0846..e16ba4d 100644
--- a/src/keylist.c
+++ b/src/keylist.c
@@ -416,6 +416,23 @@ parse_sec_field15 (gpgme_key_t key, gpgme_subkey_t subkey, char *field)
}
+/* Parse the compliance field. */
+static void
+parse_pub_field18 (gpgme_subkey_t subkey, char *field)
+{
+ char *p, *endp;
+ unsigned long ul;
+
+ for (p = field; p && (ul = strtoul (p, &endp, 10)) && p != endp; p = endp)
+ {
+ switch (ul)
+ {
+ case 23: subkey->is_de_vs = 1; break;
+ }
+ }
+}
+
+
/* Parse a tfs record. */
static gpg_error_t
parse_tfs_record (gpgme_user_id_t uid, char **field, int nfield)
@@ -535,7 +552,7 @@ keylist_colon_handler (void *priv, char *line)
RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
}
rectype = RT_NONE;
-#define NR_FIELDS 17
+#define NR_FIELDS 20
char *field[NR_FIELDS];
int fields = 0;
void *hook;
@@ -712,6 +729,16 @@ keylist_colon_handler (void *priv, char *line)
return gpg_error_from_syserror ();
}
+ /* Field 18 has the compliance flags. */
+ if (fields >= 17 && *field[17])
+ parse_pub_field18 (subkey, field[17]);
+
+ if (fields >= 20)
+ {
+ key->last_update = _gpgme_parse_timestamp_ul (field[18]);
+ key->origin = 0; /* Fixme: Not yet defined in gpg. */
+ }
+
break;
case RT_SUB:
@@ -785,6 +812,10 @@ keylist_colon_handler (void *priv, char *line)
return gpg_error_from_syserror ();
}
+ /* Field 18 has the compliance flags. */
+ if (fields >= 17 && *field[17])
+ parse_pub_field18 (subkey, field[17]);
+
break;
case RT_UID:
@@ -793,12 +824,15 @@ keylist_colon_handler (void *priv, char *line)
{
if (_gpgme_key_append_name (key, field[9], 1))
return gpg_error (GPG_ERR_ENOMEM); /* FIXME */
- else
- {
- if (field[1])
- set_userid_flags (key, field[1]);
- opd->tmp_uid = key->_last_uid;
- }
+
+ if (field[1])
+ set_userid_flags (key, field[1]);
+ opd->tmp_uid = key->_last_uid;
+ if (fields >= 20)
+ {
+ opd->tmp_uid->last_update = _gpgme_parse_timestamp_ul (field[18]);
+ opd->tmp_uid->origin = 0; /* Fixme: Not yet defined in gpg. */
+ }
}
break;
@@ -1117,6 +1151,42 @@ gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
}
+/* Start a keylist operation within CTX to show keys contained
+ * in DATA. */
+gpgme_error_t
+gpgme_op_keylist_from_data_start (gpgme_ctx_t ctx, gpgme_data_t data,
+ int reserved)
+{
+ gpgme_error_t err;
+ void *hook;
+ op_data_t opd;
+
+ TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_from_data_start", ctx);
+
+ if (!ctx || !data || reserved)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ err = _gpgme_op_reset (ctx, 2);
+ if (err)
+ return TRACE_ERR (err);
+
+ err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
+ sizeof (*opd), release_op_data);
+ opd = hook;
+ if (err)
+ return TRACE_ERR (err);
+
+ _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
+ err = _gpgme_engine_set_colon_line_handler (ctx->engine,
+ keylist_colon_handler, ctx);
+ if (err)
+ return TRACE_ERR (err);
+
+ err = _gpgme_engine_op_keylist_data (ctx->engine, data);
+ return TRACE_ERR (err);
+}
+
+
/* Return the next key from the keylist in R_KEY. */
gpgme_error_t
gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index a55cd10..adc8d7d 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -126,6 +126,12 @@ GPGME_1.1 {
gpgme_op_query_swdb;
gpgme_op_query_swdb_result;
+
+ gpgme_op_set_uid_flag_start;
+ gpgme_op_set_uid_flag;
+
+ gpgme_op_decrypt_ext;
+ gpgme_op_decrypt_ext_start;
};
@@ -223,6 +229,7 @@ GPGME_1.0 {
gpgme_op_import_start;
gpgme_op_keylist_end;
gpgme_op_keylist_ext_start;
+ gpgme_op_keylist_from_data_start;
gpgme_op_keylist_next;
gpgme_op_keylist_result;
gpgme_op_keylist_start;
diff --git a/src/op-support.c b/src/op-support.c
index d9217ec..817c569 100644
--- a/src/op-support.c
+++ b/src/op-support.c
@@ -94,6 +94,7 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
_gpgme_release_result (ctx);
LOCK (ctx->lock);
ctx->canceled = 0;
+ ctx->redraw_suggested = 0;
UNLOCK (ctx->lock);
if (ctx->engine && no_reset)
diff --git a/src/ops.h b/src/ops.h
index 97b1019..cc61dc4 100644
--- a/src/ops.h
+++ b/src/ops.h
@@ -89,6 +89,9 @@ gpgme_error_t _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx);
gpgme_error_t _gpgme_decrypt_status_handler (void *priv,
gpgme_status_code_t code,
char *args);
+gpgme_error_t _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher, gpgme_data_t plain);
/* From signers.c. */
diff --git a/src/posix-io.c b/src/posix-io.c
index 5296f5f..a351806 100644
--- a/src/posix-io.c
+++ b/src/posix-io.c
@@ -287,37 +287,43 @@ get_max_fds (void)
int rc;
/* Under Linux we can figure out the highest used file descriptor by
- * reading /proc/self/fd. This is in the common cases much fast than
- * for example doing 4096 close calls where almost all of them will
- * fail. */
-#ifdef __linux__
- {
- DIR *dir = NULL;
- struct dirent *dir_entry;
- const char *s;
- int x;
-
- dir = opendir ("/proc/self/fd");
- if (dir)
- {
- while ((dir_entry = readdir (dir)))
- {
- s = dir_entry->d_name;
- if ( *s < '0' || *s > '9')
- continue;
- x = atoi (s);
- if (x > fds)
- fds = x;
- }
- closedir (dir);
- }
- if (fds != -1)
- {
- fds++;
- source = "/proc";
- }
- }
-#endif /* __linux__ */
+ * reading /proc/self/fd. This is in the common cases much faster
+ * than for example doing 4096 close calls where almost all of them
+ * will fail.
+ *
+ * Unfortunately we can't call opendir between fork and exec in a
+ * multi-threaded process because opendir uses malloc and thus a
+ * mutex which may deadlock with a malloc in another thread. Thus
+ * the code is not used until we can have a opendir variant which
+ * does not use malloc. */
+/* #ifdef __linux__ */
+/* { */
+/* DIR *dir = NULL; */
+/* struct dirent *dir_entry; */
+/* const char *s; */
+/* int x; */
+
+/* dir = opendir ("/proc/self/fd"); */
+/* if (dir) */
+/* { */
+/* while ((dir_entry = readdir (dir))) */
+/* { */
+/* s = dir_entry->d_name; */
+/* if ( *s < '0' || *s > '9') */
+/* continue; */
+/* x = atoi (s); */
+/* if (x > fds) */
+/* fds = x; */
+/* } */
+/* closedir (dir); */
+/* } */
+/* if (fds != -1) */
+/* { */
+/* fds++; */
+/* source = "/proc"; */
+/* } */
+/* } */
+/* #endif /\* __linux__ *\/ */
#ifdef RLIMIT_NOFILE
if (fds == -1)
@@ -453,10 +459,9 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
/* Intermediate child to prevent zombie processes. */
if ((pid = fork ()) == 0)
{
- int max_fds = get_max_fds ();
- int fd;
-
/* Child. */
+ int max_fds = -1;
+ int fd;
int seen_stdin = 0;
int seen_stdout = 0;
int seen_stderr = 0;
@@ -464,15 +469,40 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
if (atfork)
atfork (atforkvalue, 0);
- /* First close all fds which will not be inherited. */
- for (fd = 0; fd < max_fds; fd++)
- {
- for (i = 0; fd_list[i].fd != -1; i++)
- if (fd_list[i].fd == fd)
- break;
- if (fd_list[i].fd == -1)
- close (fd);
- }
+ /* First close all fds which will not be inherited. If we
+ * have closefrom(2) we first figure out the highest fd we
+ * do not want to close, then call closefrom, and on success
+ * use the regular code to close all fds up to the start
+ * point of closefrom. Note that Solaris' closefrom does
+ * not return errors. */
+#ifdef HAVE_CLOSEFROM
+ {
+ fd = -1;
+ for (i = 0; fd_list[i].fd != -1; i++)
+ if (fd_list[i].fd > fd)
+ fd = fd_list[i].fd;
+ fd++;
+#ifdef __sun
+ closefrom (fd);
+ max_fds = fd;
+#else /*!__sun */
+ while ((i = closefrom (fd)) && errno == EINTR)
+ ;
+ if (!i || errno == EBADF)
+ max_fds = fd;
+#endif /*!__sun*/
+ }
+#endif /*HAVE_CLOSEFROM*/
+ if (max_fds == -1)
+ max_fds = get_max_fds ();
+ for (fd = 0; fd < max_fds; fd++)
+ {
+ for (i = 0; fd_list[i].fd != -1; i++)
+ if (fd_list[i].fd == fd)
+ break;
+ if (fd_list[i].fd == -1)
+ close (fd);
+ }
/* And now dup and close those to be duplicated. */
for (i = 0; fd_list[i].fd != -1; i++)
diff --git a/src/progress.c b/src/progress.c
index c10ccaa..066a7f5 100644
--- a/src/progress.c
+++ b/src/progress.c
@@ -31,6 +31,8 @@
#include "debug.h"
+/* The status handler for progress status lines which also monitors
+ * the PINENTRY_LAUNCHED status. */
gpgme_error_t
_gpgme_progress_status_handler (void *priv, gpgme_status_code_t code,
char *args)
@@ -42,6 +44,12 @@ _gpgme_progress_status_handler (void *priv, gpgme_status_code_t code,
int current = 0;
int total = 0;
+ if (code == GPGME_STATUS_PINENTRY_LAUNCHED)
+ {
+ ctx->redraw_suggested = 1;
+ return 0;
+ }
+
if (code != GPGME_STATUS_PROGRESS || !*args || !ctx->progress_cb)
return 0;
diff --git a/src/util.h b/src/util.h
index a1be6e7..7b7924c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -95,11 +95,12 @@ _gpgme_stpcpy (char *a, const char *b)
#define stpcpy(a,b) _gpgme_stpcpy ((a), (b))
#endif /*!HAVE_STPCPY*/
-#if !HAVE_VASPRINTF
-#include <stdarg.h>
-int vasprintf (char **result, const char *format, va_list args);
-int asprintf (char **result, const char *format, ...);
-#endif
+
+/* Due to a bug in mingw32's snprintf related to the 'l' modifier and
+ for increased portability we use our snprintf on all systems. */
+#undef snprintf
+#define snprintf gpgrt_snprintf
+
#if REPLACE_TTYNAME_R
int _gpgme_ttyname_r (int fd, char *buf, size_t buflen);
@@ -164,6 +165,9 @@ gpgme_off_t _gpgme_string_to_off (const char *string);
point to the next non-parsed character in TIMESTRING. */
time_t _gpgme_parse_timestamp (const char *timestamp, char **endp);
+/* Variant of _gpgme_parse_timestamp to return an unsigned long or 0
+ * on error or missing timestamp. */
+unsigned long _gpgme_parse_timestamp_ul (const char *timestamp);
gpgme_error_t _gpgme_map_gnupg_error (char *err);
diff --git a/src/vasprintf.c b/src/vasprintf.c
deleted file mode 100644
index 4c40131..0000000
--- a/src/vasprintf.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/* Like vsprintf but provides a pointer to malloc'd storage, which must
- be freed by the caller.
- Copyright (C) 1994, 2002 Free Software Foundation, Inc.
-
-This file is part of the libiberty library.
-Libiberty is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-Libiberty is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with libiberty; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-
-#ifndef va_copy /* According to POSIX, va_copy is a macro. */
-#if defined (__GNUC__) && defined (__PPC__) \
- && (defined (_CALL_SYSV) || defined (_WIN32))
-#define va_copy(d, s) (*(d) = *(s))
-#elif defined (MUST_COPY_VA_BYVAL)
-#define va_copy(d, s) ((d) = (s))
-#else
-#define va_copy(d, s) memcpy ((d), (s), sizeof (va_list))
-#endif
-#endif
-
-
-#ifdef TEST
-int global_total_width;
-#endif
-
-static int int_vasprintf (char **, const char *, va_list *);
-
-static int
-int_vasprintf (result, format, args)
- char **result;
- const char *format;
- va_list *args;
-{
-#ifdef HAVE_W32CE_SYSTEM
- /* No va_copy and the replacement above doesn't work. */
-#define MAX_STRLEN 256
- *result = malloc (MAX_STRLEN);
- if (*result != NULL)
- {
- int res = _vsnprintf (*result, MAX_STRLEN, format, *args);
- (*result)[MAX_STRLEN - 1] = '\0';
- return res;
- }
- else
- return 0;
-#else
- const char *p = format;
- /* Add one to make sure that it is never zero, which might cause malloc
- to return NULL. */
- int total_width = strlen (format) + 1;
- va_list ap;
-
- va_copy (ap, *args);
-
- while (*p != '\0')
- {
- if (*p++ == '%')
- {
- while (strchr ("-+ #0", *p))
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- total_width += strtoul (p, (char **) &p, 10);
- if (*p == '.')
- {
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- total_width += strtoul (p, (char **) &p, 10);
- }
- while (strchr ("hlL", *p))
- ++p;
- /* Should be big enough for any format specifier except %s and floats. */
- total_width += 30;
- switch (*p)
- {
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- case 'c':
- (void) va_arg (ap, int);
- break;
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- (void) va_arg (ap, double);
- /* Since an ieee double can have an exponent of 307, we'll
- make the buffer wide enough to cover the gross case. */
- total_width += 307;
- break;
- case 's':
- {
- char *tmp = va_arg (ap, char *);
- if (tmp)
- total_width += strlen (tmp);
- else /* in case the vsprintf does prints a text */
- total_width += 25; /* e.g. "(null pointer reference)" */
- }
- break;
- case 'p':
- case 'n':
- (void) va_arg (ap, char *);
- break;
- }
- p++;
- }
- }
-#ifdef TEST
- global_total_width = total_width;
-#endif
- *result = malloc (total_width);
- if (*result != NULL)
- return vsprintf (*result, format, *args);
- else
- return 0;
-#endif
-}
-
-int
-vasprintf (result, format, args)
- char **result;
- const char *format;
-#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
- _BSD_VA_LIST_ args;
-#else
- va_list args;
-#endif
-{
- return int_vasprintf (result, format, &args);
-}
-
-
-int
-asprintf (char **buf, const char *fmt, ...)
-{
- int status;
- va_list ap;
-
- va_start (ap, fmt);
- status = vasprintf (buf, fmt, ap);
- va_end (ap);
- return status;
-}
-
-
-#ifdef TEST
-void
-checkit (const char* format, ...)
-{
- va_list args;
- char *result;
-
- va_start (args, format);
- vasprintf (&result, format, args);
- if (strlen (result) < global_total_width)
- printf ("PASS: ");
- else
- printf ("FAIL: ");
- printf ("%d %s\n", global_total_width, result);
-}
-
-int
-main (void)
-{
- checkit ("%d", 0x12345678);
- checkit ("%200d", 5);
- checkit ("%.300d", 6);
- checkit ("%100.150d", 7);
- checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
-777777777777777777333333333333366666666666622222222222777777777777733333");
- checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
-}
-#endif /* TEST */
diff --git a/src/verify.c b/src/verify.c
index faa8deb..900f925 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -46,6 +46,7 @@ typedef struct
int did_prepare_new_sig;
int only_newsig_seen;
int plaintext_seen;
+ int conflict_user_seen;
} *op_data_t;
@@ -680,6 +681,14 @@ parse_tofu_user (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol)
goto leave;
}
+ if (sig->key && sig->key->fpr && strcmp (sig->key->fpr, fpr))
+ {
+ /* GnuPG since 2.1.17 emits multiple TOFU_USER lines with
+ different fingerprints in case of conflicts for a signature. */
+ err = gpg_error (GPG_ERR_DUP_VALUE);
+ goto leave;
+ }
+
args = tail;
tail = strchr (args, ' ');
if (tail == args)
@@ -708,12 +717,6 @@ parse_tofu_user (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol)
err = trace_gpg_error (GPG_ERR_INTERNAL);
goto leave;
}
- else if (strcmp (sig->key->fpr, fpr))
- {
- /* The engine did not emit NEWSIG before a new key. */
- err = trace_gpg_error (GPG_ERR_INV_ENGINE);
- goto leave;
- }
err = _gpgme_key_append_name (sig->key, address, 0);
if (err)
@@ -930,6 +933,7 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
calc_sig_summary (sig);
err = prepare_new_sig (opd);
opd->only_newsig_seen = 1;
+ opd->conflict_user_seen = 0;
return err;
case GPGME_STATUS_GOODSIG:
@@ -995,16 +999,35 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
case GPGME_STATUS_TOFU_USER:
opd->only_newsig_seen = 0;
- return sig ? parse_tofu_user (sig, args, ctx->protocol)
- /* */ : trace_gpg_error (GPG_ERR_INV_ENGINE);
+ if (!sig)
+ return trace_gpg_error (GPG_ERR_INV_ENGINE);
+ err = parse_tofu_user (sig, args, ctx->protocol);
+ /* gpg emits TOFU User lines for each conflicting key.
+ * GPGME does not expose this to have a clean API and
+ * a GPGME user can do a keylisting with the address
+ * normalisation.
+ * So when a duplicated TOFU_USER line is encountered
+ * we ignore the conflicting tofu stats emited afterwards.
+ */
+ if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
+ {
+ opd->conflict_user_seen = 1;
+ break;
+ }
+ opd->conflict_user_seen = 0;
+ return trace_gpg_error (err);
case GPGME_STATUS_TOFU_STATS:
opd->only_newsig_seen = 0;
+ if (opd->conflict_user_seen)
+ break;
return sig ? parse_tofu_stats (sig, args)
/* */ : trace_gpg_error (GPG_ERR_INV_ENGINE);
case GPGME_STATUS_TOFU_STATS_LONG:
opd->only_newsig_seen = 0;
+ if (opd->conflict_user_seen)
+ break;
return sig ? parse_tofu_stats_long (sig, args, ctx->raw_description)
/* */ : trace_gpg_error (GPG_ERR_INV_ENGINE);
diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in
index 3ce38f0..2b1cc81 100644
--- a/src/versioninfo.rc.in
+++ b/src/versioninfo.rc.in
@@ -39,7 +39,7 @@ BEGIN
VALUE "FileDescription", "GPGME - GnuPG Made Easy\0"
VALUE "FileVersion", "@LIBGPGME_LT_CURRENT@.@LIBGPGME_LT_AGE@.@LIBGPGME_LT_REVISION@.@BUILD_REVISION@\0"
VALUE "InternalName", "gpgme\0"
- VALUE "LegalCopyright", "Copyright © 2001-2016 g10 Code GmbH\0"
+ VALUE "LegalCopyright", "Copyright © 2001-2017 g10 Code GmbH\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "gpgme.dll\0"
VALUE "PrivateBuild", "\0"
diff --git a/src/vfs-create.c b/src/vfs-create.c
index a01d4da..a3bec19 100644
--- a/src/vfs-create.c
+++ b/src/vfs-create.c
@@ -138,7 +138,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
}
- if (asprintf (&cmd, "RECIPIENT %s", recp[i]->subkeys->fpr) < 0)
+ if (gpgrt_asprintf (&cmd, "RECIPIENT %s", recp[i]->subkeys->fpr) < 0)
{
err = gpg_error_from_syserror ();
free (container_file_esc);
@@ -147,7 +147,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
NULL, NULL, op_err);
- free (cmd);
+ gpgrt_free (cmd);
if (err || *op_err)
{
free (container_file_esc);
@@ -156,7 +156,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
recp++;
}
- if (asprintf (&cmd, "CREATE -- %s", container_file_esc) < 0)
+ if (gpgrt_asprintf (&cmd, "CREATE -- %s", container_file_esc) < 0)
{
err = gpg_error_from_syserror ();
free (container_file_esc);
@@ -166,7 +166,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
NULL, NULL, op_err);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
diff --git a/src/vfs-mount.c b/src/vfs-mount.c
index 5d2f2a9..68a8efe 100644
--- a/src/vfs-mount.c
+++ b/src/vfs-mount.c
@@ -184,7 +184,7 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
if (err)
return err;
- if (asprintf (&cmd, "OPEN -- %s", container_file_esc) < 0)
+ if (gpgrt_asprintf (&cmd, "OPEN -- %s", container_file_esc) < 0)
{
err = gpg_error_from_syserror ();
free (container_file_esc);
@@ -194,7 +194,7 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
NULL, NULL, op_err);
- free (cmd);
+ gpgrt_free (cmd);
if (err || *op_err)
return err;
@@ -206,7 +206,7 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
if (err)
return err;
- if (asprintf (&cmd, "MOUNT -- %s", mount_dir_esc) < 0)
+ if (gpgrt_asprintf (&cmd, "MOUNT -- %s", mount_dir_esc) < 0)
{
err = gpg_error_from_syserror ();
free (mount_dir_esc);
@@ -216,13 +216,13 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
}
else
{
- if (asprintf (&cmd, "MOUNT") < 0)
+ if (gpgrt_asprintf (&cmd, "MOUNT") < 0)
return gpg_error_from_syserror ();
}
err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
_gpgme_vfs_mount_status_handler, ctx, op_err);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
diff --git a/src/w32-io.c b/src/w32-io.c
index 0d1c810..eed8a00 100644
--- a/src/w32-io.c
+++ b/src/w32-io.c
@@ -700,7 +700,7 @@ writer (void *arg)
for (;;)
{
LOCK (ctx->mutex);
- if (ctx->stop_me)
+ if (ctx->stop_me && !ctx->nbytes)
{
UNLOCK (ctx->mutex);
break;
@@ -717,7 +717,7 @@ writer (void *arg)
TRACE_LOG ("got data to send");
LOCK (ctx->mutex);
}
- if (ctx->stop_me)
+ if (ctx->stop_me && !ctx->nbytes)
{
UNLOCK (ctx->mutex);
break;
@@ -776,6 +776,9 @@ writer (void *arg)
TRACE_LOG ("waiting for close");
WaitForSingleObject (ctx->close_ev, INFINITE);
+ if (ctx->nbytes)
+ TRACE_LOG1 ("still %d bytes in buffer at close time", ctx->nbytes);
+
CloseHandle (ctx->close_ev);
CloseHandle (ctx->have_data);
CloseHandle (ctx->is_empty);
@@ -892,6 +895,9 @@ destroy_writer (struct writer_context_s *ctx)
SetEvent (ctx->have_data);
UNLOCK (ctx->mutex);
+ /* Give the writer a chance to flush the buffer. */
+ WaitForSingleObject (ctx->is_empty, INFINITE);
+
#ifdef HAVE_W32CE_SYSTEM
/* Scenario: We never create a full pipe, but already started
writing more than the pipe buffer. Then we need to unblock the
@@ -1637,11 +1643,11 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
"with your installation.\n"
"Please report the problem to your "
"distributor of GpgME.\n\n"
- "Developers Note: The install dir can be "
+ "Developer's Note: The install dir can be "
"manually set with: gpgme_set_global_flag",
_gpgme_get_inst_dir ());
MessageBoxA (NULL, msg, "GpgME not installed correctly", MB_OK);
- free (msg);
+ gpgrt_free (msg);
gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1);
}
diff --git a/src/w32-util.c b/src/w32-util.c
index ad36c9a..5b02c7e 100644
--- a/src/w32-util.c
+++ b/src/w32-util.c
@@ -577,9 +577,10 @@ _gpgme_get_gpgconf_path (void)
"Install Directory");
if (tmp)
{
- if (gpgrt_asprintf (&dir, "%s\\bin", tmp) == -1)
- return NULL;
+ dir = _gpgme_strconcat (tmp, "\\bin", NULL);
free (tmp);
+ if (!dir)
+ return NULL;
}
}
if (dir)