aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk.in2
-rw-r--r--configure.in18
-rw-r--r--src/libcharon/daemon.c39
-rw-r--r--src/pluto/plutomain.c46
4 files changed, 83 insertions, 22 deletions
diff --git a/Android.mk.in b/Android.mk.in
index 6277861ed..a5cc7df12 100644
--- a/Android.mk.in
+++ b/Android.mk.in
@@ -42,6 +42,8 @@ strongswan_CFLAGS := \
-DHAVE_STRUCT_SADB_X_POLICY_SADB_X_POLICY_PRIORITY \
-DHAVE_IPSEC_MODE_BEET \
-DHAVE_IPSEC_DIR_FWD \
+ -DCAPABILITIES \
+ -DCAPABILITIES_NATIVE \
-DMONOLITHIC \
-DUSE_VSTR \
-DROUTING_TABLE=0 \
diff --git a/configure.in b/configure.in
index 7589c30b3..280465032 100644
--- a/configure.in
+++ b/configure.in
@@ -40,7 +40,7 @@ ARG_WITH_SUBST([linux-headers], [\${top_srcdir}/src/include], [set director
ARG_WITH_SUBST([routing-table], [220], [set routing table to use for IPsec routes])
ARG_WITH_SUBST([routing-table-prio], [220], [set priority for IPsec routing table])
-ARG_WITH_SET([capabilities], [no], [set capability dropping library. Currently only the value "libcap" is supported])
+ARG_WITH_SET([capabilities], [no], [set capability dropping library. Currently supported values are "libcap" and "native"])
ARG_WITH_SET([mpz_powm_sec], [yes], [use the more side-channel resistant mpz_powm_sec in libgmp, if available])
AC_ARG_WITH(
@@ -613,9 +613,21 @@ 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 = xnative; then
+ AC_MSG_NOTICE([Usage of the native Linux capabilities interface is deprecated, use libcap instead])
+ dnl Linux requires the following for capset(), Android does not have it,
+ dnl but defines capset() in unistd.h instead.
+ AC_CHECK_HEADERS([sys/capability.h])
+ AC_CHECK_FUNC(capset,,[AC_MSG_ERROR([capset() not found!])])
+ AC_DEFINE(CAPABILITIES_NATIVE)
+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!])])
+ AC_CHECK_HEADER([sys/capability.h],
+ [AC_DEFINE(HAVE_SYS_CAPABILITY_H)],
+ [AC_MSG_ERROR([libcap header sys/capability.h not found!])])
+ AC_DEFINE(CAPABILITIES_LIBCAP)
fi
if test x$integrity_test = xtrue; then
@@ -879,7 +891,7 @@ dnl ==============================
if test x$mediation = xtrue; then
AC_DEFINE(ME)
fi
-if test x$capabilities = xlibcap; then
+if test x$capabilities = xlibcap -o x$capabilities = xnative; then
AC_DEFINE(CAPABILITIES)
fi
if test x$monolithic = xtrue; then
diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c
index aed0029e5..a8e5f19b1 100644
--- a/src/libcharon/daemon.c
+++ b/src/libcharon/daemon.c
@@ -22,8 +22,11 @@
#include <syslog.h>
#include <time.h>
#include <errno.h>
+
#ifdef CAPABILITIES
+#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
+#endif /* HAVE_SYS_CAPABILITY_H */
#endif /* CAPABILITIES */
#include "daemon.h"
@@ -46,12 +49,16 @@ struct private_daemon_t {
*/
daemon_t public;
-#ifdef CAPABILITIES
/**
* capabilities to keep
*/
+#ifdef CAPABILITIES_LIBCAP
cap_t caps;
-#endif /* CAPABILITIES */
+#endif /* CAPABILITIES_LIBCAP */
+#ifdef CAPABILITIES_NATIVE
+ struct __user_cap_data_struct caps;
+#endif /* CAPABILITIES_NATIVE */
+
};
/**
@@ -99,9 +106,9 @@ static void destroy(private_daemon_t *this)
DESTROY_IF(this->public.receiver);
/* unload plugins to release threads */
lib->plugins->unload(lib->plugins);
-#ifdef CAPABILITIES
+#ifdef CAPABILITIES_LIBCAP
cap_free(this->caps);
-#endif /* CAPABILITIES */
+#endif /* CAPABILITIES_LIBCAP */
DESTROY_IF(this->public.traps);
DESTROY_IF(this->public.ike_sa_manager);
DESTROY_IF(this->public.kernel_interface);
@@ -133,22 +140,36 @@ static void destroy(private_daemon_t *this)
METHOD(daemon_t, keep_cap, void,
private_daemon_t *this, u_int cap)
{
-#ifdef CAPABILITIES
+#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);
cap_set_flag(this->caps, CAP_PERMITTED, 1, &cap, CAP_SET);
-#endif /* CAPABILITIES */
+#endif /* CAPABILITIES_LIBCAP */
+#ifdef CAPABILITIES_NATIVE
+ this->caps.effective |= 1 << cap;
+ this->caps.permitted |= 1 << cap;
+ this->caps.inheritable |= 1 << cap;
+#endif /* CAPABILITIES_NATIVE */
}
METHOD(daemon_t, drop_capabilities, bool,
private_daemon_t *this)
{
-#ifdef CAPABILITIES
+#ifdef CAPABILITIES_LIBCAP
if (cap_set_proc(this->caps) != 0)
{
return FALSE;
}
-#endif /* CAPABILITIES */
+#endif /* CAPABILITIES_LIBCAP */
+#ifdef CAPABILITIES_NATIVE
+ struct __user_cap_header_struct header = {
+ .version = _LINUX_CAPABILITY_VERSION,
+ };
+ if (capset(&header, &this->caps) != 0)
+ {
+ return FALSE;
+ }
+#endif /* CAPABILITIES_NATIVE */
return TRUE;
}
@@ -397,7 +418,9 @@ private_daemon_t *daemon_create()
);
#ifdef CAPABILITIES
+#ifdef CAPABILITIES_LIBCAP
this->caps = cap_init();
+#endif /* CAPABILITIES_LIBCAP */
keep_cap(this, CAP_NET_ADMIN);
if (lib->leak_detective)
{
diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c
index 2e27b00f8..89123bb8a 100644
--- a/src/pluto/plutomain.c
+++ b/src/pluto/plutomain.c
@@ -33,7 +33,9 @@
#include <grp.h>
#ifdef CAPABILITIES
+#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
+#endif /* HAVE_SYS_CAPABILITY_H */
#endif /* CAPABILITIES */
#include <freeswan.h>
@@ -258,7 +260,6 @@ int main(int argc, char **argv)
char *virtual_private = NULL;
int lockfd;
#ifdef CAPABILITIES
- cap_t caps;
int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
#endif /* CAPABILITIES */
@@ -716,18 +717,41 @@ int main(int argc, char **argv)
}
#endif
-#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)
+#ifdef CAPABILITIES_LIBCAP
{
- plog("unable to drop daemon capabilities");
- abort();
+ cap_t caps;
+ caps = cap_init();
+ cap_set_flag(caps, CAP_EFFECTIVE, countof(keep), keep, CAP_SET);
+ cap_set_flag(caps, CAP_INHERITABLE, countof(keep), keep, CAP_SET);
+ cap_set_flag(caps, CAP_PERMITTED, countof(keep), keep, CAP_SET);
+ if (cap_set_proc(caps) != 0)
+ {
+ plog("unable to drop daemon capabilities");
+ abort();
+ }
+ cap_free(caps);
}
- cap_free(caps);
-#endif /* CAPABILITIES */
+#endif /* CAPABILITIES_LIBCAP */
+#ifdef CAPABILITIES_NATIVE
+ {
+ struct __user_cap_data_struct caps = { .effective = 0 };
+ struct __user_cap_header_struct header = {
+ .version = _LINUX_CAPABILITY_VERSION,
+ };
+ int i;
+ for (i = 0; i < countof(keep); i++)
+ {
+ caps.effective |= 1 << keep[i];
+ caps.permitted |= 1 << keep[i];
+ caps.inheritable |= 1 << keep[i];
+ }
+ if (capset(&header, &caps) != 0)
+ {
+ plog("unable to drop daemon capabilities");
+ abort();
+ }
+ }
+#endif /* CAPABILITIES_NATIVE */
/* loading X.509 CA certificates */
load_authcerts("ca", CA_CERT_PATH, X509_CA);