summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTizenOpenSource <tizenopensrc@samsung.com>2023-12-07 17:15:13 +0900
committerTizenOpenSource <tizenopensrc@samsung.com>2023-12-07 17:15:13 +0900
commit10be0aded0e820e3343e1f2ad7a6cacb60702ecc (patch)
tree80cbac1ef3109d820f7ea2ae7ba5f55a9cbbba55 /src
parent73f75b48c0470a46b31340f5cc9e5219d6ee0faa (diff)
downloadgpgme-upstream.tar.gz
gpgme-upstream.tar.bz2
gpgme-upstream.zip
Imported Upstream version 1.23.1upstream/1.23.1upstream
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile.in101
-rw-r--r--src/argparse.c2
-rw-r--r--src/assuan-support.c2
-rw-r--r--src/context.h3
-rw-r--r--src/conversion.c4
-rw-r--r--src/data-identify.c50
-rw-r--r--src/data.c4
-rw-r--r--src/data.h4
-rw-r--r--src/debug.c162
-rw-r--r--src/debug.h2
-rw-r--r--src/decrypt-verify.c10
-rw-r--r--src/dirinfo.c65
-rw-r--r--src/edit.c7
-rw-r--r--src/engine-backend.h14
-rw-r--r--src/engine-gpg.c842
-rw-r--r--src/engine-gpgsm.c133
-rw-r--r--src/engine-uiserver.c18
-rw-r--r--src/engine.c24
-rw-r--r--src/engine.h15
-rw-r--r--src/export.c15
-rw-r--r--src/gpgme-json.c127
-rw-r--r--src/gpgme-tool.c14
-rw-r--r--src/gpgme-w32spawn.c117
-rw-r--r--src/gpgme.c13
-rw-r--r--src/gpgme.def2
-rw-r--r--src/gpgme.h.in59
-rw-r--r--src/gpgme.m4146
-rw-r--r--src/gpgme.pc.in4
-rw-r--r--src/import.c15
-rw-r--r--src/key.c1
-rw-r--r--src/keylist.c91
-rw-r--r--src/libgpgme.vers3
-rw-r--r--src/parsetlv.c3
-rw-r--r--src/posix-util.c12
-rw-r--r--src/sign.c32
-rw-r--r--src/sys-util.h1
-rw-r--r--src/trustlist.c2
-rw-r--r--src/util.h9
-rw-r--r--src/verify.c51
-rw-r--r--src/version.c7
-rw-r--r--src/versioninfo.rc.in2
-rw-r--r--src/w32-glib-io.c2
-rw-r--r--src/w32-io.c10
-rw-r--r--src/w32-util.c133
45 files changed, 1664 insertions, 671 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 67805a8..ca70950 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -120,6 +120,8 @@ if HAVE_W32_SYSTEM
# wrapper process.
libexec_PROGRAMS = gpgme-w32spawn
+gpgme_w32spawn_CFLAGS = -municode
+
RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE)
diff --git a/src/Makefile.in b/src/Makefile.in
index 88c5835..404f544 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -115,7 +115,8 @@ bin_PROGRAMS = gpgme-tool$(EXEEXT) gpgme-json$(EXEEXT)
@HAVE_W32_SYSTEM_TRUE@libexec_PROGRAMS = gpgme-w32spawn$(EXEEXT)
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
@@ -125,8 +126,9 @@ 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/python.m4 $(top_srcdir)/m4/qt.m4 \
- $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt5.m4 \
+ $(top_srcdir)/m4/qt6.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
@@ -247,8 +249,12 @@ am_gpgme_tool_OBJECTS = gpgme-tool.$(OBJEXT) argparse.$(OBJEXT)
gpgme_tool_OBJECTS = $(am_gpgme_tool_OBJECTS)
gpgme_tool_DEPENDENCIES = libgpgme.la
gpgme_w32spawn_SOURCES = gpgme-w32spawn.c
-gpgme_w32spawn_OBJECTS = gpgme-w32spawn.$(OBJEXT)
+gpgme_w32spawn_OBJECTS = gpgme_w32spawn-gpgme-w32spawn.$(OBJEXT)
gpgme_w32spawn_LDADD = $(LDADD)
+gpgme_w32spawn_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(gpgme_w32spawn_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \
+ $@
SCRIPTS = $(bin_SCRIPTS) $(noinst_SCRIPTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -285,25 +291,26 @@ am__depfiles_remade = $(DEPDIR)/setenv.Plo $(DEPDIR)/stpcpy.Plo \
./$(DEPDIR)/export.Plo ./$(DEPDIR)/genkey.Plo \
./$(DEPDIR)/get-env.Plo ./$(DEPDIR)/getauditlog.Plo \
./$(DEPDIR)/gpgconf.Plo ./$(DEPDIR)/gpgme-json.Po \
- ./$(DEPDIR)/gpgme-tool.Po ./$(DEPDIR)/gpgme-w32spawn.Po \
- ./$(DEPDIR)/gpgme.Plo ./$(DEPDIR)/import.Plo \
- ./$(DEPDIR)/key.Plo ./$(DEPDIR)/keylist.Plo \
- ./$(DEPDIR)/keysign.Plo ./$(DEPDIR)/mbox-util.Plo \
- ./$(DEPDIR)/op-support.Plo ./$(DEPDIR)/opassuan.Plo \
- ./$(DEPDIR)/parsetlv.Plo ./$(DEPDIR)/passphrase.Plo \
- ./$(DEPDIR)/passwd.Plo ./$(DEPDIR)/posix-io.Plo \
- ./$(DEPDIR)/posix-util.Plo ./$(DEPDIR)/progress.Plo \
- ./$(DEPDIR)/queryswdb.Plo ./$(DEPDIR)/revsig.Plo \
- ./$(DEPDIR)/setexpire.Plo ./$(DEPDIR)/sig-notation.Plo \
- ./$(DEPDIR)/sign.Plo ./$(DEPDIR)/signers.Plo \
- ./$(DEPDIR)/spawn.Plo ./$(DEPDIR)/status-table.Plo \
- ./$(DEPDIR)/tofupolicy.Plo ./$(DEPDIR)/trust-item.Plo \
- ./$(DEPDIR)/trustlist.Plo ./$(DEPDIR)/verify.Plo \
- ./$(DEPDIR)/version.Plo ./$(DEPDIR)/vfs-create.Plo \
- ./$(DEPDIR)/vfs-mount.Plo ./$(DEPDIR)/w32-glib-io.Plo \
- ./$(DEPDIR)/w32-io.Plo ./$(DEPDIR)/w32-util.Plo \
- ./$(DEPDIR)/wait-global.Plo ./$(DEPDIR)/wait-private.Plo \
- ./$(DEPDIR)/wait-user.Plo ./$(DEPDIR)/wait.Plo
+ ./$(DEPDIR)/gpgme-tool.Po ./$(DEPDIR)/gpgme.Plo \
+ ./$(DEPDIR)/gpgme_w32spawn-gpgme-w32spawn.Po \
+ ./$(DEPDIR)/import.Plo ./$(DEPDIR)/key.Plo \
+ ./$(DEPDIR)/keylist.Plo ./$(DEPDIR)/keysign.Plo \
+ ./$(DEPDIR)/mbox-util.Plo ./$(DEPDIR)/op-support.Plo \
+ ./$(DEPDIR)/opassuan.Plo ./$(DEPDIR)/parsetlv.Plo \
+ ./$(DEPDIR)/passphrase.Plo ./$(DEPDIR)/passwd.Plo \
+ ./$(DEPDIR)/posix-io.Plo ./$(DEPDIR)/posix-util.Plo \
+ ./$(DEPDIR)/progress.Plo ./$(DEPDIR)/queryswdb.Plo \
+ ./$(DEPDIR)/revsig.Plo ./$(DEPDIR)/setexpire.Plo \
+ ./$(DEPDIR)/sig-notation.Plo ./$(DEPDIR)/sign.Plo \
+ ./$(DEPDIR)/signers.Plo ./$(DEPDIR)/spawn.Plo \
+ ./$(DEPDIR)/status-table.Plo ./$(DEPDIR)/tofupolicy.Plo \
+ ./$(DEPDIR)/trust-item.Plo ./$(DEPDIR)/trustlist.Plo \
+ ./$(DEPDIR)/verify.Plo ./$(DEPDIR)/version.Plo \
+ ./$(DEPDIR)/vfs-create.Plo ./$(DEPDIR)/vfs-mount.Plo \
+ ./$(DEPDIR)/w32-glib-io.Plo ./$(DEPDIR)/w32-io.Plo \
+ ./$(DEPDIR)/w32-util.Plo ./$(DEPDIR)/wait-global.Plo \
+ ./$(DEPDIR)/wait-private.Plo ./$(DEPDIR)/wait-user.Plo \
+ ./$(DEPDIR)/wait.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -352,8 +359,6 @@ am__define_uniq_tagged_files = \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/gpgme-config.in \
$(srcdir)/gpgme-glib.pc.in $(srcdir)/gpgme.h.in \
$(srcdir)/gpgme.pc.in $(srcdir)/versioninfo.rc.in \
@@ -380,6 +385,8 @@ CC_FOR_BUILD = @CC_FOR_BUILD@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
@@ -396,6 +403,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLED_LANGUAGES = @ENABLED_LANGUAGES@
+ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GITLOG_TO_CHANGELOG = @GITLOG_TO_CHANGELOG@
@@ -411,10 +419,14 @@ GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
-GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
-GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
-GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
-GPGME_QT_LIBS = @GPGME_QT_LIBS@
+GPGME_QT5TEST_CFLAGS = @GPGME_QT5TEST_CFLAGS@
+GPGME_QT5TEST_LIBS = @GPGME_QT5TEST_LIBS@
+GPGME_QT5_CFLAGS = @GPGME_QT5_CFLAGS@
+GPGME_QT5_LIBS = @GPGME_QT5_LIBS@
+GPGME_QT6TEST_CFLAGS = @GPGME_QT6TEST_CFLAGS@
+GPGME_QT6TEST_LIBS = @GPGME_QT6TEST_LIBS@
+GPGME_QT6_CFLAGS = @GPGME_QT6_CFLAGS@
+GPGME_QT6_LIBS = @GPGME_QT6_LIBS@
GPGRT_CONFIG = @GPGRT_CONFIG@
GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
@@ -424,6 +436,7 @@ GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
GRAPHVIZ = @GRAPHVIZ@
GREP = @GREP@
HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX17 = @HAVE_CXX17@
HAVE_DOT = @HAVE_DOT@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@@ -625,6 +638,7 @@ gpgme_tool_SOURCES = gpgme-tool.c argparse.c argparse.h
gpgme_tool_LDADD = libgpgme.la @LIBASSUAN_LIBS@ @GPG_ERROR_LIBS@
gpgme_json_SOURCES = gpgme-json.c cJSON.c cJSON.h
gpgme_json_LDADD = -lm libgpgme.la $(GPG_ERROR_LIBS)
+@HAVE_W32_SYSTEM_TRUE@gpgme_w32spawn_CFLAGS = -municode
@HAVE_W32_SYSTEM_TRUE@RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
@HAVE_W32_SYSTEM_TRUE@LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE)
@HAVE_W32_SYSTEM_TRUE@SUFFIXES = .rc .lo
@@ -851,7 +865,7 @@ gpgme-tool$(EXEEXT): $(gpgme_tool_OBJECTS) $(gpgme_tool_DEPENDENCIES) $(EXTRA_gp
gpgme-w32spawn$(EXEEXT): $(gpgme_w32spawn_OBJECTS) $(gpgme_w32spawn_DEPENDENCIES) $(EXTRA_gpgme_w32spawn_DEPENDENCIES)
@rm -f gpgme-w32spawn$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(gpgme_w32spawn_OBJECTS) $(gpgme_w32spawn_LDADD) $(LIBS)
+ $(AM_V_CCLD)$(gpgme_w32spawn_LINK) $(gpgme_w32spawn_OBJECTS) $(gpgme_w32spawn_LDADD) $(LIBS)
install-binSCRIPTS: $(bin_SCRIPTS)
@$(NORMAL_INSTALL)
@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
@@ -935,8 +949,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgconf.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgme-json.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgme-tool.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgme-w32spawn.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgme.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgme_w32spawn-gpgme-w32spawn.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/import.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/key.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keylist.Plo@am__quote@ # am--include-marker
@@ -1000,6 +1014,20 @@ am--depfiles: $(am__depfiles_remade)
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+gpgme_w32spawn-gpgme-w32spawn.o: gpgme-w32spawn.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpgme_w32spawn_CFLAGS) $(CFLAGS) -MT gpgme_w32spawn-gpgme-w32spawn.o -MD -MP -MF $(DEPDIR)/gpgme_w32spawn-gpgme-w32spawn.Tpo -c -o gpgme_w32spawn-gpgme-w32spawn.o `test -f 'gpgme-w32spawn.c' || echo '$(srcdir)/'`gpgme-w32spawn.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gpgme_w32spawn-gpgme-w32spawn.Tpo $(DEPDIR)/gpgme_w32spawn-gpgme-w32spawn.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gpgme-w32spawn.c' object='gpgme_w32spawn-gpgme-w32spawn.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpgme_w32spawn_CFLAGS) $(CFLAGS) -c -o gpgme_w32spawn-gpgme-w32spawn.o `test -f 'gpgme-w32spawn.c' || echo '$(srcdir)/'`gpgme-w32spawn.c
+
+gpgme_w32spawn-gpgme-w32spawn.obj: gpgme-w32spawn.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpgme_w32spawn_CFLAGS) $(CFLAGS) -MT gpgme_w32spawn-gpgme-w32spawn.obj -MD -MP -MF $(DEPDIR)/gpgme_w32spawn-gpgme-w32spawn.Tpo -c -o gpgme_w32spawn-gpgme-w32spawn.obj `if test -f 'gpgme-w32spawn.c'; then $(CYGPATH_W) 'gpgme-w32spawn.c'; else $(CYGPATH_W) '$(srcdir)/gpgme-w32spawn.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gpgme_w32spawn-gpgme-w32spawn.Tpo $(DEPDIR)/gpgme_w32spawn-gpgme-w32spawn.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gpgme-w32spawn.c' object='gpgme_w32spawn-gpgme-w32spawn.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpgme_w32spawn_CFLAGS) $(CFLAGS) -c -o gpgme_w32spawn-gpgme-w32spawn.obj `if test -f 'gpgme-w32spawn.c'; then $(CYGPATH_W) 'gpgme-w32spawn.c'; else $(CYGPATH_W) '$(srcdir)/gpgme-w32spawn.c'; fi`
+
mostlyclean-libtool:
-rm -f *.lo
@@ -1120,7 +1148,6 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -1160,6 +1187,8 @@ all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(SCRIPTS) $(DATA) \
$(HEADERS)
install-binPROGRAMS: install-libLTLIBRARIES
+install-libexecPROGRAMS: install-libLTLIBRARIES
+
installdirs:
for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
@@ -1241,8 +1270,8 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/gpgconf.Plo
-rm -f ./$(DEPDIR)/gpgme-json.Po
-rm -f ./$(DEPDIR)/gpgme-tool.Po
- -rm -f ./$(DEPDIR)/gpgme-w32spawn.Po
-rm -f ./$(DEPDIR)/gpgme.Plo
+ -rm -f ./$(DEPDIR)/gpgme_w32spawn-gpgme-w32spawn.Po
-rm -f ./$(DEPDIR)/import.Plo
-rm -f ./$(DEPDIR)/key.Plo
-rm -f ./$(DEPDIR)/keylist.Plo
@@ -1366,8 +1395,8 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/gpgconf.Plo
-rm -f ./$(DEPDIR)/gpgme-json.Po
-rm -f ./$(DEPDIR)/gpgme-tool.Po
- -rm -f ./$(DEPDIR)/gpgme-w32spawn.Po
-rm -f ./$(DEPDIR)/gpgme.Plo
+ -rm -f ./$(DEPDIR)/gpgme_w32spawn-gpgme-w32spawn.Po
-rm -f ./$(DEPDIR)/import.Plo
-rm -f ./$(DEPDIR)/key.Plo
-rm -f ./$(DEPDIR)/keylist.Plo
diff --git a/src/argparse.c b/src/argparse.c
index fcefbba..03c96fe 100644
--- a/src/argparse.c
+++ b/src/argparse.c
@@ -1388,7 +1388,7 @@ show_help (ARGPARSE_OPTS *opts, unsigned int flags)
}
static void
-show_version ()
+show_version (void)
{
const char *s;
int i;
diff --git a/src/assuan-support.c b/src/assuan-support.c
index 0bc003b..c605219 100644
--- a/src/assuan-support.c
+++ b/src/assuan-support.c
@@ -371,7 +371,7 @@ my_connect (assuan_context_t ctx, int sock, struct sockaddr *addr,
/* Note for Windows: Ignore the incompatible pointer type warning for
my_read and my_write. Mingw has been changed to use int for
ssize_t on 32 bit systems while we use long. For 64 bit we use
- int64_t while mingw uses __int64_t. It doe not matter at all
+ int64_t while mingw uses __int64_t. It does not matter at all
because under Windows long and int are both 32 bit even on 64
bit. */
struct assuan_system_hooks _gpgme_assuan_system_hooks =
diff --git a/src/context.h b/src/context.h
index e976ba3..7a1b9ad 100644
--- a/src/context.h
+++ b/src/context.h
@@ -134,6 +134,9 @@ struct gpgme_context
* after the operation. */
unsigned int ignore_mdc_error : 1;
+ /* True if the option --no-auto-check-trustdb shall be passed to gpg. */
+ unsigned int no_auto_check_trustdb : 1;
+
/* Pass --expert to gpg edit key. */
unsigned int extended_edit : 1;
diff --git a/src/conversion.c b/src/conversion.c
index 17dce7f..f5dd7ea 100644
--- a/src/conversion.c
+++ b/src/conversion.c
@@ -434,10 +434,10 @@ _gpgme_strtoul_field (const char *string, unsigned long *result)
/* Convert STRING into an offset value. Note that this functions only
* allows for a base-10 length. This function is similar to atoi()
* and thus there is no error checking. */
-gpgme_off_t
+uint64_t
_gpgme_string_to_off (const char *string)
{
- gpgme_off_t value = 0;
+ uint64_t value = 0;
while (*string == ' ' || *string == '\t')
string++;
diff --git a/src/data-identify.c b/src/data-identify.c
index 8e0295e..6d2500d 100644
--- a/src/data-identify.c
+++ b/src/data-identify.c
@@ -336,8 +336,10 @@ basic_detection (char *data, size_t datalen)
SEQUENCE SEQUENCE [0] INTEGER INTEGER SEQU
(tbs) (version) (s/n) (Algo)
- Thus we need to read at least 22 bytes, we add 2 bytes to cope with
- length headers stored with 4 bytes.
+ Thus we need to read at least 22 bytes, we add 2 bytes to cope
+ with length headers stored with 4 bytes. For a v0 certificate the
+ tag and the bersion are missin (they are implicit) - detect this
+ too as a cert becuase some root CA use this.
*/
@@ -357,24 +359,34 @@ basic_detection (char *data, size_t datalen)
{
if (parse_tlv (&s, &n, &ti))
goto try_pgp;
- if (!(ti.cls == ASN1_CLASS_CONTEXT && ti.tag == 0
- && ti.is_cons && ti.length == 3 && n >= ti.length))
- goto try_pgp;
+ if (ti.cls == ASN1_CLASS_CONTEXT && ti.tag == 0
+ && ti.is_cons && ti.length == 3 && n >= ti.length)
+ {
+ if (parse_tlv (&s, &n, &ti))
+ goto try_pgp;
+ if (!(ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
+ && !ti.is_cons && ti.length == 1 && n && (*s == 1 || *s == 2)))
+ goto try_pgp;
+ s++;
+ n--;
+ if (!(ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
+ && !ti.is_cons))
+ goto try_pgp;
+ /* Because the now following S/N may be larger than the sample
+ data we have, we stop parsing here and don't check for the
+ algorithm ID. */
+ return GPGME_DATA_TYPE_X509_CERT; /* regular cert. */
+ }
+ if (ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
+ && !ti.is_cons)
+ {
+ /* Because this S/N may be larger than the sample data we
+ have, we can't check that a SEQUENCE follows. */
+ return GPGME_DATA_TYPE_X509_CERT; /* v0 cert with implict tag. */
+ }
+
+ goto try_pgp;
- if (parse_tlv (&s, &n, &ti))
- goto try_pgp;
- if (!(ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
- && !ti.is_cons && ti.length == 1 && n && (*s == 1 || *s == 2)))
- goto try_pgp;
- s++;
- n--;
- if (!(ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
- && !ti.is_cons))
- goto try_pgp;
- /* Because the now following S/N may be larger than the sample
- data we have, we stop parsing here and don't check for the
- algorithm ID. */
- return GPGME_DATA_TYPE_X509_CERT;
}
if (ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_INTEGER
&& !ti.is_cons && ti.length == 1 && n && *s == 3)
diff --git a/src/data.c b/src/data.c
index e2de9f6..1bb334c 100644
--- a/src/data.c
+++ b/src/data.c
@@ -572,7 +572,7 @@ gpgme_data_set_flag (gpgme_data_t dh, const char *name, const char *value)
}
else if (!strcmp (name, "io-buffer-size"))
{
- gpgme_off_t val;
+ uint64_t val;
/* We may set this only once. */
if (dh->io_buffer_size)
@@ -744,7 +744,7 @@ _gpgme_data_get_fd (gpgme_data_t dh)
/* Get the size-hint value for DH or 0 if not available. */
-gpgme_off_t
+uint64_t
_gpgme_data_get_size_hint (gpgme_data_t dh)
{
return dh ? dh->size_hint : 0;
diff --git a/src/data.h b/src/data.h
index 648d976..3e06394 100644
--- a/src/data.h
+++ b/src/data.h
@@ -96,7 +96,7 @@ struct gpgme_data
char *file_name;
/* Hint on the to be expected total size of the data. */
- gpgme_off_t size_hint;
+ uint64_t size_hint;
/* If no 0 the size of an allocated inbound or outpund buffers. The
* value is at least BUFFER_SIZE and capped at 1MiB. */
@@ -189,7 +189,7 @@ void _gpgme_data_release (gpgme_data_t dh);
int _gpgme_data_get_fd (gpgme_data_t dh);
/* Get the size-hint value for DH or 0 if not available. */
-gpgme_off_t _gpgme_data_get_size_hint (gpgme_data_t dh);
+uint64_t _gpgme_data_get_size_hint (gpgme_data_t dh);
#endif /* DATA_H */
diff --git a/src/debug.c b/src/debug.c
index d5d11bd..b6dc445 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -1,6 +1,6 @@
/* debug.c - helpful output in desperate situations
* Copyright (C) 2000 Werner Koch (dd9jn)
- * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009, 2019 g10 Code GmbH
+ * Copyright (C) 2001-2005, 2007, 2009, 2019-2023 g10 Code GmbH
*
* This file is part of GPGME.
*
@@ -54,9 +54,6 @@
variable GPGME_DEBUG. */
static int debug_level;
-/* The output stream for the debug messages. */
-static FILE *errfp;
-
/* If not NULL, this malloced string is used instead of the
GPGME_DEBUG envvar. It must have been set before the debug
subsystem has been initialized. Using it later may or may not have
@@ -126,6 +123,37 @@ _gpgme_debug_set_debug_envvar (const char *value)
}
+static int
+safe_to_use_debug_file (void)
+{
+#ifdef HAVE_DOSISH_SYSTEM
+ return 1;
+#else /* Unix */
+ return (getuid () == geteuid ()
+#if defined(HAVE_GETGID) && defined(HAVE_GETEGID)
+ && getgid () == getegid ()
+#endif
+ );
+#endif /* Unix */
+}
+
+
+static int
+tid_log_callback (unsigned long *rvalue)
+{
+ int len = sizeof (*rvalue);
+ uintptr_t thread;
+
+ thread = ath_self ();
+ if (sizeof (thread) < len)
+ len = sizeof (thread);
+ memcpy (rvalue, &thread, len);
+
+ return 2; /* Use use hex representation. */
+}
+
+
+
static void
debug_init (void)
{
@@ -135,7 +163,7 @@ debug_init (void)
{
gpgme_error_t err;
char *e;
- const char *s1, *s2;;
+ const char *s1, *s2;
if (envvar_override)
{
@@ -151,58 +179,57 @@ debug_init (void)
}
initialized = 1;
- errfp = stderr;
if (e)
{
+ char *p, *r;
+ unsigned int flags;
+
debug_level = atoi (e);
- s1 = strchr (e, PATHSEP_C);
- if (s1)
- {
-#ifndef HAVE_DOSISH_SYSTEM
- if (getuid () == geteuid ()
-#if defined(HAVE_GETGID) && defined(HAVE_GETEGID)
- && getgid () == getegid ()
-#endif
- )
- {
-#endif
- char *p;
- FILE *fp;
-
- s1++;
- if (!(s2 = strchr (s1, PATHSEP_C)))
- s2 = s1 + strlen (s1);
- p = malloc (s2 - s1 + 1);
- if (p)
- {
- memcpy (p, s1, s2 - s1);
- p[s2-s1] = 0;
- trim_spaces (p);
- fp = fopen (p,"a");
- if (fp)
- {
- setvbuf (fp, NULL, _IOLBF, 0);
- errfp = fp;
- }
- free (p);
- }
-#ifndef HAVE_DOSISH_SYSTEM
- }
-#endif
- }
+ s1 = strchr (e, PATHSEP_C);
+ if (s1 && safe_to_use_debug_file ())
+ {
+ s1++;
+ if (!(s2 = strchr (s1, PATHSEP_C)))
+ s2 = s1 + strlen (s1);
+ p = malloc (s2 - s1 + 1);
+ if (p)
+ {
+ memcpy (p, s1, s2 - s1);
+ p[s2-s1] = 0;
+ trim_spaces (p);
+ if (strstr (p, "^//"))
+ {
+ /* map chars to allow socket: and tcp: */
+ for (r=p; *r; r++)
+ if (*r == '^')
+ *r = ':';
+ }
+ if (*p)
+ gpgrt_log_set_sink (p, NULL, -1);
+ free (p);
+ }
+ }
free (e);
+
+ gpgrt_log_get_prefix (&flags);
+ flags |= (GPGRT_LOG_WITH_PREFIX
+ | GPGRT_LOG_WITH_TIME
+ | GPGRT_LOG_WITH_PID);
+ gpgrt_log_set_prefix (*gpgrt_log_get_prefix (NULL)?NULL:"gpgme",
+ flags);
+ gpgrt_log_set_pid_suffix_cb (tid_log_callback);
}
}
if (debug_level > 0)
{
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme_debug: level=%d\n", debug_level);
+ "gpgme_debug: level=%d", debug_level);
#ifdef HAVE_W32_SYSTEM
{
const char *name = _gpgme_get_inst_dir ();
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme_debug: gpgme='%s'\n", name? name: "?");
+ "gpgme_debug: gpgme='%s'", name? name: "?");
}
#endif
}
@@ -250,9 +277,8 @@ _gpgme_debug (void **line, int level, int mode,
{
va_list arg_ptr;
int saved_errno;
- int need_lf;
int indent;
- char *prefix, *stdinfo, *userinfo;
+ char *stdinfo, *userinfo;
const char *modestr;
int no_userinfo = 0;
@@ -267,17 +293,6 @@ _gpgme_debug (void **line, int level, int mode,
saved_errno = errno;
va_start (arg_ptr, format);
- {
- struct tm *tp;
- time_t atime = time (NULL);
-
- tp = localtime (&atime);
- prefix = gpgrt_bsprintf ("GPGME %04d%02d%02dT%02d%02d%02d %04llX %*s",
- 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
- tp->tm_hour, tp->tm_min, tp->tm_sec,
- (unsigned long long) ath_self (),
- indent < 40? indent : 40, "");
- }
switch (mode)
{
@@ -305,33 +320,25 @@ _gpgme_debug (void **line, int level, int mode,
}
va_end (arg_ptr);
- if (mode != -1 && (!format || !*format))
- need_lf = 1;
- else if (userinfo && *userinfo && userinfo[strlen (userinfo) - 1] != '\n')
- need_lf = 1;
- else
- need_lf = 0;
-
if (line)
- *line = gpgrt_bsprintf ("%s%s%s",
- prefix? prefix : "GPGME out-of-core ",
- !modestr? "" : stdinfo? stdinfo :
- (!format || !*format)? "" :"out-of-core ",
+ *line = gpgrt_bsprintf ("%s%s",
+ (!modestr ? "" :
+ stdinfo ? stdinfo :
+ (!format || !*format)? "" :"out-of-core "),
userinfo? userinfo : "out-of-core");
else
{
- fprintf (errfp, "%s%s%s%s",
- prefix? prefix : "GPGME out-of-core ",
- !modestr? "" : stdinfo? stdinfo :
- (!format || !*format)? "" :"out-of-core ",
- userinfo? userinfo : no_userinfo? "" : "out-of-core",
- need_lf? "\n":"");
- fflush (errfp);
+ gpgrt_log (GPGRT_LOGLVL_INFO, "%*s%s%s",
+ indent < 40? indent : 40, "",
+ (!modestr ? "" :
+ stdinfo ? stdinfo :
+ (!format || !*format)? "" : "out-of-core "),
+ (userinfo? userinfo :
+ no_userinfo? "" : "out-of-core"));
}
gpgrt_free (userinfo);
gpgrt_free (stdinfo);
- gpgrt_free (prefix);
gpg_err_set_errno (saved_errno);
return 0;
}
@@ -378,10 +385,7 @@ _gpgme_debug_end (void **line)
return;
string = *line;
- fprintf (errfp, "%s%s",
- string,
- (*string && string[strlen (string)-1] != '\n')? "\n":"");
- fflush (errfp);
+ gpgrt_log (GPGRT_LOGLVL_INFO, "%s", string);
gpgrt_free (*line);
*line = NULL;
}
diff --git a/src/debug.h b/src/debug.h
index 7b823ee..37d58e9 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -180,7 +180,7 @@ static inline gpgme_ssize_t
_trace_sysres_ssize_t (gpgme_ssize_t res, int lvl, const char *func, int line)
{
if (res >= 0)
- _gpgme_debug (NULL, lvl, 3, func, NULL, NULL, "result=%zd", res);
+ _gpgme_debug (NULL, lvl, 3, func, NULL, NULL, "result=%zd", (ssize_t)res);
else
_gpgme_debug (NULL, lvl, -1, NULL, NULL, NULL,
"%s:%d: error: %s (%d)\n",
diff --git a/src/decrypt-verify.c b/src/decrypt-verify.c
index b63318f..3ff15fe 100644
--- a/src/decrypt-verify.c
+++ b/src/decrypt-verify.c
@@ -35,13 +35,17 @@ decrypt_verify_status_handler (void *priv, gpgme_status_code_t code,
char *args)
{
gpgme_error_t err;
+ gpgme_error_t err2;
err = _gpgme_progress_status_handler (priv, code, args);
if (!err)
err = _gpgme_decrypt_status_handler (priv, code, args);
- if (!err)
- err = _gpgme_verify_status_handler (priv, code, args);
- return err;
+ /* Allow finalization of signature verification even if previous handler
+ * returned NO DATA error which just means that the data wasn't encrypted. */
+ if (!err
+ || (code == GPGME_STATUS_EOF && gpg_err_code (err) == GPG_ERR_NO_DATA))
+ err2 = _gpgme_verify_status_handler (priv, code, args);
+ return err ? err : err2;
}
diff --git a/src/dirinfo.c b/src/dirinfo.c
index 8ea15d8..a075319 100644
--- a/src/dirinfo.c
+++ b/src/dirinfo.c
@@ -32,6 +32,12 @@
#include "sema.h"
#include "sys-util.h"
+#ifdef HAVE_DOSISH_SYSTEM
+# define EXEEXT_S ".exe"
+#else
+# define EXEEXT_S ""
+#endif
+
DEFINE_STATIC_LOCK (dirinfo_lock);
/* Constants used internally to select the data. */
@@ -59,6 +65,7 @@ enum
WANT_DIRMNGR_NAME,
WANT_PINENTRY_NAME,
WANT_GPG_WKS_CLIENT_NAME,
+ WANT_GPGTAR_NAME,
WANT_GPG_ONE_MODE
};
@@ -88,6 +95,7 @@ static struct {
char *dirmngr_name;
char *pinentry_name;
char *gpg_wks_client_name;
+ char *gpgtar_name;
int gpg_one_mode; /* System is in gpg1 mode. */
} dirinfo;
@@ -287,13 +295,13 @@ get_gpgconf_item (int what)
if (pgmname && _gpgme_access (pgmname, F_OK))
{
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: gpgconf='%s' [not installed]\n", pgmname);
+ "gpgme-dinfo: gpgconf='%s' [not installed]", pgmname);
free (pgmname);
pgmname = NULL; /* Not available. */
}
else
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: gpgconf='%s'\n",
+ "gpgme-dinfo: gpgconf='%s'",
pgmname? pgmname : "[null]");
if (!pgmname)
{
@@ -320,59 +328,59 @@ get_gpgconf_item (int what)
dirinfo.valid = 1;
if (dirinfo.gpg_name)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: gpg='%s'\n",
+ "gpgme-dinfo: gpg='%s'",
dirinfo.gpg_name);
if (dirinfo.g13_name)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: g13='%s'\n",
+ "gpgme-dinfo: g13='%s'",
dirinfo.g13_name);
if (dirinfo.gpgsm_name)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: gpgsm='%s'\n",
+ "gpgme-dinfo: gpgsm='%s'",
dirinfo.gpgsm_name);
if (dirinfo.keyboxd_name)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: keyboxd='%s'\n",
+ "gpgme-dinfo: keyboxd='%s'",
dirinfo.keyboxd_name);
if (dirinfo.agent_name)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: gpg-agent='%s'\n",
+ "gpgme-dinfo: gpg-agent='%s'",
dirinfo.agent_name);
if (dirinfo.scdaemon_name)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: scdaemon='%s'\n",
+ "gpgme-dinfo: scdaemon='%s'",
dirinfo.scdaemon_name);
if (dirinfo.dirmngr_name)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: dirmngr='%s'\n",
+ "gpgme-dinfo: dirmngr='%s'",
dirinfo.dirmngr_name);
if (dirinfo.pinentry_name)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: pinentry='%s'\n",
+ "gpgme-dinfo: pinentry='%s'",
dirinfo.pinentry_name);
if (dirinfo.homedir)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: homedir='%s'\n",
+ "gpgme-dinfo: homedir='%s'",
dirinfo.homedir);
if (dirinfo.socketdir)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: sockdir='%s'\n",
+ "gpgme-dinfo: sockdir='%s'",
dirinfo.socketdir);
if (dirinfo.agent_socket)
- _gpgme_debug (NULL,DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: agent='%s'\n",
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
+ "gpgme-dinfo: agent='%s'",
dirinfo.agent_socket);
if (dirinfo.agent_ssh_socket)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: ssh='%s'\n",
+ "gpgme-dinfo: ssh='%s'",
dirinfo.agent_ssh_socket);
if (dirinfo.dirmngr_socket)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: dirmngr='%s'\n",
+ "gpgme-dinfo: dirmngr='%s'",
dirinfo.dirmngr_socket);
if (dirinfo.uisrv_socket)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
- "gpgme-dinfo: uisrv='%s'\n",
+ "gpgme-dinfo: uisrv='%s'",
dirinfo.uisrv_socket);
}
switch (what)
@@ -402,11 +410,21 @@ get_gpgconf_item (int what)
case WANT_GPG_WKS_CLIENT_NAME:
if (!dirinfo.gpg_wks_client_name && dirinfo.libexecdir)
dirinfo.gpg_wks_client_name = _gpgme_strconcat (dirinfo.libexecdir,
- "/",
+ DIRSEP_S,
"gpg-wks-client",
+ EXEEXT_S,
NULL);
result = dirinfo.gpg_wks_client_name;
break;
+ case WANT_GPGTAR_NAME:
+ if (!dirinfo.gpgtar_name && dirinfo.bindir)
+ dirinfo.gpgtar_name = _gpgme_strconcat (dirinfo.bindir,
+ DIRSEP_S,
+ "gpgtar",
+ EXEEXT_S,
+ NULL);
+ result = dirinfo.gpgtar_name;
+ break;
}
UNLOCK (dirinfo_lock);
return result;
@@ -455,6 +473,13 @@ _gpgme_get_default_gpgconf_name (void)
return get_gpgconf_item (WANT_GPGCONF_NAME);
}
+/* Return the default gpgtar file name. Returns NULL if not known. */
+const char *
+_gpgme_get_default_gpgtar_name (void)
+{
+ return get_gpgconf_item (WANT_GPGTAR_NAME);
+}
+
/* Return the default UI-server socket name. Returns NULL if not
known. */
const char *
@@ -463,7 +488,7 @@ _gpgme_get_default_uisrv_socket (void)
return get_gpgconf_item (WANT_UISRV_SOCKET);
}
-/* Return true if we are in GnuPG-1 mode - ie. no gpgconf and agent
+/* Return true if we are in GnuPG-1 mode - i.e. no gpgconf and agent
being optional. */
int
_gpgme_in_gpg_one_mode (void)
@@ -524,6 +549,8 @@ gpgme_get_dirinfo (const char *what)
return get_gpgconf_item (WANT_PINENTRY_NAME);
else if (!strcmp (what, "gpg-wks-client-name"))
return get_gpgconf_item (WANT_GPG_WKS_CLIENT_NAME);
+ else if (!strcmp (what, "gpgtar-name"))
+ return get_gpgconf_item (WANT_GPGTAR_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/edit.c b/src/edit.c
index a7d2bb5..b0eef0c 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -122,12 +122,13 @@ interact_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key,
gpgme_error_t err;
void *hook;
op_data_t opd;
+ int card_edit = (flags & GPGME_INTERACT_CARD)? 1: 0;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
- if (!fnc || !out)
+ if ((card_edit == 0 && !key) || !fnc || !out)
return gpg_error (GPG_ERR_INV_VALUE);
err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, sizeof (*opd), NULL);
@@ -146,7 +147,7 @@ interact_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key,
_gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
return _gpgme_engine_op_edit (ctx->engine,
- (flags & GPGME_INTERACT_CARD)? 1: 0,
+ card_edit,
key, out, ctx);
}
@@ -206,7 +207,7 @@ edit_start (gpgme_ctx_t ctx, int synchronous, int type, gpgme_key_t key,
if (err)
return err;
- if (!fnc || !out)
+ if ((type == 0 && !key) || !fnc || !out)
return gpg_error (GPG_ERR_INV_VALUE);
err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, sizeof (*opd), NULL);
diff --git a/src/engine-backend.h b/src/engine-backend.h
index 75ed49c..850ffaa 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -100,12 +100,10 @@ struct engine_ops
const char *import_filter,
const char *key_origin);
gpgme_error_t (*keylist) (void *engine, const char *pattern,
- int secret_only, gpgme_keylist_mode_t mode,
- int engine_flags);
+ int secret_only, gpgme_keylist_mode_t mode);
gpgme_error_t (*keylist_ext) (void *engine, const char *pattern[],
int secret_only, int reserved,
- gpgme_keylist_mode_t mode,
- int engine_flags);
+ gpgme_keylist_mode_t mode);
gpgme_error_t (*keylist_data) (void *engine, gpgme_keylist_mode_t mode,
gpgme_data_t data);
gpgme_error_t (*keysign) (void *engine,
@@ -119,12 +117,12 @@ struct engine_ops
gpgme_key_t key,
gpgme_tofu_policy_t policy);
gpgme_error_t (*sign) (void *engine, gpgme_data_t in, gpgme_data_t out,
- gpgme_sig_mode_t mode, int use_armor,
+ gpgme_sig_mode_t flags, int use_armor,
int use_textmode, int include_certs,
gpgme_ctx_t ctx /* FIXME */);
- gpgme_error_t (*verify) (void *engine, gpgme_data_t sig,
- gpgme_data_t signed_text, gpgme_data_t plaintext,
- gpgme_ctx_t ctx);
+ gpgme_error_t (*verify) (void *engine, gpgme_verify_flags_t flags,
+ gpgme_data_t sig, gpgme_data_t signed_text,
+ gpgme_data_t plaintext, gpgme_ctx_t ctx);
gpgme_error_t (*getauditlog) (void *engine, gpgme_data_t output,
unsigned int flags);
gpgme_error_t (*setexpire) (void *engine, gpgme_key_t key,
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 3bf5223..8c9f62f 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -57,6 +57,7 @@ struct arg_and_data_s
int inbound; /* True if this is used for reading from gpg. */
int dup_to;
int print_fd; /* Print the fd number and not the special form of it. */
+ int gpg_arg; /* True if this argument is not known by gpgtar. */
int *arg_locp; /* Write back the argv idx of this argument when
building command line to this location. */
char arg[FLEXIBLE_ARRAY_MEMBER]; /* Used if data above is not used. */
@@ -145,11 +146,13 @@ struct engine_gpg
char *trust_model;
struct {
+ unsigned int use_gpgtar : 1;
unsigned int no_symkey_cache : 1;
unsigned int offline : 1;
unsigned int ignore_mdc_error : 1;
unsigned int include_key_block : 1;
unsigned int auto_key_import : 1;
+ unsigned int no_auto_check_trustdb : 1;
} flags;
/* NULL or the data object fed to --override_session_key-fd. */
@@ -221,11 +224,32 @@ close_notify_handler (int fd, void *opaque)
}
}
+static void
+_append_to_arglist (engine_gpg_t gpg, struct arg_and_data_s *a)
+{
+ a->next = NULL;
+ *gpg->argtail = a;
+ gpg->argtail = &a->next;
+}
+
+static void
+_prepend_to_arglist (engine_gpg_t gpg, struct arg_and_data_s *a)
+{
+ a->next = gpg->arglist;
+ if (!gpg->arglist)
+ {
+ /* If this is the first argument, we need to update the tail
+ pointer. */
+ gpg->argtail = &a->next;
+ }
+ gpg->arglist = a;
+}
+
/* If FRONT is true, push at the front of the list. Use this for
options added late in the process. */
static gpgme_error_t
_add_arg (engine_gpg_t gpg, const char *prefix, const char *arg, size_t arglen,
- int front, int *arg_locp)
+ int front, int *arg_locp, int gpg_arg)
{
struct arg_and_data_s *a;
size_t prefixlen = prefix? strlen (prefix) : 0;
@@ -240,28 +264,16 @@ _add_arg (engine_gpg_t gpg, const char *prefix, const char *arg, size_t arglen,
a->data = NULL;
a->dup_to = -1;
a->arg_locp = arg_locp;
+ a->gpg_arg = gpg_arg;
if (prefixlen)
memcpy (a->arg, prefix, prefixlen);
memcpy (a->arg + prefixlen, arg, arglen);
a->arg[prefixlen + arglen] = 0;
if (front)
- {
- a->next = gpg->arglist;
- if (!gpg->arglist)
- {
- /* If this is the first argument, we need to update the tail
- pointer. */
- gpg->argtail = &a->next;
- }
- gpg->arglist = a;
- }
+ _prepend_to_arglist (gpg, a);
else
- {
- a->next = NULL;
- *gpg->argtail = a;
- gpg->argtail = &a->next;
- }
+ _append_to_arglist (gpg, a);
return 0;
}
@@ -270,37 +282,50 @@ _add_arg (engine_gpg_t gpg, const char *prefix, const char *arg, size_t arglen,
static gpgme_error_t
add_arg_ext (engine_gpg_t gpg, const char *arg, int front)
{
- return _add_arg (gpg, NULL, arg, strlen (arg), front, NULL);
+ return _add_arg (gpg, NULL, arg, strlen (arg), front, NULL, 0);
}
static gpgme_error_t
-add_arg_with_locp (engine_gpg_t gpg, const char *arg, int *locp)
+add_arg_with_locp (engine_gpg_t gpg, const char *arg, int *locp, int front)
{
- return _add_arg (gpg, NULL, arg, strlen (arg), 0, locp);
+ return _add_arg (gpg, NULL, arg, strlen (arg), front, locp, 0);
}
static gpgme_error_t
add_arg (engine_gpg_t gpg, const char *arg)
{
- return _add_arg (gpg, NULL, arg, strlen (arg), 0, NULL);
+ return _add_arg (gpg, NULL, arg, strlen (arg), 0, NULL, 0);
}
static gpgme_error_t
add_arg_pfx (engine_gpg_t gpg, const char *prefix, const char *arg)
{
- return _add_arg (gpg, prefix, arg, strlen (arg), 0, NULL);
+ return _add_arg (gpg, prefix, arg, strlen (arg), 0, NULL, 0);
+}
+
+static gpgme_error_t
+add_gpg_arg (engine_gpg_t gpg, const char *arg)
+{
+ return _add_arg (gpg, NULL, arg, strlen (arg), 0, NULL, 1);
+}
+
+static gpgme_error_t
+add_gpg_arg_with_value (engine_gpg_t gpg, const char *arg, const char *value,
+ int front)
+{
+ return _add_arg (gpg, arg, value, strlen (value), front, NULL, 1);
}
static gpgme_error_t
add_arg_len (engine_gpg_t gpg, const char *prefix,
const char *arg, size_t arglen)
{
- return _add_arg (gpg, prefix, arg, arglen, 0, NULL);
+ return _add_arg (gpg, prefix, arg, arglen, 0, NULL, 0);
}
static gpgme_error_t
-add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
+add_data_ext (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound, int front)
{
struct arg_and_data_s *a;
@@ -310,7 +335,6 @@ add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
a = malloc (offsetof (struct arg_and_data_s, arg));
if (!a)
return gpg_error_from_syserror ();
- a->next = NULL;
a->data = data;
a->inbound = inbound;
a->arg_locp = NULL;
@@ -325,12 +349,34 @@ add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
a->print_fd = 0;
a->dup_to = dup_to;
}
- *gpg->argtail = a;
- gpg->argtail = &a->next;
+
+ if (front)
+ _prepend_to_arglist (gpg, a);
+ else
+ _append_to_arglist (gpg, a);
+
return 0;
}
+static gpgme_error_t
+add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
+{
+ return add_data_ext (gpg, data, dup_to, inbound, 0);
+}
+
+
+static gpgme_error_t
+add_file_name_arg_or_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
+{
+ const char *file_name = gpgme_data_get_file_name (data);
+ if (file_name)
+ return add_arg (gpg, file_name);
+ else
+ return add_data (gpg, data, dup_to, inbound);
+}
+
+
/* Return true if the engine's version is at least VERSION. */
static int
have_gpg_version (engine_gpg_t gpg, const char *version)
@@ -355,6 +401,14 @@ gpg_get_req_version (void)
}
+static int
+have_usable_gpgtar (engine_gpg_t gpg)
+{
+ return have_gpg_version (gpg, "2.4.1")
+ || (have_gpg_version (gpg, "2.2.42") && !have_gpg_version (gpg, "2.3.0"));
+}
+
+
static void
free_argv (char **argv)
{
@@ -539,34 +593,18 @@ gpg_new (void **engine, const char *file_name, const char *home_dir,
if (home_dir)
{
- rc = add_arg (gpg, "--homedir");
- if (!rc)
- rc = add_arg (gpg, home_dir);
+ rc = add_gpg_arg_with_value (gpg, "--homedir=", home_dir, 0);
if (rc)
goto leave;
}
- rc = add_arg (gpg, "--status-fd");
- if (rc)
- goto leave;
-
- {
- char buf[25];
- _gpgme_io_fd2str (buf, sizeof (buf), gpg->status.fd[1]);
- rc = add_arg_with_locp (gpg, buf, &gpg->status.arg_loc);
- if (rc)
- goto leave;
- }
-
- rc = add_arg (gpg, "--no-tty");
+ rc = add_gpg_arg (gpg, "--no-tty");
if (!rc)
- rc = add_arg (gpg, "--charset");
+ rc = add_gpg_arg (gpg, "--charset=utf8");
if (!rc)
- rc = add_arg (gpg, "utf8");
- if (!rc)
- rc = add_arg (gpg, "--enable-progress-filter");
+ rc = add_gpg_arg (gpg, "--enable-progress-filter");
if (!rc && have_gpg_version (gpg, "2.1.11"))
- rc = add_arg (gpg, "--exit-on-status-write-error");
+ rc = add_gpg_arg (gpg, "--exit-on-status-write-error");
if (rc)
goto leave;
@@ -575,9 +613,7 @@ gpg_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_display)
{
- rc = add_arg (gpg, "--display");
- if (!rc)
- rc = add_arg (gpg, dft_display);
+ rc = add_gpg_arg_with_value (gpg, "--display=", dft_display, 0);
free (dft_display);
if (rc)
@@ -604,11 +640,7 @@ gpg_new (void **engine, const char *file_name, const char *home_dir,
if (!err)
{
if (*dft_ttyname)
- {
- rc = add_arg (gpg, "--ttyname");
- if (!rc)
- rc = add_arg (gpg, dft_ttyname);
- }
+ rc = add_gpg_arg_with_value (gpg, "--ttyname=", dft_ttyname, 0);
else
rc = 0;
if (!rc)
@@ -618,11 +650,7 @@ gpg_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_ttytype)
- {
- rc = add_arg (gpg, "--ttytype");
- if (!rc)
- rc = add_arg (gpg, dft_ttytype);
- }
+ rc = add_gpg_arg_with_value (gpg, "--ttytype=", dft_ttytype, 0);
free (dft_ttytype);
}
@@ -631,16 +659,6 @@ gpg_new (void **engine, const char *file_name, const char *home_dir,
}
}
- rc = gpgme_data_new (&gpg->diagnostics);
- if (rc)
- goto leave;
-
- rc = add_arg (gpg, "--logger-fd");
- if (rc)
- goto leave;
-
- rc = add_data (gpg, gpg->diagnostics, -2, 1);
-
leave:
if (rc)
gpg_release (gpg);
@@ -695,6 +713,8 @@ gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
if (ctx->include_key_block)
gpg->flags.include_key_block = 1;
}
+
+ gpg->flags.no_auto_check_trustdb = !!ctx->no_auto_check_trustdb;
}
@@ -866,11 +886,11 @@ gpg_set_command_handler (void *engine, engine_command_handler_t fnc,
static gpgme_error_t
build_argv (engine_gpg_t gpg, const char *pgmname)
{
- gpgme_error_t err;
+ gpgme_error_t err = 0;
struct arg_and_data_s *a;
- struct fd_data_map_s *fd_data_map;
+ struct fd_data_map_s *fd_data_map = NULL;
size_t datac=0, argc=0, allocated_argc=0;
- char **argv;
+ char **argv = NULL;
int need_special = 0;
int use_agent = 0;
char *p;
@@ -904,7 +924,7 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argc++; /* For argv[0]. */
for (a = gpg->arglist; a; a = a->next)
{
- argc++;
+ argc += 1 + (gpg->flags.use_gpgtar && a->gpg_arg);
if (a->data)
{
/*fprintf (stderr, "build_argv: data\n" );*/
@@ -923,24 +943,24 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
if (use_agent)
argc++;
if (*gpg->request_origin)
- argc++;
+ argc += 1 + !!gpg->flags.use_gpgtar;
if (gpg->auto_key_locate)
- argc++;
+ argc += 1 + !!gpg->flags.use_gpgtar;
if (gpg->trust_model)
- argc++;
+ argc += 1 + !!gpg->flags.use_gpgtar;
if (gpg->flags.no_symkey_cache)
- argc++;
+ argc += 1 + !!gpg->flags.use_gpgtar;
if (gpg->flags.ignore_mdc_error)
- argc++;
+ argc += 1 + !!gpg->flags.use_gpgtar;
if (gpg->flags.offline)
- argc++;
+ argc += 1 + !!gpg->flags.use_gpgtar;
+ if (gpg->flags.no_auto_check_trustdb)
+ argc += 1 + !!gpg->flags.use_gpgtar;
if (gpg->pinentry_mode)
- argc++;
+ argc += 1 + !!gpg->flags.use_gpgtar;
if (!gpg->cmd.used)
argc++; /* --batch */
- argc++; /* --no-sk-comments */
-
argv = calloc (argc + 1, sizeof *argv);
allocated_argc = argc;
@@ -949,19 +969,16 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
fd_data_map = calloc (datac + 1, sizeof *fd_data_map);
if (!fd_data_map)
{
- int saved_err = gpg_error_from_syserror ();
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc = datac = 0;
argv[argc] = strdup (_gpgme_get_basename (pgmname)); /* argv[0] */
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
if (need_special)
@@ -969,10 +986,8 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argv[argc] = strdup ("--enable-special-filenames");
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
@@ -981,10 +996,8 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argv[argc] = strdup ("--use-agent");
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
@@ -993,79 +1006,148 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
if (*gpg->request_origin)
{
+ if (gpg->flags.use_gpgtar)
+ {
+ argv[argc] = strdup ("--gpg-args");
+ if (!argv[argc])
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ argc++;
+ }
argv[argc] = _gpgme_strconcat ("--request-origin=",
gpg->request_origin, NULL);
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
if (gpg->auto_key_locate)
{
+ if (gpg->flags.use_gpgtar)
+ {
+ argv[argc] = strdup ("--gpg-args");
+ if (!argv[argc])
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ argc++;
+ }
argv[argc] = strdup (gpg->auto_key_locate);
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
if (gpg->trust_model)
{
+ if (gpg->flags.use_gpgtar)
+ {
+ argv[argc] = strdup ("--gpg-args");
+ if (!argv[argc])
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ argc++;
+ }
argv[argc] = strdup (gpg->trust_model);
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
if (gpg->flags.no_symkey_cache)
{
+ if (gpg->flags.use_gpgtar)
+ {
+ argv[argc] = strdup ("--gpg-args");
+ if (!argv[argc])
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ argc++;
+ }
argv[argc] = strdup ("--no-symkey-cache");
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
if (gpg->flags.ignore_mdc_error)
{
+ if (gpg->flags.use_gpgtar)
+ {
+ argv[argc] = strdup ("--gpg-args");
+ if (!argv[argc])
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ argc++;
+ }
argv[argc] = strdup ("--ignore-mdc-error");
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
if (gpg->flags.offline)
{
+ if (gpg->flags.use_gpgtar)
+ {
+ argv[argc] = strdup ("--gpg-args");
+ if (!argv[argc])
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ argc++;
+ }
argv[argc] = strdup ("--disable-dirmngr");
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ argc++;
+ }
+
+ if (gpg->flags.no_auto_check_trustdb)
+ {
+ if (gpg->flags.use_gpgtar)
+ {
+ argv[argc] = strdup ("--gpg-args");
+ if (!argv[argc])
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ argc++;
+ }
+ argv[argc] = strdup ("--no-auto-check-trustdb");
+ if (!argv[argc])
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
@@ -1083,13 +1165,21 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
}
if (s)
{
+ if (gpg->flags.use_gpgtar)
+ {
+ argv[argc] = strdup ("--gpg-args");
+ if (!argv[argc])
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ argc++;
+ }
argv[argc] = strdup (s);
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
@@ -1100,22 +1190,11 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argv[argc] = strdup ("--batch");
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
- argv[argc] = strdup ("--no-sk-comments");
- if (!argv[argc])
- {
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
- }
- argc++;
for (a = gpg->arglist; a; a = a->next)
{
if (a->arg_locp)
@@ -1133,10 +1212,8 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound ? 1 : 0)
== -1)
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
if (_gpgme_io_set_close_notify (fds[0],
close_notify_handler, gpg)
@@ -1184,10 +1261,8 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argv[argc] = malloc (buflen);
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
ptr = argv[argc];
@@ -1206,13 +1281,21 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
}
else
{
+ if (gpg->flags.use_gpgtar && a->gpg_arg)
+ {
+ argv[argc] = strdup ("--gpg-args");
+ if (!argv[argc])
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ argc++;
+ }
argv[argc] = strdup (a->arg);
if (!argv[argc])
{
- int saved_err = gpg_error_from_syserror ();
- free (fd_data_map);
- free_argv (argv);
- return saved_err;
+ err = gpg_error_from_syserror ();
+ goto leave;
}
argc++;
}
@@ -1223,9 +1306,18 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
allocated array like ccparray in gnupg. */
assert (argc <= allocated_argc);
- gpg->argv = argv;
- gpg->fd_data_map = fd_data_map;
- return 0;
+leave:
+ if (err)
+ {
+ free (fd_data_map);
+ free_argv (argv);
+ }
+ else
+ {
+ gpg->argv = argv;
+ gpg->fd_data_map = fd_data_map;
+ }
+ return err;
}
@@ -1543,28 +1635,61 @@ start (engine_gpg_t gpg)
if (!gpg)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!gpg->file_name && !_gpgme_get_default_gpg_name ())
+ if (!gpg->flags.use_gpgtar)
+ pgmname = gpg->file_name ? gpg->file_name : _gpgme_get_default_gpg_name ();
+ else
+ pgmname = _gpgme_get_default_gpgtar_name ();
+ if (!pgmname)
return trace_gpg_error (GPG_ERR_INV_ENGINE);
+ rc = gpgme_data_new (&gpg->diagnostics);
+ if (rc)
+ return rc;
+
+ if (gpg->flags.use_gpgtar)
+ {
+ /* Read the diagnostics output from gpgtar's stderr. */
+ rc = add_data (gpg, gpg->diagnostics, 2, 1);
+ if (rc)
+ return rc;
+ }
+ else
+ {
+ rc = add_data_ext (gpg, gpg->diagnostics, -2, 1, 1);
+ if (rc)
+ return rc;
+
+ rc = add_arg_ext (gpg, "--logger-fd", 1);
+ if (rc)
+ return rc;
+ }
+
+ {
+ char buf[25];
+ _gpgme_io_fd2str (buf, sizeof (buf), gpg->status.fd[1]);
+ rc = add_arg_with_locp (gpg, buf, &gpg->status.arg_loc, 1);
+ if (rc)
+ return rc;
+ }
+
+ rc = add_arg_ext (gpg, "--status-fd", 1);
+ if (rc)
+ return rc;
+
if (gpg->lc_ctype)
{
- rc = add_arg_ext (gpg, gpg->lc_ctype, 1);
- if (!rc)
- rc = add_arg_ext (gpg, "--lc-ctype", 1);
+ rc = add_gpg_arg_with_value (gpg, "--lc-ctype=", gpg->lc_ctype, 1);
if (rc)
return rc;
}
if (gpg->lc_messages)
{
- rc = add_arg_ext (gpg, gpg->lc_messages, 1);
- if (!rc)
- rc = add_arg_ext (gpg, "--lc-messages", 1);
+ rc = add_gpg_arg_with_value (gpg, "--lc-messages=", gpg->lc_messages, 1);
if (rc)
return rc;
}
- pgmname = gpg->file_name ? gpg->file_name : _gpgme_get_default_gpg_name ();
rc = build_argv (gpg, pgmname);
if (rc)
return rc;
@@ -1661,28 +1786,23 @@ start (engine_gpg_t gpg)
static gpgme_error_t
add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data)
{
- gpgme_error_t err;
- gpgme_off_t value = _gpgme_data_get_size_hint (data);
+ uint64_t value = _gpgme_data_get_size_hint (data);
char numbuf[50]; /* Large enough for even 2^128 in base-10. */
char *p;
if (!value || !have_gpg_version (gpg, "2.1.15"))
return 0;
- err = add_arg (gpg, "--input-size-hint");
- if (!err)
+ p = numbuf + sizeof numbuf;
+ *--p = 0;
+ do
{
- p = numbuf + sizeof numbuf;
- *--p = 0;
- do
- {
- *--p = '0' + (value % 10);
- value /= 10;
- }
- while (value);
- err = add_arg (gpg, p);
+ *--p = '0' + (value % 10);
+ value /= 10;
}
- return err;
+ while (value);
+
+ return add_gpg_arg_with_value (gpg, "--input-size-hint=", p, 0);
}
@@ -1696,6 +1816,14 @@ gpg_decrypt (void *engine,
engine_gpg_t gpg = engine;
gpgme_error_t err;
+ gpg->flags.use_gpgtar = !!(flags & GPGME_DECRYPT_ARCHIVE);
+
+ if (gpg->flags.use_gpgtar && !have_usable_gpgtar (gpg))
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ if (gpg->flags.use_gpgtar && (flags & GPGME_DECRYPT_UNWRAP))
+ return gpg_error (GPG_ERR_INV_VALUE);
+
err = add_arg (gpg, "--decrypt");
if (!err && (flags & GPGME_DECRYPT_UNWRAP))
@@ -1707,17 +1835,17 @@ gpg_decrypt (void *engine,
}
if (!err && export_session_key)
- err = add_arg (gpg, "--show-session-key");
+ err = add_gpg_arg (gpg, "--show-session-key");
if (!err && auto_key_retrieve)
- err = add_arg (gpg, "--auto-key-retrieve");
+ err = add_gpg_arg (gpg, "--auto-key-retrieve");
if (!err && gpg->flags.auto_key_import)
- err = add_arg (gpg, "--auto-key-import");
+ err = add_gpg_arg (gpg, "--auto-key-import");
if (!err && override_session_key && *override_session_key)
{
- if (have_gpg_version (gpg, "2.1.16"))
+ if (have_gpg_version (gpg, "2.1.16") && !gpg->flags.use_gpgtar)
{
gpgme_data_release (gpg->override_session_key);
TRACE (DEBUG_ENGINE, "override", gpg, "seskey='%s' len=%zu\n",
@@ -1747,25 +1875,43 @@ gpg_decrypt (void *engine,
else
{
/* Using that option may leak the session key via ps(1). */
- err = add_arg (gpg, "--override-session-key");
- if (!err)
- err = add_arg (gpg, override_session_key);
+ err = add_gpg_arg_with_value (gpg, "--override-session-key=",
+ override_session_key, 0);
}
}
/* Tell the gpg object about the data. */
- if (!err)
- err = add_arg (gpg, "--output");
- if (!err)
- err = add_arg (gpg, "-");
- if (!err)
- err = add_data (gpg, plain, 1, 1);
- if (!err)
- err = add_input_size_hint (gpg, ciph);
- if (!err)
- err = add_arg (gpg, "--");
- if (!err)
- err = add_data (gpg, ciph, -1, 0);
+ if (gpg->flags.use_gpgtar)
+ {
+ const char *file_name = gpgme_data_get_file_name (plain);
+ if (!err && file_name)
+ {
+ err = add_arg (gpg, "--directory");
+ if (!err)
+ err = add_arg (gpg, file_name);
+ }
+ if (!err)
+ err = add_input_size_hint (gpg, ciph);
+ if (!err)
+ err = add_arg (gpg, "--");
+ if (!err)
+ err = add_file_name_arg_or_data (gpg, ciph, 0, 0);
+ }
+ else
+ {
+ if (!err)
+ err = add_arg (gpg, "--output");
+ if (!err)
+ err = add_arg (gpg, "-");
+ if (!err)
+ err = add_data (gpg, plain, 1, 1);
+ if (!err)
+ err = add_input_size_hint (gpg, ciph);
+ if (!err)
+ err = add_arg (gpg, "--");
+ if (!err)
+ err = add_file_name_arg_or_data (gpg, ciph, -1, 0);
+ }
if (!err)
err = start (gpg);
@@ -1849,16 +1995,11 @@ append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
static gpgme_error_t
append_args_from_sender (engine_gpg_t gpg, gpgme_ctx_t ctx)
{
- gpgme_error_t err;
+ gpgme_error_t err = 0;
if (ctx->sender && have_gpg_version (gpg, "2.1.15"))
- {
- err = add_arg (gpg, "--sender");
- if (!err)
- err = add_arg (gpg, ctx->sender);
- }
- else
- err = 0;
+ err = add_gpg_arg_with_value (gpg, "--sender=", ctx->sender, 0);
+
return err;
}
@@ -1912,14 +2053,12 @@ append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */,
if (!err)
{
if ((flags & NOTATION_FLAG_SET))
- err = add_arg (gpg, "--set-notation");
+ err = add_gpg_arg_with_value (gpg, "--set-notation=", arg, 0);
else if ((flags & NOTATION_FLAG_CERT))
- err = add_arg (gpg, "--cert-notation");
+ err = add_gpg_arg_with_value (gpg, "--cert-notation=", arg, 0);
else
- err = add_arg (gpg, "--sig-notation");
+ err = add_gpg_arg_with_value (gpg, "--sig-notation=", arg, 0);
}
- if (!err)
- err = add_arg (gpg, arg);
if (arg)
free (arg);
@@ -1946,9 +2085,7 @@ append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */,
value = notation->value;
if (!err)
- err = add_arg (gpg, "--sig-policy-url");
- if (!err)
- err = add_arg (gpg, value);
+ err = add_gpg_arg_with_value (gpg, "--sig-policy-url=", value, 0);
if (value != notation->value)
free (value);
@@ -2181,6 +2318,14 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
engine_gpg_t gpg = engine;
gpgme_error_t err = 0;
+ gpg->flags.use_gpgtar = !!(flags & GPGME_ENCRYPT_ARCHIVE);
+
+ if (gpg->flags.use_gpgtar && !have_usable_gpgtar (gpg))
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ if (gpg->flags.use_gpgtar && (flags & GPGME_ENCRYPT_WRAP))
+ return gpg_error (GPG_ERR_INV_VALUE);
+
if (recp || recpstring)
err = add_arg (gpg, "--encrypt");
@@ -2188,7 +2333,7 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
err = add_arg (gpg, "--symmetric");
if (!err && use_armor)
- err = add_arg (gpg, "--armor");
+ err = add_gpg_arg (gpg, "--armor");
if (!err && (flags & GPGME_ENCRYPT_WRAP))
{
@@ -2198,31 +2343,31 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
* the encryption would add an additional compression layer.
* We better suppress that. */
flags |= GPGME_ENCRYPT_NO_COMPRESS;
- err = add_arg (gpg, "--no-literal");
+ err = add_gpg_arg (gpg, "--no-literal");
}
if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
- err = add_arg (gpg, "--compress-algo=none");
+ err = add_gpg_arg (gpg, "--compress-algo=none");
if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
- err = add_arg (gpg, "--throw-keyids");
+ err = add_gpg_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");
+ err = add_gpg_arg (gpg, "--mimemode");
if (!err && gpg->flags.include_key_block)
- err = add_arg (gpg, "--include-key-block");
+ err = add_gpg_arg (gpg, "--include-key-block");
if (recp || recpstring)
{
/* If we know that all recipients are valid (full or ultimate trust)
we can suppress further checks. */
if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
- err = add_arg (gpg, "--always-trust");
+ err = add_gpg_arg (gpg, "--always-trust");
if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
- err = add_arg (gpg, "--no-encrypt-to");
+ err = add_gpg_arg (gpg, "--no-encrypt-to");
if (!err && !recp && recpstring)
err = append_args_from_recipients_string (gpg, flags, recpstring);
@@ -2234,22 +2379,50 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
if (!err)
err = add_arg (gpg, "--output");
if (!err)
- err = add_arg (gpg, "-");
- if (!err)
- err = add_data (gpg, ciph, 1, 1);
- if (gpgme_data_get_file_name (plain))
{
+ const char *output = gpgme_data_get_file_name (ciph);
+ if (output)
+ err = add_arg (gpg, output);
+ else
+ {
+ err = add_arg (gpg, "-");
+ if (!err)
+ err = add_data (gpg, ciph, 1, 1);
+ }
+ }
+ if (gpg->flags.use_gpgtar)
+ {
+ const char *file_name = gpgme_data_get_file_name (plain);
+ if (!err && file_name)
+ {
+ err = add_arg (gpg, "--directory");
+ if (!err)
+ err = add_arg (gpg, file_name);
+ }
+ if (!err)
+ err = add_arg (gpg, "--files-from");
+ if (!err)
+ err = add_arg (gpg, "-");
if (!err)
- err = add_arg (gpg, "--set-filename");
+ err = add_arg (gpg, "--null");
if (!err)
- err = add_arg (gpg, gpgme_data_get_file_name (plain));
+ err = add_arg (gpg, "--utf8-strings");
+ /* Pass the filenames to gpgtar's stdin. */
+ if (!err)
+ err = add_data (gpg, plain, 0, 0);
+ }
+ else
+ {
+ const char *file_name = gpgme_data_get_file_name (plain);
+ if (!err && file_name)
+ err = add_gpg_arg_with_value (gpg, "--set-filename=", file_name, 0);
+ if (!err)
+ err = add_input_size_hint (gpg, plain);
+ if (!err)
+ err = add_arg (gpg, "--");
+ if (!err)
+ err = add_data (gpg, plain, -1, 0);
}
- if (!err)
- err = add_input_size_hint (gpg, plain);
- if (!err)
- err = add_arg (gpg, "--");
- if (!err)
- err = add_data (gpg, plain, -1, 0);
if (!err)
err = start (gpg);
@@ -2268,6 +2441,11 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
engine_gpg_t gpg = engine;
gpgme_error_t err = 0;
+ gpg->flags.use_gpgtar = !!(flags & GPGME_ENCRYPT_ARCHIVE);
+
+ if (gpg->flags.use_gpgtar && !have_usable_gpgtar (gpg))
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
if (recp || recpstring)
err = add_arg (gpg, "--encrypt");
@@ -2277,30 +2455,30 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
if (!err)
err = add_arg (gpg, "--sign");
if (!err && use_armor)
- err = add_arg (gpg, "--armor");
+ err = add_gpg_arg (gpg, "--armor");
if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
- err = add_arg (gpg, "--compress-algo=none");
+ err = add_gpg_arg (gpg, "--compress-algo=none");
if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
- err = add_arg (gpg, "--throw-keyids");
+ err = add_gpg_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");
+ err = add_gpg_arg (gpg, "--mimemode");
if (!err && gpg->flags.include_key_block)
- err = add_arg (gpg, "--include-key-block");
+ err = add_gpg_arg (gpg, "--include-key-block");
if (recp || recpstring)
{
/* If we know that all recipients are valid (full or ultimate trust)
we can suppress further checks. */
if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
- err = add_arg (gpg, "--always-trust");
+ err = add_gpg_arg (gpg, "--always-trust");
if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
- err = add_arg (gpg, "--no-encrypt-to");
+ err = add_gpg_arg (gpg, "--no-encrypt-to");
if (!err && !recp && recpstring)
err = append_args_from_recipients_string (gpg, flags, recpstring);
@@ -2321,22 +2499,50 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
if (!err)
err = add_arg (gpg, "--output");
if (!err)
- err = add_arg (gpg, "-");
- if (!err)
- err = add_data (gpg, ciph, 1, 1);
- if (gpgme_data_get_file_name (plain))
{
+ const char *output = gpgme_data_get_file_name (ciph);
+ if (output)
+ err = add_arg (gpg, output);
+ else
+ {
+ err = add_arg (gpg, "-");
+ if (!err)
+ err = add_data (gpg, ciph, 1, 1);
+ }
+ }
+ if (gpg->flags.use_gpgtar)
+ {
+ const char *file_name = gpgme_data_get_file_name (plain);
+ if (!err && file_name)
+ {
+ err = add_arg (gpg, "--directory");
+ if (!err)
+ err = add_arg (gpg, file_name);
+ }
+ if (!err)
+ err = add_arg (gpg, "--files-from");
+ if (!err)
+ err = add_arg (gpg, "-");
if (!err)
- err = add_arg (gpg, "--set-filename");
+ err = add_arg (gpg, "--null");
if (!err)
- err = add_arg (gpg, gpgme_data_get_file_name (plain));
+ err = add_arg (gpg, "--utf8-strings");
+ /* Pass the filenames to gpgtar's stdin. */
+ if (!err)
+ err = add_data (gpg, plain, 0, 0);
+ }
+ else
+ {
+ const char *file_name = gpgme_data_get_file_name (plain);
+ if (!err && file_name)
+ err = add_gpg_arg_with_value (gpg, "--set-filename=", file_name, 0);
+ if (!err)
+ err = add_input_size_hint (gpg, plain);
+ if (!err)
+ err = add_arg (gpg, "--");
+ if (!err)
+ err = add_data (gpg, plain, -1, 0);
}
- if (!err)
- err = add_input_size_hint (gpg, plain);
- if (!err)
- err = add_arg (gpg, "--");
- if (!err)
- err = add_data (gpg, plain, -1, 0);
if (!err)
err = start (gpg);
@@ -3061,6 +3267,12 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
err = add_arg (gpg, "--with-fingerprint");
}
+ if (!err && (mode & GPGME_KEYLIST_MODE_WITH_V5FPR)
+ && (have_gpg_version (gpg, "2.4.4")
+ || (have_gpg_version (gpg, "2.2.42")
+ && !have_gpg_version (gpg, "2.3.0"))))
+ err = add_arg (gpg, "--with-v5-fingerprint");
+
if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU)
&& have_gpg_version (gpg, "2.1.16"))
err = add_arg (gpg, "--with-tofu-info");
@@ -3135,13 +3347,11 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
static gpgme_error_t
gpg_keylist (void *engine, const char *pattern, int secret_only,
- gpgme_keylist_mode_t mode, int engine_flags)
+ gpgme_keylist_mode_t mode)
{
engine_gpg_t gpg = engine;
gpgme_error_t err;
- (void)engine_flags;
-
err = gpg_keylist_build_options (gpg, secret_only, mode);
if (!err && pattern && *pattern)
@@ -3156,13 +3366,11 @@ gpg_keylist (void *engine, const char *pattern, int secret_only,
static gpgme_error_t
gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
- int reserved, gpgme_keylist_mode_t mode, int engine_flags)
+ int reserved, gpgme_keylist_mode_t mode)
{
engine_gpg_t gpg = engine;
gpgme_error_t err;
- (void)engine_flags;
-
if (reserved)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -3267,7 +3475,7 @@ gpg_keysign (void *engine, gpgme_key_t key, const char *userid,
if (!err)
err = add_arg (gpg, key->fpr);
- if (!err && userid)
+ if (!err && userid && *userid)
{
if ((flags & GPGME_KEYSIGN_LFSEP))
{
@@ -3313,7 +3521,7 @@ gpg_revsig (void *engine, gpgme_key_t key, gpgme_key_t signing_key,
if (!err)
err = add_arg (gpg, signing_key->fpr);
- if (!err && userid)
+ if (!err && userid && *userid)
{
if ((flags & GPGME_REVSIG_LFSEP))
{
@@ -3376,35 +3584,45 @@ gpg_tofu_policy (void *engine, gpgme_key_t key, gpgme_tofu_policy_t policy)
static gpgme_error_t
gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
- gpgme_sig_mode_t mode, int use_armor, int use_textmode,
+ gpgme_sig_mode_t flags, int use_armor, int use_textmode,
int include_certs, gpgme_ctx_t ctx /* FIXME */)
{
engine_gpg_t gpg = engine;
gpgme_error_t err;
+ const char *output = NULL;
(void)include_certs;
- if (mode == GPGME_SIG_MODE_CLEAR)
+ if ((flags != GPGME_SIG_MODE_NORMAL) && (flags != GPGME_SIG_MODE_DETACH)
+ && (flags != GPGME_SIG_MODE_CLEAR) && (flags != GPGME_SIG_MODE_ARCHIVE))
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ gpg->flags.use_gpgtar = !!(flags & GPGME_SIG_MODE_ARCHIVE);
+
+ if (gpg->flags.use_gpgtar && !have_usable_gpgtar (gpg))
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ if (flags & GPGME_SIG_MODE_CLEAR)
err = add_arg (gpg, "--clearsign");
else
{
err = add_arg (gpg, "--sign");
- if (!err && mode == GPGME_SIG_MODE_DETACH)
+ if (!err && (flags & GPGME_SIG_MODE_DETACH))
err = add_arg (gpg, "--detach");
if (!err && use_armor)
- err = add_arg (gpg, "--armor");
+ err = add_gpg_arg (gpg, "--armor");
if (!err)
{
if (gpgme_data_get_encoding (in) == GPGME_DATA_ENCODING_MIME
&& have_gpg_version (gpg, "2.1.14"))
- err = add_arg (gpg, "--mimemode");
+ err = add_gpg_arg (gpg, "--mimemode");
else if (use_textmode)
- err = add_arg (gpg, "--textmode");
+ err = add_gpg_arg (gpg, "--textmode");
}
}
if (!err && gpg->flags.include_key_block)
- err = add_arg (gpg, "--include-key-block");
+ err = add_gpg_arg (gpg, "--include-key-block");
if (!err)
err = append_args_from_signers (gpg, ctx);
if (!err)
@@ -3412,22 +3630,53 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
if (!err)
err = append_args_from_sig_notations (gpg, ctx, NOTATION_FLAG_SIG);
- if (gpgme_data_get_file_name (in))
+ if (!err)
+ {
+ output = gpgme_data_get_file_name (out);
+ if (output)
+ {
+ err = add_arg (gpg, "--output");
+ if (!err)
+ err = add_arg (gpg, output);
+ }
+ }
+
+ /* Tell the gpg object about the data. */
+ if (gpg->flags.use_gpgtar)
+ {
+ const char *file_name = gpgme_data_get_file_name (in);
+ if (!err && file_name)
+ {
+ err = add_arg (gpg, "--directory");
+ if (!err)
+ err = add_arg (gpg, file_name);
+ }
+ if (!err)
+ err = add_arg (gpg, "--files-from");
+ if (!err)
+ err = add_arg (gpg, "-");
+ if (!err)
+ err = add_arg (gpg, "--null");
+ if (!err)
+ err = add_arg (gpg, "--utf8-strings");
+ /* Pass the filenames to gpgtar's stdin. */
+ if (!err)
+ err = add_data (gpg, in, 0, 0);
+ }
+ else
{
+ const char *file_name = gpgme_data_get_file_name (in);
+ if (!err && file_name)
+ err = add_gpg_arg_with_value (gpg, "--set-filename=", file_name, 0);
if (!err)
- err = add_arg (gpg, "--set-filename");
+ err = add_input_size_hint (gpg, in);
if (!err)
- err = add_arg (gpg, gpgme_data_get_file_name (in));
+ err = add_arg (gpg, "--");
+ if (!err)
+ err = add_data (gpg, in, -1, 0);
}
- /* Tell the gpg object about the data. */
- if (!err)
- err = add_input_size_hint (gpg, in);
- if (!err)
- err = add_arg (gpg, "--");
- if (!err)
- err = add_data (gpg, in, -1, 0);
- if (!err)
+ if (!err && !output)
err = add_data (gpg, out, 1, 1);
if (!err)
@@ -3437,34 +3686,55 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
}
static gpgme_error_t
-gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
- gpgme_data_t plaintext, gpgme_ctx_t ctx)
+gpg_verify (void *engine, gpgme_verify_flags_t flags, gpgme_data_t sig,
+ gpgme_data_t signed_text, gpgme_data_t plaintext, gpgme_ctx_t ctx)
{
engine_gpg_t gpg = engine;
gpgme_error_t err;
+ gpg->flags.use_gpgtar = !!(flags & GPGME_VERIFY_ARCHIVE);
+
+ if (gpg->flags.use_gpgtar && !have_usable_gpgtar (gpg))
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
err = append_args_from_sender (gpg, ctx);
if (!err && gpg->flags.auto_key_import)
- err = add_arg (gpg, "--auto-key-import");
+ err = add_gpg_arg (gpg, "--auto-key-import");
if (!err && ctx->auto_key_retrieve)
- err = add_arg (gpg, "--auto-key-retrieve");
+ err = add_gpg_arg (gpg, "--auto-key-retrieve");
if (err)
;
+ else if (gpg->flags.use_gpgtar)
+ {
+ const char *file_name = gpgme_data_get_file_name (plaintext);
+ if (!err && file_name)
+ {
+ err = add_arg (gpg, "--directory");
+ if (!err)
+ err = add_arg (gpg, file_name);
+ }
+ /* gpgtar uses --decrypt also for signed-only archives */
+ err = add_arg (gpg, "--decrypt");
+ if (!err)
+ err = add_input_size_hint (gpg, sig);
+ if (!err)
+ err = add_arg (gpg, "--");
+ if (!err)
+ err = add_file_name_arg_or_data (gpg, sig, 0, 0);
+ }
else if (plaintext)
{
/* Normal or cleartext signature. */
err = add_arg (gpg, "--output");
if (!err)
- err = add_arg (gpg, "-");
+ err = add_data (gpg, plaintext, -1, 1);
if (!err)
err = add_input_size_hint (gpg, sig);
if (!err)
err = add_arg (gpg, "--");
if (!err)
- err = add_data (gpg, sig, -1, 0);
- if (!err)
- err = add_data (gpg, plaintext, 1, 1);
+ err = add_file_name_arg_or_data (gpg, sig, -1, 0);
}
else
{
@@ -3474,9 +3744,9 @@ gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
if (!err)
err = add_arg (gpg, "--");
if (!err)
- err = add_data (gpg, sig, -1, 0);
+ err = add_file_name_arg_or_data (gpg, sig, -1, 0);
if (!err && signed_text)
- err = add_data (gpg, signed_text, -1, 0);
+ err = add_file_name_arg_or_data (gpg, signed_text, -1, 0);
}
if (!err)
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index 9ab0555..24b142c 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -68,6 +68,7 @@ typedef struct
struct engine_gpgsm
{
assuan_context_t assuan_ctx;
+ char *version;
int lc_ctype_set;
int lc_messages_set;
@@ -113,6 +114,10 @@ struct engine_gpgsm
/* Memory data containing diagnostics (--logger-fd) of gpgsm */
gpgme_data_t diagnostics;
+
+ struct {
+ unsigned int offline : 1;
+ } flags;
};
typedef struct engine_gpgsm *engine_gpgsm_t;
@@ -122,6 +127,13 @@ static void gpgsm_io_event (void *engine,
gpgme_event_io_t type, void *type_data);
+/* Return true if the engine's version is at least VERSION. */
+static int
+have_gpgsm_version (engine_gpgsm_t gpgsm, const char *version)
+{
+ return _gpgme_compare_versions (gpgsm->version, version);
+}
+
static char *
gpgsm_get_version (const char *file_name)
@@ -254,6 +266,9 @@ gpgsm_release (void *engine)
gpgsm_cancel (engine);
+ if (gpgsm->version)
+ free (gpgsm->version);
+
gpgme_data_release (gpgsm->diagnostics);
free (gpgsm->colon.attic.line);
@@ -281,12 +296,20 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
char *optstr;
unsigned int connect_flags;
- (void)version; /* Not yet used. */
-
gpgsm = calloc (1, sizeof *gpgsm);
if (!gpgsm)
return gpg_error_from_syserror ();
+ if (version)
+ {
+ gpgsm->version = strdup (version);
+ if (!gpgsm->version)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ }
+
gpgsm->status_cb.fd = -1;
gpgsm->status_cb.dir = 1;
gpgsm->status_cb.tag = 0;
@@ -601,6 +624,8 @@ gpgsm_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
}
else
*gpgsm->request_origin = 0;
+
+ gpgsm->flags.offline = (ctx->offline && have_gpgsm_version (gpgsm, "2.1.6"));
}
@@ -1163,6 +1188,12 @@ start (engine_gpgsm_t gpgsm, const char *command)
return err;
}
+ gpgsm_assuan_simple_command (gpgsm,
+ gpgsm->flags.offline ?
+ "OPTION offline=1":
+ "OPTION offline=0" ,
+ NULL, NULL);
+
/* We need to know the fd used by assuan for reads. We do this by
using the assumption that the first returned fd from
assuan_get_active_fds() is always this one. */
@@ -1224,7 +1255,7 @@ gpgsm_reset (void *engine)
/* IF we have an active connection we must send a reset because we
need to reset the list of signers. Note that RESET does not
- reset OPTION commands. */
+ reset all OPTION commands. */
return (gpgsm->assuan_ctx
? gpgsm_assuan_simple_command (gpgsm, "RESET", NULL, NULL)
: 0);
@@ -1232,6 +1263,38 @@ gpgsm_reset (void *engine)
#endif
+/* Send the input-size-hint option. Note that we need to send it
+ * always so that we don't actually use a wrong hint from the last
+ * command. */
+static gpgme_error_t
+send_input_size_hint (engine_gpgsm_t gpgsm, gpgme_data_t data)
+{
+ gpg_error_t err;
+ uint64_t value;
+ char numbuf[50]; /* Large enough for even 2^128 in base-10. */
+ char cmd[100];
+ char *p;
+
+ value = _gpgme_data_get_size_hint (data);
+ if (!value)
+ value = 0;
+
+ p = numbuf + sizeof numbuf;
+ *--p = 0;
+ do
+ {
+ *--p = '0' + (value % 10);
+ value /= 10;
+ }
+ while (value);
+
+ snprintf (cmd, sizeof cmd, "OPTION input-size-hint=%s", p);
+ err = gpgsm_assuan_simple_command (gpgsm, cmd, NULL, NULL);
+ if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
+ err = 0; /* Ignore error from older gpgsm versions. */
+ return err;
+}
+
static gpgme_error_t
gpgsm_decrypt (void *engine,
@@ -1256,6 +1319,10 @@ gpgsm_decrypt (void *engine,
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
+ err = send_input_size_hint (gpgsm, ciph);
+ if (err)
+ return err;
+
gpgsm->input_cb.data = ciph;
err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
if (err)
@@ -1469,6 +1536,9 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
if (!recp && !recpstring) /* Symmetric only */
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ if (flags & GPGME_ENCRYPT_ARCHIVE)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
if ((flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
{
err = gpgsm_assuan_simple_command (gpgsm,
@@ -1477,6 +1547,21 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
return err;
}
+ if ((flags & GPGME_ENCRYPT_ALWAYS_TRUST))
+ {
+ /* Note that a RESET and the actual operation resets the
+ * always-trust option. To support older gnupg versions we
+ * ignore the unknown option error. */
+ err = gpgsm_assuan_simple_command (gpgsm,
+ "OPTION always-trust", NULL, NULL);
+ if (err && gpg_err_code (err) != GPG_ERR_UNKNOWN_OPTION)
+ return err;
+ }
+
+ err = send_input_size_hint (gpgsm, plain);
+ if (err)
+ return err;
+
gpgsm->input_cb.data = plain;
err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
if (err)
@@ -1817,7 +1902,7 @@ gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray,
static gpgme_error_t
gpgsm_keylist (void *engine, const char *pattern, int secret_only,
- gpgme_keylist_mode_t mode, int engine_flags)
+ gpgme_keylist_mode_t mode)
{
engine_gpgsm_t gpgsm = engine;
char *line;
@@ -1873,12 +1958,6 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
"OPTION with-secret=1":
"OPTION with-secret=0" ,
NULL, NULL);
- gpgsm_assuan_simple_command (gpgsm,
- (engine_flags & GPGME_ENGINE_FLAG_OFFLINE)?
- "OPTION offline=1":
- "OPTION offline=0" ,
- NULL, NULL);
-
/* Length is "LISTSECRETKEYS " + p + '\0'. */
line = malloc (15 + strlen (pattern) + 1);
@@ -1908,7 +1987,7 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
static gpgme_error_t
gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
- int reserved, gpgme_keylist_mode_t mode, int engine_flags)
+ int reserved, gpgme_keylist_mode_t mode)
{
engine_gpgsm_t gpgsm = engine;
char *line;
@@ -1948,11 +2027,6 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
"OPTION with-secret=1":
"OPTION with-secret=0" ,
NULL, NULL);
- gpgsm_assuan_simple_command (gpgsm,
- (engine_flags & GPGME_ENGINE_FLAG_OFFLINE)?
- "OPTION offline=1":
- "OPTION offline=0" ,
- NULL, NULL);
if (pattern && *pattern)
{
@@ -2040,7 +2114,7 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
static gpgme_error_t
gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
- gpgme_sig_mode_t mode, int use_armor, int use_textmode,
+ gpgme_sig_mode_t flags, int use_armor, int use_textmode,
int include_certs, gpgme_ctx_t ctx /* FIXME */)
{
engine_gpgsm_t gpgsm = engine;
@@ -2054,6 +2128,9 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
+ if (flags & (GPGME_SIG_MODE_CLEAR | GPGME_SIG_MODE_ARCHIVE))
+ return gpg_error (GPG_ERR_INV_VALUE);
+
/* FIXME: This does not work as RESET does not reset it so we can't
revert back to default. */
if (include_certs != GPGME_INCLUDE_CERTS_DEFAULT)
@@ -2090,6 +2167,10 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
return err;
}
+ err = send_input_size_hint (gpgsm, in);
+ if (err)
+ return err;
+
gpgsm->input_cb.data = in;
err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
if (err)
@@ -2102,15 +2183,16 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
gpgsm_clear_fd (gpgsm, MESSAGE_FD);
gpgsm->inline_data = NULL;
- err = start (gpgsm, mode == GPGME_SIG_MODE_DETACH
+ err = start (gpgsm, (flags & GPGME_SIG_MODE_DETACH)
? "SIGN --detached" : "SIGN");
return err;
}
static gpgme_error_t
-gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
- gpgme_data_t plaintext, gpgme_ctx_t ctx)
+gpgsm_verify (void *engine, gpgme_verify_flags_t flags, gpgme_data_t sig,
+ gpgme_data_t signed_text, gpgme_data_t plaintext,
+ gpgme_ctx_t ctx)
{
engine_gpgsm_t gpgsm = engine;
gpgme_error_t err;
@@ -2120,6 +2202,9 @@ gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
+ if (flags & GPGME_VERIFY_ARCHIVE)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
gpgsm->input_cb.data = sig;
err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
if (err)
@@ -2127,6 +2212,10 @@ gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
if (!signed_text)
{
/* Normal or cleartext signature. */
+ err = send_input_size_hint (gpgsm, sig);
+ if (err)
+ return err;
+
if (plaintext)
{
gpgsm->output_cb.data = plaintext;
@@ -2142,6 +2231,10 @@ gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
else
{
/* Detached signature. */
+ err = send_input_size_hint (gpgsm, signed_text);
+ if (err)
+ return err;
+
gpgsm->message_cb.data = signed_text;
err = gpgsm_set_fd (gpgsm, MESSAGE_FD, 0);
gpgsm_clear_fd (gpgsm, OUTPUT_FD);
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index 9fce1de..a298bec 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -1145,6 +1145,9 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
else
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
+ if (flags & GPGME_ENCRYPT_ARCHIVE)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
if (flags & GPGME_ENCRYPT_PREPARE)
{
if (!recp || plain || ciph)
@@ -1211,7 +1214,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
static gpgme_error_t
uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
- gpgme_sig_mode_t mode, int use_armor, int use_textmode,
+ gpgme_sig_mode_t flags, int use_armor, int use_textmode,
int include_certs, gpgme_ctx_t ctx /* FIXME */)
{
engine_uiserver_t uiserver = engine;
@@ -1234,8 +1237,11 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
else
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
+ if (flags & (GPGME_SIG_MODE_CLEAR | GPGME_SIG_MODE_ARCHIVE))
+ return gpg_error (GPG_ERR_INV_VALUE);
+
if (gpgrt_asprintf (&cmd, "SIGN%s%s", protocol,
- (mode == GPGME_SIG_MODE_DETACH) ? " --detached" : "") < 0)
+ (flags & GPGME_SIG_MODE_DETACH) ? " --detached" : "") < 0)
return gpg_error_from_syserror ();
key = gpgme_signers_enum (ctx, 0);
@@ -1291,8 +1297,9 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
/* FIXME: Missing a way to specify --silent. */
static gpgme_error_t
-uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
- gpgme_data_t plaintext, gpgme_ctx_t ctx)
+uiserver_verify (void *engine, gpgme_verify_flags_t flags, gpgme_data_t sig,
+ gpgme_data_t signed_text, gpgme_data_t plaintext,
+ gpgme_ctx_t ctx)
{
engine_uiserver_t uiserver = engine;
gpgme_error_t err;
@@ -1313,6 +1320,9 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
else
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
+ if (flags & GPGME_VERIFY_ARCHIVE)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
if (gpgrt_asprintf (&cmd, "VERIFY%s", protocol) < 0)
return gpg_error_from_syserror ();
diff --git a/src/engine.c b/src/engine.c
index 895b7e1..69f1c15 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -866,8 +866,7 @@ _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
gpgme_error_t
_gpgme_engine_op_keylist (engine_t engine, const char *pattern,
- int secret_only, gpgme_keylist_mode_t mode,
- int engine_flags)
+ int secret_only, gpgme_keylist_mode_t mode)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -875,15 +874,14 @@ _gpgme_engine_op_keylist (engine_t engine, const char *pattern,
if (!engine->ops->keylist)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode,
- engine_flags);
+ return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode);
}
gpgme_error_t
_gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
int secret_only, int reserved,
- gpgme_keylist_mode_t mode, int engine_flags)
+ gpgme_keylist_mode_t mode)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -892,7 +890,7 @@ _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
- reserved, mode, engine_flags);
+ reserved, mode);
}
@@ -912,7 +910,7 @@ _gpgme_engine_op_keylist_data (engine_t engine, gpgme_keylist_mode_t mode,
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,
+ gpgme_sig_mode_t flags, int use_armor,
int use_textmode, int include_certs,
gpgme_ctx_t ctx /* FIXME */)
{
@@ -922,7 +920,7 @@ _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,
if (!engine->ops->sign)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
+ return (*engine->ops->sign) (engine->engine, in, out, flags, use_armor,
use_textmode, include_certs, ctx);
}
@@ -940,9 +938,9 @@ _gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
gpgme_error_t
-_gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
- gpgme_data_t signed_text, gpgme_data_t plaintext,
- gpgme_ctx_t ctx)
+_gpgme_engine_op_verify (engine_t engine, gpgme_verify_flags_t flags,
+ gpgme_data_t sig, gpgme_data_t signed_text,
+ gpgme_data_t plaintext, gpgme_ctx_t ctx)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -950,8 +948,8 @@ _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
if (!engine->ops->verify)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext,
- ctx);
+ return (*engine->ops->verify) (engine->engine, flags, sig, signed_text,
+ plaintext, ctx);
}
diff --git a/src/engine.h b/src/engine.h
index d580d99..654dedd 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -148,25 +148,25 @@ gpgme_error_t _gpgme_engine_op_import (engine_t engine,
gpgme_error_t _gpgme_engine_op_keylist (engine_t engine,
const char *pattern,
int secret_only,
- gpgme_keylist_mode_t mode,
- int engine_flags);
+ gpgme_keylist_mode_t mode);
gpgme_error_t _gpgme_engine_op_keylist_ext (engine_t engine,
const char *pattern[],
int secret_only,
int reserved,
- gpgme_keylist_mode_t mode,
- int engine_flags);
+ gpgme_keylist_mode_t mode);
gpgme_error_t _gpgme_engine_op_keylist_data (engine_t engine,
gpgme_keylist_mode_t mode,
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,
+ gpgme_data_t out, gpgme_sig_mode_t flags,
int use_armor, int use_textmode,
int include_certs,
gpgme_ctx_t ctx /* FIXME */);
gpgme_error_t _gpgme_engine_op_trustlist (engine_t engine,
const char *pattern);
-gpgme_error_t _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
+gpgme_error_t _gpgme_engine_op_verify (engine_t engine,
+ gpgme_verify_flags_t flags,
+ gpgme_data_t sig,
gpgme_data_t signed_text,
gpgme_data_t plaintext,
gpgme_ctx_t ctx);
@@ -225,8 +225,5 @@ gpgme_error_t _gpgme_engine_op_setexpire (engine_t engine,
const char *subfprs,
unsigned int reserved);
-/* The available engine option flags. */
-#define GPGME_ENGINE_FLAG_OFFLINE 1
-
#endif /* ENGINE_H */
diff --git a/src/export.c b/src/export.c
index 155085f..d513786 100644
--- a/src/export.c
+++ b/src/export.c
@@ -35,7 +35,12 @@
/* Local operation data. */
typedef struct
{
- gpg_error_t err; /* Error encountered during the export. */
+ /* The error code from a FAILURE status line or 0. */
+ gpg_error_t failure_code;
+
+ /* Error encountered during the export. */
+ gpg_error_t err;
+
} *op_data_t;
@@ -110,6 +115,10 @@ export_status_handler (void *priv, gpgme_status_code_t code, char *args)
opd->err = err;
break;
+ case GPGME_STATUS_FAILURE:
+ opd->failure_code = _gpgme_parse_failure (args);
+ break;
+
default:
break;
}
@@ -356,7 +365,7 @@ gpgme_op_export_ext (gpgme_ctx_t ctx, const char *pattern[],
err = _gpgme_op_data_lookup (ctx, OPDATA_EXPORT, &hook, -1, NULL);
opd = hook;
if (!err)
- err = opd->err;
+ err = opd->err ? opd->err : opd->failure_code;
}
}
@@ -501,7 +510,7 @@ gpgme_op_export_keys (gpgme_ctx_t ctx,
err = _gpgme_op_data_lookup (ctx, OPDATA_EXPORT, &hook, -1, NULL);
opd = hook;
if (!err)
- err = opd->err;
+ err = opd->err ? opd->err : opd->failure_code;
}
}
diff --git a/src/gpgme-json.c b/src/gpgme-json.c
index 6077278..3d18eee 100644
--- a/src/gpgme-json.c
+++ b/src/gpgme-json.c
@@ -3064,6 +3064,59 @@ leave:
+static const char *
+data_type_to_string (gpgme_data_type_t dt)
+{
+ const char *s = "[?]";
+
+ switch (dt)
+ {
+ case GPGME_DATA_TYPE_INVALID : s = "invalid"; break;
+ case GPGME_DATA_TYPE_UNKNOWN : s = "unknown"; break;
+ case GPGME_DATA_TYPE_PGP_SIGNED : s = "PGP-signed"; break;
+ case GPGME_DATA_TYPE_PGP_SIGNATURE: s = "PGP-signature"; break;
+ case GPGME_DATA_TYPE_PGP_ENCRYPTED: s = "PGP-encrypted"; break;
+ case GPGME_DATA_TYPE_PGP_OTHER : s = "PGP"; break;
+ case GPGME_DATA_TYPE_PGP_KEY : s = "PGP-key"; break;
+ case GPGME_DATA_TYPE_CMS_SIGNED : s = "CMS-signed"; break;
+ case GPGME_DATA_TYPE_CMS_ENCRYPTED: s = "CMS-encrypted"; break;
+ case GPGME_DATA_TYPE_CMS_OTHER : s = "CMS"; break;
+ case GPGME_DATA_TYPE_X509_CERT : s = "X.509"; break;
+ case GPGME_DATA_TYPE_PKCS12 : s = "PKCS12"; break;
+ }
+ return s;
+}
+
+
+static const char hlp_identify[] =
+ "op: \"identify\"\n"
+ "data: The data to identify.\n"
+ "\n"
+ "Optional boolean flags (default is false):\n"
+ "base64: Input data is base64 encoded.\n"
+ "\n"
+ "Response:\n"
+ "result: A string describing the object.\n";
+static gpg_error_t
+op_identify (cjson_t request, cjson_t result)
+{
+ gpg_error_t err;
+ gpgme_data_t input = NULL;
+ gpgme_data_type_t dt;
+
+ if ((err = get_string_data (request, result, "data", &input)))
+ goto leave;
+
+ dt = gpgme_data_identify (input, 0);
+ xjson_AddStringToObject (result, "result", data_type_to_string (dt));
+
+ leave:
+ gpgme_data_release (input);
+ return err;
+}
+
+
+
static const char hlp_getmore[] =
"op: \"getmore\"\n"
"\n"
@@ -3163,6 +3216,7 @@ static const char hlp_help[] =
" keylist List keys.\n"
" sign Sign data.\n"
" verify Verify data.\n"
+ " identify Identify the type of the data\n"
" version Get engine information.\n"
" getmore Retrieve remaining data if chunksize was used.\n"
" help Help overview.\n"
@@ -3218,6 +3272,7 @@ process_request (const char *request)
{ "createkey", op_createkey, hlp_createkey },
{ "keylist", op_keylist, hlp_keylist },
{ "import", op_import, hlp_import },
+ { "identify", op_identify, hlp_identify },
{ "sign", op_sign, hlp_sign },
{ "verify", op_verify, hlp_verify },
{ "version", op_version, hlp_version },
@@ -3787,6 +3842,64 @@ native_messaging_repl (void)
}
+/* Run the --identify command. */
+static gpg_error_t
+cmd_identify (const char *fname)
+{
+ gpg_error_t err;
+ estream_t fp;
+ gpgme_data_t data;
+ gpgme_data_type_t dt;
+
+ if (fname)
+ {
+ fp = es_fopen (fname, "rb");
+ if (!fp)
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("can't open '%s': %s\n", fname, gpg_strerror (err));
+ return err;
+ }
+ err = gpgme_data_new_from_estream (&data, fp);
+ }
+ else
+ {
+ char *buffer;
+ int n;
+
+ fp = NULL;
+ es_set_binary (es_stdin);
+
+ /* Urgs: gpgme_data_identify does a seek and that fails for stdin. */
+ buffer = xmalloc (2048+1);
+ n = es_fread (buffer, 1, 2048, es_stdin);
+ if (n < 0 || es_ferror (es_stdin))
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("error reading '%s': %s\n", "[stdin]", gpg_strerror (err));
+ xfree (buffer);
+ return err;
+ }
+ buffer[n] = 0;
+ err = gpgme_data_new_from_mem (&data, buffer, n, 1);
+ xfree (buffer);
+ }
+
+ if (err)
+ {
+ log_error ("error creating data object: %s\n", gpg_strerror (err));
+ return err;
+ }
+
+ dt = gpgme_data_identify (data, 0);
+ if (dt == GPGME_DATA_TYPE_INVALID)
+ log_error ("error identifying data\n");
+ printf ("%s\n", data_type_to_string (dt));
+ gpgme_data_release (data);
+ es_fclose (fp);
+ return 0;
+}
+
static const char *
my_strusage( int level )
@@ -3822,6 +3935,7 @@ main (int argc, char *argv[])
CMD_INTERACTIVE = 'i',
CMD_SINGLE = 's',
CMD_LIBVERSION = 501,
+ CMD_IDENTIFY
} cmd = CMD_DEFAULT;
enum {
OPT_DEBUG = 600
@@ -3830,13 +3944,13 @@ main (int argc, char *argv[])
static gpgrt_opt_t opts[] = {
ARGPARSE_c (CMD_INTERACTIVE, "interactive", "Interactive REPL"),
ARGPARSE_c (CMD_SINGLE, "single", "Single request mode"),
+ ARGPARSE_c (CMD_IDENTIFY, "identify", "Identify the input"),
ARGPARSE_c (CMD_LIBVERSION, "lib-version", "Show library version"),
ARGPARSE_s_n(OPT_DEBUG, "debug", "Flyswatter"),
ARGPARSE_end()
};
gpgrt_argparse_t pargs = { &argc, &argv};
-
int log_file_set = 0;
gpgrt_set_strusage (my_strusage);
@@ -3860,6 +3974,7 @@ main (int argc, char *argv[])
opt_interactive = 1;
/*FALLTHROUGH*/
case CMD_SINGLE:
+ case CMD_IDENTIFY:
case CMD_LIBVERSION:
cmd = pargs.r_opt;
break;
@@ -3922,6 +4037,16 @@ main (int argc, char *argv[])
interactive_repl ();
break;
+ case CMD_IDENTIFY:
+ if (argc > 1)
+ {
+ log_error ("usage: %s --identify [filename|-]\n",
+ gpgrt_strusage (11));
+ exit (1);
+ }
+ cmd_identify (argc && strcmp (*argv, "-")? *argv : NULL);
+ break;
+
case CMD_LIBVERSION:
printf ("Version from header: %s (0x%06x)\n",
GPGME_VERSION, GPGME_VERSION_NUMBER);
diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c
index 7d3ca16..0aa2451 100644
--- a/src/gpgme-tool.c
+++ b/src/gpgme-tool.c
@@ -1909,7 +1909,19 @@ server_data_obj (assuan_fd_t fd, char *fn, int out,
err = gpgme_data_new_from_stream (data, *fs);
}
else
- err = gpgme_data_new_from_fd (data, (int) fd);
+ {
+ int posix_fd;
+
+#if defined(HAVE_W32_SYSTEM)
+ posix_fd = _open_osfhandle ((intptr_t)fd, out ? 1 : 0);
+ if (posix_fd == -1)
+ return gpg_error_from_syserror ();
+#else
+ posix_fd = fd;
+#endif
+
+ err = gpgme_data_new_from_fd (data, posix_fd);
+ }
if (err)
return err;
diff --git a/src/gpgme-w32spawn.c b/src/gpgme-w32spawn.c
index 64913b0..03ad1fb 100644
--- a/src/gpgme-w32spawn.c
+++ b/src/gpgme-w32spawn.c
@@ -40,19 +40,27 @@
#include "priv-io.h"
+/* #define DEBUG_TO_FILE 1 */
+
/* Name of this program. */
#define PGM "gpgme-w32spawn"
+#ifdef DEBUG_TO_FILE
+static FILE *mystderr;
+#else
+#define mystderr stderr
+#endif
+
-static char *
-build_commandline (char **argv)
+static wchar_t *
+build_commandline (wchar_t **argv)
{
int i;
int n = 0;
- char *buf;
- char *p;
+ wchar_t *buf;
+ wchar_t *p;
/* We have to quote some things because under Windows the program
parses the commandline and does some unquoting. We enclose the
@@ -67,7 +75,7 @@ build_commandline (char **argv)
while (*p)
{
/* An extra one for each literal that must be escaped. */
- if (*p == '\\' || *p == '"')
+ if (*p == L'\\' || *p == L'"')
n++;
n++;
p++;
@@ -78,22 +86,22 @@ build_commandline (char **argv)
/* And a trailing zero. */
n++;
- buf = p = malloc (n);
+ buf = p = malloc (n * sizeof (wchar_t));
if (!buf)
return NULL;
for (i = 0; argv[i]; i++)
{
- char *argvp = argv[i];
+ wchar_t *argvp = argv[i];
- *(p++) = '"';
+ *(p++) = L'"';
while (*argvp)
{
- if (*argvp == '\\' || *argvp == '"')
- *(p++) = '\\';
+ if (*argvp == L'\\' || *argvp == L'"')
+ *(p++) = L'\\';
*(p++) = *(argvp++);
}
- *(p++) = '"';
- *(p++) = ' ';
+ *(p++) = L'"';
+ *(p++) = L' ';
}
*(p++) = 0;
@@ -102,7 +110,7 @@ build_commandline (char **argv)
int
-my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
+my_spawn (wchar_t **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
{
SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi =
@@ -112,12 +120,11 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
0, /* returns pid */
0 /* returns tid */
};
- STARTUPINFO si;
- char *envblock = NULL;
+ STARTUPINFOW si;
int cr_flags = CREATE_DEFAULT_ERROR_MODE
| GetPriorityClass (GetCurrentProcess ());
int i;
- char *arg_string;
+ wchar_t *arg_string;
int duped_stdin = 0;
int duped_stdout = 0;
int duped_stderr = 0;
@@ -126,7 +133,7 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
i = 0;
while (argv[i])
{
- fprintf (stderr, PGM": argv[%2i] = %s\n", i, argv[i]);
+ fprintf (mystderr, PGM": argv[%2i] = %S\n", i, argv[i]);
i++;
}
@@ -146,8 +153,6 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
- fprintf (stderr, PGM": spawning: %s\n", arg_string);
-
for (i = 0; fd_list[i].fd != -1; i++)
{
/* The handle already is inheritable. */
@@ -155,19 +160,19 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
{
si.hStdInput = (HANDLE) fd_list[i].peer_name;
duped_stdin = 1;
- fprintf (stderr, PGM": dup 0x%x to stdin\n", fd_list[i].peer_name);
+ fprintf (mystderr, PGM": dup 0x%x to stdin\n", fd_list[i].peer_name);
}
else if (fd_list[i].dup_to == 1)
{
si.hStdOutput = (HANDLE) fd_list[i].peer_name;
duped_stdout = 1;
- fprintf (stderr, PGM": dup 0x%x to stdout\n", fd_list[i].peer_name);
+ fprintf (mystderr, PGM": dup 0x%x to stdout\n", fd_list[i].peer_name);
}
else if (fd_list[i].dup_to == 2)
{
si.hStdError = (HANDLE) fd_list[i].peer_name;
duped_stderr = 1;
- fprintf (stderr, PGM":dup 0x%x to stderr\n", fd_list[i].peer_name);
+ fprintf (mystderr, PGM":dup 0x%x to stderr\n", fd_list[i].peer_name);
}
}
@@ -178,13 +183,13 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
memset (&sa, 0, sizeof sa);
sa.nLength = sizeof sa;
sa.bInheritHandle = TRUE;
- hnul = CreateFile ("nul",
- GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- &sa,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
+ hnul = CreateFileW (L"nul",
+ GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ &sa,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
if (hnul == INVALID_HANDLE_VALUE)
{
free (arg_string);
@@ -204,18 +209,19 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
}
cr_flags |= CREATE_SUSPENDED;
- if (!CreateProcessA (argv[0],
+ if (!CreateProcessW (argv[0],
arg_string,
&sec_attr, /* process security attributes */
&sec_attr, /* thread security attributes */
TRUE, /* inherit handles */
cr_flags, /* creation flags */
- envblock, /* environment */
+ NULL, /* environment */
NULL, /* use current drive/directory */
&si, /* startup information */
&pi)) /* returns process information */
{
free (arg_string);
+ fprintf (mystderr, PGM": spawn error: %d\n", (int)GetLastError ());
/* FIXME: Should translate the error code. */
errno = EIO;
return -1;
@@ -240,7 +246,7 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
{
/* Available since W2000; thus we dynload it. */
initialized = 1;
- handle = LoadLibrary ("user32.dll");
+ handle = LoadLibraryA ("user32.dll");
if (handle)
{
func = GetProcAddress (handle, "AllowSetForegroundWindow");
@@ -252,7 +258,7 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
if (func)
{
int rc = func (pi.dwProcessId);
- fprintf (stderr, PGM": AllowSetForegroundWindow(%d): rc=%d\n",
+ fprintf (mystderr, PGM": AllowSetForegroundWindow(%d): rc=%d\n",
(int)pi.dwProcessId, rc);
}
}
@@ -268,7 +274,7 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
#define MAX_TRANS 10
int
-translate_get_from_file (const char *trans_file,
+translate_get_from_file (const wchar_t *trans_file,
struct spawn_fd_item_s *fd_list,
unsigned int *r_flags)
{
@@ -285,7 +291,7 @@ translate_get_from_file (const char *trans_file,
*r_flags = 0;
- fd = open (trans_file, O_RDONLY);
+ fd = _wopen (trans_file, O_RDONLY);
if (fd < 0)
return -1;
@@ -382,14 +388,14 @@ translate_get_from_file (const char *trans_file,
/* Read the translated handles from TRANS_FILE and do a substitution
in ARGV. Returns the new argv and the list of substitutions in
FD_LIST (which must be MAX_TRANS+1 large). */
-char **
-translate_handles (const char *trans_file, const char * const *argv,
+wchar_t **
+translate_handles (const wchar_t *trans_file, const wchar_t * const *argv,
struct spawn_fd_item_s *fd_list, unsigned int *r_flags)
{
int res;
int idx;
int n_args;
- char **args;
+ wchar_t **args;
res = translate_get_from_file (trans_file, fd_list, r_flags);
if (res < 0)
@@ -400,7 +406,7 @@ translate_handles (const char *trans_file, const char * const *argv,
args = malloc (sizeof (*args) * (idx + 1));
for (idx = 0; argv[idx]; idx++)
{
- args[idx] = strdup (argv[idx]);
+ args[idx] = wcsdup (argv[idx]);
if (!args[idx])
return NULL;
}
@@ -409,7 +415,7 @@ translate_handles (const char *trans_file, const char * const *argv,
for (idx = 0; fd_list[idx].fd != -1; idx++)
{
- char buf[25];
+ wchar_t buf[25];
int aidx;
aidx = fd_list[idx].arg_loc;
@@ -418,7 +424,7 @@ translate_handles (const char *trans_file, const char * const *argv,
if (aidx >= n_args)
{
- fprintf (stderr, PGM": translation file does not match args\n");
+ fprintf (mystderr, PGM": translation file does not match args\n");
return NULL;
}
@@ -432,20 +438,27 @@ translate_handles (const char *trans_file, const char * const *argv,
/* NOTE: Here is the part where application specific knowledge
comes in. GPGME/GnuPG uses two forms of descriptor
specification, a plain number and a "-&" form. */
- if (argv[aidx][0] == '-' && argv[aidx][1] == '&')
- snprintf (args[aidx], sizeof (buf), "-&%d", fd_list[idx].peer_name);
+ if (argv[aidx][0] == L'-' && argv[aidx][1] == L'&')
+ snwprintf (args[aidx], sizeof (buf), L"-&%d", fd_list[idx].peer_name);
else
- snprintf (args[aidx], sizeof (buf), "%d", fd_list[idx].peer_name);
+ snwprintf (args[aidx], sizeof (buf), L"%d", fd_list[idx].peer_name);
}
return args;
}
+/* Since GPGME might be installed in a unicode directory it
+ must be callable with CreateProcessW which provides the
+ arguments in Unicode form.
+
+ So GPGME converts from its internal UTF-8 representation
+ to wchar, spawns gpgme-w32-spawn with CreateProcessW and then
+ we also forward this as wchar. */
int
-main (int argc, const char * const *argv)
+wmain (int argc, const wchar_t * const *argv)
{
int rc = 0;
- char **argv_spawn;
+ wchar_t **argv_spawn;
struct spawn_fd_item_s fd_list[MAX_TRANS + 1];
unsigned int flags;
@@ -455,6 +468,10 @@ main (int argc, const char * const *argv)
goto leave;
}
+#ifdef DEBUG_TO_FILE
+ mystderr = fopen ("h:/gpgme-w32spawn.log", "w");
+#endif
+
argv_spawn = translate_handles (argv[1], &argv[2], fd_list, &flags);
if (!argv_spawn)
{
@@ -468,7 +485,7 @@ main (int argc, const char * const *argv)
rc = my_spawn (argv_spawn, fd_list, flags);
if (rc < 0)
{
- fprintf (stderr, PGM": executing `%s' failed: %s\n",
+ fprintf (mystderr, PGM": executing `%S' failed: %s\n",
argv[0], strerror (errno));
rc = 2;
goto leave;
@@ -476,12 +493,12 @@ main (int argc, const char * const *argv)
leave:
if (rc)
- fprintf (stderr, PGM": internal error\n");
+ fprintf (mystderr, PGM": internal error\n");
/* Always try to delete the temporary file. */
if (argc >= 2)
{
- if (DeleteFile (argv[1]) == 0)
- fprintf (stderr, PGM": failed to delete %s: ec=%ld\n",
+ if (DeleteFileW (argv[1]) == 0)
+ fprintf (mystderr, PGM": failed to delete %S: ec=%ld\n",
argv[1], GetLastError ());
}
return rc;
diff --git a/src/gpgme.c b/src/gpgme.c
index 2c5b51e..135a75a 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -79,6 +79,11 @@ gpgme_set_global_flag (const char *name, const char *value)
return _gpgme_set_default_gpgconf_name (value);
else if (!strcmp (name, "gpg-name"))
return _gpgme_set_default_gpg_name (value);
+ else if (!strcmp (name, "inst-type"))
+ {
+ _gpgme_set_get_inst_type (value);
+ return 0;
+ }
else if (!strcmp (name, "w32-inst-dir"))
return _gpgme_set_override_inst_dir (value);
else
@@ -602,6 +607,10 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
if (!ctx->import_filter)
err = gpg_error_from_syserror ();
}
+ else if (!strcmp (name, "no-auto-check-trustdb"))
+ {
+ ctx->no_auto_check_trustdb = abool;
+ }
else
err = gpg_error (GPG_ERR_UNKNOWN_NAME);
@@ -683,6 +692,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
{
return ctx->import_filter? ctx->import_filter : "";
}
+ else if (!strcmp (name, "no-auto-check-trustdb"))
+ {
+ return ctx->no_auto_check_trustdb? "1":"";
+ }
else
return NULL;
}
diff --git a/src/gpgme.def b/src/gpgme.def
index d8ccd4c..67c189c 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -283,5 +283,7 @@ EXPORTS
gpgme_op_receive_keys @209
gpgme_op_receive_keys_start @210
+ gpgme_op_verify_ext @211
+ gpgme_op_verify_ext_start @212
; END
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 502d68c..d44994a 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -303,12 +303,13 @@ typedef enum
gpgme_hash_algo_t;
-/* The available signature modes. */
+/* The available signature mode flags. */
typedef enum
{
GPGME_SIG_MODE_NORMAL = 0,
GPGME_SIG_MODE_DETACH = 1,
- GPGME_SIG_MODE_CLEAR = 2
+ GPGME_SIG_MODE_CLEAR = 2,
+ GPGME_SIG_MODE_ARCHIVE = 4
}
gpgme_sig_mode_t;
@@ -383,6 +384,7 @@ gpgme_protocol_t;
#define GPGME_KEYLIST_MODE_EPHEMERAL 128
#define GPGME_KEYLIST_MODE_VALIDATE 256
#define GPGME_KEYLIST_MODE_FORCE_EXTERN 512
+#define GPGME_KEYLIST_MODE_WITH_V5FPR 1024
#define GPGME_KEYLIST_MODE_LOCATE (1|2)
#define GPGME_KEYLIST_MODE_LOCATE_EXTERNAL (1|2|512)
@@ -574,8 +576,17 @@ struct _gpgme_subkey
/* True if the key is compliant to the de-vs mode. */
unsigned int is_de_vs : 1;
+ /* True if the key can be used for restricted encryption (ADSK). */
+ unsigned int can_renc : 1;
+
+ /* True if the key can be used for timestamping. */
+ unsigned int can_timestamp : 1;
+
+ /* True if the private key is possessed by more than one person. */
+ unsigned int is_group_owned : 1;
+
/* Internal to GPGME, do not use. */
- unsigned int _unused : 20;
+ unsigned int _unused : 17;
/* Public key algorithm supported by this subkey. */
gpgme_pubkey_algo_t pubkey_algo;
@@ -606,6 +617,9 @@ struct _gpgme_subkey
/* The keygrip of the subkey in hex digit form or NULL if not available. */
char *keygrip;
+
+ /* For OpenPGP the v5 fpr of a v4 key. For X.509 the SHA256 fingerprint. */
+ char *v5fpr;
};
typedef struct _gpgme_subkey *gpgme_subkey_t;
@@ -786,8 +800,20 @@ struct _gpgme_key
/* True if subkey is qualified for signatures according to German law. */
unsigned int is_qualified : 1;
+ /* True if key has at least one encryption subkey. */
+ unsigned int has_encrypt : 1;
+
+ /* True if key has at least one signing subkey. */
+ unsigned int has_sign : 1;
+
+ /* True if key has a certification capability. */
+ unsigned int has_certify : 1;
+
+ /* True if key has at least one authentication subkey. */
+ unsigned int has_authenticate : 1;
+
/* Internal to GPGME, do not use. */
- unsigned int _unused : 17;
+ unsigned int _unused : 13;
/* Origin of this key. */
unsigned int origin : 5;
@@ -1299,7 +1325,8 @@ typedef enum
GPGME_ENCRYPT_SYMMETRIC = 32,
GPGME_ENCRYPT_THROW_KEYIDS = 64,
GPGME_ENCRYPT_WRAP = 128,
- GPGME_ENCRYPT_WANT_ADDRESS = 256
+ GPGME_ENCRYPT_WANT_ADDRESS = 256,
+ GPGME_ENCRYPT_ARCHIVE = 512
}
gpgme_encrypt_flags_t;
@@ -1424,6 +1451,7 @@ gpgme_decrypt_result_t gpgme_op_decrypt_result (gpgme_ctx_t ctx);
typedef enum
{
GPGME_DECRYPT_VERIFY = 1,
+ GPGME_DECRYPT_ARCHIVE = 2,
GPGME_DECRYPT_UNWRAP = 128
}
gpgme_decrypt_flags_t;
@@ -1519,10 +1547,10 @@ gpgme_sign_result_t gpgme_op_sign_result (gpgme_ctx_t ctx);
/* Sign the plaintext PLAIN and store the signature in SIG. */
gpgme_error_t gpgme_op_sign_start (gpgme_ctx_t ctx,
gpgme_data_t plain, gpgme_data_t sig,
- gpgme_sig_mode_t mode);
+ gpgme_sig_mode_t flags);
gpgme_error_t gpgme_op_sign (gpgme_ctx_t ctx,
gpgme_data_t plain, gpgme_data_t sig,
- gpgme_sig_mode_t mode);
+ gpgme_sig_mode_t flags);
/*
@@ -1631,6 +1659,13 @@ typedef struct _gpgme_op_verify_result *gpgme_verify_result_t;
/* Retrieve a pointer to the result of the verify operation. */
gpgme_verify_result_t gpgme_op_verify_result (gpgme_ctx_t ctx);
+/* The valid verify flags. */
+typedef enum
+ {
+ GPGME_VERIFY_ARCHIVE = 1
+ }
+gpgme_verify_flags_t;
+
/* Verify within CTX that SIG is a valid signature for TEXT. */
gpgme_error_t gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
gpgme_data_t signed_text,
@@ -1638,6 +1673,16 @@ gpgme_error_t gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
gpgme_error_t gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig,
gpgme_data_t signed_text,
gpgme_data_t plaintext);
+gpgme_error_t gpgme_op_verify_ext_start (gpgme_ctx_t ctx,
+ gpgme_verify_flags_t flags,
+ gpgme_data_t sig,
+ gpgme_data_t signed_text,
+ gpgme_data_t plaintext);
+gpgme_error_t gpgme_op_verify_ext (gpgme_ctx_t ctx,
+ gpgme_verify_flags_t flags,
+ gpgme_data_t sig,
+ gpgme_data_t signed_text,
+ gpgme_data_t plaintext);
/*
diff --git a/src/gpgme.m4 b/src/gpgme.m4
index c749a5d..f2906c1 100644
--- a/src/gpgme.m4
+++ b/src/gpgme.m4
@@ -1,5 +1,5 @@
# gpgme.m4 - autoconf macro to detect GPGME.
-# Copyright (C) 2002, 2003, 2004, 2014, 2018 g10 Code GmbH
+# Copyright (C) 2002, 2003, 2004, 2014, 2018, 2022 g10 Code GmbH
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
@@ -9,13 +9,102 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
-# Last-changed: 2020-11-20
+# Last-changed: 2022-11-25
-AC_DEFUN([_AM_PATH_GPGME_CONFIG],
-[ AC_ARG_WITH(gpgme-prefix,
- AS_HELP_STRING([--with-gpgme-prefix=PFX],
- [prefix where GPGME is installed (optional)]),
+dnl
+dnl Find gpgrt-config, which uses .pc file
+dnl (minimum pkg-config functionality, supporting cross build)
+dnl
+dnl _AM_PATH_GPGRT_CONFIG
+AC_DEFUN([_AM_PATH_GPGRT_CONFIG],[dnl
+ AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no, [$prefix/bin:$PATH])
+ if test "$GPGRT_CONFIG" != "no"; then
+ # Determine gpgrt_libdir
+ #
+ # Get the prefix of gpgrt-config assuming it's something like:
+ # <PREFIX>/bin/gpgrt-config
+ gpgrt_prefix=${GPGRT_CONFIG%/*/*}
+ possible_libdir1=${gpgrt_prefix}/lib
+ # Determine by using system libdir-format with CC, it's like:
+ # Normal style: /usr/lib
+ # GNU cross style: /usr/<triplet>/lib
+ # Debian style: /usr/lib/<multiarch-name>
+ # Fedora/openSUSE style: /usr/lib, /usr/lib32 or /usr/lib64
+ # It is assumed that CC is specified to the one of host on cross build.
+ if libdir_candidates=$(${CC:-cc} -print-search-dirs | \
+ sed -n -e "/^libraries/{s/libraries: =//;s/:/\\
+/g;p;}"); then
+ # From the output of -print-search-dirs, select valid pkgconfig dirs.
+ libdir_candidates=$(for dir in $libdir_candidates; do
+ if p=$(cd $dir 2>/dev/null && pwd); then
+ test -d "$p/pkgconfig" && echo $p;
+ fi
+ done)
+
+ for possible_libdir0 in $libdir_candidates; do
+ # possible_libdir0:
+ # Fallback candidate, the one of system-installed (by $CC)
+ # (/usr/<triplet>/lib, /usr/lib/<multiarch-name> or /usr/lib32)
+ # possible_libdir1:
+ # Another candidate, user-locally-installed
+ # (<gpgrt_prefix>/lib)
+ # possible_libdir2
+ # Most preferred
+ # (<gpgrt_prefix>/<triplet>/lib,
+ # <gpgrt_prefix>/lib/<multiarch-name> or <gpgrt_prefix>/lib32)
+ if test "${possible_libdir0##*/}" = "lib"; then
+ possible_prefix0=${possible_libdir0%/lib}
+ possible_prefix0_triplet=${possible_prefix0##*/}
+ if test -z "$possible_prefix0_triplet"; then
+ continue
+ fi
+ possible_libdir2=${gpgrt_prefix}/$possible_prefix0_triplet/lib
+ else
+ possible_prefix0=${possible_libdir0%%/lib*}
+ possible_libdir2=${gpgrt_prefix}${possible_libdir0#$possible_prefix0}
+ fi
+ if test -f ${possible_libdir2}/pkgconfig/gpg-error.pc; then
+ gpgrt_libdir=${possible_libdir2}
+ elif test -f ${possible_libdir1}/pkgconfig/gpg-error.pc; then
+ gpgrt_libdir=${possible_libdir1}
+ elif test -f ${possible_libdir0}/pkgconfig/gpg-error.pc; then
+ gpgrt_libdir=${possible_libdir0}
+ fi
+ if test -n "$gpgrt_libdir"; then break; fi
+ done
+ if test -z "$libdir_candidates"; then
+ # No valid pkgconfig dir in any of the system directories, fallback
+ gpgrt_libdir=${possible_libdir1}
+ fi
+ else
+ # When we cannot determine system libdir-format, use this:
+ gpgrt_libdir=${possible_libdir1}
+ fi
+ else
+ unset GPGRT_CONFIG
+ fi
+
+ if test -n "$gpgrt_libdir"; then
+ GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir"
+ if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then
+ GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error"
+ AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config])
+ gpg_error_config_version=`$GPG_ERROR_CONFIG --modversion`
+ else
+ unset GPGRT_CONFIG
+ fi
+ elif test "$GPG_ERROR_CONFIG" != "no"; then
+ gpg_error_config_version=`$GPG_ERROR_CONFIG --version`
+ unset GPGRT_CONFIG
+ fi
+])
+
+AC_DEFUN([_AM_PATH_GPGME_CONFIG],[dnl
+AC_REQUIRE([_AM_PATH_GPGRT_CONFIG])dnl
+ AC_ARG_WITH(gpgme-prefix,
+ AS_HELP_STRING([--with-gpgme-prefix=PFX],
+ [prefix where GPGME is installed (optional)]),
gpgme_config_prefix="$withval", gpgme_config_prefix="")
if test x"${GPGME_CONFIG}" = x ; then
if test x"${gpgme_config_prefix}" != x ; then
@@ -37,7 +126,7 @@ AC_DEFUN([_AM_PATH_GPGME_CONFIG],
fi
use_gpgrt_config=""
- if test x"${GPGME_CONFIG}" = x -a x"$GPGRT_CONFIG" != x -a "$GPGRT_CONFIG" != "no"; then
+ if test x"$GPGRT_CONFIG" != x -a "$GPGRT_CONFIG" != "no"; then
if $GPGRT_CONFIG gpgme --exists; then
GPGME_CONFIG="$GPGRT_CONFIG gpgme"
AC_MSG_NOTICE([Use gpgrt-config as gpgme-config])
@@ -169,8 +258,9 @@ dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for libgpgme and define GPGME_PTHREAD_CFLAGS
dnl and GPGME_PTHREAD_LIBS.
dnl
-AC_DEFUN([AM_PATH_GPGME_PTHREAD],
-[ AC_REQUIRE([_AM_PATH_GPGME_CONFIG])dnl
+AC_DEFUN([AM_PATH_GPGME_PTHREAD],[
+ AC_OBSOLETE([$0], [; use AM_PATH_GPGME instead to use GPGME_CFLAGS and GPGME_LIBS])dnl
+ AC_REQUIRE([_AM_PATH_GPGME_CONFIG])dnl
tmp=ifelse([$1], ,1:0.4.2,$1)
if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
req_gpgme_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
@@ -183,35 +273,37 @@ AC_DEFUN([AM_PATH_GPGME_PTHREAD],
AC_MSG_CHECKING(for GPGME pthread - version >= $min_gpgme_version)
ok=no
if test "$GPGME_CONFIG" != "no" ; then
- if `$GPGME_CONFIG --thread=pthread 2> /dev/null` ; then
- req_major=`echo $min_gpgme_version | \
+ req_major=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
- req_minor=`echo $min_gpgme_version | \
+ req_minor=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
- req_micro=`echo $min_gpgme_version | \
+ req_micro=`echo $min_gpgme_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
- if test "$gpgme_version_major" -gt "$req_major"; then
+ if test "$gpgme_version_major" -gt "$req_major"; then
ok=yes
- else
+ else
if test "$gpgme_version_major" -eq "$req_major"; then
- if test "$gpgme_version_minor" -gt "$req_minor"; then
- ok=yes
- else
- if test "$gpgme_version_minor" -eq "$req_minor"; then
- if test "$gpgme_version_micro" -ge "$req_micro"; then
- ok=yes
- fi
+ if test "$gpgme_version_minor" -gt "$req_minor"; then
+ ok=yes
+ else
+ if test "$gpgme_version_minor" -eq "$req_minor"; then
+ if test "$gpgme_version_micro" -ge "$req_micro"; then
+ ok=yes
+ fi
+ fi
fi
- fi
fi
- fi
fi
fi
if test $ok = yes; then
# If we have a recent GPGME, we should also check that the
# API is compatible.
if test "$req_gpgme_api" -gt 0 ; then
- tmp=`$GPGME_CONFIG --api-version 2>/dev/null || echo 0`
+ if test -z "$use_gpgrt_config"; then
+ tmp=`$GPGME_CONFIG --api-version 2>/dev/null || echo 0`
+ else
+ tmp=`$GPGME_CONFIG --variable=api_version 2>/dev/null || echo 0`
+ fi
if test "$tmp" -gt 0 ; then
if test "$req_gpgme_api" -ne "$tmp" ; then
ok=no
@@ -220,8 +312,8 @@ AC_DEFUN([AM_PATH_GPGME_PTHREAD],
fi
fi
if test $ok = yes; then
- GPGME_PTHREAD_CFLAGS=`$GPGME_CONFIG --thread=pthread --cflags`
- GPGME_PTHREAD_LIBS=`$GPGME_CONFIG --thread=pthread --libs`
+ GPGME_PTHREAD_CFLAGS=`$GPGME_CONFIG --cflags`
+ GPGME_PTHREAD_LIBS=`$GPGME_CONFIG --libs`
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
_AM_PATH_GPGME_CONFIG_HOST_CHECK
diff --git a/src/gpgme.pc.in b/src/gpgme.pc.in
index 80d59de..9ddef5c 100644
--- a/src/gpgme.pc.in
+++ b/src/gpgme.pc.in
@@ -9,6 +9,6 @@ Name: gpgme
Description: GnuPG Made Easy to access GnuPG
Requires.private: gpg-error, libassuan
Version: @PACKAGE_VERSION@
-Cflags: -I${includedir} @GPGME_CONFIG_CFLAGS@
-Libs: -L${libdir} @GPGME_CONFIG_LIBS@
+Cflags: @GPGME_CONFIG_CFLAGS@
+Libs: @GPGME_CONFIG_LIBS@
URL: https://www.gnupg.org/software/gpgme/index.html
diff --git a/src/import.c b/src/import.c
index cd9f960..f46313c 100644
--- a/src/import.c
+++ b/src/import.c
@@ -129,7 +129,7 @@ parse_import (char *args, gpgme_import_status_t *import_status, int problem)
gpg_err_set_errno (0);
nr = strtol (args, &tail, 0);
- if (errno || args == tail || *tail != ' ')
+ if (errno || args == tail)
{
/* The crypto backend does not behave. */
free (import);
@@ -173,12 +173,17 @@ parse_import (char *args, gpgme_import_status_t *import_status, int problem)
if (tail)
*tail = '\0';
- import->fpr = strdup (args);
- if (!import->fpr)
+ if (*args)
{
- free (import);
- return gpg_error_from_syserror ();
+ import->fpr = strdup (args);
+ if (!import->fpr)
+ {
+ free (import);
+ return gpg_error_from_syserror ();
+ }
}
+ else
+ import->fpr = NULL;
*import_status = import;
return 0;
diff --git a/src/key.c b/src/key.c
index 322bd0a..93cdc1c 100644
--- a/src/key.c
+++ b/src/key.c
@@ -342,6 +342,7 @@ gpgme_key_unref (gpgme_key_t key)
{
gpgme_subkey_t next = subkey->next;
free (subkey->fpr);
+ free (subkey->v5fpr);
free (subkey->curve);
free (subkey->keygrip);
free (subkey->card_number);
diff --git a/src/keylist.c b/src/keylist.c
index 1c01bd4..2f6ae82 100644
--- a/src/keylist.c
+++ b/src/keylist.c
@@ -58,6 +58,9 @@ typedef struct
/* The error code from ERROR keydb_search. */
gpgme_error_t keydb_search_err;
+ /* The error code from a FAILURE status line or 0. */
+ gpg_error_t failure_code;
+
gpgme_key_t tmp_key;
/* This points to the last uid in tmp_key. */
@@ -146,6 +149,13 @@ keylist_status_handler (void *priv, gpgme_status_code_t code, char *args)
err = 0;
break;
+ case GPGME_STATUS_FAILURE:
+ opd->failure_code = _gpgme_parse_failure (args);
+ if (opd->failure_code && !strcmp (args, "option-parser")
+ && gpg_err_code (opd->failure_code) == GPG_ERR_GENERAL)
+ err = gpg_error (GPG_ERR_INV_ENGINE);
+ break;
+
case GPGME_STATUS_IMPORT_OK:
case GPGME_STATUS_IMPORT_PROBLEM:
case GPGME_STATUS_IMPORT_RES:
@@ -287,6 +297,18 @@ set_subkey_capability (gpgme_subkey_t subkey, const char *src)
subkey->can_authenticate = 1;
break;
+ case 'r':
+ subkey->can_renc = 1;
+ break;
+
+ case 't':
+ subkey->can_timestamp = 1;
+ break;
+
+ case 'g':
+ subkey->is_group_owned = 1;
+ break;
+
case 'q':
subkey->is_qualified = 1;
break;
@@ -541,6 +563,26 @@ static void
finish_key (gpgme_ctx_t ctx, op_data_t opd)
{
gpgme_key_t key = opd->tmp_key;
+ gpgme_subkey_t subkey;
+
+ /* Set the has_foo flags from the subkey capabilities. */
+ if (key)
+ {
+ /* Note that we could have set has_certify always for OpenPGP
+ * but for X.509 a key is often not allowed to certify and thus
+ * we better take it from the subkey capabilities. */
+ for (subkey = key->subkeys; subkey; subkey = subkey->next)
+ {
+ if (subkey->can_encrypt)
+ key->has_encrypt = 1;
+ if (subkey->can_sign)
+ key->has_sign = 1;
+ if (subkey->can_certify)
+ key->has_certify = 1;
+ if (subkey->can_authenticate)
+ key->has_authenticate = 1;
+ }
+ }
opd->tmp_key = NULL;
opd->tmp_uid = NULL;
@@ -558,7 +600,7 @@ keylist_colon_handler (void *priv, char *line)
gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
enum
{
- RT_NONE, RT_SIG, RT_UID, RT_TFS, RT_SUB, RT_PUB, RT_FPR, RT_GRP,
+ RT_NONE, RT_SIG, RT_UID, RT_TFS, RT_SUB, RT_PUB, RT_FPR, RT_FP2, RT_GRP,
RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
}
rectype = RT_NONE;
@@ -611,6 +653,8 @@ keylist_colon_handler (void *priv, char *line)
rectype = RT_CRS;
else if (!strcmp (field[0], "fpr") && key)
rectype = RT_FPR;
+ else if (!strcmp (field[0], "fp2") && key)
+ rectype = RT_FP2;
else if (!strcmp (field[0], "grp") && key)
rectype = RT_GRP;
else if (!strcmp (field[0], "uid") && key)
@@ -902,6 +946,27 @@ keylist_colon_handler (void *priv, char *line)
}
break;
+ case RT_FP2:
+ /* Either the SHA256 fingerprint of an X.509 cert or the
+ * alternate fingerprint of a v4 OpenPGP packet. (We take only
+ * the first one). */
+ if (fields >= 10 && field[9] && *field[9])
+ {
+ /* Need to apply it to the last subkey because all subkeys
+ do have fingerprints. */
+ subkey = key->_last_subkey;
+ if (!subkey->v5fpr)
+ {
+ subkey->v5fpr = strdup (field[9]);
+ if (!subkey->v5fpr)
+ return gpg_error_from_syserror ();
+ }
+ /* Note that we don't store a copy in the key object as we
+ * do with the standard fingerprint. */
+ }
+ break;
+
+
case RT_GRP:
/* Field 10 has the keygrip. */
if (fields >= 10 && field[9] && *field[9])
@@ -1114,7 +1179,6 @@ gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
gpgme_error_t err;
void *hook;
op_data_t opd;
- int flags = 0;
TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_start", ctx,
"pattern=%s, secret_only=%i", pattern, secret_only);
@@ -1143,11 +1207,8 @@ gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
if (err)
return TRACE_ERR (err);
- if (ctx->offline)
- flags |= GPGME_ENGINE_FLAG_OFFLINE;
-
err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
- ctx->keylist_mode, flags);
+ ctx->keylist_mode);
return TRACE_ERR (err);
}
@@ -1162,7 +1223,6 @@ gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
gpgme_error_t err;
void *hook;
op_data_t opd;
- int flags = 0;
TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_ext_start", ctx,
"secret_only=%i, reserved=0x%x", secret_only, reserved);
@@ -1190,12 +1250,8 @@ gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
if (err)
return TRACE_ERR (err);
- if (ctx->offline)
- flags |= GPGME_ENGINE_FLAG_OFFLINE;
-
err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
- reserved, ctx->keylist_mode,
- flags);
+ reserved, ctx->keylist_mode);
return TRACE_ERR (err);
}
@@ -1296,12 +1352,21 @@ gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
gpgme_error_t
gpgme_op_keylist_end (gpgme_ctx_t ctx)
{
+ void *hook;
+ op_data_t opd;
+ gpg_error_t err;
+
TRACE (DEBUG_CTX, "gpgme_op_keylist_end", ctx, "");
if (!ctx)
return gpg_error (GPG_ERR_INV_VALUE);
- return 0;
+ err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
+ opd = hook;
+ if (!err && opd && opd->failure_code)
+ err = opd->failure_code;
+
+ return err;
}
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index 86d2a5d..20ae9fe 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -282,6 +282,9 @@ GPGME_1.0 {
gpgme_op_receive_keys;
gpgme_op_receive_keys_start;
+ gpgme_op_verify_ext;
+ gpgme_op_verify_ext_start;
+
local:
*;
diff --git a/src/parsetlv.c b/src/parsetlv.c
index 69f48eb..e6ae44d 100644
--- a/src/parsetlv.c
+++ b/src/parsetlv.c
@@ -98,6 +98,9 @@ _gpgme_parse_tlv (char const **buffer, size_t *size, tlvinfo_t *ti)
ti->length = len;
}
+ if (ti->length > ti->nhdr && (ti->nhdr + ti->length) < ti->length)
+ return -1; /* Integer overflow. */
+
*buffer = (void*)buf;
*size = length;
return 0;
diff --git a/src/posix-util.c b/src/posix-util.c
index cf066d6..09c2554 100644
--- a/src/posix-util.c
+++ b/src/posix-util.c
@@ -79,6 +79,15 @@ _gpgme_set_override_inst_dir (const char *dir)
return 0;
}
+/* Dummy function - see w32-util.c for the actual code. */
+int
+_gpgme_set_get_inst_type (const char *value)
+{
+ (void)value;
+ return 0; /* Posix installation type is fixed. */
+}
+
+
/* Find an executable program in the colon seperated paths. */
static char *
walk_path_str (const char *path_str, const char *pgm)
@@ -135,7 +144,8 @@ find_executable (const char *pgm)
/* On apple, especially when started through gpgme-json via
the browser interface we should look into some additional
fallback paths. */
- const char *additional_path = "/usr/local/bin:/usr/local/MacGPG2/bin";
+ const char *additional_path
+ = "/usr/local/bin:/usr/local/MacGPG2/bin:/opt/homebrew/bin";
if (!ret)
{
ret = walk_path_str (additional_path, pgm);
diff --git a/src/sign.c b/src/sign.c
index 31081ae..51f581c 100644
--- a/src/sign.c
+++ b/src/sign.c
@@ -125,7 +125,7 @@ gpgme_op_sign_result (gpgme_ctx_t ctx)
if (gpgme_signers_count (ctx)
&& signatures + inv_signers != gpgme_signers_count (ctx))
{
- /* In this case at least one signatures was not created perhaps
+ /* In this case at least one signature was not created perhaps
due to a bad passphrase etc. Thus the entire message is
broken and should not be used. We add the already created
signatures to the invalid signers list and thus this case can
@@ -251,7 +251,16 @@ parse_sig_created (char *args, gpgme_new_signature_t *sigp,
}
args = tail;
+ /* strtol has been used wrongly here. We can't change this anymore
+ * but we now take care of the 0x1f class which would otherwise let
+ * us run into an error. */
sig->sig_class = strtol (args, &tail, 0);
+ if (!errno && args != tail && sig->sig_class == 1
+ && (*tail == 'F' || *tail == 'f'))
+ {
+ tail++;
+ sig->sig_class = 131; /* Arbitrary unused value in rfc4880. */
+ }
sig->class = sig->sig_class;
sig->_obsolete_class = sig->sig_class;
if (errno || args == tail || *tail != ' ')
@@ -422,7 +431,7 @@ _gpgme_op_sign_init_result (gpgme_ctx_t ctx)
static gpgme_error_t
sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t plain,
- gpgme_data_t sig, gpgme_sig_mode_t mode)
+ gpgme_data_t sig, gpgme_sig_mode_t flags)
{
gpgme_error_t err;
@@ -437,8 +446,9 @@ sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t plain,
if (err)
return err;
- if (mode != GPGME_SIG_MODE_NORMAL && mode != GPGME_SIG_MODE_DETACH
- && mode != GPGME_SIG_MODE_CLEAR)
+ if (flags & ~(GPGME_SIG_MODE_DETACH
+ |GPGME_SIG_MODE_CLEAR
+ |GPGME_SIG_MODE_ARCHIVE))
return gpg_error (GPG_ERR_INV_VALUE);
if (!plain)
@@ -457,7 +467,7 @@ sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t plain,
_gpgme_engine_set_status_handler (ctx->engine, sign_status_handler,
ctx);
- return _gpgme_engine_op_sign (ctx->engine, plain, sig, mode, ctx->use_armor,
+ return _gpgme_engine_op_sign (ctx->engine, plain, sig, flags, ctx->use_armor,
ctx->use_textmode, ctx->include_certs,
ctx /* FIXME */);
}
@@ -466,16 +476,16 @@ sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t plain,
/* Sign the plaintext PLAIN and store the signature in SIG. */
gpgme_error_t
gpgme_op_sign_start (gpgme_ctx_t ctx, gpgme_data_t plain, gpgme_data_t sig,
- gpgme_sig_mode_t mode)
+ gpgme_sig_mode_t flags)
{
gpg_error_t err;
TRACE_BEG (DEBUG_CTX, "gpgme_op_sign_start", ctx,
- "plain=%p, sig=%p, mode=%i", plain, sig, mode);
+ "plain=%p, sig=%p, flags=%i", plain, sig, flags);
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = sign_start (ctx, 0, plain, sig, mode);
+ err = sign_start (ctx, 0, plain, sig, flags);
return TRACE_ERR (err);
}
@@ -483,17 +493,17 @@ gpgme_op_sign_start (gpgme_ctx_t ctx, gpgme_data_t plain, gpgme_data_t sig,
/* Sign the plaintext PLAIN and store the signature in SIG. */
gpgme_error_t
gpgme_op_sign (gpgme_ctx_t ctx, gpgme_data_t plain, gpgme_data_t sig,
- gpgme_sig_mode_t mode)
+ gpgme_sig_mode_t flags)
{
gpgme_error_t err;
TRACE_BEG (DEBUG_CTX, "gpgme_op_sign", ctx,
- "plain=%p, sig=%p, mode=%i", plain, sig, mode);
+ "plain=%p, sig=%p, flags=%i", plain, sig, flags);
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = sign_start (ctx, 1, plain, sig, mode);
+ err = sign_start (ctx, 1, plain, sig, flags);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
diff --git a/src/sys-util.h b/src/sys-util.h
index e537613..b3ae721 100644
--- a/src/sys-util.h
+++ b/src/sys-util.h
@@ -24,6 +24,7 @@
int _gpgme_set_default_gpg_name (const char *name);
int _gpgme_set_default_gpgconf_name (const char *name);
int _gpgme_set_override_inst_dir (const char *dir);
+int _gpgme_set_get_inst_type (const char *value);
char *_gpgme_get_gpg_path (void);
char *_gpgme_get_gpgconf_path (void);
diff --git a/src/trustlist.c b/src/trustlist.c
index a0e8238..e31c245 100644
--- a/src/trustlist.c
+++ b/src/trustlist.c
@@ -65,7 +65,7 @@ trustlist_status_handler (void *priv, gpgme_status_code_t code, char *args)
With TYPE = U for a user ID
K for a key
The RECNO is either the one of the dir record or the one of the uid
- record. OT is the the usual trust letter and only available on K
+ record. OT is the usual trust letter and only available on K
lines. VAL is the calculated validity MC is the marginal trust
counter and only available on U lines CC is the same for the
complete count NAME ist the username and only printed on U
diff --git a/src/util.h b/src/util.h
index 8907584..20a9ff7 100644
--- a/src/util.h
+++ b/src/util.h
@@ -35,6 +35,8 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
+#include <stdint.h>
+
#include "gpgme.h"
@@ -56,6 +58,7 @@ const char *_gpgme_get_default_gpg_name (void);
const char *_gpgme_get_default_gpgsm_name (void);
const char *_gpgme_get_default_g13_name (void);
const char *_gpgme_get_default_gpgconf_name (void);
+const char *_gpgme_get_default_gpgtar_name (void);
const char *_gpgme_get_default_uisrv_socket (void);
int _gpgme_in_gpg_one_mode (void);
@@ -96,7 +99,7 @@ int _gpgme_ttyname_r (int fd, char *buf, size_t buflen);
/*-- conversion.c --*/
-/* Make sure to to erase the memory (PTR,LEN). */
+/* Make sure to erase the memory (PTR,LEN). */
void _gpgme_wipememory (void *ptr, size_t len);
/* Concatenate the string S1 with all the following strings up to a
@@ -132,7 +135,7 @@ gpgme_error_t _gpgme_encode_percent_string (const char *src, char **destp,
size_t len);
/* Split a string into space delimited fields and remove leading and
- * trailing spaces from each field. A pointer to the each field is
+ * trailing spaces from each field. A pointer to each field is
* stored in ARRAY. Stop splitting at ARRAYSIZE fields. The function
* modifies STRING. The number of parsed fields is returned. */
int _gpgme_split_fields (char *string, char **array, int arraysize);
@@ -142,7 +145,7 @@ int _gpgme_split_fields (char *string, char **array, int arraysize);
gpgme_error_t _gpgme_strtoul_field (const char *string, unsigned long *result);
/* Convert STRING into an offset value similar to atoi(). */
-gpgme_off_t _gpgme_string_to_off (const char *string);
+uint64_t _gpgme_string_to_off (const char *string);
/* Parse the string TIMESTAMP into a time_t. The string may either be
seconds since Epoch or in the ISO 8601 format like
diff --git a/src/verify.c b/src/verify.c
index 81b2ff9..3ae94c6 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -979,7 +979,7 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
case GPGME_STATUS_UNEXPECTED:
opd->only_newsig_seen = 0;
if (!sig)
- return gpg_error (GPG_ERR_GENERAL);
+ return gpg_error (GPG_ERR_BAD_DATA);
sig->status = gpg_error (GPG_ERR_NO_DATA);
break;
@@ -1135,8 +1135,9 @@ _gpgme_op_verify_init_result (gpgme_ctx_t ctx)
static gpgme_error_t
-verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t sig,
- gpgme_data_t signed_text, gpgme_data_t plaintext)
+verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_verify_flags_t flags,
+ gpgme_data_t sig, gpgme_data_t signed_text,
+ gpgme_data_t plaintext)
{
gpgme_error_t err;
@@ -1153,26 +1154,45 @@ verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t sig,
if (!sig)
return gpg_error (GPG_ERR_NO_DATA);
- return _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext,
- ctx);
+ return _gpgme_engine_op_verify (ctx->engine, flags, sig, signed_text,
+ plaintext, ctx);
}
-/* Decrypt ciphertext CIPHER and make a signature verification within
- CTX and store the resulting plaintext in PLAIN. */
+/* Old version of gpgme_op_verify_ext_start without FLAGS. */
gpgme_error_t
gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
gpgme_data_t signed_text, gpgme_data_t plaintext)
{
+ return gpgme_op_verify_ext_start (ctx, 0, sig, signed_text, plaintext);
+}
+
+
+/* Old version of gpgme_op_verify_ext without FLAGS. */
+gpgme_error_t
+gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig, gpgme_data_t signed_text,
+ gpgme_data_t plaintext)
+{
+ return gpgme_op_verify_ext (ctx, 0, sig, signed_text, plaintext);
+}
+
+
+/* Decrypt ciphertext CIPHER and make a signature verification within
+ CTX and store the resulting plaintext in PLAIN. */
+gpgme_error_t
+gpgme_op_verify_ext_start (gpgme_ctx_t ctx, gpgme_verify_flags_t flags,
+ gpgme_data_t sig, gpgme_data_t signed_text,
+ gpgme_data_t plaintext)
+{
gpg_error_t err;
TRACE_BEG (DEBUG_CTX, "gpgme_op_verify_start", ctx,
- "sig=%p, signed_text=%p, plaintext=%p",
- sig, signed_text, plaintext);
+ "flags=0x%x, sig=%p, signed_text=%p, plaintext=%p",
+ flags, sig, signed_text, plaintext);
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = verify_start (ctx, 0, sig, signed_text, plaintext);
+ err = verify_start (ctx, 0, flags, sig, signed_text, plaintext);
return TRACE_ERR (err);
}
@@ -1180,19 +1200,20 @@ gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
/* Decrypt ciphertext CIPHER and make a signature verification within
CTX and store the resulting plaintext in PLAIN. */
gpgme_error_t
-gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig, gpgme_data_t signed_text,
- gpgme_data_t plaintext)
+gpgme_op_verify_ext (gpgme_ctx_t ctx, gpgme_verify_flags_t flags,
+ gpgme_data_t sig, gpgme_data_t signed_text,
+ gpgme_data_t plaintext)
{
gpgme_error_t err;
TRACE_BEG (DEBUG_CTX, "gpgme_op_verify", ctx,
- "sig=%p, signed_text=%p, plaintext=%p",
- sig, signed_text, plaintext);
+ "flags=0x%x, sig=%p, signed_text=%p, plaintext=%p",
+ flags, sig, signed_text, plaintext);
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = verify_start (ctx, 1, sig, signed_text, plaintext);
+ err = verify_start (ctx, 1, flags, sig, signed_text, plaintext);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
diff --git a/src/version.c b/src/version.c
index 5beb63a..b0e2a10 100644
--- a/src/version.c
+++ b/src/version.c
@@ -72,6 +72,9 @@ do_subsystem_inits (void)
WSAStartup (0x202, &wsadat);
}
+
+ /* We want gpgrt's gettext to always output UTF-8. */
+ gettext_use_utf8 (1);
#endif
_gpgme_debug_subsystem_init ();
@@ -183,7 +186,7 @@ _gpgme_compare_versions (const char *my_version,
}
-/* Check that the the version of the library is at minimum the
+/* Check that the version of the library is at minimum the
requested one and return the version string; return NULL if the
condition is not met. If a NULL is passed to this function, no
check is done and the version string is simply returned.
@@ -200,7 +203,7 @@ gpgme_check_version (const char *req_version)
/* Catch-22: We need to get at least the debug subsystem ready
before using the trace facility. If we won't the trace would
- automagically initialize the debug system with out the locks
+ automagically initialize the debug system without the locks
being initialized and missing the assuan log level setting. */
TRACE (DEBUG_INIT, "gpgme_check_version", NULL,
"req_version=%s, VERSION=%s",
diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in
index 7800368..5f7ee45 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-2021 g10 Code GmbH\0"
+ VALUE "LegalCopyright", "Copyright © 2001-2023 g10 Code GmbH\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "gpgme.dll\0"
VALUE "PrivateBuild", "\0"
diff --git a/src/w32-glib-io.c b/src/w32-glib-io.c
index 09ffffa..943b207 100644
--- a/src/w32-glib-io.c
+++ b/src/w32-glib-io.c
@@ -903,7 +903,7 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
TRACE_END (dbg_help, "]");
}
- /* COUNT is used to stop the lop as soon as possible. */
+ /* COUNT is used to stop the loop as soon as possible. */
for (n = count, i = 0; i < npollfds && n; i++)
{
j = pollfds_map[i];
diff --git a/src/w32-io.c b/src/w32-io.c
index 80978f9..a403a73 100644
--- a/src/w32-io.c
+++ b/src/w32-io.c
@@ -143,7 +143,7 @@ static struct
/* The context of an associated writer object or NULL. */
struct writer_context_s *writer;
- /* A notification handler. Noet that we current support only one
+ /* A notification handler. Note that we currently support only one
* callback per fd. */
struct {
_gpgme_close_notify_handler_t handler;
@@ -410,7 +410,7 @@ reader (void *arg)
else
{
/* Check whether the shutdown triggered the error -
- no need to to print a warning in this case. */
+ no need to print a warning in this case. */
if ( ctx->error_code == WSAECONNABORTED
|| ctx->error_code == WSAECONNRESET)
{
@@ -749,8 +749,8 @@ _gpgme_io_read (int fd, void *buffer, size_t count)
/* The writer does use a simple buffering strategy so that we are
- informed about write errors as soon as possible (i. e. with the the
- next call to the write function. */
+ informed about write errors as soon as possible (i.e. with the
+ next call to the write function). */
static DWORD CALLBACK
writer (void *arg)
{
@@ -1275,7 +1275,7 @@ _gpgme_io_close (int fd)
/* Set a close notification callback which is called right after FD
- * has been closed but before its slot (ie. the FD number) is being
+ * has been closed but before its slot (i.e. the FD number) is being
* released. The HANDLER may thus use the provided value of the FD
* but it may not pass it to any I/O functions. Note: Only the last
* handler set for an FD is used. */
diff --git a/src/w32-util.c b/src/w32-util.c
index e4757a2..c661fb4 100644
--- a/src/w32-util.c
+++ b/src/w32-util.c
@@ -83,16 +83,27 @@
# define GNUPG_REGKEY_3 "Software\\GnuPG"
#endif
+/* Installation type constants. */
+#define INST_TYPE_GPG4WIN 1
+#define INST_TYPE_GPGDESK 2
+
+/* Relative name parts for different installation types. */
+#define INST_TYPE_GPG4WIN_DIR "\\..\\..\\GnuPG\\bin"
+#define INST_TYPE_GPGDESK_DIR "\\..\\GnuPG\\bin"
+
+
+
+
DEFINE_STATIC_LOCK (get_path_lock);
/* The module handle of this DLL. If we are linked statically,
- dllmain does not exists and thus the value of my_hmodule will be
+ dllmain does not exist and thus the value of my_hmodule will be
NULL. The effect is that a GetModuleFileName always returns the
file name of the DLL or executable which contains the gpgme code. */
static HMODULE my_hmodule;
/* These variables store the malloced name of alternative default
- binaries. The are set only once by gpgme_set_global_flag. */
+ binaries. They are set only once by gpgme_set_global_flag. */
static char *default_gpg_name;
static char *default_gpgconf_name;
/* If this variable is not NULL the value is assumed to be the
@@ -168,7 +179,7 @@ wchar_to_utf8 (const wchar_t *string)
}
-/* Return a malloced wide char string from an UTF-8 encoded input
+/* Return a malloced wide char string from a UTF-8 encoded input
string STRING. Caller must free this value. On failure returns
NULL; caller may use GetLastError to get the actual error number.
Calling this function with STRING set to NULL is not defined. */
@@ -536,6 +547,27 @@ _gpgme_set_override_inst_dir (const char *dir)
}
+/* Used by gpgme_set_global_flag to set the installation type.
+ * VALUE is a string interpreted as integer with this meaning:
+ * 0 = standard
+ * 1 = Gpg4win 4 style (INST_TYPE_GPG4WIN)
+ * 2 = GnuPG (VS-)Desktop style (INST_TYPE_GPGDESK)
+ * If VALUE is NULL, nothing is changed. The return value is the
+ * previous value.
+ */
+int
+_gpgme_set_get_inst_type (const char *value)
+{
+ static int inst_type;
+ int previous_type;
+
+ previous_type = inst_type;
+ if (value)
+ inst_type = atoi (value);
+ return previous_type;
+}
+
+
/* Return the full file name of the GPG binary. This function is used
iff gpgconf was not found and thus it can be assumed that gpg2 is
not installed. This function is only called by get_gpgconf_item
@@ -586,6 +618,33 @@ _gpgme_get_gpg_path (void)
}
+/* Helper for _gpgme_get_gpgconf_path. */
+static char *
+find_version_file (const char *inst_dir)
+{
+ char *fname;
+
+ fname = _gpgme_strconcat (inst_dir, "\\..\\", "VERSION.sig", NULL);
+ if (fname && !_gpgme_access (fname, F_OK))
+ {
+ fname[strlen(fname)-4] = 0;
+ if (!_gpgme_access (fname, F_OK))
+ return fname;
+ }
+ free (fname);
+ /* Check the case that a binary in gnupg/bin uses libgpgme. */
+ fname = _gpgme_strconcat (inst_dir, "\\..\\..\\", "VERSION.sig", NULL);
+ if (fname && !_gpgme_access (fname, F_OK))
+ {
+ fname[strlen(fname)-4] = 0;
+ if (!_gpgme_access (fname, F_OK))
+ return fname;
+ }
+ free (fname);
+ return NULL;
+}
+
+
/* This function is only called by get_gpgconf_item and may not be
called concurrently. */
char *
@@ -593,12 +652,53 @@ _gpgme_get_gpgconf_path (void)
{
char *gpgconf = NULL;
const char *inst_dir, *name;
+ int inst_type;
+ char *dir = NULL;
name = default_gpgconf_name? get_basename(default_gpgconf_name):"gpgconf.exe";
- /* 1. Try to find gpgconf.exe in the installation directory of gpgme. */
inst_dir = _gpgme_get_inst_dir ();
- if (inst_dir)
+ inst_type = _gpgme_set_get_inst_type (NULL);
+
+ /* 0.0. If no installation type has been explicitly requested guess
+ * one by looking at files used by the installation type. */
+ if (inst_dir && !inst_type)
+ {
+ gpgrt_stream_t fp;
+ char buffer[128];
+ int n;
+
+ free (dir);
+ dir = find_version_file (inst_dir);
+ if (dir && (fp = gpgrt_fopen (dir, "r")))
+ {
+ n = gpgrt_fread (buffer, 1, 128, fp);
+ if (n > 10)
+ {
+ buffer[n-1] = 0;
+ if (strstr (buffer, "GnuPG") && strstr (buffer, "Desktop"))
+ inst_type = INST_TYPE_GPGDESK;
+ }
+ gpgrt_fclose (fp);
+ }
+ }
+
+ /* 0.1. If an installation type was requested or guessed try to find
+ * gpgconf.exe depending on that installation type. */
+ if (inst_dir
+ && (inst_type == INST_TYPE_GPG4WIN || inst_type == INST_TYPE_GPGDESK))
+ {
+ free (dir);
+ dir = _gpgme_strconcat
+ (inst_dir,
+ inst_type == INST_TYPE_GPG4WIN? INST_TYPE_GPG4WIN_DIR
+ /* */ : INST_TYPE_GPGDESK_DIR,
+ NULL);
+ gpgconf = find_program_in_dir (dir, name);
+ }
+
+ /* 1. Try to find gpgconf.exe in the installation directory of gpgme. */
+ if (!gpgconf && inst_dir)
{
gpgconf = find_program_in_dir (inst_dir, name);
}
@@ -614,8 +714,7 @@ _gpgme_get_gpgconf_path (void)
/* 3. Try to find gpgconf.exe using the Windows registry. */
if (!gpgconf)
{
- char *dir;
-
+ free (dir);
dir = read_w32_registry_string (NULL,
GNUPG_REGKEY_2,
"Install Directory");
@@ -633,10 +732,7 @@ _gpgme_get_gpgconf_path (void)
}
}
if (dir)
- {
- gpgconf = find_program_in_dir (dir, name);
- free (dir);
- }
+ gpgconf = find_program_in_dir (dir, name);
}
/* 4. Try to find gpgconf.exe from Gpg4win below CSIDL_PROGRAM_FILES. */
@@ -645,19 +741,28 @@ _gpgme_get_gpgconf_path (void)
gpgconf = find_program_at_standard_place ("GNU\\GnuPG\\gpgconf.exe");
}
- /* 5. Try to find gpgconf.exe relative to us. */
+ /* 5. Try to find gpgconf.exe relative to us as Gpg4win installs it. */
if (!gpgconf && inst_dir)
{
- char *dir = _gpgme_strconcat (inst_dir, "\\..\\..\\GnuPG\\bin", NULL);
+ free (dir);
+ dir = _gpgme_strconcat (inst_dir, INST_TYPE_GPG4WIN_DIR, NULL);
gpgconf = find_program_in_dir (dir, name);
+ }
+
+ /* 6. Try to find gpgconf.exe relative to us as GnuPG VSD installs it. */
+ if (!gpgconf && inst_dir)
+ {
free (dir);
+ dir = _gpgme_strconcat (inst_dir, INST_TYPE_GPGDESK_DIR, NULL);
+ gpgconf = find_program_in_dir (dir, name);
}
- /* 5. Print a debug message if not found. */
+ /* Print a debug message if not found. */
if (!gpgconf)
_gpgme_debug (NULL, DEBUG_ENGINE, -1, NULL, NULL, NULL,
"_gpgme_get_gpgconf_path: '%s' not found",name);
+ free (dir);
return gpgconf;
}