Do not test for GnuPG version and use gpgconf to find it.
authorWerner Koch <wk@gnupg.org>
Mon, 25 Feb 2019 11:43:42 +0000 (12:43 +0100)
committerWerner Koch <wk@gnupg.org>
Mon, 25 Feb 2019 11:43:42 +0000 (12:43 +0100)
* configure.ac: Remove all tests for GPGSM and GPG_CONNECT_AGENT.
* src/agent.c (agent_connect): Change to use gpgconf.
* src/get-path.c (get_gpg_connect_agent_path): Rename to ...
(get_gpgconf_path): this.
(get_bindir): New.
(get_gpgsm_path): Implement using get_bindir.
--

gpgconf is the suggested way to test for gnupg and to find properties
of the installation.

Signed-off-by: Werner Koch <wk@gnupg.org>
configure.ac
src/agent.c
src/get-path.c
src/support.h

index e36f56d..7c3374b 100644 (file)
@@ -66,7 +66,7 @@ VERSION_MINOR=0
 
 NEED_GPG_ERROR_VERSION=1.24
 NEED_LIBASSUAN_VERSION=2.5.0
-NEED_GPGSM_VERSION=2.2.0
+
 # Some status variables to give feedback at the end of a configure run.
 have_gpg_error=no
 have_libassuan=no
@@ -190,9 +190,6 @@ AC_ARG_ENABLE(optimization,
 AC_SUBST(LIBSCUTE_LT_CURRENT)
 AC_SUBST(LIBSCUTE_LT_AGE)
 AC_SUBST(LIBSCUTE_LT_REVISION)
-AC_DEFINE_UNQUOTED(NEED_GPGSM_VERSION, "$NEED_GPGSM_VERSION",
-                                      [Min. needed GPGSM version.])
-
 AC_SUBST(PACKAGE)
 AC_SUBST(VERSION)
 AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package])
@@ -230,14 +227,10 @@ case "${host}" in
 esac
 AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
 
-GPGSM_DEFAULT=no
-GPG_CONNECT_AGENT_DEFAULT=no
 have_w32_system=no
 case "${host}" in
     *-mingw32*)
-        # special stuff for Windoze NT
-       GPGSM_DEFAULT='c:\\gnupg\\gpgsm.exe'
-        GPG_CONNECT_AGENT_DEFAULT='c:\\gnupg\\gpg-connect-agent.exe'
+        # special stuff for Windows NT
        have_w32_system=yes
         ;;
     *)
@@ -271,133 +264,6 @@ AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION",
 AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_VERSION",
                   have_libassuan=yes, have_libassuan=no)
 
