Remove support for the GPG_AGENT_INFO envvar.

* agent/agent.h (opt): Remove field use_standard_socket.
* agent/command.c (cmd_killagent): Always allow killing.
* agent/gpg-agent.c (main): Turn --{no,}use-standard-socket and
--write-env-file into dummy options.  Always return true for
--use-standard-socket-p. Do not print the GPG_AGENT_INFO envvar
setting or set that envvar.
(create_socket_name): Simplify by removing non standard socket
support.
(check_for_running_agent): Ditto.
* common/asshelp.c (start_new_gpg_agent): Remove GPG_AGENT_INFO use.
* common/simple-pwquery.c (agent_open): Ditto.
* configure.ac (GPG_AGENT_INFO_NAME): Remove.
* g10/server.c (gpg_server): Do not print the AgentInfo comment.
* g13/server.c (g13_server): Ditto.
* sm/server.c (gpgsm_server): Ditto.
* tools/gpgconf.c (main): Simplify by removing non standard socket
support.
--

The indented fix to allow using a different socket than the one in the
gnupg home directory is to change Libassuan to check whether the
socket files exists as a regualr file with a special keyword to
redirect to another socket file name.
This commit is contained in:
Werner Koch 2014-10-03 11:58:58 +02:00
parent 688a903b4b
commit 9c380384da
15 changed files with 221 additions and 538 deletions

View File

@ -58,9 +58,6 @@ struct
int batch; /* Batch mode */
const char *homedir; /* Configuration directory name */
/* True if we are listening on the standard socket. */
int use_standard_socket;
/* True if we handle sigusr2. */
int sigusr2_enabled;

View File

