aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/charon-nm/nm/nm_backend.c7
-rw-r--r--src/libcharon/daemon.c8
-rw-r--r--src/libcharon/plugins/xauth_pam/xauth_pam_plugin.c10
-rw-r--r--src/libstrongswan/utils/capabilities.c53
-rw-r--r--src/libstrongswan/utils/capabilities.h9
5 files changed, 77 insertions, 10 deletions
diff --git a/src/charon-nm/nm/nm_backend.c b/src/charon-nm/nm/nm_backend.c
index c18bf992a..e07919827 100644
--- a/src/charon-nm/nm/nm_backend.c
+++ b/src/charon-nm/nm/nm_backend.c
@@ -142,7 +142,12 @@ static bool nm_backend_init()
}
/* bypass file permissions to read from users ssh-agent */
- charon->caps->keep(charon->caps, CAP_DAC_OVERRIDE);
+ if (!charon->caps->keep(charon->caps, CAP_DAC_OVERRIDE))
+ {
+ DBG1(DBG_CFG, "NM backend requires CAP_DAC_OVERRIDE capability");
+ nm_backend_deinit();
+ return FALSE;
+ }
lib->processor->queue_job(lib->processor,
(job_t*)callback_job_create_with_prio((callback_job_cb_t)run, this,
diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c
index 70262b736..e375ab731 100644
--- a/src/libcharon/daemon.c
+++ b/src/libcharon/daemon.c
@@ -591,8 +591,6 @@ private_daemon_t *daemon_create(const char *name)
this->public.shunts = shunt_manager_create();
this->kernel_handler = kernel_handler_create();
- this->public.caps->keep(this->public.caps, CAP_NET_ADMIN);
-
return this;
}
@@ -628,6 +626,12 @@ bool libcharon_init(const char *name)
this = daemon_create(name);
+ if (!this->public.caps->keep(this->public.caps, CAP_NET_ADMIN))
+ {
+ dbg(DBG_DMN, 1, "libcharon requires CAP_NET_ADMIN capability");
+ return FALSE;
+ }
+
/* for uncritical pseudo random numbers */
srandom(time(NULL) + getpid());
diff --git a/src/libcharon/plugins/xauth_pam/xauth_pam_plugin.c b/src/libcharon/plugins/xauth_pam/xauth_pam_plugin.c
index b9ba0b5ac..522cc2426 100644
--- a/src/libcharon/plugins/xauth_pam/xauth_pam_plugin.c
+++ b/src/libcharon/plugins/xauth_pam/xauth_pam_plugin.c
@@ -52,6 +52,13 @@ plugin_t *xauth_pam_plugin_create()
{
xauth_pam_plugin_t *this;
+ /* required for PAM authentication */
+ if (!charon->caps->keep(charon->caps, CAP_AUDIT_WRITE))
+ {
+ DBG1(DBG_DMN, "xauth-pam plugin requires CAP_AUDIT_WRITE capability");
+ return NULL;
+ }
+
INIT(this,
.plugin = {
.get_name = _get_name,
@@ -60,8 +67,5 @@ plugin_t *xauth_pam_plugin_create()
},
);
- /* required for PAM authentication */
- charon->caps->keep(charon->caps, CAP_AUDIT_WRITE);
-
return &this->plugin;
}
diff --git a/src/libstrongswan/utils/capabilities.c b/src/libstrongswan/utils/capabilities.c
index 89f47820e..059271713 100644
--- a/src/libstrongswan/utils/capabilities.c
+++ b/src/libstrongswan/utils/capabilities.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2013 Tobias Brunner
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2012 Martin Willi
* Copyright (C) 2012 revosec AG
@@ -76,9 +76,57 @@ struct private_capabilities_t {
#endif
};
-METHOD(capabilities_t, keep, void,
+static bool has_capability(u_int cap)
+{
+#ifndef CAPABILITIES
+ /* if we can't check the actual capabilities assume only root has it */
+ return getuid() == 0;
+#endif /* !CAPABILITIES */
+#ifdef CAPABILITIES_LIBCAP
+ cap_flag_value_t val;
+ cap_t caps;
+ bool ok;
+
+ caps = cap_get_proc();
+ if (!caps)
+ {
+ return FALSE;
+ }
+ ok = cap_get_flag(caps, cap, CAP_PERMITTED, &val) == 0 && val == CAP_SET;
+ cap_free(caps);
+ return ok;
+#endif /* CAPABILITIES_LIBCAP */
+#ifdef CAPABILITIES_NATIVE
+ struct __user_cap_header_struct header = {
+#if defined(_LINUX_CAPABILITY_VERSION_3)
+ .version = _LINUX_CAPABILITY_VERSION_3,
+#elif defined(_LINUX_CAPABILITY_VERSION_2)
+ .version = _LINUX_CAPABILITY_VERSION_2,
+#elif defined(_LINUX_CAPABILITY_VERSION_1)
+ .version = _LINUX_CAPABILITY_VERSION_1,
+#else
+ .version = _LINUX_CAPABILITY_VERSION,
+#endif
+ };
+ struct __user_cap_data_struct caps[2];
+ int i = 0;
+
+ if (cap >= 32)
+ {
+ i++;
+ cap -= 32;
+ }
+ return capget(&header, caps) == 0 && caps[i].permitted & (1 << cap);
+#endif /* CAPABILITIES_NATIVE */
+}
+
+METHOD(capabilities_t, keep, bool,
private_capabilities_t *this, u_int cap)
{
+ if (!has_capability(cap))
+ {
+ return FALSE;
+ }
#ifdef CAPABILITIES_LIBCAP
cap_set_flag(this->caps, CAP_EFFECTIVE, 1, &cap, CAP_SET);
cap_set_flag(this->caps, CAP_INHERITABLE, 1, &cap, CAP_SET);
@@ -96,6 +144,7 @@ METHOD(capabilities_t, keep, void,
this->caps[i].permitted |= 1 << cap;
this->caps[i].inheritable |= 1 << cap;
#endif /* CAPABILITIES_NATIVE */
+ return TRUE;
}
METHOD(capabilities_t, get_uid, uid_t,
diff --git a/src/libstrongswan/utils/capabilities.h b/src/libstrongswan/utils/capabilities.h
index cd23cbf10..3de11bc6c 100644
--- a/src/libstrongswan/utils/capabilities.h
+++ b/src/libstrongswan/utils/capabilities.h
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2013 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2012 Martin Willi
* Copyright (C) 2012 revosec AG
*
@@ -36,11 +38,14 @@ typedef struct capabilities_t capabilities_t;
struct capabilities_t {
/**
- * Register a capability to keep while calling drop().
+ * Register a capability to keep while calling drop(). Verifies that the
+ * capability is currently held.
*
* @param cap capability to keep
+ * @return FALSE if the capability is currently not held
*/
- void (*keep)(capabilities_t *this, u_int cap);
+ bool (*keep)(capabilities_t *this,
+ u_int cap) __attribute__((warn_unused_result));
/**
* Get the user ID set through set_uid/resolve_uid.