From 5d321eb00be0774418de1a05678ac0ec44d7193b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 12 Mar 2014 19:33:30 +0100 Subject: [PATCH] dirmngr: Default to a user socket name and enable autostart. * common/homedir.c (dirmngr_socket_name): Rename to dirmngr_sys_socket_name. (dirmngr_user_socket_name): New. * common/asshelp.c (start_new_dirmngr): Handle sys and user dirmngr socket. * dirmngr/dirmngr.c (main): Ditto. * dirmngr/server.c (cmd_getinfo): Ditto. * sm/server.c (gpgsm_server): Ditto. * dirmngr/dirmngr-client.c (start_dirmngr): Likewise. * tools/gpgconf.c (main): Print "dirmngr-sys-socket" with --list-dirs. * configure.ac (USE_DIRMNGR_AUTO_START): Set by default. --- common/asshelp.c | 56 +++++++++++++++++++++++++++++++++------- common/homedir.c | 20 ++++++++++++-- common/util.h | 3 ++- configure.ac | 11 +++----- dirmngr/dirmngr-client.c | 5 +++- dirmngr/dirmngr.c | 6 ++++- dirmngr/server.c | 5 +++- sm/server.c | 5 +++- tools/gpgconf.c | 16 ++++++++++-- 9 files changed, 101 insertions(+), 26 deletions(-) diff --git a/common/asshelp.c b/common/asshelp.c index b5dde5a46..4763de1b3 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -600,19 +600,41 @@ start_new_dirmngr (assuan_context_t *r_ctx, return err; } - sockname = dirmngr_socket_name (); + sockname = dirmngr_user_socket_name (); + if (sockname) + { + /* First try the local socket name and only if that fails try + the system socket. */ + err = assuan_socket_connect (ctx, sockname, 0, 0); + if (err) + sockname = dirmngr_sys_socket_name (); + } + else + sockname = dirmngr_sys_socket_name (); + err = assuan_socket_connect (ctx, sockname, 0, 0); + #ifdef USE_DIRMNGR_AUTO_START if (err) { lock_spawn_t lock; - const char *argv[2]; + const char *argv[4]; + int try_system_daemon = 0; + char *abs_homedir; + + /* No connection: Try start a new Dirmngr. On Windows this will + fail because the Dirmngr is expected to be a system service. + However on WinCE we don't distinguish users and thus we can + start it. */ + + /* We prefer to start it as a user daemon. */ + sockname = dirmngr_user_socket_name (); + if (!sockname) + { + sockname = dirmngr_sys_socket_name (); + try_system_daemon = 1; + } - /* With no success try start a new Dirmngr. On most systems - this will fail because the Dirmngr is expected to be a system - service. However on Wince we don't distinguish users and - thus we can start it. A future extension might be to use the - userv system to start the Dirmngr as a system service. */ if (!dirmngr_program || !*dirmngr_program) dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR); @@ -624,6 +646,8 @@ start_new_dirmngr (assuan_context_t *r_ctx, status_cb (status_cb_arg, STATUS_PROGRESS, "starting_dirmngr ? 0 0", NULL); + abs_homedir = make_filename (homedir, NULL); + if (fflush (NULL)) { gpg_error_t tmperr = gpg_err_make (errsource, @@ -635,12 +659,25 @@ start_new_dirmngr (assuan_context_t *r_ctx, } argv[0] = "--daemon"; - argv[1] = NULL; + if (try_system_daemon) + argv[1] = NULL; + else + { /* Try starting as user daemon - dirmngr does this if the + home directory is given on the command line. */ + argv[1] = "--homedir"; + argv[2] = abs_homedir; + argv[3] = NULL; + } + + /* On the use of HOMEDIR for locking: Under Windows HOMEDIR is + not used thus it does not matter. Under Unix we should + TRY_SYSTEM_DAEMON should never be true because + dirmngr_user_socket_name() won't return NULL. */ if (!(err = lock_spawning (&lock, homedir, "dirmngr", verbose)) && assuan_socket_connect (ctx, sockname, 0, 0)) { - err = gnupg_spawn_process_detached (dirmngr_program, argv,NULL); + err = gnupg_spawn_process_detached (dirmngr_program, argv, NULL); if (err) log_error ("failed to start the dirmngr '%s': %s\n", dirmngr_program, gpg_strerror (err)); @@ -671,6 +708,7 @@ start_new_dirmngr (assuan_context_t *r_ctx, } unlock_spawning (&lock, "dirmngr"); + xfree (abs_homedir); } #else (void)homedir; diff --git a/common/homedir.c b/common/homedir.c index 77622a1d4..e2a117bd7 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -555,9 +555,9 @@ gnupg_cachedir (void) } -/* Return the default socket name used by DirMngr. */ +/* Return the system socket name used by DirMngr. */ const char * -dirmngr_socket_name (void) +dirmngr_sys_socket_name (void) { #ifdef HAVE_W32_SYSTEM static char *name; @@ -600,6 +600,22 @@ dirmngr_socket_name (void) } +/* Return the user socket name used by DirMngr. If a a user specific + dirmngr installation is not supported, NULL is returned. */ +const char * +dirmngr_user_socket_name (void) +{ +#ifdef HAVE_W32_SYSTEM + return NULL; /* We support only a system service. */ +#else /*!HAVE_W32_SYSTEM*/ + static char *name; + + if (!name) + name = make_filename (default_homedir (), DIRMNGR_SOCK_NAME, NULL); + return name; +#endif /*!HAVE_W32_SYSTEM*/ +} + /* Return the file name of a helper tool. WHICH is one of the GNUPG_MODULE_NAME_foo constants. */ diff --git a/common/util.h b/common/util.h index c4acb0bd3..4b3cbfc4d 100644 --- a/common/util.h +++ b/common/util.h @@ -231,7 +231,8 @@ const char *gnupg_libdir (void); const char *gnupg_datadir (void); const char *gnupg_localedir (void); const char *gnupg_cachedir (void); -const char *dirmngr_socket_name (void); +const char *dirmngr_sys_socket_name (void); +const char *dirmngr_user_socket_name (void); /* All module names. We also include gpg and gpgsm for the sake for gpgconf. */ diff --git a/configure.ac b/configure.ac index c20984afd..e384fba2d 100644 --- a/configure.ac +++ b/configure.ac @@ -92,7 +92,7 @@ disable_keyserver_path=no card_support=yes use_ccid_driver=yes use_standard_socket=yes -dirmngr_auto_start=no +dirmngr_auto_start=yes try_ks_ldap=no @@ -428,15 +428,10 @@ AC_ARG_ENABLE(ccid-driver, use_ccid_driver=$enableval) AC_MSG_RESULT($use_ccid_driver) -# -# Dirmngr is nowadays a system service and thus it usually does no -# make sense to start it as needed. However on some systems this is -# possible; this option enable the feature. -# AC_MSG_CHECKING([whether to auto start dirmngr]) AC_ARG_ENABLE(dirmngr-auto-start, - AC_HELP_STRING([--enable-dirmngr-auto-start], - [enable auto starting of the dirmngr]), + AC_HELP_STRING([--disable-dirmngr-auto-start], + [disable auto starting of the dirmngr]), dirmngr_auto_start=$enableval) AC_MSG_RESULT($dirmngr_auto_start) if test "$dirmngr_auto_start" = yes ; then diff --git a/dirmngr/dirmngr-client.c b/dirmngr/dirmngr-client.c index da9744359..0e627642d 100644 --- a/dirmngr/dirmngr-client.c +++ b/dirmngr/dirmngr-client.c @@ -443,7 +443,10 @@ start_dirmngr (int only_daemon) infostr = opt.force_pipe_server? NULL : getenv (DIRMNGR_INFO_NAME); if (only_daemon && (!infostr || !*infostr)) { - infostr = xstrdup (dirmngr_socket_name ()); + if (dirmngr_user_socket_name ()) + infostr = xstrdup (dirmngr_user_socket_name ()); + else + infostr = xstrdup (dirmngr_sys_socket_name ()); try_default = 1; } diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 7bcff7a6a..e3f98c04e 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -666,7 +666,6 @@ main (int argc, char **argv) opt.ldaptimeout = DEFAULT_LDAP_TIMEOUT; /* Other defaults. */ - socket_name = dirmngr_socket_name (); /* Check whether we have a config file given on the commandline */ orig_argc = argc; @@ -721,7 +720,12 @@ main (int argc, char **argv) #endif opt.homedir_data = gnupg_datadir (); opt.homedir_cache = gnupg_cachedir (); + socket_name = dirmngr_sys_socket_name (); } + else if (dirmngr_user_socket_name ()) + socket_name = dirmngr_user_socket_name (); + else + socket_name = dirmngr_sys_socket_name (); if (default_config) configname = make_filename (opt.homedir, DIRMNGR_NAME".conf", NULL ); diff --git a/dirmngr/server.c b/dirmngr/server.c index a1d20334b..f1319ad28 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1781,7 +1781,10 @@ cmd_getinfo (assuan_context_t ctx, char *line) } else if (!strcmp (line, "socket_name")) { - const char *s = dirmngr_socket_name (); + const char *s = dirmngr_user_socket_name (); + + if (!s) + s = dirmngr_sys_socket_name (); if (s) err = assuan_send_data (ctx, s, strlen (s)); diff --git a/sm/server.c b/sm/server.c index 74caf6c5c..201a34b3e 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1296,6 +1296,7 @@ gpgsm_server (certlist_t default_recplist) 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" @@ -1305,7 +1306,9 @@ gpgsm_server (certlist_t default_recplist) opt.homedir, opt.config_filename, s1?s1:"[not set]", - dirmngr_socket_name (), + (dirmngr_user_socket_name () + ? dirmngr_user_socket_name () + : dirmngr_sys_socket_name ()), hello) > 0) { assuan_set_hello_line (ctx, tmp); diff --git a/tools/gpgconf.c b/tools/gpgconf.c index a9bf491ec..fbce6d371 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -347,8 +347,20 @@ main (int argc, char **argv) gc_percent_escape (gnupg_datadir ())); es_fprintf (outfp, "localedir:%s\n", gc_percent_escape (gnupg_localedir ())); - es_fprintf (outfp, "dirmngr-socket:%s\n", - gc_percent_escape (dirmngr_socket_name ())); + + if (dirmngr_user_socket_name ()) + { + es_fprintf (outfp, "dirmngr-socket:%s\n", + gc_percent_escape (dirmngr_user_socket_name ())); + es_fprintf (outfp, "dirmngr-sys-socket:%s\n", + gc_percent_escape (dirmngr_sys_socket_name ())); + } + else + { + es_fprintf (outfp, "dirmngr-socket:%s\n", + gc_percent_escape (dirmngr_sys_socket_name ())); + } + { char *infostr = getenv (GPG_AGENT_INFO_NAME);