Add "gpgconf --kill dirmngr" and avoid useless launch before a kill.
authorWerner Koch <wk@gnupg.org>
Wed, 19 Nov 2014 09:31:34 +0000 (10:31 +0100)
committerWerner Koch <wk@gnupg.org>
Wed, 19 Nov 2014 09:47:56 +0000 (10:47 +0100)
* common/asshelp.c (start_new_gpg_agent): Add arg autostart.  Change
all callers to use 1 for it.
(start_new_dirmngr): Ditto.
* tools/gpg-connect-agent.c: Add option --no-autostart.
(main): Default autostart to 1.
(start_agent): Implement no-autostart.
* tools/gpgconf-comp.c (gpg_agent_runtime_change): Use --no-autostart.
(scdaemon_runtime_change): Ditto.
(dirmngr_runtime_change): New.

Signed-off-by: Werner Koch <wk@gnupg.org>
common/asshelp.c
common/asshelp.h
common/get-passphrase.c
g10/call-agent.c
g10/call-dirmngr.c
sm/call-agent.c
sm/call-dirmngr.c
tools/gpg-connect-agent.c
tools/gpgconf-comp.c

index 3fc28a1..e675fda 100644 (file)
@@ -344,9 +344,10 @@ unlock_spawning (lock_spawn_t *lock, const char *name)
     }
 }
 
-/* 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. */
+/* Try to connect to the agent via socket or start it if it is not
+   running and AUTOSTART is set.  Handle the server's initial
+   greeting.  Returns a new assuan context at R_CTX or an error
+   code. */
 gpg_error_t
 start_new_gpg_agent (assuan_context_t *r_ctx,
                      gpg_err_source_t errsource,
@@ -355,7 +356,7 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
                      const char *opt_lc_ctype,
                      const char *opt_lc_messages,
                      session_env_t session_env,
-                     int verbose, int debug,
+                     int autostart, int verbose, int debug,
                      gpg_error_t (*status_cb)(ctrl_t, int, ...),
                      ctrl_t status_cb_arg)
 {
@@ -376,7 +377,7 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
 
   sockname = make_absfilename (homedir, GPG_AGENT_SOCK_NAME, NULL);
   err = assuan_socket_connect (ctx, sockname, 0, 0);
-  if (err)
+  if (err && autostart)
     {
       char *abs_homedir;
       lock_spawn_t lock;
@@ -491,7 +492,8 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
   xfree (sockname);
   if (err)
     {
-      log_error ("can't connect to the agent: %s\n", gpg_strerror (err));
+      if (autostart || gpg_err_code (err) != GPG_ERR_ASS_CONNECT_FAILED)
+        log_error ("can't connect to the agent: %s\n", gpg_strerror (err));
       assuan_release (ctx);
       return gpg_err_make (errsource, GPG_ERR_NO_AGENT);
     }
@@ -517,13 +519,14 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
 
 
 /* Try to connect to the dirmngr via a socket.  On platforms
-   supporting it, start it up if needed.  Returns a new assuan context
-   at R_CTX or an error code. */
+   supporting it, start it up if needed and if AUTOSTART is true.
+   Returns a new assuan context at R_CTX or an error code. */
 gpg_error_t
 start_new_dirmngr (assuan_context_t *r_ctx,
                    gpg_err_source_t errsource,
                    const char *homedir,
                    const char *dirmngr_program,
+                   int autostart,
                    int verbose, int debug,
                    gpg_error_t (*status_cb)(ctrl_t, int, ...),
                    ctrl_t status_cb_arg)
@@ -557,7 +560,7 @@ start_new_dirmngr (assuan_context_t *r_ctx,
   err = assuan_socket_connect (ctx, sockname, 0, 0);
 
 #ifdef USE_DIRMNGR_AUTO_START
-  if (err)
+  if (err && autostart)
     {
       lock_spawn_t lock;
       const char *argv[4];
@@ -670,8 +673,9 @@ start_new_dirmngr (assuan_context_t *r_ctx,
 
   if (err)
     {
-      log_error ("connecting dirmngr at '%s' failed: %s\n",
-                 sockname, gpg_strerror (err));
+      if (autostart || gpg_err_code (err) != GPG_ERR_ASS_CONNECT_FAILED)
+        log_error ("connecting dirmngr at '%s' failed: %s\n",
+                   sockname, gpg_strerror (err));
       assuan_release (ctx);
       return gpg_err_make (errsource, GPG_ERR_NO_DIRMNGR);
     }
index 08c3c8c..7b30585 100644 (file)
@@ -58,7 +58,7 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
                      const char *opt_lc_ctype,
                      const char *opt_lc_messages,
                      session_env_t session_env,
-                     int verbose, int debug,
+                     int autostart, int verbose, int debug,
                      gpg_error_t (*status_cb)(ctrl_t, int, ...),
                      ctrl_t status_cb_arg);
 
@@ -69,7 +69,7 @@ start_new_dirmngr (assuan_context_t *r_ctx,
                    gpg_err_source_t errsource,
                    const char *homedir,
                    const char *dirmngr_program,
-                   int verbose, int debug,
+                   int autostart, int verbose, int debug,
                    gpg_error_t (*status_cb)(ctrl_t, int, ...),
                    ctrl_t status_cb_arg);
 
index 5b11eb1..53ce7d1 100644 (file)
@@ -98,7 +98,7 @@ start_agent (void)
                              agentargs.lc_ctype,
                              agentargs.lc_messages,
                              agentargs.session_env,
-                             agentargs.verbosity, 0, NULL, NULL);
+                             1, agentargs.verbosity, 0, NULL, NULL);
   if (!err)
     {
       /* Tell the agent that we support Pinentry notifications.  No
index bacb9d5..74d8cec 100644 (file)
@@ -285,7 +285,7 @@ start_agent (ctrl_t ctrl, int for_card)
                                 opt.agent_program,
                                 opt.lc_ctype, opt.lc_messages,
                                 opt.session_env,
-                                opt.verbose, DBG_ASSUAN,
+                                1, opt.verbose, DBG_ASSUAN,
                                 NULL, NULL);
       if (!rc)
         {
index 71f5324..7150853 100644 (file)
@@ -130,7 +130,7 @@ create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
                            GPG_ERR_SOURCE_DEFAULT,
                            opt.homedir,
                            opt.dirmngr_program,
-                           opt.verbose, DBG_ASSUAN,
+                           1, opt.verbose, DBG_ASSUAN,
                            NULL /*gpg_status2*/, ctrl);
   if (!err)
     {
index f99caad..59b1509 100644 (file)
@@ -95,7 +95,7 @@ start_agent (ctrl_t ctrl)
                                 opt.agent_program,
                                 opt.lc_ctype, opt.lc_messages,
                                 opt.session_env,
-                                opt.verbose, DBG_ASSUAN,
+                                1, opt.verbose, DBG_ASSUAN,
                                 gpgsm_status2, ctrl);
 
       if (!rc)
index 99a14c0..4dc8425 100644 (file)
@@ -209,7 +209,7 @@ start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r)
 
   err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT,
                            opt.homedir, opt.dirmngr_program,
-                           opt.verbose, DBG_ASSUAN,
+                           1, opt.verbose, DBG_ASSUAN,
                            gpgsm_status2, ctrl);
   prepare_dirmngr (ctrl, ctx, err);
   if (err)
