dirmngr: Remove all system daemon features.

* dirmngr/dirmngr.h (opts): Remove fields 'system_service' and
'system_daemon'.
* common/homedir.c (dirmngr_sys_socket_name): Remove.
(dirmngr_user_socket_name): Rename to ...
(dirmngr_socket_name): this.  Change call callers.
* common/asshelp.c (start_new_dirmngr): Remove the system socket
feature.
* tools/gpgconf.c (list_dirs): Do not print "dirmngr-sys-socket".
* sm/server.c (gpgsm_server): Adjust for removed system socket feature.
* dirmngr/server.c (cmd_getinfo): Ditto.
(cmd_killdirmngr): Remove check for system daemon.
(cmd_reloaddirmngr): Ditto.
* dirmngr/dirmngr.c (USE_W32_SERVICE): Remove macro.
(aService): Remove.
(opts): Remove --service.
(w32_service_control): Remove.
(real_main, call_real_main) [W32]: Remove wrapper.
(main): Remove Windows system service feature.  Remove system dameon
feature.  Use only the "~/.gnupg/dirmngr_ldapservers.conf" file.
* dirmngr/certcache.c (load_certs_from_dir): Remove warning in the
system dameon case.
* dirmngr/crlcache.c (DBDIR_D): Always use "~/.gnupg/crls.d".
* dirmngr/ocsp.c (validate_responder_cert): Do not call
validate_cert_chain which was used only in system daemon mode.
* dirmngr/validate.c (validate_cert_chain): Always use the code.
--

We are now starting dirmngr as needed as a user daemon.  The
deprecated system daemon mode does not anymore make sense.  In case a
system wide daemon is required, it is better to setup a dedicated
account to run dirmngr and tweak socket permissions accordingly.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2016-08-18 11:23:40 +02:00
parent de6e3217cd
commit d83ba4897b
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
13 changed files with 29 additions and 365 deletions

View File

@ -564,18 +564,7 @@ start_new_dirmngr (assuan_context_t *r_ctx,
return err;
}
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 ();
sockname = dirmngr_socket_name ();
err = assuan_socket_connect (ctx, sockname, 0, 0);
#ifdef USE_DIRMNGR_AUTO_START
@ -583,22 +572,9 @@ start_new_dirmngr (assuan_context_t *r_ctx,
{
lock_spawn_t lock;
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;
}
/* No connection: Try start a new Dirmngr. */
if (!dirmngr_program || !*dirmngr_program)
dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR);
@ -631,20 +607,11 @@ start_new_dirmngr (assuan_context_t *r_ctx,
}
argv[0] = "--daemon";
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. */
/* Try starting the daemon. Versions of dirmngr < 2.1.15 do
* this only if the home directory is given on the command line. */
argv[1] = "--homedir";
argv[2] = abs_homedir;
argv[3] = NULL;
if (!(err = lock_spawning (&lock, gnupg_homedir (), "dirmngr", verbose))
&& assuan_socket_connect (ctx, sockname, 0, 0))

View File

