diff options
author | Werner Koch <wk@gnupg.org> | 2014-10-03 11:58:58 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2014-10-03 11:58:58 +0200 |
commit | 9c380384dafb213334f8834178c5ceb0bf33db6e (patch) | |
tree | 3522eab22d31542094d95c605394542a857e1c55 | |
parent | gpg: Fix regression removing SHA256. (diff) | |
download | gnupg2-9c380384dafb213334f8834178c5ceb0bf33db6e.tar.xz gnupg2-9c380384dafb213334f8834178c5ceb0bf33db6e.zip |
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.
-rw-r--r-- | agent/agent.h | 3 | ||||
-rw-r--r-- | agent/command.c | 6 | ||||
-rw-r--r-- | agent/gpg-agent.c | 224 | ||||
-rw-r--r-- | common/asshelp.c | 255 | ||||
-rw-r--r-- | common/exechelp-w32.c | 5 | ||||
-rw-r--r-- | common/simple-pwquery.c | 21 | ||||
-rw-r--r-- | configure.ac | 28 | ||||
-rw-r--r-- | doc/gpg-agent.texi | 68 | ||||
-rw-r--r-- | doc/gpg.texi | 10 | ||||
-rw-r--r-- | doc/gpgsm.texi | 13 | ||||
-rw-r--r-- | g10/server.c | 3 | ||||
-rw-r--r-- | g13/server.c | 3 | ||||
-rw-r--r-- | scd/scdaemon.c | 81 | ||||
-rw-r--r-- | sm/server.c | 3 | ||||
-rw-r--r-- | tools/gpgconf.c | 24 |
15 files changed, 215 insertions, 532 deletions
diff --git a/agent/agent.h b/agent/agent.h index a420baed9..7342475e7 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -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; diff --git a/agent/command.c b/agent/command.c index e17232e98..8c6849840 100644 --- a/agent/command.c +++ b/agent/command.c @@ -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; diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 3febaf841..0c163e124 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -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) - { - 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); - } + sockname = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL); - rc = assuan_new (&ctx); - if (! rc) - rc = assuan_socket_connect (ctx, infostr, pid, 0); - xfree (infostr); - if (rc) + err = assuan_new (&ctx); + if (!err) + err = assuan_socket_connect (ctx, sockname, (pid_t)(-1), 0); + xfree (sockname); + if (err) { - 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); diff --git a/common/asshelp.c b/common/asshelp.c index 5e3f66359..e97d39603 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -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; - - /* 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); + char *abs_homedir; + lock_spawn_t lock; - if (err) - { - char *abs_homedir; + /* With no success start a new server. */ + if (!agent_program || !*agent_program) + agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); - /* With no success start a new server. */ - if (!agent_program || !*agent_program) - agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); + if (verbose) + log_info (_("no running gpg-agent - starting '%s'\n"), + agent_program); - 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); - 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) + { + 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; + } - /* 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; + } - 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 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. */ - 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); + 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_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))) + else { - if (excode == -1) - log_debug ("running '%s' for testing failed (wait): %s\n", - agent_program, gpg_strerror (err)); - } - gnupg_release_process (pid); + int i; - 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)) + for (i=0; i < SECS_TO_WAIT_FOR_AGENT; i++) { - 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 + 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) { - int i; - - for (i=0; i < SECS_TO_WAIT_FOR_AGENT; i++) + if (verbose) { - 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; - } + 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); - } - xfree (abs_homedir); } - xfree (sockname); - } - 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; - } + unlock_spawning (&lock, "agent"); + xfree (abs_homedir); } - + 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); diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 7bcd79bed..05e9e1000 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -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)) diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index 7dcc05747..0eff5c5c9 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -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); diff --git a/configure.ac b/configure.ac index be1079102..9e1dd8943 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index b42d3535a..7c2188911 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -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 diff --git a/doc/gpg.texi b/doc/gpg.texi index 31bdda0b8..33329a130 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -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 diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 078d2ad6a..bc6326ca4 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -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 diff --git a/g10/server.c b/g10/server.c index b019d1aa1..d02f20e3c 100644 --- a/g10/server.c +++ b/g10/server.c @@ -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) { diff --git a/g13/server.c b/g13/server.c index 573f6706a..07b74f8bf 100644 --- a/g13/server.c +++ b/g13/server.c @@ -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) { diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 9cc4d117c..be99b001a 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -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); diff --git a/sm/server.c b/sm/server.c index 978e70a55..0bee5b205 100644 --- a/sm/server.c +++ b/sm/server.c @@ -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 ()), diff --git a/tools/gpgconf.c b/tools/gpgconf.c index cb37a2593..f63c05ed1 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -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 "~/". */ |