use libcap for capability dropping

optional, must be enabled --with-capabilities=libcap
	will be extended to support --with-capabilities=libcap2
This commit is contained in:
Martin Willi
2008-08-29 09:24:14 +00:00
parent 8fa6f2dc66
commit eb3e27059b
7 changed files with 71 additions and 60 deletions
+5
View File
@@ -129,6 +129,11 @@ if USE_SELF_TEST
AM_CFLAGS += -DSELF_TEST
endif
if USE_CAPABILITIES
charon_LDADD += -lcap
endif
# build optional plugins
########################
+24 -31
View File
@@ -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).
+2 -1
View File
@@ -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
+4
View File
@@ -139,3 +139,7 @@ if USE_SMARTCARD
AM_CFLAGS += -DSMARTCARD
endif
if USE_CAPABILITIES
pluto_LDADD += -lcap
endif
+18 -18
View File
@@ -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);