diff options
-rw-r--r-- | configure.in | 26 | ||||
-rwxr-xr-x | scripts/cfg-leak | 2 | ||||
-rw-r--r-- | src/charon/Makefile.am | 5 | ||||
-rw-r--r-- | src/charon/daemon.c | 55 | ||||
-rw-r--r-- | src/charon/plugins/eap_gtc/eap_gtc_plugin.c | 3 | ||||
-rw-r--r-- | src/pluto/Makefile.am | 4 | ||||
-rw-r--r-- | src/pluto/plutomain.c | 36 |
7 files changed, 71 insertions, 60 deletions
diff --git a/configure.in b/configure.in index 289e627ef..c3dd7280f 100644 --- a/configure.in +++ b/configure.in @@ -138,6 +138,14 @@ AC_ARG_WITH( [AC_SUBST(ipsecgroup, "root")] ) +dnl Will be extended to --with-capabilities=libcap|libcap2 +AC_ARG_WITH( + [capabilities], + AS_HELP_STRING([--with-capabilities=libcap],[capability dropping using libcap. Currenlty only the value "libcap" is supported (default is NO).]), + [capabilities="$withval"], + [capabilities=no] +) + AC_ARG_ENABLE( [curl], AS_HELP_STRING([--enable-curl],[enable CURL fetcher plugin to fetch files via libcurl (default is NO). Requires libcurl.]), @@ -628,15 +636,6 @@ AC_HAVE_LIBRARY(dl) AC_CHECK_FUNCS(backtrace) AC_CHECK_FUNCS(dladdr) -AC_MSG_CHECKING([capset() definition]) -AC_TRY_COMPILE( - [#include <linux/capset.h>], - [ - void *test = capset; - ], - [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]); AC_DEFINE_UNQUOTED(NO_CAPSET_DEFINED, 1)] -) - if test x$gmp = xtrue; then AC_HAVE_LIBRARY([gmp],[LIBS="$LIBS"],[AC_MSG_ERROR([GNU Multi Precision library gmp not found])]) AC_MSG_CHECKING([gmp.h version >= 4.1.4]) @@ -732,6 +731,11 @@ if test x$eap_gtc = xtrue; then AC_CHECK_HEADER([security/pam_appl.h],,[AC_MSG_ERROR([PAM header security/pam_appl.h not found!])]) fi +if test x$capabilities = xlibcap; then + AC_HAVE_LIBRARY([cap],[LIBS="$LIBS"],[AC_MSG_ERROR([libcap library not found])]) + AC_CHECK_HEADER([sys/capability.h],,[AC_MSG_ERROR([libcap header sys/capability.h not found!])]) +fi + dnl ====================================== dnl collect all plugins for libstrongswan dnl ====================================== @@ -850,6 +854,7 @@ AM_CONDITIONAL(USE_MANAGER, test x$manager = xtrue) AM_CONDITIONAL(USE_ME, test x$me = xtrue) AM_CONDITIONAL(USE_INTEGRITY_TEST, test x$integrity_test = xtrue) AM_CONDITIONAL(USE_SELF_TEST, test x$self_test = xtrue) +AM_CONDITIONAL(USE_CAPABILITIES, test x$capabilities = xlibcap) AM_CONDITIONAL(USE_PLUTO, test x$pluto = xtrue) AM_CONDITIONAL(USE_CHARON, test x$charon = xtrue) AM_CONDITIONAL(USE_TOOLS, test x$tools = xtrue) @@ -864,6 +869,9 @@ dnl ============================== if test x$me = xtrue; then AC_DEFINE(ME) fi +if test x$capabilities = xlibcap; then + AC_DEFINE(CAPABILITIES) +fi dnl ============================== dnl build Makefiles diff --git a/scripts/cfg-leak b/scripts/cfg-leak index 4ec425e30..8ccf1d6b2 100755 --- a/scripts/cfg-leak +++ b/scripts/cfg-leak @@ -1,4 +1,4 @@ #!/bin/bash CFLAGS="-Wall -Wno-format -Wno-pointer-sign -Wno-strict-aliasing -g -O2" ./configure \ ---sysconfdir=/etc --disable-tools --disable-pluto --enable-leak-detective --enable-dumm \ +--sysconfdir=/etc --disable-tools --disable-pluto --enable-leak-detective --enable-dumm --with-capabilities=libcap \ $1 $2 $3 $4 $5 diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am index 82f521fc6..c7fb7ffbd 100644 --- a/src/charon/Makefile.am +++ b/src/charon/Makefile.am @@ -129,6 +129,11 @@ if USE_SELF_TEST AM_CFLAGS += -DSELF_TEST endif +if USE_CAPABILITIES + charon_LDADD += -lcap +endif + + # build optional plugins ######################## diff --git a/src/charon/daemon.c b/src/charon/daemon.c index 3d2ad77e8..127a15862 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,16 +47,6 @@ #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 */ - -/* missing on older kernel headers */ -#ifndef CAP_AUDIT_WRITE -#define CAP_AUDIT_WRITE 29 -#endif /* CAP_AUDIT_WRITE */ - #ifdef INTEGRITY_TEST #include <fips/fips.h> #include <fips/fips_signature.h> @@ -80,11 +72,13 @@ struct private_daemon_t { * The thread_id of main-thread. */ pthread_t main_thread_id; - + +#ifdef CAPABILITIES /** * capabilities to keep */ - u_int32_t keep; + cap_t caps; +#endif /* CAPABILITIES */ }; /** @@ -193,6 +187,9 @@ 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); @@ -253,10 +250,7 @@ static void kill_daemon(private_daemon_t *this, char *reason) * drop daemon capabilities */ static void drop_capabilities(private_daemon_t *this) -{ - struct __user_cap_header_struct hdr; - struct __user_cap_data_struct data; - +{ prctl(PR_SET_KEEPCAPS, 1); if (setgid(charon->gid) != 0) @@ -267,21 +261,13 @@ static void drop_capabilities(private_daemon_t *this) { 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 = this->keep; - if (capset(&hdr, &data)) +#ifdef CAPABILITIES + if (cap_set_proc(this->caps) != 0) { kill_daemon(this, "unable to drop daemon capabilities"); } +#endif /* CAPABILITIES */ } /** @@ -289,7 +275,11 @@ static void drop_capabilities(private_daemon_t *this) */ static void keep_cap(private_daemon_t *this, u_int cap) { - this->keep |= 1 << 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 */ } /** @@ -498,11 +488,14 @@ private_daemon_t *daemon_create(void) this->public.gid = 0; this->main_thread_id = pthread_self(); - this->keep = 1<<CAP_NET_ADMIN; +#ifdef CAPABILITIES + this->caps = cap_init(); + keep_cap(this, CAP_NET_ADMIN); if (lib->leak_detective) { - this->keep = 1<<CAP_SYS_NICE; + keep_cap(this, CAP_SYS_NICE); } +#endif /* CAPABILITIES */ /* add handler for SEGV and ILL, * add handler for USR1 (cancellation). diff --git a/src/charon/plugins/eap_gtc/eap_gtc_plugin.c b/src/charon/plugins/eap_gtc/eap_gtc_plugin.c index 0407edc97..cea88ef9f 100644 --- a/src/charon/plugins/eap_gtc/eap_gtc_plugin.c +++ b/src/charon/plugins/eap_gtc/eap_gtc_plugin.c @@ -21,7 +21,8 @@ #include <daemon.h> -#include <linux/capability.h> +/* missing in cababilities.h */ +#define CAP_AUDIT_WRITE 29 /** * Implementation of plugin_t.destroy diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am index 156b81018..c28fbf6e0 100644 --- a/src/pluto/Makefile.am +++ b/src/pluto/Makefile.am @@ -139,3 +139,7 @@ if USE_SMARTCARD AM_CFLAGS += -DSMARTCARD endif +if USE_CAPABILITIES + pluto_LDADD += -lcap +endif + diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c index f1b31637a..b7bb8df98 100644 --- a/src/pluto/plutomain.c +++ b/src/pluto/plutomain.c @@ -29,11 +29,14 @@ #include <resolv.h> #include <arpa/nameser.h> /* missing from <resolv.h> on old systems */ #include <sys/queue.h> -#include <linux/capability.h> #include <sys/prctl.h> #include <pwd.h> #include <grp.h> +#ifdef CAPABILITIES +#include <sys/capability.h> +#endif /* CAPABILITIES */ + #include <freeswan.h> #include <pfkeyv2.h> @@ -68,11 +71,6 @@ #include "nat_traversal.h" #include "virtual.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 */ - static void usage(const char *mess) { @@ -236,8 +234,10 @@ main(int argc, char **argv) bool force_keepalive = FALSE; char *virtual_private = NULL; int lockfd; - struct __user_cap_header_struct hdr; - struct __user_cap_data_struct data; +#ifdef CAPABILITIES + cap_t caps; + int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE }; +#endif /* CAPABILITIES */ /* handle arguments */ for (;;) @@ -619,14 +619,6 @@ main(int argc, char **argv) init_fetch(); /* drop unneeded capabilities and change UID/GID */ -#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 = - 1<<CAP_NET_ADMIN | 1<<CAP_NET_BIND_SERVICE; prctl(PR_SET_KEEPCAPS, 1); @@ -656,11 +648,19 @@ main(int argc, char **argv) } } #endif - if (capset(&hdr, &data)) + +#ifdef CAPABILITIES + caps = cap_init(); + cap_set_flag(caps, CAP_EFFECTIVE, 2, keep, CAP_SET); + cap_set_flag(caps, CAP_INHERITABLE, 2, keep, CAP_SET); + cap_set_flag(caps, CAP_PERMITTED, 2, keep, CAP_SET); + if (cap_set_proc(caps) != 0) { - plog("unable to drop root privileges"); + plog("unable to drop daemon capabilities"); abort(); } + cap_free(caps); +#endif /* CAPABILITIES */ /* loading X.509 CA certificates */ load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA); |