[svn] GnuPG - r5326 - in branches/STABLE-BRANCH-2-0: . agent common doc
svn author wk
cvs at cvs.gnupg.org
Tue May 4 11:56:43 CEST 2010
Author: wk
Date: 2010-05-04 11:56:42 +0200 (Tue, 04 May 2010)
New Revision: 5326
Modified:
branches/STABLE-BRANCH-2-0/ChangeLog
branches/STABLE-BRANCH-2-0/NEWS
branches/STABLE-BRANCH-2-0/agent/ChangeLog
branches/STABLE-BRANCH-2-0/agent/gpg-agent.c
branches/STABLE-BRANCH-2-0/common/ChangeLog
branches/STABLE-BRANCH-2-0/common/asshelp.c
branches/STABLE-BRANCH-2-0/common/exechelp.c
branches/STABLE-BRANCH-2-0/configure.ac
branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi
Log:
Start the agent on demand if option --enable-standard socket has been
enabled.
Modified: branches/STABLE-BRANCH-2-0/ChangeLog
===================================================================
--- branches/STABLE-BRANCH-2-0/ChangeLog 2010-05-03 15:23:10 UTC (rev 5325)
+++ branches/STABLE-BRANCH-2-0/ChangeLog 2010-05-04 09:56:42 UTC (rev 5326)
@@ -1,3 +1,7 @@
+2010-05-04 Werner Koch <wk at g10code.com>
+
+ * configure.ac: Add option --enable-standard-socket.
+
2010-03-09 Werner Koch <wk at g10code.com>
Release 2.0.15.
Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog
===================================================================
--- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-03 15:23:10 UTC (rev 5325)
+++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-04 09:56:42 UTC (rev 5326)
@@ -1,3 +1,7 @@
+2010-05-04 Werner Koch <wk at g10code.com>
+
+ * gpg-agent.c (main): Add command --use-standard-socket-p.
+
2010-05-03 Werner Koch <wk at g10code.com>
* gpg-agent.c (check_own_socket_thread): Do not release SOCKNAME
Modified: branches/STABLE-BRANCH-2-0/common/ChangeLog
===================================================================
--- branches/STABLE-BRANCH-2-0/common/ChangeLog 2010-05-03 15:23:10 UTC (rev 5325)
+++ branches/STABLE-BRANCH-2-0/common/ChangeLog 2010-05-04 09:56:42 UTC (rev 5326)
@@ -1,3 +1,13 @@
+2010-05-03 Werner Koch <wk at g10code.com>
+
+ * asshelp.c (lock_agent_spawning, unlock_agent_spawning): New.
+ (start_new_gpg_agent): Test for configured standard socket and
+ try to fire up the agent in this case.
+
+ * exechelp.c (gnupg_spawn_process_detached): Do not reuse PID for
+ the second fork.
+ (gnupg_wait_process): Do not log a message if EXITCODE is given.
+
2010-03-17 Werner Koch <wk at g10code.com>
* asshelp.c (start_new_gpg_agent) [W32]: Use a named mutex to
Modified: branches/STABLE-BRANCH-2-0/NEWS
===================================================================
--- branches/STABLE-BRANCH-2-0/NEWS 2010-05-03 15:23:10 UTC (rev 5325)
+++ branches/STABLE-BRANCH-2-0/NEWS 2010-05-04 09:56:42 UTC (rev 5326)
@@ -1,7 +1,15 @@
Noteworthy changes in version 2.0.16 (unreleased)
-------------------------------------------------
+ * If the agent's --use-standard-socket option is active, all tools
+ try to start and daemonize the agent on the fly. In the past this
+ was only supported on W32; on non-W32 systems the new configure
+ option --use-standard-socket may now be used to use this feature by
+ default.
+ * Minor bug fixes.
+
+
Noteworthy changes in version 2.0.15 (2010-03-09)
-------------------------------------------------
Modified: branches/STABLE-BRANCH-2-0/agent/gpg-agent.c
===================================================================
--- branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-05-03 15:23:10 UTC (rev 5325)
+++ branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-05-04 09:56:42 UTC (rev 5326)
@@ -1,6 +1,6 @@
/* gpg-agent.c - The GnuPG Agent
* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005,
- * 2006, 2007, 2009 Free Software Foundation, Inc.
+ * 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -60,6 +60,7 @@
oNoVerbose = 500,
aGPGConfList,
aGPGConfTest,
+ aUseStandardSocketP,
oOptions,
oDebug,
oDebugAll,
@@ -114,6 +115,7 @@
{ aGPGConfList, "gpgconf-list", 256, "@" },
{ aGPGConfTest, "gpgconf-test", 256, "@" },
+ { aUseStandardSocketP, "use-standard-socket-p", 256, "@" },
{ 301, NULL, 0, N_("@Options:\n ") },
@@ -628,7 +630,7 @@
/* Set default options. */
parse_rereadable_options (NULL, 0); /* Reset them to default values. */
-#ifdef HAVE_W32_SYSTEM
+#ifdef USE_STANDARD_SOCKET
use_standard_socket = 1; /* Under Windows we always use a standard
socket. */
#endif
@@ -748,6 +750,7 @@
{
case aGPGConfList: gpgconf_list = 1; break;
case aGPGConfTest: gpgconf_list = 2; break;
+ case aUseStandardSocketP: gpgconf_list = 3; break;
case oBatch: opt.batch=1; break;
case oDebugWait: debug_wait = pargs.r.ret_int; break;
@@ -858,6 +861,8 @@
log_debug ("... okay\n");
}
+ if (gpgconf_list == 3)
+ agent_exit (!use_standard_socket);
if (gpgconf_list == 2)
agent_exit (0);
if (gpgconf_list)
Modified: branches/STABLE-BRANCH-2-0/common/asshelp.c
===================================================================
--- branches/STABLE-BRANCH-2-0/common/asshelp.c 2010-05-03 15:23:10 UTC (rev 5325)
+++ branches/STABLE-BRANCH-2-0/common/asshelp.c 2010-05-04 09:56:42 UTC (rev 5326)
@@ -1,5 +1,5 @@
/* asshelp.c - Helper functions for Assuan
- * Copyright (C) 2002, 2004, 2007, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2004, 2007, 2009, 2010 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -27,6 +27,7 @@
#include <locale.h>
#endif
+#define JNLIB_NEED_LOG_LOGV
#include "i18n.h"
#include "util.h"
#include "exechelp.h"
@@ -34,6 +35,14 @@
#include "status.h"
#include "asshelp.h"
+/* The type we use for lock_agent_spawning. */
+#ifdef HAVE_W32_SYSTEM
+# define lock_agent_t HANDLE
+#else
+# define lock_agent_t DOTLOCK
+#endif
+
+
static gpg_error_t
send_one_option (assuan_context_t ctx, gpg_err_source_t errsource,
const char *name, const char *value, int use_putenv)
@@ -70,7 +79,9 @@
{
gpg_error_t err = 0;
+#if defined(HAVE_SETLOCALE)
char *old_lc = NULL;
+#endif
char *dft_lc = NULL;
const char *dft_ttyname;
int iterator;
@@ -158,6 +169,77 @@
}
+/* Lock the agent spawning process. The caller needs to provide the
+ address of a variable to store the lock information. */
+static gpg_error_t
+lock_agent_spawning (lock_agent_t *lock, const char *homedir)
+{
+#ifdef HAVE_W32_SYSTEM
+ int waitrc;
+
+ (void)homedir; /* Not required. */
+
+ *lock = CreateMutex (NULL, FALSE, "GnuPG_spawn_agent_sentinel");
+ if (!*lock)
+ {
+ log_error ("failed to create the spawn_agent mutex: %s\n",
+ w32_strerror (-1));
+ return gpg_error (GPG_ERR_GENERAL);
+ }
+
+ waitrc = WaitForSingleObject (*lock, 5000);
+ if (waitrc == WAIT_OBJECT_0)
+ return 0;
+
+ if (waitrc == WAIT_TIMEOUT)
+ log_info ("error waiting for the spawn_agent mutex: timeout\n");
+ else
+ log_info ("error waiting for the spawn_agent mutex: "
+ "(code=%d) %s\n", waitrc, w32_strerror (-1));
+ return gpg_error (GPG_ERR_GENERAL);
+#else /*!HAVE_W32_SYSTEM*/
+ char *fname;
+
+ *lock = NULL;
+
+ fname = make_filename (homedir, "gnupg_spawn_agent_sentinel", NULL);
+ if (!fname)
+ return gpg_error_from_syserror ();
+
+ *lock = create_dotlock (fname);
+ xfree (fname);
+ if (!*lock)
+ return gpg_error_from_syserror ();
+
+ /* FIXME: We should use a timeout of 5000 here - however
+ make_dotlock does not yet support values other than -1 and 0. */
+ if (make_dotlock (*lock, -1))
+ return gpg_error_from_syserror ();
+
+ return 0;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+/* Unlock the spawning process. */
+static void
+unlock_agent_spawning (lock_agent_t *lock)
+{
+ if (*lock)
+ {
+#ifdef HAVE_W32_SYSTEM
+ if (!ReleaseMutex (*lock))
+ log_error ("failed to release the spawn_agent mutex: %s\n",
+ w32_strerror (-1));
+ CloseHandle (*lock);
+#else /*!HAVE_W32_SYSTEM*/
+ destroy_dotlock (*lock);
+#endif /*!HAVE_W32_SYSTEM*/
+ *lock = NULL;
+ }
+}
+
+
/* Try to connect to the agent via socket or fork it off and work by
pipes. Handle the server's initial greeting. Returns a new assuan
context at R_CTX or an error code. */
@@ -177,17 +259,17 @@
of the pipe based server for the lifetime of the process. */
static int force_pipe_server = 0;
- gpg_error_t rc = 0;
+ gpg_error_t err = 0;
char *infostr, *p;
assuan_context_t ctx;
*r_ctx = NULL;
- rc = assuan_new (&ctx);
- if (rc)
+ err = assuan_new (&ctx);
+ if (err)
{
- log_error ("error allocating assuan context: %s\n", gpg_strerror (rc));
- return rc;
+ log_error ("error allocating assuan context: %s\n", gpg_strerror (err));
+ return err;
}
restart:
@@ -195,13 +277,16 @@
if (!infostr || !*infostr)
{
char *sockname;
+ const char *argv[3];
+ pid_t pid;
+ int excode;
/* First check whether we can connect at the standard
socket. */
sockname = make_filename (homedir, "S.gpg-agent", NULL);
- rc = assuan_socket_connect (ctx, sockname, 0, 0);
+ err = assuan_socket_connect (ctx, sockname, 0, 0);
- if (rc)
+ if (err)
{
/* With no success start a new server. */
if (verbose)
@@ -224,102 +309,86 @@
if (!agent_program || !*agent_program)
agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
-#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. We use a
- named mutex to interlock the spawning. There is just
- one problem with that: If gpg-agent needs more than 3
- seconds to come up and listen on the socket we might
- still spawn another agent. However this is no serious
- problem because an agent detects this and handles it.
- Thus the mutex merely helps to save resources in the
- most common cases. */
- const char *argv[3];
- HANDLE mutex;
- int waitrc;
+ argv[0] = "--use-standard-socket-p";
+ argv[1] = NULL;
+ err = gnupg_spawn_process_fd (agent_program, argv, -1, -1, -1, &pid);
+ if (err)
+ log_debug ("starting `%s' for testing failed: %s\n",
+ agent_program, gpg_strerror (err));
+ else if ((err = gnupg_wait_process (agent_program, pid, &excode)))
+ {
+ if (excode == -1)
+ log_debug ("running `%s' for testing failed: %s\n",
+ agent_program, gpg_strerror (err));
+ }
- argv[0] = "--daemon";
- argv[1] = "--use-standard-socket";
- argv[2] = NULL;
+ if (!err && !excode)
+ {
+ /* If the agent has been configured for use with a
+ standard socket, an environment variable is not
+ required and thus we we can savely start the agent
+ here. */
+ lock_agent_t lock;
- mutex = CreateMutex (NULL, FALSE, "GnuPG_spawn_agent_sentinel");
- if (!mutex)
- {
- log_error ("failed to create the spawn_agent mutex: %s\n",
- w32_strerror (-1));
- rc = gpg_error (GPG_ERR_GENERAL);
- }
- else if ((waitrc = WaitForSingleObject (mutex, 5000))
- == WAIT_OBJECT_0)
- {
- rc = assuan_socket_connect (&ctx, sockname, 0);
- if (rc)
- {
- /* Still not available. */
- rc = gnupg_spawn_process_detached (agent_program,
- argv, NULL);
- if (rc)
- log_debug ("failed to start agent `%s': %s\n",
- agent_program, gpg_strerror (rc));
- else
- {
- /* Give the agent some time to prepare itself. */
- gnupg_sleep (3);
- /* Now try again to connect the agent. */
- rc = assuan_socket_connect (&ctx, sockname, 0);
- }
- }
- if (!ReleaseMutex (mutex))
- log_error ("failed to release the spawn_agent mutex: %s\n",
- w32_strerror (-1));
- }
- else if (waitrc == WAIT_TIMEOUT)
- {
- log_info ("error waiting for the spawn_agent mutex: timeout\n");
- rc = gpg_error (GPG_ERR_GENERAL);
- }
- else
- {
- log_debug ("error waiting for the spawn_agent mutex: "
- "(code=%d) %s\n", waitrc, w32_strerror (-1));
- rc = gpg_error (GPG_ERR_GENERAL);
- }
-
- if (mutex)
- CloseHandle (mutex);
- }
-#else /*!HAVE_W32_SYSTEM*/
- {
- const char *pgmname;
- const char *argv[3];
- int no_close_list[3];
- int i;
+ argv[0] = "--daemon";
+ argv[1] = "--use-standard-socket";
+ argv[2] = NULL;
- if ( !(pgmname = strrchr (agent_program, '/')))
- pgmname = agent_program;
- else
- pgmname++;
-
- argv[0] = pgmname;
- argv[1] = "--server";
- argv[2] = NULL;
-
- i=0;
- if (log_get_fd () != -1)
- no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
- no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
- no_close_list[i] = -1;
-
- /* Connect to the agent and perform initial handshaking. */
- rc = assuan_pipe_connect (ctx, agent_program, argv,
- no_close_list, NULL, NULL, 0);
- }
-#endif /*!HAVE_W32_SYSTEM*/
+ if (!(err = lock_agent_spawning (&lock, homedir))
+ && assuan_socket_connect (ctx, sockname, 0, 0))
+ {
+ err = gnupg_spawn_process_detached (agent_program, argv,NULL);
+ if (err)
+ log_error ("failed to start agent `%s': %s\n",
+ agent_program, gpg_strerror (err));
+ else
+ {
+ int i;
+
+ if (verbose)
+ log_info (_("waiting %d seconds for the agent "
+ "to come up\n"), 5);
+ for (i=0; i < 5; i++)
+ {
+ gnupg_sleep (1);
+ err = assuan_socket_connect (ctx, sockname, 0, 0);
+ if (!err)
+ break;
+ }
+ }
+ }
+
+ unlock_agent_spawning (&lock);
+ }
+ else
+ {
+ /* If using the standard socket is not the default we
+ start the agent as a pipe server which gives us most
+ of the required features except for passphrase
+ caching etc. */
+ const char *pgmname;
+ 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;
+ if (log_get_fd () != -1)
+ no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
+ 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);
+ }
}
xfree (sockname);
}
@@ -350,9 +419,9 @@
goto restart;
}
- rc = assuan_socket_connect (ctx, infostr, pid, 0);
+ err = assuan_socket_connect (ctx, infostr, pid, 0);
xfree (infostr);
- if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
+ if (gpg_err_code (err) == GPG_ERR_ASS_CONNECT_FAILED)
{
log_info (_("can't connect to the agent - trying fall back\n"));
force_pipe_server = 1;
@@ -360,9 +429,9 @@
}
}
- if (rc)
+ if (err)
{
- log_error ("can't connect to the agent: %s\n", gpg_strerror (rc));
+ log_error ("can't connect to the agent: %s\n", gpg_strerror (err));
assuan_release (ctx);
return gpg_error (GPG_ERR_NO_AGENT);
}
@@ -370,16 +439,16 @@
if (debug)
log_debug ("connection to agent established\n");
- rc = assuan_transact (ctx, "RESET",
+ err = assuan_transact (ctx, "RESET",
NULL, NULL, NULL, NULL, NULL, NULL);
- if (!rc)
- rc = send_pinentry_environment (ctx, errsource,
+ if (!err)
+ err = send_pinentry_environment (ctx, errsource,
opt_lc_ctype, opt_lc_messages,
session_env);
- if (rc)
+ if (err)
{
assuan_release (ctx);
- return rc;
+ return err;
}
*r_ctx = ctx;
Modified: branches/STABLE-BRANCH-2-0/common/exechelp.c
===================================================================
--- branches/STABLE-BRANCH-2-0/common/exechelp.c 2010-05-03 15:23:10 UTC (rev 5325)
+++ branches/STABLE-BRANCH-2-0/common/exechelp.c 2010-05-04 09:56:42 UTC (rev 5326)
@@ -872,9 +872,11 @@
}
else if (WIFEXITED (status) && WEXITSTATUS (status))
{
- log_error (_("error running `%s': exit status %d\n"), pgmname,
- WEXITSTATUS (status));
- if (exitcode)
+
+ if (!exitcode)
+ log_error (_("error running `%s': exit status %d\n"), pgmname,
+ WEXITSTATUS (status));
+ else
*exitcode = WEXITSTATUS (status);
ec = GPG_ERR_GENERAL;
}
@@ -1002,13 +1004,15 @@
}
if (!pid)
{
+ pid_t pid2;
+
gcry_control (GCRYCTL_TERM_SECMEM);
if (setsid() == -1 || chdir ("/"))
_exit (1);
- pid = fork (); /* Double fork to let init takes over the new child. */
- if (pid == (pid_t)(-1))
+ pid2 = fork (); /* Double fork to let init takes over the new child. */
+ if (pid2 == (pid_t)(-1))
_exit (1);
- if (pid)
+ if (pid2)
_exit (0); /* Let the parent exit immediately. */
if (envp)
Modified: branches/STABLE-BRANCH-2-0/configure.ac
===================================================================
--- branches/STABLE-BRANCH-2-0/configure.ac 2010-05-03 15:23:10 UTC (rev 5325)
+++ branches/STABLE-BRANCH-2-0/configure.ac 2010-05-04 09:56:42 UTC (rev 5326)
@@ -75,6 +75,7 @@
use_exec=yes
disable_keyserver_path=no
use_ccid_driver=yes
+use_standard_socket=no
GNUPG_BUILD_PROGRAM(gpg, yes)
GNUPG_BUILD_PROGRAM(gpgsm, yes)
@@ -251,17 +252,17 @@
[enable email keyserver interface only]),
try_mailto=$enableval, try_mailto=no)
AC_MSG_RESULT($try_mailto)
- fi
+ fi
- AC_MSG_CHECKING([whether keyserver exec-path is enabled])
- AC_ARG_ENABLE(keyserver-path,
+ AC_MSG_CHECKING([whether keyserver exec-path is enabled])
+ AC_ARG_ENABLE(keyserver-path,
AC_HELP_STRING([--disable-keyserver-path],
- [disable the exec-path option for keyserver helpers]),
- [if test "$enableval" = no ; then
- disable_keyserver_path=yes
- fi],enableval=yes)
- AC_MSG_RESULT($enableval)
- fi
+ [disable the exec-path option for keyserver helpers]),
+ [if test "$enableval" = no ; then
+ disable_keyserver_path=yes
+ fi],enableval=yes)
+ AC_MSG_RESULT($enableval)
+fi
#
@@ -586,6 +587,30 @@
[Defined to disable exec-path for keyserver helpers])
fi
+#
+# Allows enabling the use of a standard socket by default This is
+# gpg-agent's option --[no-]use-standard-socket. For Windows we force
+# the use of this.
+#
+AC_MSG_CHECKING([whether to use a standard socket by default])
+AC_ARG_ENABLE(standard-socket,
+ AC_HELP_STRING([--enable-standard-socket],
+ [use a standard socket for the agent by default]),
+ use_standard_socket=$enableval)
+tmp=""
+if test "$use_standard_socket" != yes; then
+ if test "$have_w32_system" = yes; then
+ use_standard_socket=yes
+ tmp=" (forced)"
+ fi
+fi
+AC_MSG_RESULT($use_standard_socket$tmp)
+if test "$use_standard_socket" = yes; then
+ AC_DEFINE(USE_STANDARD_SOCKET,1,
+ [Use a standard socket for the agent by default])
+fi
+
+
# (These need to go after AC_PROG_CC so that $EXEEXT is defined)
AC_DEFINE_UNQUOTED(EXEEXT,"$EXEEXT",[The executable file extension, if any])
Modified: branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi
===================================================================
--- branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi 2010-05-03 15:23:10 UTC (rev 5325)
+++ branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi 2010-05-04 09:56:42 UTC (rev 5326)
@@ -435,7 +435,11 @@
environment variable @var{GPG_AGENT_INFO} and then fall back to this
socket. This option may not be used if the home directory is mounted as
a remote file system. Note, that @option{--use-standard-socket} is the
-default on Windows systems.
+default on Windows systems. The default may be changed at build time.
+It is possible to test at runtime whether the agent has been configured
+for use with the standard socket by issuing the command
+ at command{gpg-agent --use-standard-socket-p} which returns success if the
+standard socket option has been enabled.
@item --display @var{string}
More information about the Gnupg-commits
mailing list