summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJinWang An <jinwang.an@samsung.com>2021-12-01 16:54:34 +0900
committerJinWang An <jinwang.an@samsung.com>2021-12-01 16:54:34 +0900
commit4db435874bc286631d5dc726f68ba5bb86a1bb89 (patch)
tree272c0eda6487854588390073f08ce293a82560f0 /src
parent670d9afb902f264b6410d307c429f02ed8685fd3 (diff)
downloadgpgme-4db435874bc286631d5dc726f68ba5bb86a1bb89.tar.gz
gpgme-4db435874bc286631d5dc726f68ba5bb86a1bb89.tar.bz2
gpgme-4db435874bc286631d5dc726f68ba5bb86a1bb89.zip
Imported Upstream version 1.4.3upstream/1.4.3
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am5
-rw-r--r--src/Makefile.in133
-rw-r--r--src/data-identify.c247
-rw-r--r--src/dirinfo.c166
-rw-r--r--src/engine-g13.c8
-rw-r--r--src/engine-gpg.c8
-rw-r--r--src/engine-gpgconf.c6
-rw-r--r--src/engine-gpgsm.c10
-rw-r--r--src/engine-uiserver.c4
-rw-r--r--src/gpgme-tool.c73
-rw-r--r--src/gpgme.def4
-rw-r--r--src/gpgme.h.in22
-rw-r--r--src/libgpgme.vers2
-rw-r--r--src/parsetlv.c103
-rw-r--r--src/parsetlv.h48
-rw-r--r--src/posix-util.c24
-rw-r--r--src/signers.c8
-rw-r--r--src/sys-util.h29
-rw-r--r--src/util.h11
-rw-r--r--src/w32-util.c253
20 files changed, 930 insertions, 234 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index fa3b077..1f95103 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -103,8 +103,9 @@ endif
# unresolved symbols to the thread module.
main_sources = \
util.h conversion.c get-env.c context.h ops.h \
+ parsetlv.c parsetlv.h \
data.h data.c data-fd.c data-stream.c data-mem.c data-user.c \
- data-compat.c \
+ data-compat.c data-identify.c \
signers.c sig-notation.c \
wait.c wait-global.c wait-private.c wait-user.c wait.h \
op-support.c \
@@ -118,7 +119,7 @@ main_sources = \
$(uiserver_components) \
$(g13_components) vfs-mount.c vfs-create.c \
gpgconf.c \
- sema.h priv-io.h $(system_components) dirinfo.c \
+ sema.h priv-io.h $(system_components) sys-util.h dirinfo.c \
debug.c debug.h gpgme.c version.c error.c
libgpgme_la_SOURCES = $(main_sources) \
diff --git a/src/Makefile.in b/src/Makefile.in
index 49c7c28..145e234 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -128,20 +128,21 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" \
LTLIBRARIES = $(lib_LTLIBRARIES)
@HAVE_W32_SYSTEM_TRUE@am__DEPENDENCIES_1 = versioninfo.lo
am__libgpgme_glib_la_SOURCES_DIST = util.h conversion.c get-env.c \
- context.h ops.h data.h data.c data-fd.c data-stream.c \
- data-mem.c data-user.c data-compat.c signers.c sig-notation.c \
- wait.c wait-global.c wait-private.c wait-user.c wait.h \
- op-support.c encrypt.c encrypt-sign.c decrypt.c \
- decrypt-verify.c verify.c sign.c passphrase.c progress.c key.c \
- keylist.c trust-item.c trustlist.c import.c export.c genkey.c \
- delete.c edit.c getauditlog.c opassuan.c passwd.c engine.h \
- engine-backend.h engine.c engine-gpg.c status-table.c \
- engine-gpgsm.c assuan-support.c engine-assuan.c \
- engine-gpgconf.c engine-uiserver.c engine-g13.c vfs-mount.c \
- vfs-create.c gpgconf.c sema.h priv-io.h ath.h posix-util.c \
- posix-sema.c posix-io.c w32-ce.h w32-ce.c w32-util.c \
- w32-sema.c dirinfo.c debug.c debug.h gpgme.c version.c error.c \
- ath.c w32-glib-io.c
+ context.h ops.h parsetlv.c parsetlv.h data.h data.c data-fd.c \
+ data-stream.c data-mem.c data-user.c data-compat.c \
+ data-identify.c signers.c sig-notation.c wait.c wait-global.c \
+ wait-private.c wait-user.c wait.h op-support.c encrypt.c \
+ encrypt-sign.c decrypt.c decrypt-verify.c verify.c sign.c \
+ passphrase.c progress.c key.c keylist.c trust-item.c \
+ trustlist.c import.c export.c genkey.c delete.c edit.c \
+ getauditlog.c opassuan.c passwd.c engine.h engine-backend.h \
+ engine.c engine-gpg.c status-table.c engine-gpgsm.c \
+ assuan-support.c engine-assuan.c engine-gpgconf.c \
+ engine-uiserver.c engine-g13.c vfs-mount.c vfs-create.c \
+ gpgconf.c sema.h priv-io.h ath.h posix-util.c posix-sema.c \
+ posix-io.c w32-ce.h w32-ce.c w32-util.c w32-sema.c sys-util.h \
+ dirinfo.c debug.c debug.h gpgme.c version.c error.c ath.c \
+ w32-glib-io.c
@HAVE_GPGSM_TRUE@am__objects_1 = engine-gpgsm.lo
@HAVE_ASSUAN_TRUE@am__objects_2 = assuan-support.lo engine-assuan.lo
@HAVE_GPGCONF_TRUE@am__objects_3 = engine-gpgconf.lo
@@ -152,18 +153,19 @@ am__libgpgme_glib_la_SOURCES_DIST = util.h conversion.c get-env.c \
@HAVE_DOSISH_SYSTEM_FALSE@ posix-io.lo $(am__objects_6)
@HAVE_DOSISH_SYSTEM_TRUE@am__objects_7 = w32-util.lo w32-sema.lo \
@HAVE_DOSISH_SYSTEM_TRUE@ $(am__objects_6)
-am__objects_8 = conversion.lo get-env.lo data.lo data-fd.lo \
- data-stream.lo data-mem.lo data-user.lo data-compat.lo \
- signers.lo sig-notation.lo wait.lo wait-global.lo \
- wait-private.lo wait-user.lo op-support.lo encrypt.lo \
- encrypt-sign.lo decrypt.lo decrypt-verify.lo verify.lo sign.lo \
- passphrase.lo progress.lo key.lo keylist.lo trust-item.lo \
- trustlist.lo import.lo export.lo genkey.lo delete.lo edit.lo \
- getauditlog.lo opassuan.lo passwd.lo engine.lo engine-gpg.lo \
- status-table.lo $(am__objects_1) $(am__objects_2) \
- $(am__objects_3) $(am__objects_4) $(am__objects_5) \
- vfs-mount.lo vfs-create.lo gpgconf.lo $(am__objects_7) \
- dirinfo.lo debug.lo gpgme.lo version.lo error.lo
+am__objects_8 = conversion.lo get-env.lo parsetlv.lo data.lo \
+ data-fd.lo data-stream.lo data-mem.lo data-user.lo \
+ data-compat.lo data-identify.lo signers.lo sig-notation.lo \
+ wait.lo wait-global.lo wait-private.lo wait-user.lo \
+ op-support.lo encrypt.lo encrypt-sign.lo decrypt.lo \
+ decrypt-verify.lo verify.lo sign.lo passphrase.lo progress.lo \
+ key.lo keylist.lo trust-item.lo trustlist.lo import.lo \
+ export.lo genkey.lo delete.lo edit.lo getauditlog.lo \
+ opassuan.lo passwd.lo engine.lo engine-gpg.lo status-table.lo \
+ $(am__objects_1) $(am__objects_2) $(am__objects_3) \
+ $(am__objects_4) $(am__objects_5) vfs-mount.lo vfs-create.lo \
+ gpgconf.lo $(am__objects_7) dirinfo.lo debug.lo gpgme.lo \
+ version.lo error.lo
@BUILD_W32_GLIB_TRUE@am_libgpgme_glib_la_OBJECTS = $(am__objects_8) \
@BUILD_W32_GLIB_TRUE@ ath.lo w32-glib-io.lo
libgpgme_glib_la_OBJECTS = $(am_libgpgme_glib_la_OBJECTS)
@@ -172,19 +174,20 @@ libgpgme_glib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(libgpgme_glib_la_LDFLAGS) $(LDFLAGS) -o $@
@BUILD_W32_GLIB_TRUE@am_libgpgme_glib_la_rpath = -rpath $(libdir)
am__libgpgme_pthread_la_SOURCES_DIST = util.h conversion.c get-env.c \
- context.h ops.h data.h data.c data-fd.c data-stream.c \
- data-mem.c data-user.c data-compat.c signers.c sig-notation.c \
- wait.c wait-global.c wait-private.c wait-user.c wait.h \
- op-support.c encrypt.c encrypt-sign.c decrypt.c \
- decrypt-verify.c verify.c sign.c passphrase.c progress.c key.c \
- keylist.c trust-item.c trustlist.c import.c export.c genkey.c \
- delete.c edit.c getauditlog.c opassuan.c passwd.c engine.h \
- engine-backend.h engine.c engine-gpg.c status-table.c \
- engine-gpgsm.c assuan-support.c engine-assuan.c \
- engine-gpgconf.c engine-uiserver.c engine-g13.c vfs-mount.c \
- vfs-create.c gpgconf.c sema.h priv-io.h ath.h posix-util.c \
- posix-sema.c posix-io.c w32-ce.h w32-ce.c w32-util.c \
- w32-sema.c dirinfo.c debug.c debug.h gpgme.c version.c error.c \
+ context.h ops.h parsetlv.c parsetlv.h data.h data.c data-fd.c \
+ data-stream.c data-mem.c data-user.c data-compat.c \
+ data-identify.c signers.c sig-notation.c wait.c wait-global.c \
+ wait-private.c wait-user.c wait.h op-support.c encrypt.c \
+ encrypt-sign.c decrypt.c decrypt-verify.c verify.c sign.c \
+ passphrase.c progress.c key.c keylist.c trust-item.c \
+ trustlist.c import.c export.c genkey.c delete.c edit.c \
+ getauditlog.c opassuan.c passwd.c engine.h engine-backend.h \
+ engine.c engine-gpg.c status-table.c engine-gpgsm.c \
+ assuan-support.c engine-assuan.c engine-gpgconf.c \
+ engine-uiserver.c engine-g13.c vfs-mount.c vfs-create.c \
+ gpgconf.c sema.h priv-io.h ath.h posix-util.c posix-sema.c \
+ posix-io.c w32-ce.h w32-ce.c w32-util.c w32-sema.c sys-util.h \
+ dirinfo.c debug.c debug.h gpgme.c version.c error.c \
ath-pthread.c w32-io.c
@HAVE_DOSISH_SYSTEM_TRUE@am__objects_9 = w32-io.lo
am_libgpgme_pthread_la_OBJECTS = $(am__objects_8) ath-pthread.lo \
@@ -195,20 +198,21 @@ libgpgme_pthread_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(libgpgme_pthread_la_LDFLAGS) $(LDFLAGS) -o $@
@HAVE_PTHREAD_TRUE@am_libgpgme_pthread_la_rpath = -rpath $(libdir)
am__libgpgme_qt_la_SOURCES_DIST = util.h conversion.c get-env.c \
- context.h ops.h data.h data.c data-fd.c data-stream.c \
- data-mem.c data-user.c data-compat.c signers.c sig-notation.c \
- wait.c wait-global.c wait-private.c wait-user.c wait.h \
- op-support.c encrypt.c encrypt-sign.c decrypt.c \
- decrypt-verify.c verify.c sign.c passphrase.c progress.c key.c \
- keylist.c trust-item.c trustlist.c import.c export.c genkey.c \
- delete.c edit.c getauditlog.c opassuan.c passwd.c engine.h \
- engine-backend.h engine.c engine-gpg.c status-table.c \
- engine-gpgsm.c assuan-support.c engine-assuan.c \
- engine-gpgconf.c engine-uiserver.c engine-g13.c vfs-mount.c \
- vfs-create.c gpgconf.c sema.h priv-io.h ath.h posix-util.c \
- posix-sema.c posix-io.c w32-ce.h w32-ce.c w32-util.c \
- w32-sema.c dirinfo.c debug.c debug.h gpgme.c version.c error.c \
- ath.c w32-qt-io.cpp kdpipeiodevice.h kdpipeiodevice.cpp \
+ context.h ops.h parsetlv.c parsetlv.h data.h data.c data-fd.c \
+ data-stream.c data-mem.c data-user.c data-compat.c \
+ data-identify.c signers.c sig-notation.c wait.c wait-global.c \
+ wait-private.c wait-user.c wait.h op-support.c encrypt.c \
+ encrypt-sign.c decrypt.c decrypt-verify.c verify.c sign.c \
+ passphrase.c progress.c key.c keylist.c trust-item.c \
+ trustlist.c import.c export.c genkey.c delete.c edit.c \
+ getauditlog.c opassuan.c passwd.c engine.h engine-backend.h \
+ engine.c engine-gpg.c status-table.c engine-gpgsm.c \
+ assuan-support.c engine-assuan.c engine-gpgconf.c \
+ engine-uiserver.c engine-g13.c vfs-mount.c vfs-create.c \
+ gpgconf.c sema.h priv-io.h ath.h posix-util.c posix-sema.c \
+ posix-io.c w32-ce.h w32-ce.c w32-util.c w32-sema.c sys-util.h \
+ dirinfo.c debug.c debug.h gpgme.c version.c error.c ath.c \
+ w32-qt-io.cpp kdpipeiodevice.h kdpipeiodevice.cpp \
kdpipeiodevice.moc
@BUILD_W32_QT_TRUE@am_libgpgme_qt_la_OBJECTS = $(am__objects_8) ath.lo \
@BUILD_W32_QT_TRUE@ w32-qt-io.lo kdpipeiodevice.lo
@@ -218,19 +222,21 @@ libgpgme_qt_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(CXXFLAGS) $(libgpgme_qt_la_LDFLAGS) $(LDFLAGS) -o $@
@BUILD_W32_QT_TRUE@am_libgpgme_qt_la_rpath = -rpath $(libdir)
am__libgpgme_la_SOURCES_DIST = util.h conversion.c get-env.c context.h \
- ops.h data.h data.c data-fd.c data-stream.c data-mem.c \
- data-user.c data-compat.c signers.c sig-notation.c wait.c \
- wait-global.c wait-private.c wait-user.c wait.h op-support.c \
- encrypt.c encrypt-sign.c decrypt.c decrypt-verify.c verify.c \
- sign.c passphrase.c progress.c key.c keylist.c trust-item.c \
+ ops.h parsetlv.c parsetlv.h data.h data.c data-fd.c \
+ data-stream.c data-mem.c data-user.c data-compat.c \
+ data-identify.c signers.c sig-notation.c wait.c wait-global.c \
+ wait-private.c wait-user.c wait.h op-support.c encrypt.c \
+ encrypt-sign.c decrypt.c decrypt-verify.c verify.c sign.c \
+ passphrase.c progress.c key.c keylist.c trust-item.c \
trustlist.c import.c export.c genkey.c delete.c edit.c \
getauditlog.c opassuan.c passwd.c engine.h engine-backend.h \
engine.c engine-gpg.c status-table.c engine-gpgsm.c \
assuan-support.c engine-assuan.c engine-gpgconf.c \
engine-uiserver.c engine-g13.c vfs-mount.c vfs-create.c \
gpgconf.c sema.h priv-io.h ath.h posix-util.c posix-sema.c \
- posix-io.c w32-ce.h w32-ce.c w32-util.c w32-sema.c dirinfo.c \
- debug.c debug.h gpgme.c version.c error.c ath.c w32-io.c
+ posix-io.c w32-ce.h w32-ce.c w32-util.c w32-sema.c sys-util.h \
+ dirinfo.c debug.c debug.h gpgme.c version.c error.c ath.c \
+ w32-io.c
am_libgpgme_la_OBJECTS = $(am__objects_8) ath.lo $(am__objects_9)
libgpgme_la_OBJECTS = $(am_libgpgme_la_OBJECTS)
libgpgme_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -485,8 +491,9 @@ lib_LTLIBRARIES = libgpgme.la $(ltlib_gpgme_glib) $(ltlib_gpgme_qt) \
# unresolved symbols to the thread module.
main_sources = \
util.h conversion.c get-env.c context.h ops.h \
+ parsetlv.c parsetlv.h \
data.h data.c data-fd.c data-stream.c data-mem.c data-user.c \
- data-compat.c \
+ data-compat.c data-identify.c \
signers.c sig-notation.c \
wait.c wait-global.c wait-private.c wait-user.c wait.h \
op-support.c \
@@ -500,7 +507,7 @@ main_sources = \
$(uiserver_components) \
$(g13_components) vfs-mount.c vfs-create.c \
gpgconf.c \
- sema.h priv-io.h $(system_components) dirinfo.c \
+ sema.h priv-io.h $(system_components) sys-util.h dirinfo.c \
debug.c debug.h gpgme.c version.c error.c
libgpgme_la_SOURCES = $(main_sources) \
@@ -766,6 +773,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conversion.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data-compat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data-fd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data-identify.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data-mem.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data-stream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data-user.Plo@am__quote@
@@ -800,6 +808,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keylist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op-support.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opassuan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parsetlv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passphrase.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passwd.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posix-io.Plo@am__quote@
diff --git a/src/data-identify.c b/src/data-identify.c
new file mode 100644
index 0000000..9600633
--- /dev/null
+++ b/src/data-identify.c
@@ -0,0 +1,247 @@
+/* data-identify.c - Try to identify the data
+ Copyright (C) 2013 g10 Code GmbH
+
+ This file is part of GPGME.
+
+ GPGME is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ GPGME is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gpgme.h"
+#include "data.h"
+#include "util.h"
+#include "parsetlv.h"
+
+/* The size of the sample data we take for detection. */
+#define SAMPLE_SIZE 2048
+
+
+
+/* Note that DATA may be binary but a final nul is required so that
+ string operations will find a terminator.
+
+ Returns: GPGME_DATA_TYPE_xxxx */
+static gpgme_data_type_t
+basic_detection (const char *data, size_t datalen)
+{
+ tlvinfo_t ti;
+ const char *s;
+ size_t n;
+ int maybe_p12 = 0;
+
+ if (datalen < 24) /* Object is probably too short for detection. */
+ return GPGME_DATA_TYPE_UNKNOWN;
+
+ /* This is a common example of a CMS object - it is obvious that we
+ only need to read a few bytes to get to the OID:
+ 30 82 0B 59 06 09 2A 86 48 86 F7 0D 01 07 02 A0 82 0B 4A 30 82 0B 46 02
+ ----------- ++++++++++++++++++++++++++++++++
+ SEQUENCE OID (signedData)
+ (2 byte len)
+
+ A PKCS#12 message is:
+
+ 30 82 08 59 02 01 03 30 82 08 1F 06 09 2A 86 48 86 F7 0D 01 07 01 A0 82
+ ----------- ++++++++ ----------- ++++++++++++++++++++++++++++++++
+ SEQUENCE INTEGER SEQUENCE OID (data)
+
+ A X.509 certificate is:
+
+ 30 82 05 B8 30 82 04 A0 A0 03 02 01 02 02 07 15 46 A0 BF 30 07 39 30 0D
+ ----------- +++++++++++ ----- ++++++++ --------------------------
+ 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.
+ */
+
+
+ s = data;
+ n = datalen;
+
+ if (parse_tlv (&s, &n, &ti))
+ goto try_pgp; /* Not properly BER encoded. */
+ if (!(ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_SEQUENCE
+ && ti.is_cons))
+ goto try_pgp; /* A CMS object always starts with a sequence. */
+
+ if (parse_tlv (&s, &n, &ti))
+ goto try_pgp; /* Not properly BER encoded. */
+ if (ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_SEQUENCE
+ && ti.is_cons && n >= ti.length)
+ {
+ 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 (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)
+ {
+ maybe_p12 = 1;
+ s++;
+ n--;
+ if (parse_tlv (&s, &n, &ti))
+ goto try_pgp;
+ if (!(ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_SEQUENCE
+ && ti.is_cons))
+ goto try_pgp;
+ if (parse_tlv (&s, &n, &ti))
+ goto try_pgp;
+ }
+ if (ti.cls == ASN1_CLASS_UNIVERSAL && ti.tag == ASN1_TAG_OBJECT_ID
+ && !ti.is_cons && ti.length && n >= ti.length)
+ {
+ if (ti.length == 9)
+ {
+ if (!memcmp (s, "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x01", 9))
+ {
+ /* Data. */
+ return (maybe_p12 ? GPGME_DATA_TYPE_PKCS12
+ /* */ : GPGME_DATA_TYPE_CMS_OTHER);
+ }
+ if (!memcmp (s, "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02", 9))
+ {
+ /* Signed Data. */
+ return (maybe_p12 ? GPGME_DATA_TYPE_PKCS12
+ /* */ : GPGME_DATA_TYPE_CMS_SIGNED);
+ }
+ if (!memcmp (s, "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x03", 9))
+ return GPGME_DATA_TYPE_CMS_ENCRYPTED; /* Enveloped Data. */
+ if (!memcmp (s, "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x05", 9))
+ return GPGME_DATA_TYPE_CMS_OTHER; /* Digested Data. */
+ if (!memcmp (s, "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x06", 9))
+ return GPGME_DATA_TYPE_CMS_OTHER; /* Encrypted Data. */
+ }
+ else if (ti.length == 11)
+ {
+ if (!memcmp (s, "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x01\x02", 11))
+ return GPGME_DATA_TYPE_CMS_OTHER; /* Auth Data. */
+ }
+ }
+
+
+ try_pgp:
+ /* Check whether this might be a non-armored PGP message. We need
+ to do this before checking for armor lines, so that we don't get
+ fooled by armored messages inside a signed binary PGP message. */
+ if ((data[0] & 0x80))
+ {
+ /* That might be a binary PGP message. At least it is not plain
+ ASCII. Of course this might be certain lead-in text of
+ armored CMS messages. However, I am not sure whether this is
+ at all defined and in any case it is uncommon. Thus we don't
+ do any further plausibility checks but stupidly assume no CMS
+ armored data will follow. */
+ return GPGME_DATA_TYPE_UNKNOWN;
+ }
+
+ /* Now check whether there are armor lines. */
+ for (s = data; s && *s; s = (*s=='\n')?(s+1):((s=strchr (s,'\n'))?(s+1):s))
+ {
+ if (!strncmp (s, "-----BEGIN ", 11))
+ {
+ if (!strncmp (s+11, "SIGNED ", 7))
+ return GPGME_DATA_TYPE_CMS_SIGNED;
+ if (!strncmp (s+11, "ENCRYPTED ", 10))
+ return GPGME_DATA_TYPE_CMS_ENCRYPTED;
+ if (!strncmp (s+11, "PGP ", 4))
+ {
+ if (!strncmp (s+15, "SIGNATURE", 9))
+ return GPGME_DATA_TYPE_PGP_SIGNED;
+ if (!strncmp (s+15, "SIGNED MESSAGE", 14))
+ return GPGME_DATA_TYPE_PGP_SIGNED;
+ if (!strncmp (s+15, "PUBLIC KEY BLOCK", 16))
+ return GPGME_DATA_TYPE_PGP_KEY;
+ if (!strncmp (s+15, "PRIVATE KEY BLOCK", 17))
+ return GPGME_DATA_TYPE_PGP_KEY;
+ if (!strncmp (s+15, "SECRET KEY BLOCK", 16))
+ return GPGME_DATA_TYPE_PGP_KEY;
+ if (!strncmp (s+15, "ARMORED FILE", 12))
+ return GPGME_DATA_TYPE_UNKNOWN;
+ return GPGME_DATA_TYPE_PGP_OTHER; /* PGP MESSAGE */
+ }
+ if (!strncmp (s+11, "CERTIFICATE", 11))
+ return GPGME_DATA_TYPE_X509_CERT;
+ if (!strncmp (s+11, "PKCS12", 6))
+ return GPGME_DATA_TYPE_PKCS12;
+ return GPGME_DATA_TYPE_CMS_OTHER; /* Not PGP, thus we assume CMS. */
+ }
+ }
+
+ return GPGME_DATA_TYPE_UNKNOWN;
+}
+
+
+/* Try to detect the type of the data. Note that this function works
+ only on seekable data objects. The function tries to reset the
+ file pointer but there is no guarantee that it will work.
+
+ FIXME: We may want to add internal buffering so that this function
+ can be implemented for allmost all kind of data objects.
+ */
+gpgme_data_type_t
+gpgme_data_identify (gpgme_data_t dh, int reserved)
+{
+ gpgme_data_type_t result;
+ char *sample;
+ int n;
+ gpgme_off_t off;
+
+ /* Check whether we can seek the data object. */
+ off = gpgme_data_seek (dh, 0, SEEK_CUR);
+ if (off == (gpgme_off_t)(-1))
+ return GPGME_DATA_TYPE_INVALID;
+
+ /* Allocate a buffer and read the data. */
+ sample = malloc (SAMPLE_SIZE);
+ if (!sample)
+ return GPGME_DATA_TYPE_INVALID; /* Ooops. */
+ n = gpgme_data_read (dh, sample, SAMPLE_SIZE - 1);
+ if (n < 0)
+ {
+ free (sample);
+ return GPGME_DATA_TYPE_INVALID; /* Ooops. */
+ }
+ sample[n] = 0; /* (Required for our string functions.) */
+
+ result = basic_detection (sample, n);
+ free (sample);
+ gpgme_data_seek (dh, off, SEEK_SET);
+
+ return result;
+}
diff --git a/src/dirinfo.c b/src/dirinfo.c
index 267e988..27c0dd7 100644
--- a/src/dirinfo.c
+++ b/src/dirinfo.c
@@ -1,5 +1,5 @@
/* dirinfo.c - Get directory information
- * Copyright (C) 2009 g10 Code GmbH
+ * Copyright (C) 2009, 2013 g10 Code GmbH
*
* This file is part of GPGME.
*
@@ -29,6 +29,7 @@
#include "priv-io.h"
#include "debug.h"
#include "sema.h"
+#include "sys-util.h"
DEFINE_STATIC_LOCK (dirinfo_lock);
@@ -36,7 +37,11 @@ DEFINE_STATIC_LOCK (dirinfo_lock);
enum
{
WANT_HOMEDIR,
- WANT_AGENT_SOCKET
+ WANT_AGENT_SOCKET,
+ WANT_GPG_NAME,
+ WANT_GPGSM_NAME,
+ WANT_G13_NAME,
+ WANT_UISRV_SOCKET
};
/* Values retrieved via gpgconf and cached here. */
@@ -44,13 +49,18 @@ static struct {
int valid; /* Cached information is valid. */
char *homedir;
char *agent_socket;
+ char *gpg_name;
+ char *gpgsm_name;
+ char *g13_name;
+ char *uisrv_socket;
} dirinfo;
/* Parse the output of "gpgconf --list-dirs". This function expects
- that DIRINFO_LOCK is held by the caller. */
+ that DIRINFO_LOCK is held by the caller. If COMPONENTS is set, the
+ output of --list-components is expected. */
static void
-parse_output (char *line)
+parse_output (char *line, int components)
{
char *value, *p;
@@ -58,6 +68,14 @@ parse_output (char *line)
if (!value)
return;
*value++ = 0;
+ if (components)
+ {
+ /* Skip the second field. */
+ value = strchr (value, ':');
+ if (!value)
+ return;
+ *value++ = 0;
+ }
p = strchr (value, ':');
if (p)
*p = 0;
@@ -66,19 +84,45 @@ parse_output (char *line)
if (!*value)
return;
- if (!strcmp (line, "homedir") && !dirinfo.homedir)
- dirinfo.homedir = strdup (value);
- else if (!strcmp (line, "agent-socket") && !dirinfo.agent_socket)
- dirinfo.agent_socket = strdup (value);
+ if (components)
+ {
+ if (!strcmp (line, "gpg") && !dirinfo.gpg_name)
+ dirinfo.gpg_name = strdup (value);
+ else if (!strcmp (line, "gpgsm") && !dirinfo.gpgsm_name)
+ dirinfo.gpgsm_name = strdup (value);
+ else if (!strcmp (line, "g13") && !dirinfo.g13_name)
+ dirinfo.g13_name = strdup (value);
+ }
+ else
+ {
+ if (!strcmp (line, "homedir") && !dirinfo.homedir)
+ {
+ const char name[] = "S.uiserver";
+
+ dirinfo.homedir = strdup (value);
+ if (dirinfo.homedir)
+ {
+ dirinfo.uisrv_socket = malloc (strlen (dirinfo
+ .homedir)
+ + 1 + strlen (name) + 1);
+ if (dirinfo.uisrv_socket)
+ strcpy (stpcpy (stpcpy (dirinfo.uisrv_socket, dirinfo.homedir),
+ DIRSEP_S), name);
+ }
+ }
+ else if (!strcmp (line, "agent-socket") && !dirinfo.agent_socket)
+ dirinfo.agent_socket = strdup (value);
+ }
}
/* Read the directory information from gpgconf. This function expects
- that DIRINFO_LOCK is held by the caller. */
+ that DIRINFO_LOCK is held by the caller. PGNAME is the name of the
+ gpgconf binary. If COMPONENTS is set, not the directories bit the
+ name of the componeNts are read. */
static void
-read_gpgconf_dirs (void)
+read_gpgconf_dirs (const char *pgmname, int components)
{
- const char *pgmname;
char linebuf[1024] = {0};
int linelen = 0;
char * argv[3];
@@ -89,12 +133,8 @@ read_gpgconf_dirs (void)
int nread;
char *mark = NULL;
- pgmname = _gpgme_get_gpgconf_path ();
- if (!pgmname)
- return; /* No way. */
-
argv[0] = (char *)pgmname;
- argv[1] = "--list-dirs";
+ argv[1] = components? "--list-components" : "--list-dirs";
argv[2] = NULL;
if (_gpgme_io_pipe (rp, 1) < 0)
@@ -132,7 +172,7 @@ read_gpgconf_dirs (void)
else
mark[0] = '\0';
- parse_output (line);
+ parse_output (line, components);
}
nused = lastmark? (lastmark + 1 - linebuf) : 0;
@@ -147,14 +187,38 @@ read_gpgconf_dirs (void)
static const char *
-get_gpgconf_dir (int what)
+get_gpgconf_item (int what)
{
const char *result = NULL;
LOCK (dirinfo_lock);
if (!dirinfo.valid)
{
- read_gpgconf_dirs ();
+ const char *pgmname;
+
+ pgmname = _gpgme_get_gpgconf_path ();
+ if (pgmname && access (pgmname, F_OK))
+ {
+ _gpgme_debug (DEBUG_INIT,
+ "gpgme_dinfo: gpgconf='%s' [not installed]\n", pgmname);
+ pgmname = NULL; /* Not available. */
+ }
+ else
+ _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: gpgconf='%s'\n",
+ pgmname? pgmname : "[null]");
+ if (!pgmname)
+ {
+ /* Probably gpgconf is not installed. Assume we are using
+ GnuPG-1. */
+ pgmname = _gpgme_get_gpg_path ();
+ if (pgmname)
+ dirinfo.gpg_name = strdup (pgmname);
+ }
+ else
+ {
+ read_gpgconf_dirs (pgmname, 0);
+ read_gpgconf_dirs (pgmname, 1);
+ }
/* Even if the reading of the directories failed (e.g. due to an
too old version gpgconf or no gpgconf at all), we need to
mark the entries as valid so that we won't try over and over
@@ -162,11 +226,33 @@ get_gpgconf_dir (int what)
the read values later because they are practically statically
allocated. */
dirinfo.valid = 1;
+ if (dirinfo.gpg_name)
+ _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: gpg='%s'\n",
+ dirinfo.gpg_name);
+ if (dirinfo.g13_name)
+ _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: g13='%s'\n",
+ dirinfo.g13_name);
+ if (dirinfo.gpgsm_name)
+ _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: gpgsm='%s'\n",
+ dirinfo.gpgsm_name);
+ if (dirinfo.homedir)
+ _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: homedir='%s'\n",
+ dirinfo.homedir);
+ if (dirinfo.agent_socket)
+ _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: agent='%s'\n",
+ dirinfo.agent_socket);
+ if (dirinfo.uisrv_socket)
+ _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: uisrv='%s'\n",
+ dirinfo.uisrv_socket);
}
switch (what)
{
case WANT_HOMEDIR: result = dirinfo.homedir; break;
case WANT_AGENT_SOCKET: result = dirinfo.agent_socket; break;
+ case WANT_GPG_NAME: result = dirinfo.gpg_name; break;
+ case WANT_GPGSM_NAME: result = dirinfo.gpgsm_name; break;
+ case WANT_G13_NAME: result = dirinfo.g13_name; break;
+ case WANT_UISRV_SOCKET: result = dirinfo.uisrv_socket; break;
}
UNLOCK (dirinfo_lock);
return result;
@@ -177,13 +263,51 @@ get_gpgconf_dir (int what)
const char *
_gpgme_get_default_homedir (void)
{
- return get_gpgconf_dir (WANT_HOMEDIR);
+ return get_gpgconf_item (WANT_HOMEDIR);
}
/* Return the default gpg-agent socket name. Returns NULL if not known. */
const char *
_gpgme_get_default_agent_socket (void)
{
- return get_gpgconf_dir (WANT_AGENT_SOCKET);
+ return get_gpgconf_item (WANT_AGENT_SOCKET);
+}
+
+/* Return the default gpg file name. Returns NULL if not known. */
+const char *
+_gpgme_get_default_gpg_name (void)
+{
+ return get_gpgconf_item (WANT_GPG_NAME);
+}
+
+/* Return the default gpgsm file name. Returns NULL if not known. */
+const char *
+_gpgme_get_default_gpgsm_name (void)
+{
+ return get_gpgconf_item (WANT_GPGSM_NAME);
+}
+
+/* Return the default g13 file name. Returns NULL if not known. */
+const char *
+_gpgme_get_default_g13_name (void)
+{
+ return get_gpgconf_item (WANT_G13_NAME);
}
+/* Return the default gpgconf file name. Returns NULL if not known.
+ Because gpgconf is the binary used to retrieved all these default
+ names, this function is merely a simple wrapper around the function
+ used to locate this binary. */
+const char *
+_gpgme_get_default_gpgconf_name (void)
+{
+ return _gpgme_get_gpgconf_path ();
+}
+
+/* Return the default UI-server socket name. Returns NULL if not
+ known. */
+const char *
+_gpgme_get_default_uisrv_socket (void)
+{
+ return get_gpgconf_item (WANT_UISRV_SOCKET);
+}
diff --git a/src/engine-g13.c b/src/engine-g13.c
index de0aac8..b97e0b4 100644
--- a/src/engine-g13.c
+++ b/src/engine-g13.c
@@ -100,7 +100,7 @@ static char *
g13_get_version (const char *file_name)
{
return _gpgme_get_program_version (file_name ? file_name
- : _gpgme_get_g13_path ());
+ : _gpgme_get_default_g13_name ());
}
@@ -251,11 +251,11 @@ g13_new (void **engine, const char *file_name, const char *home_dir)
#if USE_DESCRIPTOR_PASSING
err = assuan_pipe_connect
- (g13->assuan_ctx, file_name ? file_name : _gpgme_get_g13_path (),
+ (g13->assuan_ctx, file_name ? file_name : _gpgme_get_default_g13_name (),
argv, NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING);
#else
err = assuan_pipe_connect
- (g13->assuan_ctx, file_name ? file_name : _gpgme_get_g13_path (),
+ (g13->assuan_ctx, file_name ? file_name : _gpgme_get_default_g13_name (),
argv, NULL, NULL, NULL, 0);
#endif
if (err)
@@ -757,7 +757,7 @@ g13_io_event (void *engine, gpgme_event_io_t type, void *type_data)
struct engine_ops _gpgme_engine_ops_g13 =
{
/* Static functions. */
- _gpgme_get_g13_path,
+ _gpgme_get_default_g13_name,
NULL,
g13_get_version,
g13_get_req_version,
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 72d3ad1..3bc9f66 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -296,7 +296,7 @@ static char *
gpg_get_version (const char *file_name)
{
return _gpgme_get_program_version (file_name ? file_name
- : _gpgme_get_gpg_path ());
+ : _gpgme_get_default_gpg_name ());
}
@@ -1296,7 +1296,7 @@ start (engine_gpg_t gpg)
if (!gpg)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!gpg->file_name && !_gpgme_get_gpg_path ())
+ if (!gpg->file_name && !_gpgme_get_default_gpg_name ())
return trace_gpg_error (GPG_ERR_INV_ENGINE);
if (gpg->lc_ctype)
@@ -1352,7 +1352,7 @@ start (engine_gpg_t gpg)
fd_list[n].dup_to = -1;
status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name :
- _gpgme_get_gpg_path (), gpg->argv,
+ _gpgme_get_default_gpg_name (), gpg->argv,
IOSPAWN_FLAG_ALLOW_SET_FG,
fd_list, NULL, NULL, &pid);
{
@@ -2401,7 +2401,7 @@ gpg_set_pinentry_mode (void *engine, gpgme_pinentry_mode_t mode)
struct engine_ops _gpgme_engine_ops_gpg =
{
/* Static functions. */
- _gpgme_get_gpg_path,
+ _gpgme_get_default_gpg_name,
NULL,
gpg_get_version,
gpg_get_req_version,
diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c
index 3a1c1c1..1d457bb 100644
--- a/src/engine-gpgconf.c
+++ b/src/engine-gpgconf.c
@@ -61,7 +61,7 @@ static char *
gpgconf_get_version (const char *file_name)
{
return _gpgme_get_program_version (file_name ? file_name
- : _gpgme_get_gpgconf_path ());
+ : _gpgme_get_default_gpgconf_name ());
}
@@ -100,7 +100,7 @@ gpgconf_new (void **engine, const char *file_name, const char *home_dir)
return gpg_error_from_syserror ();
gpgconf->file_name = strdup (file_name ? file_name
- : _gpgme_get_gpgconf_path ());
+ : _gpgme_get_default_gpgconf_name ());
if (!gpgconf->file_name)
err = gpg_error_from_syserror ();
@@ -923,7 +923,7 @@ _gpgme_conf_release (gpgme_conf_comp_t conf)
struct engine_ops _gpgme_engine_ops_gpgconf =
{
/* Static functions. */
- _gpgme_get_gpgconf_path,
+ _gpgme_get_default_gpgconf_name,
NULL,
gpgconf_get_version,
gpgconf_get_req_version,
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index 391b632..cee20e3 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -120,7 +120,7 @@ static char *
gpgsm_get_version (const char *file_name)
{
return _gpgme_get_program_version (file_name ? file_name
- : _gpgme_get_gpgsm_path ());
+ : _gpgme_get_default_gpgsm_name ());
}
@@ -340,7 +340,8 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
#if USE_DESCRIPTOR_PASSING
err = assuan_pipe_connect
- (gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (),
+ (gpgsm->assuan_ctx,
+ file_name ? file_name : _gpgme_get_default_gpgsm_name (),
argv, NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING);
#else
{
@@ -352,7 +353,8 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
achild_fds[i] = (assuan_fd_t) child_fds[i];
err = assuan_pipe_connect
- (gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (),
+ (gpgsm->assuan_ctx,
+ file_name ? file_name : _gpgme_get_default_gpgsm_name (),
argv, achild_fds, NULL, NULL, 0);
/* For now... */
@@ -1945,7 +1947,7 @@ gpgsm_passwd (void *engine, gpgme_key_t key, unsigned int flags)
struct engine_ops _gpgme_engine_ops_gpgsm =
{
/* Static functions. */
- _gpgme_get_gpgsm_path,
+ _gpgme_get_default_gpgsm_name,
NULL,
gpgsm_get_version,
gpgsm_get_req_version,
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index a0008e4..bd140f9 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -296,7 +296,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir)
err = assuan_socket_connect (uiserver->assuan_ctx,
file_name ?
- file_name : _gpgme_get_uiserver_socket_path (),
+ file_name : _gpgme_get_default_uisrv_socket (),
0, ASSUAN_SOCKET_SERVER_FDPASSING);
if (err)
goto leave;
@@ -1302,7 +1302,7 @@ uiserver_io_event (void *engine, gpgme_event_io_t type, void *type_data)
struct engine_ops _gpgme_engine_ops_uiserver =
{
/* Static functions. */
- _gpgme_get_uiserver_socket_path,
+ _gpgme_get_default_uisrv_socket,
NULL,
uiserver_get_version,
uiserver_get_req_version,
diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c
index 0ebabab..2bf7654 100644
--- a/src/gpgme-tool.c
+++ b/src/gpgme-tool.c
@@ -1435,7 +1435,8 @@ typedef enum status
STATUS_INCLUDE_CERTS,
STATUS_KEYLIST_MODE,
STATUS_RECIPIENT,
- STATUS_ENCRYPT_RESULT
+ STATUS_ENCRYPT_RESULT,
+ STATUS_IDENTIFY_RESULT
} status_t;
const char *status_string[] =
@@ -1448,7 +1449,8 @@ const char *status_string[] =
"INCLUDE_CERTS",
"KEYLIST_MODE",
"RECIPIENT",
- "ENCRYPT_RESULT"
+ "ENCRYPT_RESULT",
+ "IDENTIFY_RESULT"
};
struct gpgme_tool
@@ -2065,11 +2067,6 @@ gt_vfs_create (gpgme_tool_t gt, const char *container_file, int flags)
}
-static const char hlp_passwd[] =
- "PASSWD <user-id>\n"
- "\n"
- "Ask the backend to change the passphrase for the key\n"
- "specified by USER-ID.";
gpg_error_t
gt_passwd (gpgme_tool_t gt, char *fpr)
{
@@ -2086,6 +2083,29 @@ gt_passwd (gpgme_tool_t gt, char *fpr)
}
+gpg_error_t
+gt_identify (gpgme_tool_t gt, gpgme_data_t data)
+{
+ const char *s = "?";
+
+ switch (gpgme_data_identify (data, 0))
+ {
+ case GPGME_DATA_TYPE_INVALID: return gpg_error (GPG_ERR_GENERAL);
+ case GPGME_DATA_TYPE_UNKNOWN : s = "unknown"; break;
+ case GPGME_DATA_TYPE_PGP_SIGNED : s = "PGP-signed"; 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;
+ }
+ gt_write_status (gt, STATUS_IDENTIFY_RESULT, s, NULL);
+ return 0;
+}
+
+
#define GT_RESULT_ENCRYPT 0x1
#define GT_RESULT_DECRYPT 0x2
#define GT_RESULT_SIGN 0x4
@@ -3374,6 +3394,11 @@ cmd_vfs_create (assuan_context_t ctx, char *line)
}
+static const char hlp_passwd[] =
+ "PASSWD <user-id>\n"
+ "\n"
+ "Ask the backend to change the passphrase for the key\n"
+ "specified by USER-ID.";
static gpg_error_t
cmd_passwd (assuan_context_t ctx, char *line)
{
@@ -3430,6 +3455,39 @@ cmd_hash_algo_name (assuan_context_t ctx, char *line)
}
+static const char hlp_identify[] =
+ "IDENTIY\n"
+ "\n"
+ "Identify the type of data set with the INPUT command.";
+static gpg_error_t
+cmd_identify (assuan_context_t ctx, char *line)
+{
+ struct server *server = assuan_get_pointer (ctx);
+ gpg_error_t err;
+ assuan_fd_t inp_fd;
+ char *inp_fn;
+ gpgme_data_t inp_data;
+
+ inp_fd = server->input_fd;
+ inp_fn = server->input_filename;
+ if (inp_fd == ASSUAN_INVALID_FD && !inp_fn)
+ return GPG_ERR_ASS_NO_INPUT;
+
+ err = server_data_obj (inp_fd, inp_fn, 0, server->input_enc, &inp_data,
+ &server->input_stream);
+ if (err)
+ return err;
+
+ err = gt_identify (server->gt, inp_data);
+
+ gpgme_data_release (inp_data);
+ server_reset_fds (server);
+
+ return err;
+}
+
+
+
/* Tell the assuan library about our commands. */
static gpg_error_t
register_commands (assuan_context_t ctx)
@@ -3488,6 +3546,7 @@ register_commands (assuan_context_t ctx)
{ "PUBKEY_ALGO_NAME", cmd_pubkey_algo_name },
{ "HASH_ALGO_NAME", cmd_hash_algo_name },
{ "PASSWD", cmd_passwd, hlp_passwd },
+ { "IDENTIFY", cmd_identify, hlp_identify },
{ NULL }
};
int idx;
diff --git a/src/gpgme.def b/src/gpgme.def
index 3a6e0e3..0478cb6 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -209,5 +209,9 @@ EXPORTS
gpgme_set_pinentry_mode @158
gpgme_get_pinentry_mode @159
+ gpgme_signers_count @160
+
+ gpgme_data_identify @161
+
; END
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 11780d1..5c4de6b 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -210,6 +210,22 @@ typedef enum
}
gpgme_data_encoding_t;
+/* Known data types. */
+typedef enum
+ {
+ GPGME_DATA_TYPE_INVALID = 0, /* Not detected. */
+ GPGME_DATA_TYPE_UNKNOWN = 1,
+ GPGME_DATA_TYPE_PGP_SIGNED = 0x10,
+ GPGME_DATA_TYPE_PGP_OTHER = 0x12,
+ GPGME_DATA_TYPE_PGP_KEY = 0x13,
+ GPGME_DATA_TYPE_CMS_SIGNED = 0x20,
+ GPGME_DATA_TYPE_CMS_ENCRYPTED= 0x21,
+ GPGME_DATA_TYPE_CMS_OTHER = 0x22,
+ GPGME_DATA_TYPE_X509_CERT = 0x23,
+ GPGME_DATA_TYPE_PKCS12 = 0x24,
+ }
+gpgme_data_type_t;
+
/* Public key algorithms from libgcrypt. */
typedef enum
@@ -934,6 +950,9 @@ void gpgme_signers_clear (gpgme_ctx_t ctx);
/* Add KEY to list of signers in CTX. */
gpgme_error_t gpgme_signers_add (gpgme_ctx_t ctx, const gpgme_key_t key);
+/* Return the number of signers in CTX. */
+unsigned int gpgme_signers_count (const gpgme_ctx_t ctx);
+
/* Return the SEQth signer's key in CTX. */
gpgme_key_t gpgme_signers_enum (const gpgme_ctx_t ctx, int seq);
@@ -1146,6 +1165,9 @@ char *gpgme_data_get_file_name (gpgme_data_t dh);
gpgme_error_t gpgme_data_set_file_name (gpgme_data_t dh,
const char *file_name);
+/* Try to identify the type of the data in DH. */
+gpgme_data_type_t gpgme_data_identify (gpgme_data_t dh, int reserved);
+
/* Create a new data buffer which retrieves the data from the callback
function READ_CB. Deprecated, please use gpgme_data_new_from_cbs
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index 358b63c..fe18e6a 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -29,6 +29,7 @@ GPGME_1.1 {
gpgme_data_set_file_name;
gpgme_data_get_file_name;
+ gpgme_data_identify;
gpgme_sig_notation_clear;
gpgme_sig_notation_add;
@@ -143,6 +144,7 @@ GPGME_1.0 {
gpgme_set_textmode;
gpgme_signers_add;
gpgme_signers_clear;
+ gpgme_signers_count;
gpgme_signers_enum;
gpgme_key_ref;
diff --git a/src/parsetlv.c b/src/parsetlv.c
new file mode 100644
index 0000000..70c9518
--- /dev/null
+++ b/src/parsetlv.c
@@ -0,0 +1,103 @@
+/* parsetlv.c - ASN.1 TLV functions
+ * Copyright (C) 2005, 2007, 2008, 2012 g10 Code GmbH
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "parsetlv.h"
+
+
+/* Simple but pretty complete ASN.1 BER parser. Parse the data at the
+ address of BUFFER with a length given at the address of SIZE. On
+ success return 0 and update BUFFER and SIZE to point to the value.
+ Do not update them on error. The information about the object are
+ stored in the caller allocated TI structure. */
+int
+_gpgme_parse_tlv (char const **buffer, size_t *size, tlvinfo_t *ti)
+{
+ int c;
+ unsigned long tag;
+ const unsigned char *buf = (const unsigned char *)(*buffer);
+ size_t length = *size;
+
+ ti->cls = 0;
+ ti->tag = 0;
+ ti->is_cons = 0;
+ ti->is_ndef = 0;
+ ti->length = 0;
+ ti->nhdr = 0;
+
+ if (!length)
+ return -1;
+ c = *buf++; length--; ++ti->nhdr;
+
+ ti->cls = (c & 0xc0) >> 6;
+ ti->is_cons = !!(c & 0x20);
+ tag = c & 0x1f;
+
+ if (tag == 0x1f)
+ {
+ tag = 0;
+ do
+ {
+ tag <<= 7;
+ if (!length)
+ return -1;
+ c = *buf++; length--; ++ti->nhdr;
+ tag |= c & 0x7f;
+ }
+ while (c & 0x80);
+ }
+ ti->tag = tag;
+
+ if (!length)
+ return -1;
+ c = *buf++; length--; ++ti->nhdr;
+
+ if ( !(c & 0x80) )
+ ti->length = c;
+ else if (c == 0x80)
+ ti->is_ndef = 1;
+ else if (c == 0xff)
+ return -1;
+ else
+ {
+ unsigned long len = 0;
+ int count = (c & 0x7f);
+
+ if (count > sizeof (len) || count > sizeof (size_t))
+ return -1;
+
+ for (; count; count--)
+ {
+ len <<= 8;
+ if (!length)
+ return -1;
+ c = *buf++; length--; ++ti->nhdr;
+ len |= c & 0xff;
+ }
+ ti->length = len;
+ }
+
+ *buffer = (void*)buf;
+ *size = length;
+ return 0;
+}
diff --git a/src/parsetlv.h b/src/parsetlv.h
new file mode 100644
index 0000000..153073c
--- /dev/null
+++ b/src/parsetlv.h
@@ -0,0 +1,48 @@
+/* parsetlv.h - TLV functions defintions
+ * Copyright (C) 2012 g10 Code GmbH
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PARSETLV_H
+#define PARSETLV_H
+
+/* ASN.1 constants. */
+#define ASN1_CLASS_UNIVERSAL 0
+#define ASN1_CLASS_APPLICATION 1
+#define ASN1_CLASS_CONTEXT 2
+#define ASN1_CLASS_PRIVATE 3
+#define ASN1_TAG_INTEGER 2
+#define ASN1_TAG_OBJECT_ID 6
+#define ASN1_TAG_SEQUENCE 16
+
+
+/* Object used with parse_tlv. */
+struct tlvinfo_s
+{
+ int cls; /* The class of the tag. */
+ int tag; /* The tag. */
+ int is_cons; /* True if it is a constructed object. */
+ int is_ndef; /* True if the object has an indefinite length. */
+ size_t length; /* The length of the value. */
+ size_t nhdr; /* The number of octets in the header (tag,length). */
+};
+typedef struct tlvinfo_s tlvinfo_t;
+
+/*-- parsetlv.c --*/
+int _gpgme_parse_tlv (char const **buffer, size_t *size, tlvinfo_t *ti);
+#define parse_tlv(a,b,c) _gpgme_parse_tlv ((a), (b), (c))
+
+
+#endif /*PARSETLV_H*/
diff --git a/src/posix-util.c b/src/posix-util.c
index 478055a..fd44507 100644
--- a/src/posix-util.c
+++ b/src/posix-util.c
@@ -28,6 +28,7 @@
#include <assert.h>
#include "util.h"
+#include "sys-util.h"
const char *
_gpgme_get_gpg_path (void)
@@ -70,29 +71,6 @@ _gpgme_get_g13_path (void)
}
-const char *
-_gpgme_get_uiserver_socket_path (void)
-{
- static char *socket_path;
- const char *homedir;
- const char name[] = "S.uiserver";
-
- if (socket_path)
- return socket_path;
-
- homedir = _gpgme_get_default_homedir ();
- if (! homedir)
- return NULL;
-
- socket_path = malloc (strlen (homedir) + 1 + strlen (name) + 1);
- if (! socket_path)
- return NULL;
-
- strcpy (stpcpy (stpcpy (socket_path, homedir), "/"), name);
- return socket_path;
-}
-
-
/* See w32-util.c */
int
_gpgme_get_conf_int (const char *key, int *value)
diff --git a/src/signers.c b/src/signers.c
index 88f923c..f43fafc 100644
--- a/src/signers.c
+++ b/src/signers.c
@@ -93,6 +93,14 @@ gpgme_signers_add (gpgme_ctx_t ctx, const gpgme_key_t key)
}
+/* Return the number of signers in CTX. */
+unsigned int
+gpgme_signers_count (const gpgme_ctx_t ctx)
+{
+ return ctx? ctx->signers_len : 0;
+}
+
+
/* Return the SEQth signer's key in CTX with one reference. */
gpgme_key_t
gpgme_signers_enum (const gpgme_ctx_t ctx, int seq)
diff --git a/src/sys-util.h b/src/sys-util.h
new file mode 100644
index 0000000..f6506d3
--- /dev/null
+++ b/src/sys-util.h
@@ -0,0 +1,29 @@
+/* sys-util.h - System utilities not generally used.
+ * Copyright (C) 2013 g10 Code GmbH
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SYS_UTIL_H
+#define SYS_UTIL_H
+
+/*-- {posix,w32}-util.c --*/
+const char *_gpgme_get_gpg_path (void);
+const char *_gpgme_get_gpgsm_path (void);
+const char *_gpgme_get_gpgconf_path (void);
+const char *_gpgme_get_g13_path (void);
+
+#endif /* SYS_UTIL_H */
diff --git a/src/util.h b/src/util.h
index db8dc39..c432980 100644
--- a/src/util.h
+++ b/src/util.h
@@ -47,18 +47,17 @@
/*-- {posix,w32}-util.c --*/
-const char *_gpgme_get_gpg_path (void);
-const char *_gpgme_get_gpgsm_path (void);
-const char *_gpgme_get_gpgconf_path (void);
-const char *_gpgme_get_g13_path (void);
-const char *_gpgme_get_uiserver_socket_path (void);
-
int _gpgme_get_conf_int (const char *key, int *value);
void _gpgme_allow_set_foreground_window (pid_t pid);
/*-- dirinfo.c --*/
const char *_gpgme_get_default_homedir (void);
const char *_gpgme_get_default_agent_socket (void);
+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_uisrv_socket (void);
diff --git a/src/w32-util.c b/src/w32-util.c
index a90f405..4cee1cb 100644
--- a/src/w32-util.c
+++ b/src/w32-util.c
@@ -1,24 +1,23 @@
/* w32-util.c - Utility functions for the W32 API
- Copyright (C) 1999 Free Software Foundation, Inc
- Copyright (C) 2001 Werner Koch (dd9jn)
- Copyright (C) 2001, 2002, 2003, 2004, 2007 g10 Code GmbH
-
- This file is part of GPGME.
-
- GPGME is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of
- the License, or (at your option) any later version.
-
- GPGME is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ * Copyright (C) 1999 Free Software Foundation, Inc
+ * Copyright (C) 2001 Werner Koch (dd9jn)
+ * Copyright (C) 2001, 2002, 2003, 2004, 2007, 2013 g10 Code GmbH
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ **/
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -63,6 +62,7 @@
#include "ath.h"
#include "sema.h"
#include "debug.h"
+#include "sys-util.h"
#ifndef HAVE_W32CE_SYSTEM
@@ -75,6 +75,12 @@
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
+ 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;
+
#ifdef HAVE_ALLOW_SET_FOREGROUND_WINDOW
@@ -112,6 +118,39 @@ dlclose (void * hd)
}
#endif /* HAVE_ALLOW_SET_FOREGROUND_WINDOW */
+
+/* Return a malloced string encoded in UTF-8 from the wide char input
+ string STRING. Caller must free this value. Returns NULL and sets
+ ERRNO on failure. Calling this function with STRING set to NULL is
+ not defined. */
+static char *
+wchar_to_utf8 (const wchar_t *string)
+{
+ int n;
+ char *result;
+
+ n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
+ if (n < 0)
+ {
+ gpg_err_set_errno (EINVAL);
+ return NULL;
+ }
+
+ result = malloc (n+1);
+ if (!result)
+ return NULL;
+
+ n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
+ if (n < 0)
+ {
+ free (result);
+ gpg_err_set_errno (EINVAL);
+ result = NULL;
+ }
+ return result;
+}
+
+
void
_gpgme_allow_set_foreground_window (pid_t pid)
{
@@ -270,51 +309,53 @@ read_w32_registry_string (const char *root, const char *dir, const char *name)
}
-#if 0
-static char *
-find_program_in_registry (const char *name)
+/* Return the name of the directory with the gpgme DLL or the EXE (if
+ statically linked). May return NULL on severe errors. */
+const char *
+_gpgme_get_inst_dir (void)
{
- char *program = NULL;
+ static char *inst_dir;
- program = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", name);
- if (program)
+ LOCK (get_path_lock);
+ if (!inst_dir)
{
- int i;
+ wchar_t *moddir;
- TRACE2 (DEBUG_CTX, "gpgme:find_program_in_registry", 0,
- "found %s in registry: `%s'", name, program);
- for (i = 0; program[i]; i++)
- {
- if (program[i] == '/')
- program[i] = '\\';
- }
+ moddir = malloc ((MAX_PATH+5) * sizeof *moddir);
+ if (moddir)
+ {
+ if (!GetModuleFileNameW (my_hmodule, moddir, MAX_PATH))
+ *moddir = 0;
+ if (!*moddir)
+ gpg_err_set_errno (ENOENT);
+ else
+ {
+ inst_dir = wchar_to_utf8 (moddir);
+ if (inst_dir)
+ {
+ char *p = strrchr (inst_dir, '\\');
+ if (p)
+ *p = 0;
+ }
+ }
+ free (moddir);
+ }
}
- return program;
+ UNLOCK (get_path_lock);
+ return inst_dir;
}
-#endif
static char *
-find_program_in_inst_dir (const char *name)
+find_program_in_dir (const char *dir, const char *name)
{
- char *result = NULL;
- char *tmp;
-
- tmp = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
- "Software\\GNU\\GnuPG",
- "Install Directory");
- if (!tmp)
- return NULL;
+ char *result;
- result = malloc (strlen (tmp) + 1 + strlen (name) + 1);
+ result = malloc (strlen (dir) + 1 + strlen (name) + 1);
if (!result)
- {
- free (tmp);
- return NULL;
- }
+ return NULL;
- strcpy (stpcpy (stpcpy (result, tmp), "\\"), name);
- free (tmp);
+ strcpy (stpcpy (stpcpy (result, dir), "\\"), name);
if (access (result, F_OK))
{
free (result);
@@ -326,6 +367,40 @@ find_program_in_inst_dir (const char *name)
static char *
+find_program_in_inst_dir (const char *inst_dir, const char *name)
+{
+ char *result;
+ char *dir;
+
+ /* If an installation directory has been passed, this overrides a
+ location given bu the registry. The idea here is that we prefer
+ a a program installed alongside with gpgme. We don't want the
+ registry to override this to have a better isolation of an gpgme
+ aware applications for other effects. Note that the "Install
+ Directory" registry item has been used for ages in Gpg4win and
+ earlier GnuPG windows installers. It is technically not anymore
+ required. */
+ if (inst_dir)
+ {
+ result = find_program_in_dir (inst_dir, name);
+ if (result)
+ return result;
+ }
+
+ dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
+ "Software\\GNU\\GnuPG",
+ "Install Directory");
+ if (dir)
+ {
+ result = find_program_in_dir (dir, name);
+ free (dir);
+ return result;
+ }
+ return NULL;
+}
+
+
+static char *
find_program_at_standard_place (const char *name)
{
char path[MAX_PATH];
@@ -353,14 +428,12 @@ const char *
_gpgme_get_gpg_path (void)
{
static char *gpg_program;
+ const char *inst_dir;
+ inst_dir = _gpgme_get_inst_dir ();
LOCK (get_path_lock);
-#if 0
if (!gpg_program)
- gpg_program = find_program_in_registry ("gpgProgram");
-#endif
- if (!gpg_program)
- gpg_program = find_program_in_inst_dir ("gpg.exe");
+ gpg_program = find_program_in_inst_dir (inst_dir, "gpg.exe");
if (!gpg_program)
gpg_program = find_program_at_standard_place ("GNU\\GnuPG\\gpg.exe");
UNLOCK (get_path_lock);
@@ -372,14 +445,12 @@ const char *
_gpgme_get_gpgsm_path (void)
{
static char *gpgsm_program;
+ const char *inst_dir;
+ inst_dir = _gpgme_get_inst_dir ();
LOCK (get_path_lock);
-#if 0
if (!gpgsm_program)
- gpgsm_program = find_program_in_registry ("gpgsmProgram");
-#endif
- if (!gpgsm_program)
- gpgsm_program = find_program_in_inst_dir ("gpgsm.exe");
+ gpgsm_program = find_program_in_inst_dir (inst_dir, "gpgsm.exe");
if (!gpgsm_program)
gpgsm_program = find_program_at_standard_place ("GNU\\GnuPG\\gpgsm.exe");
UNLOCK (get_path_lock);
@@ -391,14 +462,12 @@ const char *
_gpgme_get_gpgconf_path (void)
{
static char *gpgconf_program;
+ const char *inst_dir;
+ inst_dir = _gpgme_get_inst_dir ();
LOCK (get_path_lock);
-#if 0
- if (!gpgconf_program)
- gpgconf_program = find_program_in_registry ("gpgconfProgram");
-#endif
if (!gpgconf_program)
- gpgconf_program = find_program_in_inst_dir ("gpgconf.exe");
+ gpgconf_program = find_program_in_inst_dir (inst_dir, "gpgconf.exe");
if (!gpgconf_program)
gpgconf_program
= find_program_at_standard_place ("GNU\\GnuPG\\gpgconf.exe");
@@ -411,14 +480,12 @@ const char *
_gpgme_get_g13_path (void)
{
static char *g13_program;
+ const char *inst_dir;
+ inst_dir = _gpgme_get_inst_dir ();
LOCK (get_path_lock);
-#if 0
if (!g13_program)
- g13_program = find_program_in_registry ("g13Program");
-#endif
- if (!g13_program)
- g13_program = find_program_in_inst_dir ("g13.exe");
+ g13_program = find_program_in_inst_dir (inst_dir, "g13.exe");
if (!g13_program)
g13_program = find_program_at_standard_place ("GNU\\GnuPG\\g13.exe");
UNLOCK (get_path_lock);
@@ -427,36 +494,15 @@ _gpgme_get_g13_path (void)
const char *
-_gpgme_get_uiserver_socket_path (void)
-{
- static char *socket_path;
- const char *homedir;
- const char name[] = "S.uiserver";
-
- if (socket_path)
- return socket_path;
-
- homedir = _gpgme_get_default_homedir ();
- if (! homedir)
- return NULL;
-
- socket_path = malloc (strlen (homedir) + 1 + strlen (name) + 1);
- if (! socket_path)
- return NULL;
-
- strcpy (stpcpy (stpcpy (socket_path, homedir), "\\"), name);
- return socket_path;
-}
-
-
-const char *
_gpgme_get_w32spawn_path (void)
{
static char *w32spawn_program;
+ const char *inst_dir;
+ inst_dir = _gpgme_get_inst_dir ();
LOCK (get_path_lock);
if (!w32spawn_program)
- w32spawn_program = find_program_in_inst_dir ("gpgme-w32spawn.exe");
+ w32spawn_program = find_program_in_inst_dir (inst_dir,"gpgme-w32spawn.exe");
if (!w32spawn_program)
w32spawn_program
= find_program_at_standard_place ("GNU\\GnuPG\\gpgme-w32spawn.exe");
@@ -641,3 +687,18 @@ _gpgme_w32ce_get_debug_envvar (void)
return tmp;
}
#endif /*HAVE_W32CE_SYSTEM*/
+
+
+/* Entry point called by the DLL loader. */
+#ifdef DLL_EXPORT
+int WINAPI
+DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved)
+{
+ (void)reserved;
+
+ if (reason == DLL_PROCESS_ATTACH)
+ my_hmodule = hinst;
+
+ return TRUE;
+}
+#endif /*DLL_EXPORT*/