-# GPGSM
-NO_OVERRIDE=no
-AC_ARG_WITH(gpgsm,
-           AC_HELP_STRING([--with-gpgsm=PATH], [use GpgSM binary at PATH]),
-           GPGSM=$withval, NO_OVERRIDE=yes)
-if test "$NO_OVERRIDE" = "yes" || test "$GPGSM" = "yes"; then
-  GPGSM=
-  NO_OVERRIDE=yes
-  if test "$cross_compiling" != "yes"; then
-    AC_PATH_PROG(GPGSM, gpgsm)
-  fi
-  if test -z "$GPGSM"; then
-    GPGSM="$GPGSM_DEFAULT"
-  fi
-fi
-if test "$GPGSM" = no; then
-  if test "$NO_OVERRIDE" = "yes"; then
-    if test "$cross_compiling" != "yes"; then
-      AC_MSG_ERROR([
-***
-*** Could not find GpgSM, install GpgSM or use --with-gpgsm=PATH to enable it
-***])
-    else
-      AC_MSG_ERROR([
-***
-*** Can not determine path to GpgSM when cross-compiling, use --with-gpgsm=PATH
-***])
-    fi
-  fi
-else
-  AC_DEFINE_UNQUOTED(GPGSM_PATH, "$GPGSM", [Path to the GPGSM binary.])
-  AC_DEFINE(ENABLE_GPGSM,1,[Whether GPGSM support is enabled])
-fi
-AM_CONDITIONAL(HAVE_GPGSM, test "$GPGSM" != "no")
-
-
-dnl Check for GPGSM version requirement.
-GPGSM_VERSION=unknown
-ok=maybe
-if test -z "$GPGSM" -o "x$GPGSM" = "xno"; then
-  ok=no
-else
-  if test "$cross_compiling" = "yes"; then
-    AC_MSG_WARN([GPGSM version can not be checked when cross compiling])
-    ok=no
-  else
-    if test ! -x "$GPGSM"; then
-      AC_MSG_WARN([GPGSM not executable, version check disabled])
-      ok=no
-    fi
-  fi
-fi
-if test "$ok" = "maybe"; then
-  AC_MSG_CHECKING(for GPGSM >= $NEED_GPGSM_VERSION)
-  req_major=`echo $NEED_GPGSM_VERSION | \
-             sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
-  req_minor=`echo $NEED_GPGSM_VERSION | \
-            sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
-  req_micro=`echo $NEED_GPGSM_VERSION | \
-            sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
-  gpgsm_version=`$GPGSM --version | grep ^gpgsm`
-  major=`echo $gpgsm_version | \
-        sed 's/^gpgsm (GnuPG) \([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
-  minor=`echo $gpgsm_version | \
-        sed 's/^gpgsm (GnuPG) \([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
-  micro=`echo $gpgsm_version | \
-        sed 's/^gpgsm (GnuPG) \([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
-  GPGSM_VERSION=`echo $gpgsm_version | sed 's/^gpgsm (GnuPG) //'`
-
-  if test "$major" -gt "$req_major"; then
-    ok=yes
-  else
-    if test "$major" -eq "$req_major"; then
-      if test "$minor" -gt "$req_minor"; then
-        ok=yes
-      else
-        if test "$minor" -eq "$req_minor"; then
-          if test "$micro" -ge "$req_micro"; then
-            ok=yes
-         fi
-        fi
-      fi
-    fi
-  fi
-  if test "$ok" = "yes"; then
-    AC_MSG_RESULT(yes)
-  else
-    AC_MSG_RESULT(no)
-    AC_MSG_WARN([GPGSM must be at least version $NEED_GPGSM_VERSION])
-  fi
-fi
-gpgsm_ok="$ok"
-
-# GPG_CONNECT_AGENT
-NO_OVERRIDE=no
-AC_ARG_WITH(gpg-connect-agent,
-            AC_HELP_STRING([--with-gpg-connect-agent=PATH],
-                           [use gpg-connect-agent binary at PATH]),
-            GPG_CONNECT_AGENT=$withval, NO_OVERRIDE=yes)
-if test "$NO_OVERRIDE" = "yes" || test "$GPG_CONNECT_AGENT" = "yes"; then
-  GPG_CONNECT_AGENT=
-  NO_OVERRIDE=yes
-  if test "$cross_compiling" != "yes"; then
-    AC_CHECK_PROG(GPG_CONNECT_AGENT, gpg-connect-agent, gpg-connect-agent)
-  fi
-  if test -z "$GPG_CONNECT_AGENT"; then
-    GPG_CONNECT_AGENT="$GPG_CONNECT_AGENT_DEFAULT"
-  fi
-fi
-if test "$GPG_CONNECT_AGENT" = no; then
-  if test "$NO_OVERRIDE" = "yes"; then
-    if test "$cross_compiling" != "yes"; then
-      AC_MSG_ERROR([
-***
-*** Could not find gpg-connect-agent, use --with-gpg-connect-agent=PATH to enable it
-***])
-    else
-      AC_MSG_ERROR([
-***
-*** Can not determine path to gpg-connect-agent when cross-compiling, use --with-gpg-connect-agent=PATH
-***])
-    fi
-  fi
-else
-  AC_DEFINE_UNQUOTED(GPG_CONNECT_AGENT_PATH, "$GPG_CONNECT_AGENT",
-                     [Path to the GPG_CONNECT_AGENT binary.])
-fi
 
 
 # Checks for header files.
@@ -473,8 +339,4 @@ echo "
 
         Revision: mym4_revision  (mym4_revision_dec)
         Platform: $host
-
-        GpgSM:             ${GPGSM}
-        Gpg-connect-agent: ${GPG_CONNECT_AGENT}
-
 "
index c168a2e..d146a24 100644 (file)
@@ -49,7 +49,7 @@
 
 \f
 /* The global agent context.  */
-static assuan_context_t agent_ctx = NULL;
+static assuan_context_t agent_ctx;
 
 /* The version number of the agent.  */
 static int agent_version_major;