index 78dea2a..8e8ebcb 100644 (file)
@@ -63,7 +63,8 @@ enum cmd_and_opt_values
     oHex,
     oDecode,
     oNoExtConnect,
-    oDirmngr
+    oDirmngr,
+    oNoAutostart,
 
   };
 
@@ -89,6 +90,7 @@ static ARGPARSE_OPTS opts[] = {
                 N_("|FILE|run commands from FILE on startup")),
   ARGPARSE_s_n (oSubst, "subst",     N_("run /subst on startup")),
 
+  ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
   ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
   ARGPARSE_s_s (oHomedir, "homedir", "@" ),
   ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
@@ -103,6 +105,7 @@ struct
 {
   int verbose;         /* Verbosity level.  */
   int quiet;           /* Be extra quiet.  */
+  int autostart;        /* Start the server if not running.  */
   const char *homedir;  /* Configuration directory name */
   const char *agent_program;  /* Value of --agent-program.  */
   const char *dirmngr_program;  /* Value of --dirmngr-program.  */
@@ -1175,6 +1178,7 @@ main (int argc, char **argv)
 
 
   opt.homedir = default_homedir ();
+  opt.autostart = 1;
   opt.connect_flags = 1;
 
   /* Parse the command line. */
@@ -1191,6 +1195,7 @@ main (int argc, char **argv)
         case oHomedir:   opt.homedir = pargs.r.ret_str; break;
         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
+        case oNoAutostart:    opt.autostart = 0; break;
         case oHex:       opt.hex = 1; break;
         case oDecode:    opt.decode = 1; break;
         case oDirmngr:   opt.use_dirmngr = 1; break;
@@ -2195,6 +2200,7 @@ start_agent (void)
                              GPG_ERR_SOURCE_DEFAULT,
                              opt.homedir,
                              opt.dirmngr_program,
+                             opt.autostart,
                              !opt.quiet, 0,
                              NULL, NULL);
   else
@@ -2204,14 +2210,30 @@ start_agent (void)
                                opt.agent_program,
                                NULL, NULL,
                                session_env,
