/*
- * Copyright (C) 2006-2012 Tobias Brunner
+ * Copyright (C) 2006-2018 Tobias Brunner
* Copyright (C) 2005-2014 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
+ * HSR Hochschule fuer Technik Rapperswil
* Copyright (C) 2014 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
#include <systemd/sd-daemon.h>
#include <systemd/sd-journal.h>
-#include <hydra.h>
#include <daemon.h>
#include <library.h>
struct journal_logger_t {
/**
- * Implements logger_t
+ * Public interface
*/
- logger_t logger;
+ custom_logger_t public;
/**
* Configured loglevels
return level;
}
-/**
- * Reload journal logger configuration
- */
-CALLBACK(journal_reload, bool,
- journal_logger_t **journal)
+METHOD(custom_logger_t, set_level, void,
+ journal_logger_t *this, debug_t group, level_t level)
{
- journal_logger_t *this = *journal;
- debug_t group;
- level_t def;
-
- def = lib->settings->get_int(lib->settings, "%s.journal.default", 1, lib->ns);
-
this->lock->write_lock(this->lock);
- for (group = 0; group < DBG_MAX; group++)
- {
- this->levels[group] =
- lib->settings->get_int(lib->settings,
- "%s.journal.%N", def, lib->ns, debug_lower_names, group);
- }
+ this->levels[group] = level;
this->lock->unlock(this->lock);
+}
- charon->bus->add_logger(charon->bus, &this->logger);
-
- return TRUE;
+METHOD(custom_logger_t, logger_destroy, void,
+ journal_logger_t *this)
+{
+ this->lock->destroy(this->lock);
+ free(this);
}
-/**
- * Initialize/deinitialize journal logger
- */
-static bool journal_register(void *plugin, plugin_feature_t *feature,
- bool reg, journal_logger_t **logger)
+static custom_logger_t *journal_logger_create(const char *name)
{
journal_logger_t *this;
- if (reg)
- {
- INIT(this,
+ INIT(this,
+ .public = {
.logger = {
.vlog = _vlog,
.get_level = _get_level,
},
- .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
- );
-
- journal_reload(&this);
-
- *logger = this;
- return TRUE;
- }
- else
- {
- this = *logger;
-
- charon->bus->remove_logger(charon->bus, &this->logger);
-
- this->lock->destroy(this->lock);
- free(this);
-
- return TRUE;
- }
+ .set_level = _set_level,
+ .destroy = _logger_destroy,
+ },
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+ return &this->public;
}
/**
sigset_t set;
sigemptyset(&set);
+ sigaddset(&set, SIGHUP);
sigaddset(&set, SIGTERM);
sigprocmask(SIG_BLOCK, &set, NULL);
while (TRUE)
{
- int sig, error;
+ int sig;
- error = sigwait(&set, &sig);
- if (error)
+ sig = sigwaitinfo(&set, NULL);
+ if (sig == -1)
{
- DBG1(DBG_DMN, "waiting for signal failed: %s", strerror(error));
+ if (errno == EINTR)
+ { /* ignore signals we didn't wait for */
+ continue;
+ }
+ DBG1(DBG_DMN, "waiting for signal failed: %s", strerror(errno));
return SS_RC_INITIALIZATION_FAILED;
}
switch (sig)
{
+ case SIGHUP:
+ {
+ DBG1(DBG_DMN, "signal of type SIGHUP received. Reloading "
+ "configuration");
+ if (lib->settings->load_files(lib->settings, lib->conf, FALSE))
+ {
+ charon->load_loggers(charon);
+ lib->plugins->reload(lib->plugins, NULL);
+ }
+ else
+ {
+ DBG1(DBG_DMN, "reloading config failed, keeping old");
+ }
+ break;
+ }
case SIGTERM:
{
DBG1(DBG_DMN, "SIGTERM received, shutting down");
charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
return 0;
}
- default:
- {
- DBG1(DBG_DMN, "unknown signal %d received. Ignored", sig);
- break;
- }
}
}
}
*/
static bool lookup_uid_gid()
{
- char *name
+ char *name;
name = lib->settings->get_str(lib->settings, "%s.user", IPSEC_USER,
lib->ns);
return TRUE;
}
+#ifndef DISABLE_SIGNAL_HANDLER
/**
* Handle SIGSEGV/SIGILL signals raised by threads
*/
DBG1(DBG_DMN, "killing ourself, received critical signal");
abort();
}
+#endif /* DISABLE_SIGNAL_HANDLER */
/**
- * The journal logger instance
+ * Add namespace alias
*/
-static journal_logger_t *journal;
+static void __attribute__ ((constructor))register_namespace()
+{
+ /* inherit settings from charon */
+ library_add_namespace("charon");
+}
/**
- * Journal static features
+ * Register journal logger
*/
-static plugin_feature_t features[] = {
- PLUGIN_CALLBACK((plugin_feature_callback_t)journal_register, &journal),
- PLUGIN_PROVIDE(CUSTOM, "systemd-journal"),
-};
+static void __attribute__ ((constructor))register_logger()
+{
+ register_custom_logger("journal", journal_logger_create);
+}
/**
* Main function, starts the daemon.
{
struct sigaction action;
struct utsname utsname;
+ int status = SS_RC_INITIALIZATION_FAILED;
dbg = dbg_stderr;
sd_notifyf(0, "STATUS=integrity check of charon-systemd failed");
return SS_RC_INITIALIZATION_FAILED;
}
- atexit(libhydra_deinit);
- if (!libhydra_init())
- {
- sd_notifyf(0, "STATUS=libhydra initialization failed");
- return SS_RC_INITIALIZATION_FAILED;
- }
- atexit(libcharon_deinit);
if (!libcharon_init())
{
sd_notifyf(0, "STATUS=libcharon initialization failed");
- return SS_RC_INITIALIZATION_FAILED;
+ goto error;
}
if (!lookup_uid_gid())
{
sd_notifyf(0, "STATUS=unknown uid/gid");
- return SS_RC_INITIALIZATION_FAILED;
+ goto error;
}
- charon->load_loggers(charon, NULL, FALSE);
-
- lib->plugins->add_static_features(lib->plugins, lib->ns, features,
- countof(features), TRUE, journal_reload, &journal);
-
- if (!charon->initialize(charon, PLUGINS))
+ /* we registered the journal logger as custom logger, which gets its
+ * settings from <ns>.customlog.journal, let it fallback to <ns>.journal */
+ lib->settings->add_fallback(lib->settings, "%s.customlog.journal",
+ "%s.journal", lib->ns);
+ /* load the journal logger by default */
+ lib->settings->set_default_str(lib->settings, "%s.journal.default", "1",
+ lib->ns);
+
+ charon->load_loggers(charon);
+
+ if (!charon->initialize(charon,
+ lib->settings->get_str(lib->settings, "%s.load", PLUGINS, lib->ns)))
{
sd_notifyf(0, "STATUS=charon initialization failed");
- return SS_RC_INITIALIZATION_FAILED;
+ goto error;
}
lib->plugins->status(lib->plugins, LEVEL_CTRL);
if (!lib->caps->drop(lib->caps))
{
sd_notifyf(0, "STATUS=dropping capabilities failed");
- return SS_RC_INITIALIZATION_FAILED;
+ goto error;
}
- /* add handler for SEGV and ILL,
- * INT, TERM and HUP are handled by sigwait() in run() */
- action.sa_handler = segv_handler;
+ /* add handler for fatal signals,
+ * INT, TERM and HUP are handled by sigwaitinfo() in run() */
action.sa_flags = 0;
sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask, SIGINT);
sigaddset(&action.sa_mask, SIGTERM);
sigaddset(&action.sa_mask, SIGHUP);
+
+ /* optionally let the external system handle fatal signals */
+#ifndef DISABLE_SIGNAL_HANDLER
+ action.sa_handler = segv_handler;
sigaction(SIGSEGV, &action, NULL);
sigaction(SIGILL, &action, NULL);
sigaction(SIGBUS, &action, NULL);
+#endif /* DISABLE_SIGNAL_HANDLER */
+
action.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &action, NULL);
sd_notifyf(0, "STATUS=charon-systemd running, strongSwan %s, %s %s, %s",
VERSION, utsname.sysname, utsname.release, utsname.machine);
- return run();
+ status = run();
+
+error:
+ libcharon_deinit();
+ return status;
}