1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-14 00:19:50 +02:00

Add "gpgconf --kill dirmngr" and avoid useless launch before a kill.

* 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>
This commit is contained in:
Werner Koch 2014-11-19 10:31:34 +01:00
parent 734afee733
commit 0e7dd40342
9 changed files with 88 additions and 35 deletions

View 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 /* Try to connect to the agent via socket or start it if it is not
pipes. Handle the server's initial greeting. Returns a new assuan running and AUTOSTART is set. Handle the server's initial
context at R_CTX or an error code. */ greeting. Returns a new assuan context at R_CTX or an error
code. */
gpg_error_t gpg_error_t
start_new_gpg_agent (assuan_context_t *r_ctx, start_new_gpg_agent (assuan_context_t *r_ctx,
gpg_err_source_t errsource, 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_ctype,
const char *opt_lc_messages, const char *opt_lc_messages,
session_env_t session_env, session_env_t session_env,
int verbose, int debug, int autostart, int verbose, int debug,
gpg_error_t (*status_cb)(ctrl_t, int, ...), gpg_error_t (*status_cb)(ctrl_t, int, ...),
ctrl_t status_cb_arg) 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); sockname = make_absfilename (homedir, GPG_AGENT_SOCK_NAME, NULL);
err = assuan_socket_connect (ctx, sockname, 0, 0); err = assuan_socket_connect (ctx, sockname, 0, 0);
if (err) if (err && autostart)
{ {
char *abs_homedir; char *abs_homedir;
lock_spawn_t lock; lock_spawn_t lock;
@ -491,7 +492,8 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
xfree (sockname); xfree (sockname);
if (err) 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); assuan_release (ctx);
return gpg_err_make (errsource, GPG_ERR_NO_AGENT); 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 /* Try to connect to the dirmngr via a socket. On platforms
supporting it, start it up if needed. Returns a new assuan context supporting it, start it up if needed and if AUTOSTART is true.
at R_CTX or an error code. */ Returns a new assuan context at R_CTX or an error code. */
gpg_error_t gpg_error_t
start_new_dirmngr (assuan_context_t *r_ctx, start_new_dirmngr (assuan_context_t *r_ctx,
gpg_err_source_t errsource, gpg_err_source_t errsource,
const char *homedir, const char *homedir,
const char *dirmngr_program, const char *dirmngr_program,
int autostart,
int verbose, int debug, int verbose, int debug,
gpg_error_t (*status_cb)(ctrl_t, int, ...), gpg_error_t (*status_cb)(ctrl_t, int, ...),
ctrl_t status_cb_arg) 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); err = assuan_socket_connect (ctx, sockname, 0, 0);
#ifdef USE_DIRMNGR_AUTO_START #ifdef USE_DIRMNGR_AUTO_START
if (err) if (err && autostart)
{ {
lock_spawn_t lock; lock_spawn_t lock;
const char *argv[4]; const char *argv[4];
@ -670,8 +673,9 @@ start_new_dirmngr (assuan_context_t *r_ctx,
if (err) if (err)
{ {
log_error ("connecting dirmngr at '%s' failed: %s\n", if (autostart || gpg_err_code (err) != GPG_ERR_ASS_CONNECT_FAILED)
sockname, gpg_strerror (err)); log_error ("connecting dirmngr at '%s' failed: %s\n",
sockname, gpg_strerror (err));
assuan_release (ctx); assuan_release (ctx);
return gpg_err_make (errsource, GPG_ERR_NO_DIRMNGR); return gpg_err_make (errsource, GPG_ERR_NO_DIRMNGR);
} }

View File

@ -58,7 +58,7 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
const char *opt_lc_ctype, const char *opt_lc_ctype,
const char *opt_lc_messages, const char *opt_lc_messages,
session_env_t session_env, session_env_t session_env,
int verbose, int debug, int autostart, int verbose, int debug,
gpg_error_t (*status_cb)(ctrl_t, int, ...), gpg_error_t (*status_cb)(ctrl_t, int, ...),
ctrl_t status_cb_arg); ctrl_t status_cb_arg);
@ -69,7 +69,7 @@ start_new_dirmngr (assuan_context_t *r_ctx,
gpg_err_source_t errsource, gpg_err_source_t errsource,
const char *homedir, const char *homedir,
const char *dirmngr_program, const char *dirmngr_program,
int verbose, int debug, int autostart, int verbose, int debug,
gpg_error_t (*status_cb)(ctrl_t, int, ...), gpg_error_t (*status_cb)(ctrl_t, int, ...),
ctrl_t status_cb_arg); ctrl_t status_cb_arg);

View File

@ -98,7 +98,7 @@ start_agent (void)
agentargs.lc_ctype, agentargs.lc_ctype,
agentargs.lc_messages, agentargs.lc_messages,
agentargs.session_env, agentargs.session_env,
agentargs.verbosity, 0, NULL, NULL); 1, agentargs.verbosity, 0, NULL, NULL);
if (!err) if (!err)
{ {
/* Tell the agent that we support Pinentry notifications. No /* Tell the agent that we support Pinentry notifications. No

View File

@ -285,7 +285,7 @@ start_agent (ctrl_t ctrl, int for_card)
opt.agent_program, opt.agent_program,
opt.lc_ctype, opt.lc_messages, opt.lc_ctype, opt.lc_messages,
opt.session_env, opt.session_env,
opt.verbose, DBG_ASSUAN, 1, opt.verbose, DBG_ASSUAN,
NULL, NULL); NULL, NULL);
if (!rc) if (!rc)
{ {

View File

@ -130,7 +130,7 @@ create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_DEFAULT,
opt.homedir, opt.homedir,
opt.dirmngr_program, opt.dirmngr_program,
opt.verbose, DBG_ASSUAN, 1, opt.verbose, DBG_ASSUAN,
NULL /*gpg_status2*/, ctrl); NULL /*gpg_status2*/, ctrl);
if (!err) if (!err)
{ {

View File

@ -95,7 +95,7 @@ start_agent (ctrl_t ctrl)
opt.agent_program, opt.agent_program,
opt.lc_ctype, opt.lc_messages, opt.lc_ctype, opt.lc_messages,
opt.session_env, opt.session_env,
opt.verbose, DBG_ASSUAN, 1, opt.verbose, DBG_ASSUAN,
gpgsm_status2, ctrl); gpgsm_status2, ctrl);
if (!rc) if (!rc)

