diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/charon-nm/nm/nm_backend.c | 7 | ||||
-rw-r--r-- | src/libcharon/daemon.c | 8 | ||||
-rw-r--r-- | src/libcharon/plugins/xauth_pam/xauth_pam_plugin.c | 10 | ||||
-rw-r--r-- | src/libstrongswan/utils/capabilities.c | 53 | ||||
-rw-r--r-- | src/libstrongswan/utils/capabilities.h | 9 |
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. |