+                               opt.autostart,
                                !opt.quiet, 0,
                                NULL, NULL);
 
   session_env_release (session_env);
   if (err)
     {
-      log_error (_("error sending standard options: %s\n"), gpg_strerror (err));
-      exit (1);
+      if (!opt.autostart
+          && (gpg_err_code (err)
+              == opt.use_dirmngr? GPG_ERR_NO_DIRMNGR : GPG_ERR_NO_AGENT))
+        {
+          /* In the no-autostart case we don't make gpg-connect-agent
+             fail on a missing server.  */
+          log_info (opt.use_dirmngr?
+                    _("no dirmngr running in this session\n"):
+                    _("no gpg-agent running in this session\n"));
+          exit (0);
+        }
+      else
+        {
+          log_error (_("error sending standard options: %s\n"),
+                     gpg_strerror (err));
+          exit (1);
+        }
     }
 
   return ctx;
index f9999ba..77139bb 100644 (file)
@@ -107,6 +107,7 @@ gc_error (int status, int errnum, const char *fmt, ...)
 /* Forward declaration.  */
 static void gpg_agent_runtime_change (int killflag);
 static void scdaemon_runtime_change (int killflag);
+static void dirmngr_runtime_change (int killflag);
 
 /* Backend configuration.  Backends are used to decide how the default
    and current value of an option can be determined, and how the
@@ -189,7 +190,7 @@ static struct
     { SCDAEMON_DISP_NAME, SCDAEMON_NAME, GNUPG_MODULE_NAME_SCDAEMON,
       scdaemon_runtime_change, GPGCONF_NAME"-" SCDAEMON_NAME ".conf" },
     { DIRMNGR_DISP_NAME, DIRMNGR_NAME, GNUPG_MODULE_NAME_DIRMNGR,
-      NULL, GPGCONF_NAME "-" DIRMNGR_NAME ".conf" },
+      dirmngr_runtime_change, GPGCONF_NAME "-" DIRMNGR_NAME ".conf" },
     { DIRMNGR_DISP_NAME " LDAP Server List", NULL, 0,
       NULL, "ldapserverlist-file", "LDAP Server" },
     { "Pinentry", "pinentry", GNUPG_MODULE_NAME_PINENTRY,
@@ -1064,19 +1065,20 @@ gpg_agent_runtime_change (int killflag)
 {
   gpg_error_t err;
   const char *pgmname;
-  const char *argv[2];
+  const char *argv[3];
   pid_t pid;
 
   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
-  argv[0] = killflag? "KILLAGENT" : "RELOADAGENT";
-  argv[1] = NULL;
+  argv[0] = "--no-autostart";
+  argv[1] = killflag? "KILLAGENT" : "RELOADAGENT";
+  argv[2] = NULL;
 
   err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
   if (!err)
     err = gnupg_wait_process (pgmname, pid, 1, NULL);
   if (err)
-    gc_error (0, 0, "error running '%s%s': %s",
-              pgmname, " reloadagent", gpg_strerror (err));
+    gc_error (0, 0, "error running '%s %s': %s",
+              pgmname, argv[1], gpg_strerror (err));
   gnupg_release_process (pid);
 }
 
@@ -1086,7 +1088,7 @@ scdaemon_runtime_change (int killflag)
 {
   gpg_error_t err;
   const char *pgmname;
-  const char *argv[6];
+  const char *argv[7];
   pid_t pid;
 
   (void)killflag;  /* For scdaemon kill and reload are synonyms.  */
@@ -1098,18 +1100,43 @@ scdaemon_runtime_change (int killflag)
 
   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
   argv[0] = "-s";
-  argv[1] = "GETINFO scd_running";
-  argv[2] = "/if ${! $?}";
-  argv[3] = "scd killscd";
-  argv[4] = "/end";
-  argv[5] = NULL;
+  argv[1] = "--no-autostart";
+  argv[2] = "GETINFO scd_running";
+  argv[3] = "/if ${! $?}";
+  argv[4] = "scd killscd";
+  argv[5] = "/end";
+  argv[6] = NULL;
+
+  err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
+  if (!err)
+    err = gnupg_wait_process (pgmname, pid, 1, NULL);
+  if (err)
+    gc_error (0, 0, "error running '%s %s': %s",
+              pgmname, argv[4], gpg_strerror (err));
+  gnupg_release_process (pid);
+}
+
+
+static void
+dirmngr_runtime_change (int killflag)
+{
+  gpg_error_t err;
+  const char *pgmname;
+  const char *argv[4];
+  pid_t pid;
+
+  pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
+  argv[0] = "--no-autostart";
+  argv[1] = "--dirmngr";
+  argv[2] = killflag? "KILLDIRMNGR" : "RELOADDIRMNGR";
+  argv[3] = NULL;
 
   err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
   if (!err)
     err = gnupg_wait_process (pgmname, pid, 1, NULL);
   if (err)
-    gc_error (0, 0, "error running '%s%s': %s",
-              pgmname, " scd killscd", gpg_strerror (err));
+    gc_error (0, 0, "error running '%s %s': %s",
+              pgmname, argv[2], gpg_strerror (err));
   gnupg_release_process (pid);
 }