View 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, err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT,
opt.homedir, opt.dirmngr_program, opt.homedir, opt.dirmngr_program,
opt.verbose, DBG_ASSUAN, 1, opt.verbose, DBG_ASSUAN,
gpgsm_status2, ctrl); gpgsm_status2, ctrl);
prepare_dirmngr (ctrl, ctx, err); prepare_dirmngr (ctrl, ctx, err);
if (err) if (err)

View File

@ -63,7 +63,8 @@ enum cmd_and_opt_values
oHex, oHex,
oDecode, oDecode,
oNoExtConnect, oNoExtConnect,
oDirmngr oDirmngr,
oNoAutostart,
}; };
@ -89,6 +90,7 @@ static ARGPARSE_OPTS opts[] = {
N_("|FILE|run commands from FILE on startup")), N_("|FILE|run commands from FILE on startup")),
ARGPARSE_s_n (oSubst, "subst", N_("run /subst 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_n (oNoVerbose, "no-verbose", "@"),
ARGPARSE_s_s (oHomedir, "homedir", "@" ), ARGPARSE_s_s (oHomedir, "homedir", "@" ),
ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
@ -103,6 +105,7 @@ struct
{ {
int verbose; /* Verbosity level. */ int verbose; /* Verbosity level. */
int quiet; /* Be extra quiet. */ int quiet; /* Be extra quiet. */
int autostart; /* Start the server if not running. */
const char *homedir; /* Configuration directory name */ const char *homedir; /* Configuration directory name */
const char *agent_program; /* Value of --agent-program. */ const char *agent_program; /* Value of --agent-program. */
const char *dirmngr_program; /* Value of --dirmngr-program. */ const char *dirmngr_program; /* Value of --dirmngr-program. */
@ -1175,6 +1178,7 @@ main (int argc, char **argv)
opt.homedir = default_homedir (); opt.homedir = default_homedir ();
opt.autostart = 1;
opt.connect_flags = 1; opt.connect_flags = 1;
/* Parse the command line. */ /* Parse the command line. */
@ -1191,6 +1195,7 @@ main (int argc, char **argv)
case oHomedir: opt.homedir = pargs.r.ret_str; break; case oHomedir: opt.homedir = pargs.r.ret_str; break;
case oAgentProgram: opt.agent_program = 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 oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
case oNoAutostart: opt.autostart = 0; break;
case oHex: opt.hex = 1; break; case oHex: opt.hex = 1; break;
case oDecode: opt.decode = 1; break; case oDecode: opt.decode = 1; break;
case oDirmngr: opt.use_dirmngr = 1; break; case oDirmngr: opt.use_dirmngr = 1; break;
@ -2195,6 +2200,7 @@ start_agent (void)
GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_DEFAULT,
opt.homedir, opt.homedir,
opt.dirmngr_program, opt.dirmngr_program,
opt.autostart,
!opt.quiet, 0, !opt.quiet, 0,
NULL, NULL); NULL, NULL);
else else
@ -2204,14 +2210,30 @@ start_agent (void)
opt.agent_program, opt.agent_program,
NULL, NULL, NULL, NULL,
session_env, session_env,
opt.autostart,
!opt.quiet, 0, !opt.quiet, 0,
NULL, NULL); NULL, NULL);
session_env_release (session_env); session_env_release (session_env);
if (err) if (err)
{ {
log_error (_("error sending standard options: %s\n"), gpg_strerror (err)); if (!opt.autostart
exit (1); && (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; return ctx;

View File

@ -107,6 +107,7 @@ gc_error (int status, int errnum, const char *fmt, ...)
/* Forward declaration. */ /* Forward declaration. */
static void gpg_agent_runtime_change (int killflag); static void gpg_agent_runtime_change (int killflag);
static void scdaemon_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 /* Backend configuration. Backends are used to decide how the default
and current value of an option can be determined, and how the 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_DISP_NAME, SCDAEMON_NAME, GNUPG_MODULE_NAME_SCDAEMON,
scdaemon_runtime_change, GPGCONF_NAME"-" SCDAEMON_NAME ".conf" }, scdaemon_runtime_change, GPGCONF_NAME"-" SCDAEMON_NAME ".conf" },
{ DIRMNGR_DISP_NAME, DIRMNGR_NAME, GNUPG_MODULE_NAME_DIRMNGR, { 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, { DIRMNGR_DISP_NAME " LDAP Server List", NULL, 0,
NULL, "ldapserverlist-file", "LDAP Server" }, NULL, "ldapserverlist-file", "LDAP Server" },
{ "Pinentry", "pinentry", GNUPG_MODULE_NAME_PINENTRY, { "Pinentry", "pinentry", GNUPG_MODULE_NAME_PINENTRY,
@ -1064,19 +1065,20 @@ gpg_agent_runtime_change (int killflag)
{ {
gpg_error_t err; gpg_error_t err;
const char *pgmname; const char *pgmname;
const char *argv[2]; const char *argv[3];
pid_t pid; pid_t pid;
pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT); pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
argv[0] = killflag? "KILLAGENT" : "RELOADAGENT"; argv[0] = "--no-autostart";
argv[1] = NULL; argv[1] = killflag? "KILLAGENT" : "RELOADAGENT";
argv[2] = NULL;
err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid); err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
if (!err) if (!err)
err = gnupg_wait_process (pgmname, pid, 1, NULL); err = gnupg_wait_process (pgmname, pid, 1, NULL);
if (err) if (err)
gc_error (0, 0, "error running '%s%s': %s", gc_error (0, 0, "error running '%s %s': %s",
pgmname, " reloadagent", gpg_strerror (err)); pgmname, argv[1], gpg_strerror (err));
gnupg_release_process (pid); gnupg_release_process (pid);
} }
@ -1086,7 +1088,7 @@ scdaemon_runtime_change (int killflag)
{ {
gpg_error_t err; gpg_error_t err;
const char *pgmname; const char *pgmname;
const char *argv[6]; const char *argv[7];
pid_t pid; pid_t pid;
(void)killflag; /* For scdaemon kill and reload are synonyms. */ (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); pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
argv[0] = "-s"; argv[0] = "-s";
argv[1] = "GETINFO scd_running"; argv[1] = "--no-autostart";
argv[2] = "/if ${! $?}"; argv[2] = "GETINFO scd_running";
argv[3] = "scd killscd"; argv[3] = "/if ${! $?}";
argv[4] = "/end"; argv[4] = "scd killscd";
argv[5] = NULL; argv[5] = "/end";
argv[6] = NULL;
err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid); err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
if (!err) if (!err)
err = gnupg_wait_process (pgmname, pid, 1, NULL); err = gnupg_wait_process (pgmname, pid, 1, NULL);
if (err) if (err)
gc_error (0, 0, "error running '%s%s': %s", gc_error (0, 0, "error running '%s %s': %s",
pgmname, " scd killscd", gpg_strerror (err)); 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, argv[2], gpg_strerror (err));
gnupg_release_process (pid); gnupg_release_process (pid);
} }