summaryrefslogtreecommitdiff
path: root/src/charon/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/daemon.c')
-rw-r--r--src/charon/daemon.c136
1 files changed, 68 insertions, 68 deletions
diff --git a/src/charon/daemon.c b/src/charon/daemon.c
index 1ab88104a..065f7d701 100644
--- a/src/charon/daemon.c
+++ b/src/charon/daemon.c
@@ -22,7 +22,6 @@
#endif /* HAVE_DLADDR */
#include <stdio.h>
-#include <linux/capability.h>
#include <sys/prctl.h>
#include <signal.h>
#include <pthread.h>
@@ -38,6 +37,9 @@
#ifdef HAVE_BACKTRACE
# include <execinfo.h>
#endif /* HAVE_BACKTRACE */
+#ifdef CAPABILITIES
+#include <sys/capability.h>
+#endif /* CAPABILITIES */
#include "daemon.h"
@@ -45,14 +47,9 @@
#include <config/traffic_selector.h>
#include <config/proposal.h>
-/* on some distros, a capset definition is missing */
-#ifdef NO_CAPSET_DEFINED
-extern int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
-#endif /* NO_CAPSET_DEFINED */
-
#ifdef INTEGRITY_TEST
#include <fips/fips.h>
-#include <fips_signature.h>
+#include <fips/fips_signature.h>
#endif /* INTEGRITY_TEST */
typedef struct private_daemon_t private_daemon_t;
@@ -75,6 +72,13 @@ struct private_daemon_t {
* The thread_id of main-thread.
*/
pthread_t main_thread_id;
+
+#ifdef CAPABILITIES
+ /**
+ * capabilities to keep
+ */
+ cap_t caps;
+#endif /* CAPABILITIES */
};
/**
@@ -95,7 +99,7 @@ static void dbg_bus(int level, char *fmt, ...)
va_list args;
va_start(args, fmt);
- charon->bus->vsignal(charon->bus, DBG_LIB, level, fmt, args);
+ charon->bus->vsignal(charon->bus, DBG_LIB, level, NULL, fmt, args);
va_end(args);
}
@@ -183,11 +187,15 @@ static void destroy(private_daemon_t *this)
}
/* unload plugins to release threads */
lib->plugins->unload(lib->plugins);
+#ifdef CAPABILITIES
+ cap_free(this->caps);
+#endif /* CAPABILITIES */
DESTROY_IF(this->public.ike_sa_manager);
DESTROY_IF(this->public.kernel_interface);
DESTROY_IF(this->public.scheduler);
DESTROY_IF(this->public.controller);
DESTROY_IF(this->public.eap);
+ DESTROY_IF(this->public.sim);
#ifdef ME
DESTROY_IF(this->public.connect_manager);
DESTROY_IF(this->public.mediation_manager);
@@ -242,55 +250,37 @@ static void kill_daemon(private_daemon_t *this, char *reason)
/**
* drop daemon capabilities
*/
-static void drop_capabilities(private_daemon_t *this, bool full)
-{
- struct __user_cap_header_struct hdr;
- struct __user_cap_data_struct data;
-
- /* CAP_NET_ADMIN is needed to use netlink */
- u_int32_t keep = (1<<CAP_NET_ADMIN) | (1<<CAP_SYS_NICE);
-
- if (full)
+static void drop_capabilities(private_daemon_t *this)
+{
+ prctl(PR_SET_KEEPCAPS, 1);
+
+ if (setgid(charon->gid) != 0)
{
- if (setgid(charon->gid) != 0)
- {
- kill_daemon(this, "change to unprivileged group failed");
- }
- if (setuid(charon->uid) != 0)
- {
- kill_daemon(this, "change to unprivileged user failed");
- }
+ kill_daemon(this, "change to unprivileged group failed");
}
- else
+ if (setuid(charon->uid) != 0)
{
- /* CAP_NET_BIND_SERVICE to bind services below port 1024 */
- keep |= (1<<CAP_NET_BIND_SERVICE);
- /* CAP_NET_RAW to create RAW sockets */
- keep |= (1<<CAP_NET_RAW);
- /* CAP_DAC_READ_SEARCH to read ipsec.secrets */
- keep |= (1<<CAP_DAC_READ_SEARCH);
- /* CAP_CHOWN to change file permissions (socket permissions) */
- keep |= (1<<CAP_CHOWN);
- /* CAP_SETUID to call setuid() */
- keep |= (1<<CAP_SETUID);
- /* CAP_SETGID to call setgid() */
- keep |= (1<<CAP_SETGID);
+ kill_daemon(this, "change to unprivileged user failed");
}
-
- /* we use the old capset version for now. For systems with version 2
- * available, we specifiy version 1 excplicitly. */
-#ifdef _LINUX_CAPABILITY_VERSION_1
- hdr.version = _LINUX_CAPABILITY_VERSION_1;
-#else
- hdr.version = _LINUX_CAPABILITY_VERSION;
-#endif
- hdr.pid = 0;
- data.inheritable = data.effective = data.permitted = keep;
- if (capset(&hdr, &data))
+#ifdef CAPABILITIES
+ if (cap_set_proc(this->caps) != 0)
{
kill_daemon(this, "unable to drop daemon capabilities");
}
+#endif /* CAPABILITIES */
+}
+
+/**
+ * Implementation of daemon_t.keep_cap
+ */
+static void keep_cap(private_daemon_t *this, u_int cap)
+{
+#ifdef CAPABILITIES
+ cap_set_flag(this->caps, CAP_EFFECTIVE, 1, &cap, CAP_SET);
+ cap_set_flag(this->caps, CAP_INHERITABLE, 1, &cap, CAP_SET);
+ cap_set_flag(this->caps, CAP_PERMITTED, 1, &cap, CAP_SET);
+#endif /* CAPABILITIES */
}
/**
@@ -362,25 +352,13 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
DBG1(DBG_DMN, "starting charon (strongSwan Version %s)", VERSION);
-#ifdef INTEGRITY_TEST
- DBG1(DBG_DMN, "integrity test of libstrongswan code");
- if (fips_verify_hmac_signature(hmac_key, hmac_signature))
- {
- DBG1(DBG_DMN, " integrity test passed");
- }
- else
- {
- DBG1(DBG_DMN, " integrity test failed");
- return FALSE;
- }
-#endif /* INTEGRITY_TEST */
-
/* load secrets, ca certificates and crls */
this->public.processor = processor_create();
this->public.scheduler = scheduler_create();
this->public.credentials = credential_manager_create();
this->public.controller = controller_create();
this->public.eap = eap_manager_create();
+ this->public.sim = sim_manager_create();
this->public.backends = backend_manager_create();
this->public.attributes = attribute_manager_create();
this->public.kernel_interface = kernel_interface_create();
@@ -390,6 +368,22 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
lib->settings->get_str(lib->settings, "charon.load", PLUGINS));
+ /* create the kernel interfaces */
+ this->public.kernel_interface->create_interfaces(this->public.kernel_interface);
+
+#ifdef INTEGRITY_TEST
+ DBG1(DBG_DMN, "integrity test of libstrongswan code");
+ if (fips_verify_hmac_signature(hmac_key, hmac_signature))
+ {
+ DBG1(DBG_DMN, " integrity test passed");
+ }
+ else
+ {
+ DBG1(DBG_DMN, " integrity test failed");
+ return FALSE;
+ }
+#endif /* INTEGRITY_TEST */
+
this->public.ike_sa_manager = ike_sa_manager_create();
if (this->public.ike_sa_manager == NULL)
{
@@ -472,6 +466,7 @@ private_daemon_t *daemon_create(void)
/* assign methods */
this->public.kill = (void (*) (daemon_t*,char*))kill_daemon;
+ this->public.keep_cap = (void(*)(daemon_t*, u_int cap))keep_cap;
/* NULL members for clean destruction */
this->public.socket = NULL;
@@ -486,6 +481,7 @@ private_daemon_t *daemon_create(void)
this->public.processor = NULL;
this->public.controller = NULL;
this->public.eap = NULL;
+ this->public.sim = NULL;
this->public.bus = NULL;
this->public.outlog = NULL;
this->public.syslog = NULL;
@@ -498,6 +494,14 @@ private_daemon_t *daemon_create(void)
this->public.gid = 0;
this->main_thread_id = pthread_self();
+#ifdef CAPABILITIES
+ this->caps = cap_init();
+ keep_cap(this, CAP_NET_ADMIN);
+ if (lib->leak_detective)
+ {
+ keep_cap(this, CAP_SYS_NICE);
+ }
+#endif /* CAPABILITIES */
/* add handler for SEGV and ILL,
* add handler for USR1 (cancellation).
@@ -567,10 +571,6 @@ int main(int argc, char *argv[])
lookup_uid_gid(private_charon);
- /* drop the capabilities we won't need for initialization */
- prctl(PR_SET_KEEPCAPS, 1);
- drop_capabilities(private_charon, FALSE);
-
/* use CTRL loglevel for default */
for (signal = 0; signal < DBG_MAX; signal++)
{
@@ -646,8 +646,8 @@ int main(int argc, char *argv[])
fclose(pid_file);
}
- /* drop additional capabilites (bind & root) */
- drop_capabilities(private_charon, TRUE);
+ /* drop the capabilities we won't need */
+ drop_capabilities(private_charon);
/* start the engine, go multithreaded */
charon->processor->set_threads(charon->processor,