|
|
|
@ -1,670 +0,0 @@
|
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
|
|
|
index 1e4137d..d05785e 100644
|
|
|
|
|
--- a/configure.ac
|
|
|
|
|
+++ b/configure.ac
|
|
|
|
|
@@ -231,13 +231,13 @@ esac
|
|
|
|
|
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
|
|
|
|
|
|
|
|
|
|
GPGSM_DEFAULT=no
|
|
|
|
|
-GPG_AGENT_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_AGENT_DEFAULT='c:\\gnupg\\gpg-agent.exe'
|
|
|
|
|
+ GPG_CONNECT_AGENT_DEFAULT='c:\\gnupg\\gpg-connect-agent.exe'
|
|
|
|
|
have_w32_system=yes
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
@@ -371,40 +371,40 @@ if test "$ok" = "maybe"; then
|
|
|
|
|
fi
|
|
|
|
|
gpgsm_ok="$ok"
|
|
|
|
|
|
|
|
|
|
-# GPG_AGENT
|
|
|
|
|
+# GPG_CONNECT_AGENT
|
|
|
|
|
NO_OVERRIDE=no
|
|
|
|
|
-AC_ARG_WITH(gpg-agent,
|
|
|
|
|
- AC_HELP_STRING([--with-gpg-agent=PATH], [use GPG Agent binary at PATH]),
|
|
|
|
|
- GPG_AGENT=$withval, NO_OVERRIDE=yes)
|
|
|
|
|
-if test "$NO_OVERRIDE" = "yes" || test "$GPG_AGENT" = "yes"; then
|
|
|
|
|
- GPG_AGENT=
|
|
|
|
|
+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_PATH_PROG(GPG_AGENT, gpg-agent)
|
|
|
|
|
+ AC_PATH_PROG(GPG_CONNECT_AGENT, gpg-connect-agent)
|
|
|
|
|
fi
|
|
|
|
|
- if test -z "$GPG_AGENT"; then
|
|
|
|
|
- GPG_AGENT="$GPG_AGENT_DEFAULT"
|
|
|
|
|
+ if test -z "$GPG_CONNECT_AGENT"; then
|
|
|
|
|
+ GPG_CONNECT_AGENT="$GPG_CONNECT_AGENT_DEFAULT"
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
-if test "$GPG_AGENT" = no; then
|
|
|
|
|
+if test "$GPG_CONNECT_AGENT" = no; then
|
|
|
|
|
if test "$NO_OVERRIDE" = "yes"; then
|
|
|
|
|
if test "$cross_compiling" != "yes"; then
|
|
|
|
|
AC_MSG_WARN([
|
|
|
|
|
***
|
|
|
|
|
-*** Could not find GPG Agent, install GPG Agent or use --with-gpg-agent=PATH to enable it
|
|
|
|
|
+*** Could not find gpg-connect-agent, use --with-gpg-connect-agent=PATH to enable it
|
|
|
|
|
***])
|
|
|
|
|
else
|
|
|
|
|
- AC_MSG_ERROR([
|
|
|
|
|
+ AC_MSG_WARN([
|
|
|
|
|
***
|
|
|
|
|
-*** Can not determine path to GPG Agent when cross-compiling, use --with-gpg-agent=PATH
|
|
|
|
|
+*** Can not determine path to gpg-connect-agent when cross-compiling, use --with-gpg-connect-agent=PATH
|
|
|
|
|
***])
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
- AC_DEFINE_UNQUOTED(GPG_AGENT_PATH, "$GPG_AGENT", [Path to the GPG_AGENT binary.])
|
|
|
|
|
- AC_DEFINE(ENABLE_GPG_AGENT,1, [Whether GPG Agent support is enabled])
|
|
|
|
|
+ AC_DEFINE_UNQUOTED(GPG_CONNECT_AGENT_PATH, "$GPG_CONNECT_AGENT",
|
|
|
|
|
+ [Path to the GPG_CONNECT_AGENT binary.])
|
|
|
|
|
fi
|
|
|
|
|
-AM_CONDITIONAL(HAVE_GPG_AGENT, test "$GPG_AGENT" != "no")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Checks for header files.
|
|
|
|
|
diff --git a/src/agent.c b/src/agent.c
|
|
|
|
|
index 75d4933..cecf570 100644
|
|
|
|
|
--- a/src/agent.c
|
|
|
|
|
+++ b/src/agent.c
|
|
|
|
|
@@ -79,305 +79,64 @@ gnupg_allow_set_foregound_window (pid_t pid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
-/* Helper function to build_w32_commandline. */
|
|
|
|
|
-static char *
|
|
|
|
|
-build_w32_commandline_copy (char *buffer, const char *string)
|
|
|
|
|
-{
|
|
|
|
|
- char *p = buffer;
|
|
|
|
|
- const char *s;
|
|
|
|
|
-
|
|
|
|
|
- if (!*string) /* Empty string. */
|
|
|
|
|
- p = stpcpy (p, "\"\"");
|
|
|
|
|
- else if (strpbrk (string, " \t\n\v\f\""))
|
|
|
|
|
- {
|
|
|
|
|
- /* Need top do some kind of quoting. */
|
|
|
|
|
- p = stpcpy (p, "\"");
|
|
|
|
|
- for (s=string; *s; s++)
|
|
|
|
|
- {
|
|
|
|
|
- *p++ = *s;
|
|
|
|
|
- if (*s == '\"')
|
|
|
|
|
- *p++ = *s;
|
|
|
|
|
- }
|
|
|
|
|
- *p++ = '\"';
|
|
|
|
|
- *p = 0;
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- p = stpcpy (p, string);
|
|
|
|
|
-
|
|
|
|
|
- return p;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-/* Build a command line for use with W32's CreateProcess. On success
|
|
|
|
|
- CMDLINE gets the address of a newly allocated string. */
|
|
|
|
|
-static gpg_error_t
|
|
|
|
|
-build_w32_commandline (const char *pgmname, const char * const *argv,
|
|
|
|
|
- char **cmdline)
|
|
|
|
|
-{
|
|
|
|
|
- int i, n;
|
|
|
|
|
- const char *s;
|
|
|
|
|
- char *buf, *p;
|
|
|
|
|
-
|
|
|
|
|
- *cmdline = NULL;
|
|
|
|
|
- n = 0;
|
|
|
|
|
- s = pgmname;
|
|
|
|
|
- n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
|
|
|
|
|
- for (; *s; s++)
|
|
|
|
|
- if (*s == '\"')
|
|
|
|
|
- n++; /* Need to double inner quotes. */
|
|
|
|
|
- for (i=0; (s=argv[i]); i++)
|
|
|
|
|
- {
|
|
|
|
|
- n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
|
|
|
|
|
- for (; *s; s++)
|
|
|
|
|
- if (*s == '\"')
|
|
|
|
|
- n++; /* Need to double inner quotes. */
|
|
|
|
|
- }
|
|
|
|
|
- n++;
|
|
|
|
|
-
|
|
|
|
|
- buf = p = malloc (n);
|
|
|
|
|
- if (!buf)
|
|
|
|
|
- return gpg_error_from_syserror ();
|
|
|
|
|
-
|
|
|
|
|
- p = build_w32_commandline_copy (p, pgmname);
|
|
|
|
|
- for (i=0; argv[i]; i++)
|
|
|
|
|
- {
|
|
|
|
|
- *p++ = ' ';
|
|
|
|
|
- p = build_w32_commandline_copy (p, argv[i]);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- *cmdline= buf;
|
|
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-/* Spawn a new process and immediately detach from it. The name of
|
|
|
|
|
- the program to exec is PGMNAME and its arguments are in ARGV (the
|
|
|
|
|
- programname is automatically passed as first argument). An error
|
|
|
|
|
- is returned if pgmname is not executable; to make this work it is
|
|
|
|
|
- necessary to provide an absolute file name. All standard file
|
|
|
|
|
- descriptors are connected to /dev/null. */
|
|
|
|
|
-static gpg_error_t
|
|
|
|
|
-spawn_process_detached (const char *pgmname, const char *argv[])
|
|
|
|
|
-{
|
|
|
|
|
- gpg_error_t err;
|
|
|
|
|
- SECURITY_ATTRIBUTES sec_attr;
|
|
|
|
|
- PROCESS_INFORMATION pi =
|
|
|
|
|
- {
|
|
|
|
|
- NULL, /* Returns process handle. */
|
|
|
|
|
- 0, /* Returns primary thread handle. */
|
|
|
|
|
- 0, /* Returns pid. */
|
|
|
|
|
- 0 /* Returns tid. */
|
|
|
|
|
- };
|
|
|
|
|
- STARTUPINFO si;
|
|
|
|
|
- int cr_flags;
|
|
|
|
|
- char *cmdline;
|
|
|
|
|
-
|
|
|
|
|
- if (access (pgmname, X_OK))
|
|
|
|
|
- return gpg_error_from_syserror ();
|
|
|
|
|
-
|
|
|
|
|
- /* Prepare security attributes. */
|
|
|
|
|
- memset (&sec_attr, 0, sizeof sec_attr );
|
|
|
|
|
- sec_attr.nLength = sizeof sec_attr;
|
|
|
|
|
- sec_attr.bInheritHandle = FALSE;
|
|
|
|
|
-
|
|
|
|
|
- /* Build the command line. */
|
|
|
|
|
- err = build_w32_commandline (pgmname, argv, &cmdline);
|
|
|
|
|
- if (err)
|
|
|
|
|
- return err;
|
|
|
|
|
-
|
|
|
|
|
- /* Start the process. */
|
|
|
|
|
- memset (&si, 0, sizeof si);
|
|
|
|
|
- si.cb = sizeof (si);
|
|
|
|
|
- si.dwFlags = STARTF_USESHOWWINDOW;
|
|
|
|
|
- si.wShowWindow = SW_MINIMIZE;
|
|
|
|
|
-
|
|
|
|
|
- cr_flags = (CREATE_DEFAULT_ERROR_MODE
|
|
|
|
|
- | GetPriorityClass (GetCurrentProcess ())
|
|
|
|
|
- | CREATE_NEW_PROCESS_GROUP
|
|
|
|
|
- | DETACHED_PROCESS);
|
|
|
|
|
- DEBUG (DBG_INFO, "CreateProcess(detached), path=`%s' cmdline=`%s'\n",
|
|
|
|
|
- pgmname, cmdline);
|
|
|
|
|
- if (!CreateProcess (pgmname, /* Program to start. */
|
|
|
|
|
- cmdline, /* Command line arguments. */
|
|
|
|
|
- &sec_attr, /* Process security attributes. */
|
|
|
|
|
- &sec_attr, /* Thread security attributes. */
|
|
|
|
|
- FALSE, /* Inherit handles. */
|
|
|
|
|
- cr_flags, /* Creation flags. */
|
|
|
|
|
- NULL, /* Environment. */
|
|
|
|
|
- NULL, /* Use current drive/directory. */
|
|
|
|
|
- &si, /* Startup information. */
|
|
|
|
|
- &pi /* Returns process information. */
|
|
|
|
|
- ))
|
|
|
|
|
- {
|
|
|
|
|
- DEBUG (DBG_CRIT, "CreateProcess(detached) failed: %i\n",
|
|
|
|
|
- GetLastError ());
|
|
|
|
|
- free (cmdline);
|
|
|
|
|
- return gpg_error (GPG_ERR_GENERAL);
|
|
|
|
|
- }
|
|
|
|
|
- free (cmdline);
|
|
|
|
|
- cmdline = NULL;
|
|
|
|
|
-
|
|
|
|
|
- DEBUG (DBG_INFO, "CreateProcess(detached) ready: hProcess=%p hThread=%p"
|
|
|
|
|
- " dwProcessID=%d dwThreadId=%d\n", pi.hProcess, pi.hThread,
|
|
|
|
|
- (int) pi.dwProcessId, (int) pi.dwThreadId);
|
|
|
|
|
-
|
|
|
|
|
- CloseHandle (pi.hThread);
|
|
|
|
|
-
|
|
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-#endif
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
/* Establish a connection to a running GPG agent. */
|
|
|
|
|
static gpg_error_t
|
|
|
|
|
agent_connect (assuan_context_t *ctx_r)
|
|
|
|
|
{
|
|
|
|
|
- /* If we ever failed to connect via a socket we will force the use
|
|
|
|
|
- of the pipe based server for the lifetime of the process. */
|
|
|
|
|
- static int force_pipe_server = 0;
|
|
|
|
|
-
|
|
|
|
|
gpg_error_t err = 0;
|
|
|
|
|
- char *infostr;
|
|
|
|
|
- char *ptr;
|
|
|
|
|
assuan_context_t ctx = NULL;
|
|
|
|
|
+ char buffer[255];
|
|
|
|
|
+ FILE *p;
|
|
|
|
|
|
|
|
|
|
- err = assuan_new (&ctx);
|
|
|
|
|
- if (err)
|
|
|
|
|
- return err;
|
|
|
|
|
-
|
|
|
|
|
- restart:
|
|
|
|
|
-
|
|
|
|
|
- infostr = force_pipe_server ? NULL : getenv ("GPG_AGENT_INFO");
|
|
|
|
|
- if (!infostr || !*infostr)
|
|
|
|
|
- {
|
|
|
|
|
- char *sockname;
|
|
|
|
|
-
|
|
|
|
|
- /* First check whether we can connect at the standard
|
|
|
|
|
- socket. */
|
|
|
|
|
- sockname = make_filename (default_homedir (), "S.gpg-agent", NULL);
|
|
|
|
|
- if (! sockname)
|
|
|
|
|
- return gpg_error_from_errno (errno);
|
|
|
|
|
-
|
|
|
|
|
- err = assuan_socket_connect (ctx, sockname, 0, 0);
|
|
|
|
|
- if (err)
|
|
|
|
|
- {
|
|
|
|
|
- const char *agent_program;
|
|
|
|
|
-
|
|
|
|
|
- /* With no success start a new server. */
|
|
|
|
|
- DEBUG (DBG_INFO, "no running GPG agent at %s, starting one\n",
|
|
|
|
|
- sockname);
|
|
|
|
|
-
|
|
|
|
|
- agent_program = get_gpg_agent_path ();
|
|
|
|
|
-
|
|
|
|
|
+ /* 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 ());
|
|
|
|
|
#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
- {
|
|
|
|
|
- /* Under Windows we start the server in daemon mode. This
|
|
|
|
|
- is because the default is to use the standard socket
|
|
|
|
|
- and thus there is no need for the GPG_AGENT_INFO
|
|
|
|
|
- envvar. This is possible as we don't have a real unix
|
|
|
|
|
- domain socket but use a plain file and thus there is no
|
|
|
|
|
- need to care about non-local file systems. */
|
|
|
|
|
- const char *argv[3];
|
|
|
|
|
-
|
|
|
|
|
- argv[0] = "--daemon";
|
|
|
|
|
- argv[1] = "--use-standard-socket";
|
|
|
|
|
- argv[2] = NULL;
|
|
|
|
|
-
|
|
|
|
|
- err = spawn_process_detached (agent_program, argv);
|
|
|
|
|
- if (err)
|
|
|
|
|
- DEBUG (DBG_CRIT, "failed to start agent `%s': %s\n",
|
|
|
|
|
- agent_program, gpg_strerror (err));
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- /* Give the agent some time to prepare itself. */
|
|
|
|
|
- Sleep (3 * 1000);
|
|
|
|
|
- /* Now try again to connect the agent. */
|
|
|
|
|
- err = assuan_socket_connect (ctx_r, sockname, 0, 0);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-#else /*!HAVE_W32_SYSTEM*/
|
|
|
|
|
- {
|
|
|
|
|
- const char *pgmname;
|
|
|
|
|
- const char *argv[3];
|
|
|
|
|
- int no_close_list[3];
|
|
|
|
|
- int i;
|
|
|
|
|
-
|
|
|
|
|
- if ( !(pgmname = strrchr (agent_program, '/')))
|
|
|
|
|
- pgmname = agent_program;
|
|
|
|
|
- else
|
|
|
|
|
- pgmname++;
|
|
|
|
|
-
|
|
|
|
|
- argv[0] = pgmname;
|
|
|
|
|
- argv[1] = "--server";
|
|
|
|
|
- argv[2] = NULL;
|
|
|
|
|
-
|
|
|
|
|
- i=0;
|
|
|
|
|
- no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
|
|
|
|
|
- no_close_list[i] = -1;
|
|
|
|
|
-
|
|
|
|
|
- /* Connect to the agent and perform initial handshaking. */
|
|
|
|
|
- err = assuan_pipe_connect (ctx, agent_program, argv,
|
|
|
|
|
- no_close_list, NULL, NULL, 0);
|
|
|
|
|
- }
|
|
|
|
|
-#endif /*!HAVE_W32_SYSTEM*/
|
|
|
|
|
- }
|
|
|
|
|
- free (sockname);
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
+ p = _popen (buffer, "r");
|
|
|
|
|
+#else
|
|
|
|
|
+ p = popen (buffer, "r");
|
|
|
|
|
+#endif
|
|
|
|
|
+ if (p)
|
|
|
|
|
{
|
|
|
|
|
- int pid;
|
|
|
|
|
- int protocol_version;
|
|
|
|
|
-
|
|
|
|
|
- infostr = strdup (infostr);
|
|
|
|
|
- if (!infostr)
|
|
|
|
|
- return gpg_error_from_errno (errno);
|
|
|
|
|
+ int ret;
|
|
|
|
|
|
|
|
|
|
- if (!(ptr = strchr (infostr, PATHSEP_C)) || ptr == infostr)
|
|
|
|
|
- {
|
|
|
|
|
- DEBUG (DBG_CRIT, "malformed GPG_AGENT_INFO environment variable");
|
|
|
|
|
- free (infostr);
|
|
|
|
|
- force_pipe_server = 1;
|
|
|
|
|
- goto restart;
|
|
|
|
|
- }
|
|
|
|
|
+ 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);
|
|
|
|
|
|
|
|
|
|
- *(ptr++) = 0;
|
|
|
|
|
- pid = atoi (ptr);
|
|
|
|
|
- while (*ptr && *ptr != PATHSEP_C)
|
|
|
|
|
- ptr++;
|
|
|
|
|
- protocol_version = *ptr ? atoi (ptr + 1) : 0;
|
|
|
|
|
- if (protocol_version != 1)
|
|
|
|
|
- {
|
|
|
|
|
- DEBUG (DBG_CRIT, "GPG agent protocol version '%d' not supported",
|
|
|
|
|
- protocol_version);
|
|
|
|
|
- free (infostr);
|
|
|
|
|
- force_pipe_server = 1;
|
|
|
|
|
- goto restart;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- err = assuan_socket_connect (ctx, infostr, pid, 0);
|
|
|
|
|
- free (infostr);
|
|
|
|
|
- if (err)
|
|
|
|
|
- {
|
|
|
|
|
- DEBUG (DBG_CRIT, "cannot connect to GPG agent: %s", gpg_strerror (err));
|
|
|
|
|
- force_pipe_server = 1;
|
|
|
|
|
- goto restart;
|
|
|
|
|
- }
|
|
|
|
|
+ pclose (p);
|
|
|
|
|
}
|
|
|
|
|
+ else
|
|
|
|
|
+ err = gpg_error_from_errno (errno);
|
|
|
|
|
|
|
|
|
|
- if (err)
|
|
|
|
|
+ /* Then connect to the socket we got. */
|
|
|
|
|
+ if (!err)
|
|
|
|
|
{
|
|
|
|
|
- assuan_release (ctx);
|
|
|
|
|
- DEBUG (DBG_CRIT, "cannot connect to GPG agent: %s", gpg_strerror (err));
|
|
|
|
|
- return gpg_error (GPG_ERR_NO_AGENT);
|
|
|
|
|
+ err = assuan_new (&ctx);
|
|
|
|
|
+ if (!err)
|
|
|
|
|
+ {
|
|
|
|
|
+ err = assuan_socket_connect (ctx, buffer, 0, 0);
|
|
|
|
|
+ if (!err)
|
|
|
|
|
+ {
|
|
|
|
|
+ *ctx_r = ctx;
|
|
|
|
|
+ if (_scute_debug_flags & DBG_ASSUAN)
|
|
|
|
|
+ assuan_set_log_stream (*ctx_r, _scute_debug_stream);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ assuan_release (ctx);
|
|
|
|
|
+ }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- if (_scute_debug_flags & DBG_ASSUAN)
|
|
|
|
|
- assuan_set_log_stream (*ctx_r, _scute_debug_stream);
|
|
|
|
|
-
|
|
|
|
|
- *ctx_r = ctx;
|
|
|
|
|
+ /* We do not try any harder. If gpg-connect-agent somehow failed
|
|
|
|
|
+ * to give us a suitable socket, we probably cannot do better. */
|
|
|
|
|
+ if (err)
|
|
|
|
|
+ DEBUG (DBG_CRIT, "cannot connect to GPG agent: %s", gpg_strerror (err));
|
|
|
|
|
|
|
|
|
|
- return 0;
|
|
|
|
|
+ return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/get-path.c b/src/get-path.c
|
|
|
|
|
index 0abd863..bb24b12 100644
|
|
|
|
|
--- a/src/get-path.c
|
|
|
|
|
+++ b/src/get-path.c
|
|
|
|
|
@@ -33,13 +33,6 @@
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
-#include <assert.h>
|
|
|
|
|
-#include <errno.h>
|
|
|
|
|
-#include <sys/time.h>
|
|
|
|
|
-#include <sys/types.h>
|
|
|
|
|
-#include <signal.h>
|
|
|
|
|
-#include <fcntl.h>
|
|
|
|
|
-#include <stdarg.h>
|
|
|
|
|
#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#include <shlobj.h>
|
|
|
|
|
@@ -49,23 +42,6 @@
|
|
|
|
|
#include "support.h"
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
-#define GNUPG_DEFAULT_HOMEDIR "c:/gnupg"
|
|
|
|
|
-#elif defined(__VMS)
|
|
|
|
|
-#define GNUPG_DEFAULT_HOMEDIR "/SYS\$LOGIN/gnupg"
|
|
|
|
|
-#else
|
|
|
|
|
-#define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
|
|
|
|
|
-#endif
|
|
|
|
|
-
|
|
|
|
|
-#ifdef HAVE_DOSISH_SYSTEM
|
|
|
|
|
-#define DIRSEP_C '\\'
|
|
|
|
|
-#define DIRSEP_S "\\"
|
|
|
|
|
-#else
|
|
|
|
|
-#define DIRSEP_C '/'
|
|
|
|
|
-#define DIRSEP_S "/"
|
|
|
|
|
-#endif
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
#define RTLD_LAZY 0
|
|
|
|
|
|
|
|
|
|
static __inline__ void *
|
|
|
|
|
@@ -319,175 +295,17 @@ get_gpgsm_path (void)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
-get_gpg_agent_path (void)
|
|
|
|
|
+get_gpg_connect_agent_path (void)
|
|
|
|
|
{
|
|
|
|
|
static const char *pgmname;
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
if (!pgmname)
|
|
|
|
|
- pgmname = find_program_in_inst_dir ("gpg-agent.exe");
|
|
|
|
|
+ pgmname = find_program_in_inst_dir ("gpg-connect-agent.exe");
|
|
|
|
|
if (!pgmname)
|
|
|
|
|
- pgmname = find_program_at_standard_place ("GNU\\GnuPG\\gpg-agent.exe");
|
|
|
|
|
+ pgmname = find_program_at_standard_place ("GNU\\GnuPG\\gpg-connect-agent.exe");
|
|
|
|
|
#endif
|
|
|
|
|
if (!pgmname)
|
|
|
|
|
- pgmname = GPG_AGENT_PATH;
|
|
|
|
|
+ pgmname = GPG_CONNECT_AGENT_PATH;
|
|
|
|
|
return pgmname;
|
|
|
|
|
}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-/* Home directory. */
|
|
|
|
|
-
|
|
|
|
|
-#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
-#ifndef CSIDL_APPDATA
|
|
|
|
|
-#define CSIDL_APPDATA 0x001a
|
|
|
|
|
-#endif
|
|
|
|
|
-#ifndef CSIDL_LOCAL_APPDATA
|
|
|
|
|
-#define CSIDL_LOCAL_APPDATA 0x001c
|
|
|
|
|
-#endif
|
|
|
|
|
-#ifndef CSIDL_COMMON_APPDATA
|
|
|
|
|
-#define CSIDL_COMMON_APPDATA 0x0023
|
|
|
|
|
-#endif
|
|
|
|
|
-#ifndef CSIDL_FLAG_CREATE
|
|
|
|
|
-#define CSIDL_FLAG_CREATE 0x8000
|
|
|
|
|
-#endif
|
|
|
|
|
-#endif /*HAVE_W32_SYSTEM*/
|
|
|
|
|
-
|
|
|
|
|
-/* Get the standard home directory. In general this function should
|
|
|
|
|
- not be used as it does not consider a registry value (under W32) or
|
|
|
|
|
- the GNUPGHOME environment variable. It is better to use
|
|
|
|
|
- default_homedir(). */
|
|
|
|
|
-const char *
|
|
|
|
|
-standard_homedir (void)
|
|
|
|
|
-{
|
|
|
|
|
-#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
- static const char *dir;
|
|
|
|
|
-
|
|
|
|
|
- if (!dir)
|
|
|
|
|
- {
|
|
|
|
|
- char path[MAX_PATH];
|
|
|
|
|
-
|
|
|
|
|
- /* It might be better to use LOCAL_APPDATA because this is
|
|
|
|
|
- defined as "non roaming" and thus more likely to be kept
|
|
|
|
|
- locally. For private keys this is desired. However, given
|
|
|
|
|
- that many users copy private keys anyway forth and back,
|
|
|
|
|
- using a system roaming services might be better than to let
|
|
|
|
|
- them do it manually. A security conscious user will anyway
|
|
|
|
|
- use the registry entry to have better control. */
|
|
|
|
|
- if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
|
|
|
|
|
- NULL, 0, path) >= 0)
|
|
|
|
|
- {
|
|
|
|
|
- char *tmp = malloc (strlen (path) + 6 +1);
|
|
|
|
|
- if (tmp)
|
|
|
|
|
- {
|
|
|
|
|
- strcpy (stpcpy (tmp, path), "\\gnupg");
|
|
|
|
|
- dir = tmp;
|
|
|
|
|
-
|
|
|
|
|
- /* Try to create the directory if it does not yet exists. */
|
|
|
|
|
- if (access (dir, F_OK))
|
|
|
|
|
- CreateDirectory (dir, NULL);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!dir)
|
|
|
|
|
- dir = GNUPG_DEFAULT_HOMEDIR;
|
|
|
|
|
- }
|
|
|
|
|
- return dir;
|
|
|
|
|
-#else/*!HAVE_W32_SYSTEM*/
|
|
|
|
|
- return GNUPG_DEFAULT_HOMEDIR;
|
|
|
|
|
-#endif /*!HAVE_W32_SYSTEM*/
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/* Set up the default home directory. The usual --homedir option
|
|
|
|
|
- should be parsed later. */
|
|
|
|
|
-const char *
|
|
|
|
|
-default_homedir (void)
|
|
|
|
|
-{
|
|
|
|
|
- const char *dir;
|
|
|
|
|
-
|
|
|
|
|
- dir = getenv ("GNUPGHOME");
|
|
|
|
|
-#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
- if (!dir || !*dir)
|
|
|
|
|
- {
|
|
|
|
|
- static const char *saved_dir;
|
|
|
|
|
-
|
|
|
|
|
- if (!saved_dir)
|
|
|
|
|
- {
|
|
|
|
|
- if (!dir || !*dir)
|
|
|
|
|
- {
|
|
|
|
|
- char *tmp;
|
|
|
|
|
-
|
|
|
|
|
- tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG",
|
|
|
|
|
- "HomeDir");
|
|
|
|
|
- if (tmp && *tmp)
|
|
|
|
|
- {
|
|
|
|
|
- free (tmp);
|
|
|
|
|
- tmp = NULL;
|
|
|
|
|
- }
|
|
|
|
|
- if (tmp)
|
|
|
|
|
- saved_dir = tmp;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!saved_dir)
|
|
|
|
|
- saved_dir = standard_homedir ();
|
|
|
|
|
- }
|
|
|
|
|
- dir = saved_dir;
|
|
|
|
|
- }
|
|
|
|
|
-#endif /*HAVE_W32_SYSTEM*/
|
|
|
|
|
- if (!dir || !*dir)
|
|
|
|
|
- dir = GNUPG_DEFAULT_HOMEDIR;
|
|
|
|
|
-
|
|
|
|
|
- return dir;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-/* Construct a filename from the NULL terminated list of parts. Tilde
|
|
|
|
|
- expansion is done here. */
|
|
|
|
|
-char *
|
|
|
|
|
-make_filename (const char *first_part, ...)
|
|
|
|
|
-{
|
|
|
|
|
- va_list arg_ptr;
|
|
|
|
|
- size_t n;
|
|
|
|
|
- const char *s;
|
|
|
|
|
- char *name;
|
|
|
|
|
- char *home;
|
|
|
|
|
- char *p;
|
|
|
|
|
-
|
|
|
|
|
- va_start (arg_ptr, first_part);
|
|
|
|
|
- n = strlen (first_part) + 1;
|
|
|
|
|
- while ((s = va_arg (arg_ptr, const char *)))
|
|
|
|
|
- n += strlen (s) + 1;
|
|
|
|
|
- va_end (arg_ptr);
|
|
|
|
|
-
|
|
|
|
|
- home = NULL;
|
|
|
|
|
- if (*first_part == '~' && first_part[1] == '/'
|
|
|
|
|
- && (home = getenv("HOME")) && *home)
|
|
|
|
|
- n += strlen (home);
|
|
|
|
|
-
|
|
|
|
|
- name = malloc (n);
|
|
|
|
|
- if (! name)
|
|
|
|
|
- return NULL;
|
|
|
|
|
- p = (home
|
|
|
|
|
- ? stpcpy (stpcpy (name,home), first_part + 1)
|
|
|
|
|
- : stpcpy (name, first_part));
|
|
|
|
|
-
|
|
|
|
|
- va_start (arg_ptr, first_part);
|
|
|
|
|
- while ((s = va_arg(arg_ptr, const char *)))
|
|
|
|
|
- p = stpcpy (stpcpy (p,"/"), s);
|
|
|
|
|
- va_end (arg_ptr);
|
|
|
|
|
-
|
|
|
|
|
-#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
- /* We better avoid mixing slashes and backslashes and prefer
|
|
|
|
|
- backslashes. There is usual no problem with mixing them, however
|
|
|
|
|
- a very few W32 API calls can't grok plain slashes. Printing
|
|
|
|
|
- filenames with mixed slashes also looks a bit strange. */
|
|
|
|
|
- if (strchr (name, '\\'))
|
|
|
|
|
- {
|
|
|
|
|
- for (p = name; *p; p++)
|
|
|
|
|
- if (*p == '/')
|
|
|
|
|
- *p = '\\';
|
|
|
|
|
- }
|
|
|
|
|
-#endif
|
|
|
|
|
-
|
|
|
|
|
- return name;
|
|
|
|
|
-}
|
|
|
|
|
diff --git a/src/support.h b/src/support.h
|
|
|
|
|
index 3356224..38149ad 100644
|
|
|
|
|
--- a/src/support.h
|
|
|
|
|
+++ b/src/support.h
|
|
|
|
|
@@ -84,15 +84,7 @@ stpcpy (char *a, const char *b)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char *get_gpgsm_path (void);
|
|
|
|
|
-const char *get_gpg_agent_path (void);
|
|
|
|
|
-
|
|
|
|
|
-/* Set up the default home directory. The usual --homedir option
|
|
|
|
|
- should be parsed later. */
|
|
|
|
|
-const char *default_homedir (void);
|
|
|
|
|
-
|
|
|
|
|
-/* Construct a filename from the NULL terminated list of parts. Tilde
|
|
|
|
|
- expansion is done here. */
|
|
|
|
|
-char *make_filename (const char *first_part, ...);
|
|
|
|
|
+const char *get_gpg_connect_agent_path (void);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|