@ -812,55 +812,9 @@ gnupg_cachedir (void)
}
/* Return the system socket name used by DirMngr. */
/* Return the user socket name used by DirMngr. */
const char *
dirmngr_sys_socket_name (void)
{
#ifdef HAVE_W32_SYSTEM
static char *name;
if (!name)
{
char *p;
# ifdef HAVE_W32CE_SYSTEM
const char *s1, *s2;
s1 = default_homedir ();
# else
char s1buf[MAX_PATH];
const char *s1, *s2;
s1 = default_homedir ();
if (!w32_portable_app)
{
/* We need something akin CSIDL_COMMON_PROGRAMS, but local
(non-roaming). This is because the file needs to be on
the local machine and makes only sense on that machine.
CSIDL_WINDOWS seems to be the only location which
guarantees that. */
if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1buf) < 0)
strcpy (s1buf, "C:\\WINDOWS");
s1 = s1buf;
}
# endif
s2 = DIRSEP_S DIRMNGR_SOCK_NAME;
name = xmalloc (strlen (s1) + strlen (s2) + 1);
strcpy (stpcpy (name, s1), s2);
for (p=name; *p; p++)
if (*p == '/')
*p = '\\';
}
return name;
#else /*!HAVE_W32_SYSTEM*/
return GNUPG_LOCALSTATEDIR "/run/" PACKAGE_NAME "/"DIRMNGR_SOCK_NAME;
#endif /*!HAVE_W32_SYSTEM*/
}
/* Return the user socket name used by DirMngr. If a user specific
dirmngr installation is not supported, NULL is returned. */
const char *
dirmngr_user_socket_name (void)
dirmngr_socket_name (void)
{
static char *name;

View File

@ -227,8 +227,7 @@ const char *gnupg_libdir (void);
const char *gnupg_datadir (void);
const char *gnupg_localedir (void);
const char *gnupg_cachedir (void);
const char *dirmngr_sys_socket_name (void);
const char *dirmngr_user_socket_name (void);
const char *dirmngr_socket_name (void);
char *_gnupg_socketdir_internal (int skip_checks, unsigned *r_info);

View File

@ -348,9 +348,6 @@ load_certs_from_dir (const char *dirname, int are_trusted)
dir = opendir (dirname);
if (!dir)
{
if (opt.system_daemon)
log_info (_("can't access directory '%s': %s\n"),
dirname, strerror (errno));
return 0; /* We do not consider this a severe error. */
}

View File

@ -115,7 +115,7 @@
#include "cdb.h"
/* Change this whenever the format changes */
#define DBDIR_D (opt.system_daemon? "crls.d" : "dirmngr-cache.d")
#define DBDIR_D "crls.d"
#define DBDIRFILE "DIR.txt"
#define DBDIRVERSION 1

View File

@ -70,15 +70,6 @@
#include "gc-opt-flags.h"
#include "dns-stuff.h"
/* The plain Windows version uses the windows service system. For
example to start the service you may use "sc start dirmngr".
WindowsCE does not support this; the service system over there is
based on a single process with all services being DLLs - we can't
support this easily. */
#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
# define USE_W32_SERVICE 1
#endif
#ifndef ENAMETOOLONG
# define ENAMETOOLONG EINVAL
#endif
@ -94,7 +85,6 @@ enum cmd_and_opt_values {
aServer,
aDaemon,
aService,
aListCRLs,
aLoadCRL,
aFetchCRL,
@ -155,9 +145,6 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_c (aServer, "server", N_("run in server mode (foreground)") ),
ARGPARSE_c (aDaemon, "daemon", N_("run in daemon mode (background)") ),
#ifdef USE_W32_SERVICE
ARGPARSE_c (aService, "service", N_("run as windows service (background)")),
#endif
ARGPARSE_c (aListCRLs, "list-crls", N_("list the contents of the CRL cache")),
ARGPARSE_c (aLoadCRL, "load-crl", N_("|FILE|load CRL from FILE into cache")),
ARGPARSE_c (aFetchCRL, "fetch-crl", N_("|URL|fetch a CRL from URL")),
@ -635,42 +622,6 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
}
#ifdef USE_W32_SERVICE
/* The global status of our service. */
SERVICE_STATUS_HANDLE service_handle;
SERVICE_STATUS service_status;
DWORD WINAPI
w32_service_control (DWORD control, DWORD event_type, LPVOID event_data,
LPVOID context)
{
(void)event_type;
(void)event_data;
(void)context;
/* event_type and event_data are not used here. */
switch (control)
{
case SERVICE_CONTROL_SHUTDOWN:
/* For shutdown we will try to force termination. */
service_status.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus (service_handle, &service_status);
shutdown_pending = 3;
break;
case SERVICE_CONTROL_STOP:
service_status.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus (service_handle, &service_status);
shutdown_pending = 1;
break;
default:
break;
}
return 0;
}
#endif /*USE_W32_SERVICE*/
#ifndef HAVE_W32_SYSTEM
static int
pid_suffix_callback (unsigned long *r_suffix)
@ -685,15 +636,9 @@ pid_suffix_callback (unsigned long *r_suffix)
#endif /*!HAVE_W32_SYSTEM*/
#ifdef USE_W32_SERVICE
# define main real_main
#endif
int
main (int argc, char **argv)
{
#ifdef USE_W32_SERVICE
# undef main
#endif
enum cmd_and_opt_values cmd = 0;
ARGPARSE_ARGS pargs;
int orig_argc;
@ -714,34 +659,9 @@ main (int argc, char **argv)
#endif /*USE_LDAP*/
int debug_wait = 0;
int rc;
int homedir_seen = 0;
struct assuan_malloc_hooks malloc_hooks;
early_system_init ();
#ifdef USE_W32_SERVICE
/* The option will be set by main() below if we should run as a
system daemon. */
if (opt.system_service)
{
service_handle
= RegisterServiceCtrlHandlerEx ("DirMngr",
&w32_service_control, NULL /*FIXME*/);
if (service_handle == 0)
log_error ("failed to register service control handler: ec=%d",
(int) GetLastError ());
service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
service_status.dwCurrentState = SERVICE_START_PENDING;
service_status.dwControlsAccepted
= SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
service_status.dwWin32ExitCode = NO_ERROR;
service_status.dwServiceSpecificExitCode = NO_ERROR;
service_status.dwCheckPoint = 0;
service_status.dwWaitHint = 10000; /* 10 seconds timeout. */
SetServiceStatus (service_handle, &service_status);
}
#endif /*USE_W32_SERVICE*/
set_strusage (my_strusage);
log_set_prefix (DIRMNGR_NAME, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_PID);
@ -830,44 +750,10 @@ main (int argc, char **argv)
else if (pargs.r_opt == oHomedir)
{
gnupg_set_homedir (pargs.r.ret_str);
homedir_seen = 1;
}
else if (pargs.r_opt == aDaemon)
opt.system_daemon = 1;
else if (pargs.r_opt == aService)
{
/* Redundant. The main function takes care of it. */
opt.system_service = 1;
opt.system_daemon = 1;
}
#ifdef HAVE_W32_SYSTEM
else if (pargs.r_opt == aGPGConfList || pargs.r_opt == aGPGConfTest)
/* We set this so we switch to the system configuration
directory below. This is a crutch to solve the problem
that the user configuration is never used on Windows. Also
see below at aGPGConfList. */
opt.system_daemon = 1;
#endif
}
/* If --daemon has been given on the command line but not --homedir,
we switch to /etc/gnupg as default home directory. Note, that
this also overrides the GNUPGHOME environment variable. */
if (opt.system_daemon && !homedir_seen)
{
#ifdef HAVE_W32CE_SYSTEM
gnupg_set_homedir (DIRSEP_S "gnupg");
#else
gnupg_set_homedir (gnupg_sysconfdir ());
#endif
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 ();
socket_name = dirmngr_socket_name ();
if (default_config)
configname = make_filename (gnupg_homedir (), DIRMNGR_NAME".conf", NULL );
@ -911,7 +797,6 @@ main (int argc, char **argv)
{
case aServer:
case aDaemon:
case aService:
case aShutdown:
case aFlush:
case aListCRLs:
@ -1039,8 +924,7 @@ main (int argc, char **argv)
if (!ldapfile)
{
ldapfile = make_filename (gnupg_homedir (),
opt.system_daemon?
"ldapservers.conf":"dirmngr_ldapservers.conf",
"dirmngr_ldapservers.conf",
NULL);
opt.ldapservers = parse_ldapserver_file (ldapfile);
xfree (ldapfile);
@ -1058,9 +942,7 @@ main (int argc, char **argv)
#endif
/* Ready. Now to our duties. */
if (!cmd && opt.system_service)
cmd = aDaemon;
else if (!cmd)
if (!cmd)
cmd = aServer;
rc = 0;
@ -1288,23 +1170,9 @@ main (int argc, char **argv)
cert_cache_init ();
crl_cache_init ();
#ifdef USE_W32_SERVICE
if (opt.system_service)
{
service_status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (service_handle, &service_status);
}
#endif
handle_connections (fd);
assuan_sock_close (fd);
shutdown_reaper ();
#ifdef USE_W32_SERVICE
if (opt.system_service)
{
service_status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (service_handle, &service_status);
}
#endif
}
else if (cmd == aListCRLs)
{
@ -1416,8 +1284,7 @@ main (int argc, char **argv)
also only usable on the command line. --batch is unused. */
filename = make_filename (gnupg_homedir (),
opt.system_daemon?
"ldapservers.conf":"dirmngr_ldapservers.conf",
"dirmngr_ldapservers.conf",
NULL);
filename_esc = percent_escape (filename, NULL);
es_printf ("ldapserverlist-file:%lu:\"%s\n", flags | GC_OPT_FLAG_DEFAULT,
@ -1457,45 +1324,6 @@ main (int argc, char **argv)
}
#ifdef USE_W32_SERVICE
static void WINAPI
call_real_main (DWORD argc, LPSTR *argv)
{
real_main (argc, argv);
}
int
main (int argc, char *argv[])
{
int i;
/* Find out if we run in daemon mode or on the command line. */
for (i = 1; i < argc; i++)
if (!strcmp (argv[i], "--service"))
{
opt.system_service = 1;
opt.system_daemon = 1;
break;
}
if (!opt.system_service)
return real_main (argc, argv);
else
{
SERVICE_TABLE_ENTRY DispatchTable [] =
{
{ "DirMngr", &call_real_main },
{ NULL, NULL }
};
if (!StartServiceCtrlDispatcher (DispatchTable))
return 1;
return 0;
}
}
#endif /*USE_W32_SERVICE*/
static void
cleanup (void)
{

View File

@ -89,8 +89,6 @@ struct
char *http_wrapper_program; /* Override value for the HTTP wrapper
program. */
int system_service; /* We are running as W32 service (implies daemon). */
int system_daemon; /* We are running in system daemon mode. */
int running_detached; /* We are running in detached mode. */
int use_tor; /* Tor mode has been enabled. */

View File

@ -330,10 +330,6 @@ validate_responder_cert (ctrl_t ctrl, ksba_cert_t cert,
}
xfree (fpr);
}
else if (opt.system_daemon)
{
err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_OCSP, NULL);
}
else
{
/* We avoid duplicating the entire certificate validation code

View File

@ -2217,15 +2217,8 @@ cmd_getinfo (assuan_context_t ctx, char *line)
}
else if (!strcmp (line, "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));
else
err = gpg_error (GPG_ERR_NO_DATA);
const char *s = dirmngr_socket_name ();
err = assuan_send_data (ctx, s, strlen (s));
}
else if (!strcmp (line, "tor"))
{
@ -2269,29 +2262,12 @@ static gpg_error_t
cmd_killdirmngr (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
gpg_error_t err;
(void)line;
if (opt.system_daemon)
{
if (opt.system_service)
err = set_error (GPG_ERR_NOT_SUPPORTED,
"can't do that whilst running as system service");
else
err = check_owner_permission (ctx,
"no permission to kill this process");
}
else
err = 0;
if (!err)
{
ctrl->server_local->stopme = 1;
assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
err = gpg_error (GPG_ERR_EOF);
}
return err;
ctrl->server_local->stopme = 1;
assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
return gpg_error (GPG_ERR_EOF);
}
@ -2306,20 +2282,6 @@ cmd_reloaddirmngr (assuan_context_t ctx, char *line)
(void)ctx;
(void)line;
if (opt.system_daemon)
{
#ifndef HAVE_W32_SYSTEM
{
gpg_error_t err;
err = check_owner_permission (ctx,
"no permission to reload this process");
if (err)
return err;
}
#endif
}
dirmngr_sighup_action ();
return 0;
}

View File

@ -354,6 +354,10 @@ is_root_cert (ksba_cert_t cert, const char *issuerdn, const char *subjectdn)
return the closest expiration time in R_EXPTIME (this is useful for
caching issues). MODE is one of the VALIDATE_MODE_* constants.
Note that VALIDATE_MODE_OCSP is not used due to the removal of the
system service in 2.1.15. Instead only the callback to gpgsm to
validate a certificate is used.
If R_TRUST_ANCHOR is not NULL and the validation would fail only
because the root certificate is not trusted, the hexified
fingerprint of that root certificate is stored at R_TRUST_ANCHOR
@ -382,14 +386,6 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
if (r_trust_anchor)
*r_trust_anchor = NULL;
if (!opt.system_daemon)
{
/* For backward compatibility we only do this in daemon mode. */
log_info (_("running in compatibility mode - "
"certificate chain not checked!\n"));
return 0; /* Okay. */
}
if (DBG_X509)
dump_cert ("subject", cert);

View File

@ -34,11 +34,6 @@ providing access to OCSP providers. Dirmngr is invoked internally by
@command{gpg}, @command{gpgsm}, or via the @command{gpg-connect-agent}
tool.
For historical reasons it is also possible to start @command{dirmngr}
in a system daemon mode which uses a different directory layout.
However, this mode is deprecated and may eventually be removed.
@manpause
@noindent
@xref{Option Index},for an index to @command{DIRMNGR}'s commands and
@ -468,9 +463,7 @@ Dirmngr makes use of several directories when running in daemon mode:
@table @file
@item ~/.gnupg
@itemx /etc/gnupg
The first is the standard home directory for all configuration files.
In the deprecated system daemon mode the second directory is used instead.
This is the standard home directory for all configuration files.
@item /etc/gnupg/trusted-certs
This directory should be filled with certificates of Root CAs you
@ -501,20 +494,10 @@ These certificates are first tried before going
out to the net to look for them. These certificates must also be
@acronym{DER} encoded and suffixed with @file{.crt} or @file{.der}.
@item @value{LOCALRUNDIR}
This directory is only used in the deprecated system daemon mode. It
keeps the socket file for accessing @command{dirmngr} services. The
name of the socket file will be @file{S.dirmngr}. Make sure that this
directory has the proper permissions to let @command{dirmngr} create
the socket file and that eligible users may read and write to that
socket.
@item ~/.gnupg/crls.d
@itemx @value{LOCALCACHEDIR}/crls.d
The first directory is used to store cached CRLs. The @file{crls.d}
This directory is used to store cached CRLs. The @file{crls.d}
part will be created by dirmngr if it does not exists but you need to
make sure that the upper directory exists. The second directory is
used instead in the deprecated systems daemon mode.
make sure that the upper directory exists.
@end table
@manpause
@ -1040,10 +1023,6 @@ as a binary blob.
@c works. Note that mainly testing purposes this functionality may be
@c called directly using @cmd{dirmngr-client --validate @file{foo.crt}}.
@c
@c For backward compatibility this function returns success if Dirmngr is
@c not used as a system daemon. Thus not validating the certicates at
@c all. FIXME: This is definitely not correct and should be fixed ASAP.
@c
@c The function takes the target certificate and a mode argument as
@c parameters and returns an error code and optionally the closes
@c expiration time of all certificates in the chain.

View File

@ -1318,9 +1318,7 @@ gpgsm_server (certlist_t default_recplist)
"%s",
gnupg_homedir (),
opt.config_filename,
(dirmngr_user_socket_name ()
? dirmngr_user_socket_name ()
: dirmngr_sys_socket_name ()),
dirmngr_socket_name (),
hello) > 0)
{
assuan_set_hello_line (ctx, tmp);

View File

@ -156,7 +156,6 @@ list_dirs (estream_t fp, char **names)
const char *name;
const char *(*fnc)(void);
const char *extra;
int special;
} list[] = {
{ "sysconfdir", gnupg_sysconfdir, NULL },
{ "bindir", gnupg_bindir, NULL },
@ -164,9 +163,7 @@ list_dirs (estream_t fp, char **names)
{ "libdir", gnupg_libdir, NULL },
{ "datadir", gnupg_datadir, NULL },
{ "localedir", gnupg_localedir, NULL },
{ "dirmngr-socket", dirmngr_user_socket_name, NULL, 1 },
{ "dirmngr-socket", dirmngr_sys_socket_name, NULL, 2 },
{ "dirmngr-sys-socket", dirmngr_sys_socket_name, NULL, 1 },
{ "dirmngr-socket", dirmngr_socket_name, NULL,},
{ "agent-ssh-socket", gnupg_socketdir, GPG_AGENT_SSH_SOCK_NAME },
{ "agent-socket", gnupg_socketdir, GPG_AGENT_SOCK_NAME },
{ "homedir", gnupg_homedir, NULL }
@ -178,13 +175,6 @@ list_dirs (estream_t fp, char **names)
for (idx = 0; idx < DIM (list); idx++)
{
if (list[idx].special == 1 && dirmngr_user_socket_name ())
;
else if (list[idx].special == 2 && !dirmngr_user_socket_name ())
;
else if (list[idx].special == 1 || list[idx].special == 2)
continue;
s = list[idx].fnc ();
if (list[idx].extra)
{