@ -2605,8 +2605,7 @@ cmd_updatestartuptty (assuan_context_t ctx, char *line)
static const char hlp_killagent[] =
"KILLAGENT\n"
"\n"
"If the agent has been started using a standard socket\n"
"we allow a client to stop the agent.";
"Stop the agent.";
static gpg_error_t
cmd_killagent (assuan_context_t ctx, char *line)
{
@ -2614,9 +2613,6 @@ cmd_killagent (assuan_context_t ctx, char *line)
(void)line;
if (!opt.use_standard_socket)
return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
ctrl->server_local->stopme = 1;
assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
return 0;

View File

@ -1,7 +1,7 @@
/* gpg-agent.c - The GnuPG Agent
* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009,
* 2010 Free Software Foundation, Inc.
* Copyright (C) 2013 Werner Koch
* Copyright (C) 2013, 2014 Werner Koch
*
* This file is part of GnuPG.
*
@ -152,9 +152,8 @@ static ARGPARSE_OPTS opts[] = {
{ oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
{ oNoGrab, "no-grab" ,0, N_("do not grab keyboard and mouse")},
{ oLogFile, "log-file" ,2, N_("use a log file for the server")},
{ oUseStandardSocket, "use-standard-socket", 0,
N_("use a standard location for the socket")},
{ oNoUseStandardSocket, "no-use-standard-socket", 0, "@"},
{ oUseStandardSocket, "use-standard-socket", 0, "@"}, /* dummy */
{ oNoUseStandardSocket, "no-use-standard-socket", 0, "@"}, /* dummy */
{ oPinentryProgram, "pinentry-program", 2 ,
N_("|PGM|use PGM as the PIN-Entry program") },
{ oPinentryTouchFile, "pinentry-touch-file", 2 , "@" },
@ -207,8 +206,7 @@ static ARGPARSE_OPTS opts[] = {
"@"
#endif
},
{ oWriteEnvFile, "write-env-file", 2|8,
N_("|FILE|write environment settings also to FILE")},
{ oWriteEnvFile, "write-env-file", 2|8, "@" }, /* dummy */
{0}
};
@ -314,7 +312,7 @@ static int active_connections;
Local prototypes.
*/
static char *create_socket_name (char *standard_name, char *template);
static char *create_socket_name (char *standard_name);
static gnupg_fd_t create_server_socket (char *name, int is_ssh,
assuan_sock_nonce_t *nonce);
static void create_directories (void);
@ -325,7 +323,7 @@ static void agent_deinit_default_ctrl (ctrl_t ctrl);
static void handle_connections (gnupg_fd_t listen_fd,
gnupg_fd_t listen_fd_ssh);
static void check_own_socket (void);
static int check_for_running_agent (int silent, int mode);
static int check_for_running_agent (int silent);
/* Pth wrapper function definitions. */
ASSUAN_SYSTEM_NPTH_IMPL;
@ -620,7 +618,6 @@ main (int argc, char **argv )
int debug_wait = 0;
int gpgconf_list = 0;
gpg_error_t err;
const char *env_file_name = NULL;
struct assuan_malloc_hooks malloc_hooks;
/* Before we do anything else we save the list of currently open
@ -670,9 +667,6 @@ main (int argc, char **argv )
/* Set default options. */
parse_rereadable_options (NULL, 0); /* Reset them to default values. */
#ifdef USE_STANDARD_SOCKET
opt.use_standard_socket = 1;
#endif
shell = getenv ("SHELL");
if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
@ -830,8 +824,8 @@ main (int argc, char **argv )
case oXauthority: default_xauthority = xstrdup (pargs.r.ret_str);
break;
case oUseStandardSocket: opt.use_standard_socket = 1; break;
case oNoUseStandardSocket: opt.use_standard_socket = 0; break;
case oUseStandardSocket: /* dummy */ break;
case oNoUseStandardSocket: /* dummy */ break;
case oFakedSystemTime:
{
@ -853,12 +847,7 @@ main (int argc, char **argv )
# endif
break;
case oWriteEnvFile:
if (pargs.r_type)
env_file_name = pargs.r.ret_str;
else
env_file_name = make_filename ("~/.gpg-agent-info", NULL);
break;
case oWriteEnvFile: /* dummy */ break;
default : pargs.err = configfp? 1:2; break;
}
@ -914,7 +903,7 @@ main (int argc, char **argv )
print the status directly to stderr. */
opt.debug = 0;
set_debug ();
check_for_running_agent (0, 0);
check_for_running_agent (0);
agent_exit (0);
}
@ -945,9 +934,9 @@ main (int argc, char **argv )
if (gpgconf_list == 3)
{
if (opt.use_standard_socket && !opt.quiet)
log_info ("configured to use the standard socket\n");
agent_exit (!opt.use_standard_socket);
/* We now use the standard socket always - return true for
backward compatibility. */
agent_exit (0);
}
else if (gpgconf_list == 2)
agent_exit (0);
@ -1077,14 +1066,11 @@ main (int argc, char **argv )
/* Create the sockets. */
socket_name = create_socket_name
(GPG_AGENT_SOCK_NAME, "gpg-XXXXXX/"GPG_AGENT_SOCK_NAME);
socket_name = create_socket_name (GPG_AGENT_SOCK_NAME);
fd = create_server_socket (socket_name, 0, &socket_nonce);
if (opt.ssh_support)
{
socket_name_ssh = create_socket_name
(GPG_AGENT_SSH_SOCK_NAME, "gpg-XXXXXX/"GPG_AGENT_SSH_SOCK_NAME);
socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME);
fd_ssh = create_server_socket (socket_name_ssh, 1, &socket_nonce_ssh);
}
else
@ -1100,10 +1086,7 @@ main (int argc, char **argv )
#ifdef HAVE_W32_SYSTEM
(void)csh_style;
(void)nodetach;
(void)env_file_name;
pid = getpid ();
es_printf ("set %s=%s;%lu;1\n",
GPG_AGENT_INFO_NAME, socket_name, (ulong)pid);
#else /*!HAVE_W32_SYSTEM*/
pid = fork ();
if (pid == (pid_t)-1)
@ -1113,7 +1096,7 @@ main (int argc, char **argv )
}
else if (pid)
{ /* We are the parent */
char *infostr, *infostr_ssh_sock, *infostr_ssh_valid;
char *infostr_ssh_sock, *infostr_ssh_valid;
/* Close the socket FD. */
close (fd);
@ -1133,14 +1116,7 @@ main (int argc, char **argv )
log_info ("no saved signal mask\n");
#endif /*HAVE_SIGPROCMASK*/
/* Create the info string: <name>:<pid>:<protocol_version> */
if (asprintf (&infostr, "%s=%s:%lu:1",
GPG_AGENT_INFO_NAME, socket_name, (ulong)pid ) < 0)
{
log_error ("out of core\n");
kill (pid, SIGTERM);
exit (1);
}
/* Create the SSH info string if enabled. */
if (opt.ssh_support)
{
if (asprintf (&infostr_ssh_sock, "SSH_AUTH_SOCK=%s",
@ -1164,37 +1140,8 @@ main (int argc, char **argv )
if (opt.ssh_support)
*socket_name_ssh = 0;
if (env_file_name)
{
estream_t fp;
fp = es_fopen (env_file_name, "w,mode=-rw");
if (!fp)
log_error (_("error creating '%s': %s\n"),
env_file_name, strerror (errno));
else
{
es_fputs (infostr, fp);
es_putc ('\n', fp);
if (opt.ssh_support)
{
es_fputs (infostr_ssh_sock, fp);
es_putc ('\n', fp);
}
es_fclose (fp);
}
}
if (argc)
{ /* Run the program given on the commandline. */
if (putenv (infostr))
{
log_error ("failed to set environment: %s\n",
strerror (errno) );
kill (pid, SIGTERM );
exit (1);
}
if (opt.ssh_support && (putenv (infostr_ssh_sock)
|| putenv (infostr_ssh_valid)))
{
@ -1222,8 +1169,6 @@ main (int argc, char **argv )
shell's eval to set it */
if (csh_style)
{
*strchr (infostr, '=') = ' ';
es_printf ("setenv %s;\n", infostr);
if (opt.ssh_support)
{
*strchr (infostr_ssh_sock, '=') = ' ';
@ -1232,14 +1177,12 @@ main (int argc, char **argv )
}
else
{
es_printf ( "%s; export %s;\n", infostr, GPG_AGENT_INFO_NAME);
if (opt.ssh_support)
{
es_printf ("%s; export SSH_AUTH_SOCK;\n",
infostr_ssh_sock);
}
}
xfree (infostr);
if (opt.ssh_support)
{
xfree (infostr_ssh_sock);
@ -1496,45 +1439,18 @@ get_agent_scd_notify_event (void)
/* Create a name for the socket. With USE_STANDARD_SOCKET given as
true using STANDARD_NAME in the home directory or if given as
false from the mkdir type name TEMPLATE. In the latter case a
unique name in a unique new directory will be created. In both
cases check for valid characters as well as against a maximum
allowed length for a unix domain socket is done. The function
terminates the process in case of an error. Returns: Pointer to an
allocated string with the absolute name of the socket used. */
/* Create a name for the socket in the home directory as using
STANDARD_NAME. We also check for valid characters as well as
against a maximum allowed length for a unix domain socket is done.
The function terminates the process in case of an error. Returns:
Pointer to an allocated string with the absolute name of the socket
used. */
static char *
create_socket_name (char *standard_name, char *template)
create_socket_name (char *standard_name)
{
char *name, *p;
if (opt.use_standard_socket)
name = make_filename (opt.homedir, standard_name, NULL);
else
{
/* Prepend the tmp directory to the template. */
p = getenv ("TMPDIR");
if (!p || !*p)
p = "/tmp";
if (p[strlen (p) - 1] == '/')
name = xstrconcat (p, template, NULL);
else
name = xstrconcat (p, "/", template, NULL);
p = strrchr (name, '/');
if (!p)
BUG ();
*p = 0;
if (!mkdtemp (name))
{
log_error (_("can't create directory '%s': %s\n"),
name, strerror (errno));
agent_exit (2);
}
*p = '/';
}
char *name;
name = make_filename (opt.homedir, standard_name, NULL);
if (strchr (name, PATHSEP_C))
{
log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
@ -1583,22 +1499,22 @@ create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce)
/* Our error code mapping on W32CE returns EEXIST thus we also test
for this. */
if (opt.use_standard_socket && rc == -1
if (rc == -1
&& (errno == EADDRINUSE
#ifdef HAVE_W32_SYSTEM
|| errno == EEXIST
#endif
))
{
/* Check whether a gpg-agent is already running on the standard
socket. We do this test only if this is not the ssh socket.
/* Check whether a gpg-agent is already running.
We do this test only if this is not the ssh socket.
For ssh we assume that a test for gpg-agent has already been
done and reuse the requested ssh socket. Testing the
ssh-socket is not possible because at this point, though we
know the new Assuan socket, the Assuan server and thus the
ssh-agent server is not yet operational. This would lead to
a hang. */
if (!is_ssh && !check_for_running_agent (1, 1))
if (!is_ssh && !check_for_running_agent (1))
{
log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX);
log_set_file (NULL);
@ -1623,8 +1539,7 @@ create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce)
gpg_strerror (gpg_error_from_errno (errno)));
assuan_sock_close (fd);
if (opt.use_standard_socket)
*name = 0; /* Inhibit removal of the socket by cleanup(). */
*name = 0; /* Inhibit removal of the socket by cleanup(). */
agent_exit (2);
}
@ -2429,9 +2344,6 @@ check_own_socket (void)
if (disable_check_own_socket)
return;
if (!opt.use_standard_socket)
return; /* This check makes only sense in standard socket mode. */
if (check_own_socket_running || shutdown_pending)
return; /* Still running or already shutting down. */
@ -2452,73 +2364,25 @@ check_own_socket (void)
/* Figure out whether an agent is available and running. Prints an
error if not. If SILENT is true, no messages are printed. Usually
started with MODE 0. Returns 0 if the agent is running. */
error if not. If SILENT is true, no messages are printed.
Returns 0 if the agent is running. */
static int
check_for_running_agent (int silent, int mode)
check_for_running_agent (int silent)
{
int rc;
char *infostr, *p;
gpg_error_t err;
char *sockname;
assuan_context_t ctx = NULL;
int prot, pid;
if (!mode)
sockname = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
err = assuan_new (&ctx);
if (!err)
err = assuan_socket_connect (ctx, sockname, (pid_t)(-1), 0);
xfree (sockname);
if (err)
{
infostr = getenv (GPG_AGENT_INFO_NAME);
if (!infostr || !*infostr)
{
if (!check_for_running_agent (silent, 1))
return 0; /* Okay, its running on the standard socket. */
if (!silent)
log_error (_("no gpg-agent running in this session\n"));
return -1;
}
infostr = xstrdup (infostr);
if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
{
xfree (infostr);
if (!check_for_running_agent (silent, 1))
return 0; /* Okay, its running on the standard socket. */
if (!silent)
log_error (_("malformed %s environment variable\n"),
GPG_AGENT_INFO_NAME);
return -1;
}
*p++ = 0;
pid = atoi (p);
while (*p && *p != PATHSEP_C)
p++;
prot = *p? atoi (p+1) : 0;
if (prot != 1)
{
xfree (infostr);
if (!silent)
log_error (_("gpg-agent protocol version %d is not supported\n"),
prot);
if (!check_for_running_agent (silent, 1))
return 0; /* Okay, its running on the standard socket. */
return -1;
}
}
else /* MODE != 0 */
{
infostr = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
pid = (pid_t)(-1);
}
rc = assuan_new (&ctx);
if (! rc)
rc = assuan_socket_connect (ctx, infostr, pid, 0);
xfree (infostr);
if (rc)
{
if (!mode && !check_for_running_agent (silent, 1))
return 0; /* Okay, its running on the standard socket. */
if (!mode && !silent)
log_error ("can't connect to the agent: %s\n", gpg_strerror (rc));
if (!silent)
log_error (_("no gpg-agent running in this session\n"));
if (ctx)
assuan_release (ctx);

View File

@ -359,14 +359,11 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
gpg_error_t (*status_cb)(ctrl_t, int, ...),
ctrl_t status_cb_arg)
{
/* 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, *p;
gpg_error_t err;
assuan_context_t ctx;
int did_success_msg = 0;
char *sockname;
const char *argv[5];
*r_ctx = NULL;
@ -377,200 +374,96 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
return err;
}
restart:
infostr = force_pipe_server? NULL : getenv (GPG_AGENT_INFO_NAME);
if (!infostr || !*infostr)
sockname = make_absfilename (homedir, GPG_AGENT_SOCK_NAME, NULL);
err = assuan_socket_connect (ctx, sockname, 0, 0);
if (err)
{
char *sockname;
const char *argv[5];
pid_t pid;
int excode;
char *abs_homedir;
lock_spawn_t lock;
/* First check whether we can connect at the standard
socket. */
sockname = make_absfilename (homedir, GPG_AGENT_SOCK_NAME, NULL);
err = assuan_socket_connect (ctx, sockname, 0, 0);
/* With no success start a new server. */
if (!agent_program || !*agent_program)
agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
if (err)
if (verbose)
log_info (_("no running gpg-agent - starting '%s'\n"),
agent_program);
if (status_cb)
status_cb (status_cb_arg, STATUS_PROGRESS,
"starting_agent ? 0 0", NULL);
/* We better pass an absolute home directory to the agent just
in case gpg-agent does not convert the passed name to an
absolute one (which it should do). */
abs_homedir = make_absfilename_try (homedir, NULL);
if (!abs_homedir)
{
char *abs_homedir;
gpg_error_t tmperr = gpg_err_make (errsource,
gpg_err_code_from_syserror ());
log_error ("error building filename: %s\n",gpg_strerror (tmperr));
xfree (sockname);
assuan_release (ctx);
return tmperr;
}
/* With no success start a new server. */
if (!agent_program || !*agent_program)
agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
if (fflush (NULL))
{
gpg_error_t tmperr = gpg_err_make (errsource,
gpg_err_code_from_syserror ());
log_error ("error flushing pending output: %s\n",
strerror (errno));
xfree (sockname);
assuan_release (ctx);
xfree (abs_homedir);
return tmperr;
}
if (verbose)
log_info (_("no running gpg-agent - starting '%s'\n"),
agent_program);
/* 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. */
if (status_cb)
status_cb (status_cb_arg, STATUS_PROGRESS,
"starting_agent ? 0 0", NULL);
argv[0] = "--homedir";
argv[1] = abs_homedir;
argv[2] = "--use-standard-socket";
argv[3] = "--daemon";
argv[4] = NULL;
/* We better pass an absolute home directory to the agent
just in casee gpg-agent does not convert the passed name
to an absolute one (which it should do). */
abs_homedir = make_absfilename_try (homedir, NULL);
if (!abs_homedir)
{
gpg_error_t tmperr = gpg_err_make (errsource,
gpg_err_code_from_syserror ());
log_error ("error building filename: %s\n",gpg_strerror (tmperr));
xfree (sockname);
assuan_release (ctx);
return tmperr;
}
if (fflush (NULL))
{
gpg_error_t tmperr = gpg_err_make (errsource,
gpg_err_code_from_syserror ());
log_error ("error flushing pending output: %s\n",
strerror (errno));
xfree (sockname);
assuan_release (ctx);
xfree (abs_homedir);
return tmperr;
}
argv[0] = "--homedir";
argv[1] = abs_homedir;
argv[2] = "--use-standard-socket-p";
argv[3] = NULL;
err = gnupg_spawn_process_fd (agent_program, argv, -1, -1, -1, &pid);
if (!(err = lock_spawning (&lock, homedir, "agent", verbose))
&& assuan_socket_connect (ctx, sockname, 0, 0))
{
err = gnupg_spawn_process_detached (agent_program, argv,NULL);
if (err)
log_debug ("starting '%s' for testing failed: %s\n",
log_error ("failed to start agent '%s': %s\n",
agent_program, gpg_strerror (err));
else if ((err = gnupg_wait_process (agent_program, pid, 1, &excode)))
{
if (excode == -1)
log_debug ("running '%s' for testing failed (wait): %s\n",
agent_program, gpg_strerror (err));
}
gnupg_release_process (pid);
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_spawn_t lock;
argv[0] = "--homedir";
argv[1] = abs_homedir;
argv[2] = "--use-standard-socket";
argv[3] = "--daemon";
argv[4] = NULL;
if (!(err = lock_spawning (&lock, homedir, "agent", verbose))
&& 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;
for (i=0; i < SECS_TO_WAIT_FOR_AGENT; i++)
{
if (verbose)
log_info (_("waiting for the agent "
"to come up ... (%ds)\n"),
SECS_TO_WAIT_FOR_AGENT - i);
gnupg_sleep (1);
err = assuan_socket_connect (ctx, sockname, 0, 0);
if (!err)
{
if (verbose)
{
log_info (_("connection to agent "
"established\n"));
did_success_msg = 1;
}
break;
}
}
}
}
unlock_spawning (&lock, "agent");
}
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;
assuan_fd_t no_close_list[3];
int i;
if ( !(pgmname = strrchr (agent_program, '/')))
pgmname = agent_program;
else
pgmname++;
argv[0] = pgmname; /* (Assuan expects a standard argv.) */
argv[1] = "--homedir";
argv[2] = abs_homedir;
argv[3] = "--server";
argv[4] = 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] = ASSUAN_INVALID_FD;
/* Connect to the agent and perform initial handshaking. */
err = assuan_pipe_connect (ctx, agent_program, argv,
no_close_list, NULL, NULL, 0);
for (i=0; i < SECS_TO_WAIT_FOR_AGENT; i++)
{
if (verbose)
log_info (_("waiting for the agent to come up ... (%ds)\n"),
SECS_TO_WAIT_FOR_AGENT - i);
gnupg_sleep (1);
err = assuan_socket_connect (ctx, sockname, 0, 0);
if (!err)
{
if (verbose)
{
log_info (_("connection to agent established\n"));
did_success_msg = 1;
}
break;
}
}
}
xfree (abs_homedir);
}
xfree (sockname);
unlock_spawning (&lock, "agent");
xfree (abs_homedir);
}
else
{
int prot;
int pid;
infostr = xstrdup (infostr);
if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
{
log_error (_("malformed %s environment variable\n"),
GPG_AGENT_INFO_NAME);
xfree (infostr);
force_pipe_server = 1;
goto restart;
}
*p++ = 0;
pid = atoi (p);
while (*p && *p != PATHSEP_C)
p++;
prot = *p? atoi (p+1) : 0;
if (prot != 1)
{
log_error (_("gpg-agent protocol version %d is not supported\n"),
prot);
xfree (infostr);
force_pipe_server = 1;
goto restart;
}
err = assuan_socket_connect (ctx, infostr, pid, 0);
xfree (infostr);
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;
goto restart;
}
}
xfree (sockname);
if (err)
{
log_error ("can't connect to the agent: %s\n", gpg_strerror (err));
@ -582,11 +475,11 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
log_debug (_("connection to agent established\n"));
err = assuan_transact (ctx, "RESET",
NULL, NULL, NULL, NULL, NULL, NULL);
NULL, NULL, NULL, NULL, NULL, NULL);
if (!err)
err = send_pinentry_environment (ctx, errsource,
opt_lc_ctype, opt_lc_messages,
session_env);
opt_lc_ctype, opt_lc_messages,
session_env);
if (err)
{
assuan_release (ctx);

View File

@ -754,10 +754,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
char *cmdline;
/* FIXME: We don't make use of ENVP yet. It is currently only used
to pass the GPG_AGENT_INFO variable to gpg-agent. As the default
on windows is to use a standard socket, this does not really
matter. */
/* We don't use ENVP. */
(void)envp;
if (access (pgmname, X_OK))

View File

@ -69,13 +69,12 @@
#endif
/* Name of the socket to be used if GPG_AGENT_INFO has not been
set. No default socket is used if this is NULL. */
/* Name of the socket to be used. This is a kludge to keep on using
the existsing code despite that we only support a standard socket. */
static char *default_gpg_agent_info;
#ifndef HAVE_STPCPY
@ -324,14 +323,11 @@ agent_open (int *rfd)
char *infostr, *p;
struct sockaddr_un client_addr;
size_t len;
int prot;
char line[200];
int nread;
*rfd = -1;
infostr = getenv (GPG_AGENT_INFO_NAME);
if ( !infostr || !*infostr )
infostr = default_gpg_agent_info;
infostr = default_gpg_agent_info;
if ( !infostr || !*infostr )
{
#ifdef SPWQ_USE_LOGGING
@ -348,23 +344,12 @@ agent_open (int *rfd)
if ( !(p = strchr ( infostr, PATHSEP_C)) || p == infostr
|| (p-infostr)+1 >= sizeof client_addr.sun_path )
{
#ifdef SPWQ_USE_LOGGING
log_error (_("malformed %s environment variable\n"), GPG_AGENT_INFO_NAME);
#endif
return SPWQ_NO_AGENT;
}
*p++ = 0;
while (*p && *p != PATHSEP_C)
p++;
prot = *p? atoi (p+1) : 0;
if ( prot != 1)
{
#ifdef SPWQ_USE_LOGGING
log_error (_("gpg-agent protocol version %d is not supported\n"),prot);
#endif
return SPWQ_PROTOCOL_ERROR;
}
#ifdef HAVE_W32_SYSTEM
fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0);

View File

@ -104,7 +104,6 @@ use_exec=yes
use_trust_models=yes
card_support=yes
use_ccid_driver=yes
use_standard_socket=yes
dirmngr_auto_start=yes
use_tls_library=no
@ -707,30 +706,6 @@ fi
AM_CONDITIONAL(USE_LDAPWRAPPER, test "$use_ldapwrapper" = yes)
#
# 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([--disable-standard-socket],
[don't use a standard socket 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 the 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])
@ -1615,8 +1590,6 @@ AC_DEFINE_UNQUOTED(GPGCONF_DISP_NAME, "GPGConf",
AC_DEFINE_UNQUOTED(GPGTAR_NAME, "gpgtar", [The name of the gpgtar tool])
AC_DEFINE_UNQUOTED(GPG_AGENT_INFO_NAME, "GPG_AGENT_INFO",
[The name of the agent info envvar])
AC_DEFINE_UNQUOTED(GPG_AGENT_SOCK_NAME, "S.gpg-agent",
[The name of the agent socket])
AC_DEFINE_UNQUOTED(GPG_AGENT_SSH_SOCK_NAME, "S.gpg-agent.ssh",
@ -1802,7 +1775,6 @@ echo "
Default scdaemon: $show_gnupg_scdaemon_pgm
Default dirmngr: $show_gnupg_dirmngr_pgm
Use standard socket: $use_standard_socket
Dirmngr auto start: $dirmngr_auto_start
Readline support: $gnupg_cv_have_readline
DNS SRV support: $use_dns_srv

View File

@ -53,10 +53,10 @@ independently from any protocol. It is used as a backend for
utilities.
@ifset gpgtwoone
The agent is usualy started on demand by @command{gpg}, @command{gpgsm},
@command{gpgconf} or @command{gpg-connect-agent}. Thus there is no
reason to start it manually. In case you want to use the included
Secure Shell Agent you may start the agent using:
The agent is automatically started on demand by @command{gpg},
@command{gpgsm}, @command{gpgconf}, or @command{gpg-connect-agent}.
Thus there is no reason to start it manually. In case you want to use
the included Secure Shell Agent you may start the agent using:
@example
gpg-connect-agent /bye
@ -174,11 +174,15 @@ default mode is to create a socket and listen for commands there.
@item --daemon [@var{command line}]
@opindex daemon
Start the gpg-agent as a daemon; that is, detach it from the console
and run it in the background. Because @command{gpg-agent} prints out
and run it in the background.
@ifclear gpgtwoone
Because @command{gpg-agent} prints out
important information required for further use, a common way of
invoking gpg-agent is: @code{eval $(gpg-agent --daemon)} to setup the
environment variables. The option @option{--write-env-file} is
another way commonly used to do this. Yet another way is creating
another way commonly used to do this.
@end ifclear
Yet another way is creating
a new process as a child of gpg-agent: @code{gpg-agent --daemon
/bin/sh}. This way you get a new shell with the environment setup
properly; if you exit from this shell, gpg-agent terminates as well.
@ -305,6 +309,7 @@ shell or the C-shell respectively. The default is to guess it based on
the environment variable @code{SHELL} which is correct in almost all
cases.
@ifclear gpgtwoone
@item --write-env-file @var{file}
@opindex write-env-file
Often it is required to connect to the agent from a process not being an
@ -319,7 +324,7 @@ to be evaluated by a Bourne shell like in this simple example:
eval $(cat @var{file})
eval $(cut -d= -f 1 < @var{file} | xargs echo export)
@end example
@end ifclear
@item --no-grab
@ -466,6 +471,11 @@ debugging purposes.
@itemx --no-use-standard-socket
@opindex use-standard-socket
@opindex no-use-standard-socket
@ifset gpgtwoone
Since GnuPG 2.1 the standard socket is always used. These options
have no more effect.
@end ifset
@ifclear gpgtwoone
By enabling this option @command{gpg-agent} will listen on the socket
named @file{S.gpg-agent}, located in the home directory, and not create
a random socket below a temporary directory. Tools connecting to
@ -474,19 +484,16 @@ 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 on
a remote file system which does not support special files like fifos or
sockets.
@ifset gpgtwoone
Note, that @option{--use-standard-socket} is the default on all
systems since GnuPG 2.1.
@end ifset
@ifclear gpgtwoone
Note, that @option{--use-standard-socket} is the default on
Windows systems.
@end ifclear
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 @command{gpg-agent
--use-standard-socket-p} which returns success if the standard socket
option has been enabled.
@end ifclear
@item --display @var{string}
@itemx --ttyname @var{string}
@ -751,6 +758,30 @@ This signal is used for internal purposes.
@node Agent Examples
@section Examples
@ifset gpgtwoone
It is important to set the GPG_TTY environment variable in
your login shell, for example in the @file{~/.bashrc} init script:
@cartouche
@example
export GPG_TTY=$(tty)
@end example
@end cartouche
If you enabled the Ssh Agent Support, you also need to tell ssh about
it by adding this to your init script:
@cartouche
@example
unset SSH_AGENT_PID
if [ "$@{gnupg_SSH_AUTH_SOCK_by:-0@}" -ne $$ ]; then
export SSH_AUTH_SOCK="$@{HOME@}/.gnupg/S.gpg-agent.ssh"
fi
@end example
@end cartouche
@end ifset
@ifclear gpgtwoone
The usual way to invoke @command{gpg-agent} is
@example
@ -786,6 +817,7 @@ and add something like (for Bourne shells)
@noindent
to your shell initialization file (e.g. @file{~/.bashrc}).
@end ifclear
@c
@c Assuan Protocol
@ -797,15 +829,21 @@ to your shell initialization file (e.g. @file{~/.bashrc}).
Note: this section does only document the protocol, which is used by
GnuPG components; it does not deal with the ssh-agent protocol.
@ifset gpgtwoone
The @command{gpg-agent} daemon is started on demand by the GnuPG
components.
@end ifset
@ifclear gpgtwoone
The @command{gpg-agent} should be started by the login shell and set an
environment variable to tell clients about the socket to be used.
Clients should deny to access an agent with a socket name which does
not match its own configuration. An application may choose to start
an instance of the gpgagent if it does not figure that any has been
started; it should not do this if a gpgagent is running but not
an instance of the gpg-agent if it does not figure that any has been
started; it should not do this if a gpg-agent is running but not
usable. Because @command{gpg-agent} can only be used in background mode, no
special command line option is required to activate the use of the
protocol.
@end ifclear
To identify a key we use a thing called keygrip which is the SHA-1 hash
of an canonical encoded S-Expression of the public key as used in

View File

@ -1701,9 +1701,12 @@ This is dummy option. It has no effect when used with @command{gpg2}.
@item --agent-program @var{file}
@opindex agent-program
Specify an agent program to be used for secret key operations. The
default value is the @file{/usr/bin/gpg-agent}. This is only used
default value is the @file{/usr/bin/gpg-agent}.
@ifclear gpgtwoone
This is only used
as a fallback when the environment variable @code{GPG_AGENT_INFO} is not
set or a running agent cannot be connected.
@end ifclear
@ifset gpgtwoone
@item --dirmngr-program @var{file}
@ -3040,6 +3043,10 @@ Operation is further controlled by a few environment variables:
If set directory used instead of "~/.gnupg".
@item GPG_AGENT_INFO
@ifset gpgtwoone
This variable was used by GnuPG versions before 2.1
@end ifset
@ifclear gpgtwoone
Used to locate the gpg-agent.
The value consists of 3 colon delimited fields: The first is the path
@ -3047,6 +3054,7 @@ Operation is further controlled by a few environment variables:
protocol version which should be set to 1. When starting the gpg-agent
as described in its documentation, this variable is set to the correct
value. The option @option{--gpg-agent-info} can be used to override it.
@end ifclear
@item PINENTRY_USER_DATA
This value is passed via gpg-agent to pinentry. It is useful to convey

View File

@ -358,9 +358,12 @@ Change the default name of the policy file to @var{filename}.
@item --agent-program @var{file}
@opindex agent-program
Specify an agent program to be used for secret key operations. The
default value is the @file{/usr/local/bin/gpg-agent}. This is only used
default value is the @file{/usr/local/bin/gpg-agent}.
@ifclear gpgtwoone
This is only used
as a fallback when the environment variable @code{GPG_AGENT_INFO} is not
set or a running agent cannot be connected.
@end ifclear
@item --dirmngr-program @var{file}
@opindex dirmngr-program
@ -892,8 +895,12 @@ other programs of this software too.
@item S.gpg-agent
@cindex S.gpg-agent
If this file exists and the environment variable @env{GPG_AGENT_INFO} is
not set, @command{gpgsm} will first try to connect to this socket for
If this file exists
@ifclear gpgtwoone
and the environment variable @env{GPG_AGENT_INFO} is
not set,
@end ifclear
@command{gpgsm} will first try to connect to this socket for
accessing @command{gpg-agent} before starting a new @command{gpg-agent}
instance. Under Windows this socket (which in reality be a plain file
describing a regular TCP listening port) is the standard way of

View File

@ -728,15 +728,12 @@ gpg_server (ctrl_t ctrl)
if (opt.verbose || opt.debug)
{
char *tmp = NULL;
const char *s1 = getenv (GPG_AGENT_INFO_NAME);
tmp = xtryasprintf ("Home: %s\n"
"Config: %s\n"
"AgentInfo: %s\n"
"%s",
opt.homedir,
"fixme: need config filename",
s1?s1:"[not set]",
hello);
if (tmp)
{

View File

@ -612,15 +612,12 @@ g13_server (ctrl_t ctrl)
if (opt.verbose || opt.debug)
{
char *tmp = NULL;
const char *s1 = getenv (GPG_AGENT_INFO_NAME);
tmp = xtryasprintf ("Home: %s\n"
"Config: %s\n"
"AgentInfo: %s\n"
"%s",
opt.homedir,
opt.config_filename,
s1?s1:"[not set]",
hello);
if (tmp)
{

View File

@ -206,9 +206,8 @@ static int ticker_disabled;
static char *create_socket_name (int use_standard_socket,
char *standard_name, char *template);
static gnupg_fd_t create_server_socket (int is_standard_name, const char *name,
static char *create_socket_name (char *standard_name);
static gnupg_fd_t create_server_socket (const char *name,
assuan_sock_nonce_t *nonce);
static void *start_connection_thread (void *arg);
@ -399,7 +398,6 @@ main (int argc, char **argv )
int gpgconf_list = 0;
const char *config_filename = NULL;
int allow_coredump = 0;
int standard_socket = 0;
struct assuan_malloc_hooks malloc_hooks;
int res;
npth_t pipecon_handler;
@ -445,12 +443,6 @@ main (int argc, char **argv )
opt.allow_admin = 1;
opt.pcsc_driver = DEFAULT_PCSC_DRIVER;
#ifdef HAVE_W32_SYSTEM
standard_socket = 1; /* Under Windows we always use a standard
socket. */
#endif
shell = getenv ("SHELL");
if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
csh_style = 1;
@ -744,12 +736,8 @@ main (int argc, char **argv )
back the name of that socket. */
if (multi_server)
{
socket_name = create_socket_name (standard_socket,
SCDAEMON_SOCK_NAME,
"gpg-XXXXXX/" SCDAEMON_SOCK_NAME);
fd = FD2INT(create_server_socket (standard_socket,
socket_name, &socket_nonce));
socket_name = create_socket_name (SCDAEMON_SOCK_NAME);
fd = FD2INT(create_server_socket (socket_name, &socket_nonce));
}
res = npth_attr_init (&tattr);
@ -800,12 +788,8 @@ main (int argc, char **argv )
#endif
/* Create the socket. */
socket_name = create_socket_name (standard_socket,
SCDAEMON_SOCK_NAME,
"gpg-XXXXXX/" SCDAEMON_SOCK_NAME);
fd = FD2INT (create_server_socket (standard_socket,
socket_name, &socket_nonce));
socket_name = create_socket_name (SCDAEMON_SOCK_NAME);
fd = FD2INT (create_server_socket (socket_name, &socket_nonce));
fflush (NULL);
@ -1026,46 +1010,17 @@ handle_tick (void)
}
/* Create a name for the socket. With USE_STANDARD_SOCKET given as
true using STANDARD_NAME in the home directory or if given has
false from the mkdir type name TEMPLATE. In the latter case a
unique name in a unique new directory will be created. In both
cases check for valid characters as well as against a maximum
allowed length for a unix domain socket is done. The function
terminates the process in case of an error. Retunrs: Pointer to an
allcoated string with the absolute name of the socket used. */
/* Create a name for the socket. We check for valid characters as
well as against a maximum allowed length for a unix domain socket
is done. The function terminates the process in case of an error.
Retunrs: Pointer to an allcoated string with the absolute name of
the socket used. */
static char *
create_socket_name (int use_standard_socket,
char *standard_name, char *template)
create_socket_name (char *standard_name)
{
char *name, *p;
if (use_standard_socket)
name = make_filename (opt.homedir, standard_name, NULL);
else
{
/* Prepend the tmp directory to the template. */
p = getenv ("TMPDIR");
if (!p || !*p)
p = "/tmp";
if (p[strlen (p) - 1] == '/')
name = xstrconcat (p, template, NULL);
else
name = xstrconcat (p, "/", template, NULL);
p = strrchr (name, '/');
if (!p)
BUG ();
*p = 0;
if (!mkdtemp (name))
{
log_error (_("can't create directory '%s': %s\n"),
name, strerror (errno));
scd_exit (2);
}
*p = '/';
}
char *name;
name = make_filename (opt.homedir, standard_name, NULL);
if (strchr (name, PATHSEP_C))
{
log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
@ -1081,12 +1036,10 @@ create_socket_name (int use_standard_socket,
/* Create a Unix domain socket with NAME. IS_STANDARD_NAME indicates
whether a non-random socket is used. Returns the file descriptor
/* Create a Unix domain socket with NAME. Returns the file descriptor
or terminates the process in case of an error. */
static gnupg_fd_t
create_server_socket (int is_standard_name, const char *name,
assuan_sock_nonce_t *nonce)
create_server_socket (const char *name, assuan_sock_nonce_t *nonce)
{
struct sockaddr_un *serv_addr;
socklen_t len;
@ -1108,7 +1061,7 @@ create_server_socket (int is_standard_name, const char *name,
len = SUN_LEN (serv_addr);
rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len);
if (is_standard_name && rc == -1 && errno == EADDRINUSE)
if (rc == -1 && errno == EADDRINUSE)
{
remove (name);
rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len);

View File

@ -1299,18 +1299,15 @@ gpgsm_server (certlist_t default_recplist)
if (opt.verbose || opt.debug)
{
char *tmp = NULL;
const char *s1 = getenv (GPG_AGENT_INFO_NAME);
/* Fixme: Use the really used socket name. */
if (asprintf (&tmp,
"Home: %s\n"
"Config: %s\n"
"AgentInfo: %s\n"
"DirmngrInfo: %s\n"
"%s",
opt.homedir,
opt.config_filename,
s1?s1:"[not set]",
(dirmngr_user_socket_name ()
? dirmngr_user_socket_name ()
: dirmngr_sys_socket_name ()),

View File

@ -366,28 +366,10 @@ main (int argc, char **argv)
}
{
char *infostr = getenv (GPG_AGENT_INFO_NAME);
if (!infostr || !*infostr)
infostr = make_filename (default_homedir (),
char *tmp = make_filename (default_homedir (),
GPG_AGENT_SOCK_NAME, NULL);
else
{
char *tmp;
infostr = xstrdup (infostr);
tmp = strchr (infostr, PATHSEP_C);
if (!tmp || tmp == infostr)
{
xfree (infostr);
infostr = NULL;
}
else
*tmp = 0;
}
es_fprintf (outfp, "agent-socket:%s\n",
infostr? gc_percent_escape (infostr) : "");
xfree (infostr);
es_fprintf (outfp, "agent-socket:%s\n", gc_percent_escape (tmp));
xfree (tmp);
}
{
/* We need to use make_filename to expand a possible "~/". */