@@ -78,32 +78,34 @@ agent_connect (assuan_context_t *ctx_r)
 {
   gpg_error_t err = 0;
   assuan_context_t ctx = NULL;
-  char buffer[255];
-  FILE *p;
+  char buffer[512];
+  FILE *fp;
 
-  /* Use gpg-connect-agent to obtain the socket name
-   * directly from the agent itself. */
-  snprintf (buffer, sizeof buffer, "%s 'GETINFO socket_name' /bye",
-            get_gpg_connect_agent_path ());
+  /* Use gpgconf to obtain the socket name.  */
+  snprintf (buffer, sizeof buffer, "%s --null --list-dirs agent-socket",
+            get_gpgconf_path ());
 #ifdef HAVE_W32_SYSTEM
-  p = _popen (buffer, "r");
+  fp = _popen (buffer, "r");
 #else
-  p = popen (buffer, "r");
+  fp = popen (buffer, "r");
 #endif
-  if (p)
+  if (fp)
     {
-      int ret;
-
-      ret = fscanf (p, "D %254s\nOK\n", buffer);
-      if (ret == EOF)       /* I/O error? */
-        err = gpg_error_from_errno (errno);
-      else if (ret != 1)    /* Unexpected reply */
-        err = gpg_error (GPG_ERR_NO_AGENT);
-
-      pclose (p);
+      int i, c;
+
+      for (i=0; i < sizeof buffer - 1  && (c = getc (fp)) != EOF; i++)
+        buffer[i] = c;
+      if (c == EOF && ferror (fp))       /* I/O error? */
+        err = gpg_error_from_syserror ();
+      else if (!(i < sizeof buffer - 1))
+        err = gpg_error (GPG_ERR_NO_AGENT);  /* Path too long.  */
+      else if (!i || buffer[i-1])
+        err = gpg_error (GPG_ERR_NO_AGENT);  /* No terminating nul. */
+
+      pclose (fp);
     }
   else
-    err = gpg_error_from_errno (errno);
+    err = gpg_error_from_syserror ();
 
   /* Then connect to the socket we got. */
   if (!err)
index 58491fe..3647b30 100644 (file)
 # include <io.h>
 #endif
 
+#include <gpg-error.h>
+#include "debug.h"
 #include "support.h"
 
+
 #ifndef HAVE_STPCPY
 static char *
 my_stpcpy (char *a, const char *b)
@@ -286,35 +289,96 @@ find_program_at_standard_place (const char *name)
 #endif
 
 
+/* Return the file name of the gpgconf utility.  */
 const char *
-get_gpgsm_path (void)
+get_gpgconf_path (void)
 {
   static const char *pgmname;
 
 #ifdef HAVE_W32_SYSTEM
   if (!pgmname)
-    pgmname = find_program_in_inst_dir ("gpgsm.exe");
+    pgmname = find_program_in_inst_dir ("gpgconf.exe");
   if (!pgmname)
-    pgmname = find_program_at_standard_place ("GNU\\GnuPG\\gpgsm.exe");
+    pgmname = find_program_at_standard_place ("GNU\\GnuPG\\gpgconf.exe");
 #endif
   if (!pgmname)
-    pgmname = GPGSM_PATH;
+    pgmname = "gpgconf";
   return pgmname;
 }
 
 
-const char *
-get_gpg_connect_agent_path (void)
+/* Return the bindir where the main binaries are installed.  This may
+ * return NULL.  */
+static const char *
+get_bindir (void)
 {
-  static const char *pgmname;
+  static char *bindir;
+  gpg_error_t err = 0;
+  char buffer[512];
+  FILE *fp;
 
+  if (!bindir)
+    {
+      snprintf (buffer, sizeof buffer, "%s --null --list-dirs bindir",
+                get_gpgconf_path ());
 #ifdef HAVE_W32_SYSTEM
-  if (!pgmname)
-    pgmname = find_program_in_inst_dir ("gpg-connect-agent.exe");
-  if (!pgmname)
-    pgmname = find_program_at_standard_place ("GNU\\GnuPG\\gpg-connect-agent.exe");
+      fp = _popen (buffer, "r");
+#else
+      fp = popen (buffer, "r");
+#endif
+      if (fp)
+        {
+          int i, c;
+
+          for (i=0; i < sizeof buffer - 1  && (c = getc (fp)) != EOF; i++)
+            buffer[i] = c;
+          if (c == EOF && ferror (fp))
+            err = gpg_error_from_syserror ();
+          else if (!(i < sizeof buffer - 1))
+            err = gpg_error (GPG_ERR_NO_AGENT);  /* Path too long.  */
+          else if (!i || buffer[i-1])
+            err = gpg_error (GPG_ERR_NO_AGENT);  /* No terminating nul. */
+          else if (!(bindir = strdup (buffer)))
+            err = gpg_error_from_syserror ();
+
+          pclose (fp);
+        }
+      else
+        err = gpg_error_from_syserror ();
+
+      if (err)
+        DEBUG (DBG_CRIT, "error locating GnuPG's installation directory: %s",
+               gpg_strerror (err));
+    }
+
+  return bindir;
+}
+
+
+const char *
+get_gpgsm_path (void)
+{
+  static char *pgmname;
+#ifdef HAVE_W32_SYSTEM
+  static const char gpgsm[] = "gpgsm.exe";
+#else
+  static const char gpgsm[] = "gpgsm";
 #endif
+
   if (!pgmname)
-    pgmname = GPG_CONNECT_AGENT_PATH;
+    {
+      char *buffer;
+      const char *bindir = get_bindir ();
+      if (!bindir)
+        return gpgsm;  /* Error fallback without any path component.  */
+
+      buffer = malloc (strlen (bindir) + 1 + strlen (gpgsm) + 1);
+      if (!buffer)
+        return gpgsm;  /* Error fallback.  */
+
+      strcpy (stpcpy (stpcpy (buffer, bindir), "/"), gpgsm);
+      pgmname = buffer;
+    }
+
   return pgmname;
 }
index b51f3ac..4cd222f 100644 (file)
@@ -71,8 +71,8 @@ ttyname (int fd)
 #endif /* !HAVE_TTYNAME */
 
 
+const char *get_gpgconf_path (void);
 const char *get_gpgsm_path (void);
-const char *get_gpg_connect_agent_path (void);