diff options
-rw-r--r-- | src/charon/daemon.c | 64 | ||||
-rw-r--r-- | src/charon/daemon.h | 9 | ||||
-rw-r--r-- | src/charon/plugins/eap_gtc/eap_gtc_plugin.c | 5 | ||||
-rw-r--r-- | src/libstrongswan/library.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/library.h | 5 | ||||
-rw-r--r-- | src/libstrongswan/utils/leak_detective.c | 1 |
6 files changed, 51 insertions, 35 deletions
diff --git a/src/charon/daemon.c b/src/charon/daemon.c index 9e0b16aaa..3d2ad77e8 100644 --- a/src/charon/daemon.c +++ b/src/charon/daemon.c @@ -80,6 +80,11 @@ struct private_daemon_t { * The thread_id of main-thread. */ pthread_t main_thread_id; + + /** + * capabilities to keep + */ + u_int32_t keep; }; /** @@ -247,41 +252,20 @@ static void kill_daemon(private_daemon_t *this, char *reason) /** * drop daemon capabilities */ -static void drop_capabilities(private_daemon_t *this, bool full) +static void drop_capabilities(private_daemon_t *this) { struct __user_cap_header_struct hdr; struct __user_cap_data_struct data; - /* CAP_NET_ADMIN is needed to use netlink, - * CAP_AUDIT_WRITE for PAM authentication in EAP-GTC */ - u_int32_t keep = (1<<CAP_NET_ADMIN) | (1<<CAP_SYS_NICE) | - (1<<CAP_AUDIT_WRITE); - - if (full) + prctl(PR_SET_KEEPCAPS, 1); + + if (setgid(charon->gid) != 0) { - if (setgid(charon->gid) != 0) - { - kill_daemon(this, "change to unprivileged group failed"); - } - if (setuid(charon->uid) != 0) - { - kill_daemon(this, "change to unprivileged user failed"); - } + kill_daemon(this, "change to unprivileged group failed"); } - else + if (setuid(charon->uid) != 0) { - /* CAP_NET_BIND_SERVICE to bind services below port 1024 */ - keep |= (1<<CAP_NET_BIND_SERVICE); - /* CAP_NET_RAW to create RAW sockets */ - keep |= (1<<CAP_NET_RAW); - /* CAP_DAC_READ_SEARCH to read ipsec.secrets */ - keep |= (1<<CAP_DAC_READ_SEARCH); - /* CAP_CHOWN to change file permissions (socket permissions) */ - keep |= (1<<CAP_CHOWN); - /* CAP_SETUID to call setuid() */ - keep |= (1<<CAP_SETUID); - /* CAP_SETGID to call setgid() */ - keep |= (1<<CAP_SETGID); + kill_daemon(this, "change to unprivileged user failed"); } /* we use the old capset version for now. For systems with version 2 @@ -292,7 +276,7 @@ static void drop_capabilities(private_daemon_t *this, bool full) hdr.version = _LINUX_CAPABILITY_VERSION; #endif hdr.pid = 0; - data.inheritable = data.effective = data.permitted = keep; + data.inheritable = data.effective = data.permitted = this->keep; if (capset(&hdr, &data)) { @@ -301,6 +285,14 @@ static void drop_capabilities(private_daemon_t *this, bool full) } /** + * Implementation of daemon_t.keep_cap + */ +static void keep_cap(private_daemon_t *this, u_int cap) +{ + this->keep |= 1 << cap; +} + +/** * lookup UID and GID */ static void lookup_uid_gid(private_daemon_t *this) @@ -479,6 +471,7 @@ private_daemon_t *daemon_create(void) /* assign methods */ this->public.kill = (void (*) (daemon_t*,char*))kill_daemon; + this->public.keep_cap = (void(*)(daemon_t*, u_int cap))keep_cap; /* NULL members for clean destruction */ this->public.socket = NULL; @@ -505,6 +498,11 @@ private_daemon_t *daemon_create(void) this->public.gid = 0; this->main_thread_id = pthread_self(); + this->keep = 1<<CAP_NET_ADMIN; + if (lib->leak_detective) + { + this->keep = 1<<CAP_SYS_NICE; + } /* add handler for SEGV and ILL, * add handler for USR1 (cancellation). @@ -574,10 +572,6 @@ int main(int argc, char *argv[]) lookup_uid_gid(private_charon); - /* drop the capabilities we won't need for initialization */ - prctl(PR_SET_KEEPCAPS, 1); - drop_capabilities(private_charon, FALSE); - /* use CTRL loglevel for default */ for (signal = 0; signal < DBG_MAX; signal++) { @@ -653,8 +647,8 @@ int main(int argc, char *argv[]) fclose(pid_file); } - /* drop additional capabilites (bind & root) */ - drop_capabilities(private_charon, TRUE); + /* drop the capabilities we won't need */ + drop_capabilities(private_charon); /* start the engine, go multithreaded */ charon->processor->set_threads(charon->processor, diff --git a/src/charon/daemon.h b/src/charon/daemon.h index 3633e4555..3bde9a25d 100644 --- a/src/charon/daemon.h +++ b/src/charon/daemon.h @@ -303,6 +303,15 @@ struct daemon_t { gid_t gid; /** + * Do not drop a given capability after initialization. + * + * Some plugins might need additional capabilites. They tell the daemon + * during plugin initialization which one they need, the daemon won't + * drop these. + */ + void (*keep_cap)(daemon_t *this, u_int cap); + + /** * Shut down the daemon. * * @param reason describtion why it will be killed diff --git a/src/charon/plugins/eap_gtc/eap_gtc_plugin.c b/src/charon/plugins/eap_gtc/eap_gtc_plugin.c index 58a231058..0407edc97 100644 --- a/src/charon/plugins/eap_gtc/eap_gtc_plugin.c +++ b/src/charon/plugins/eap_gtc/eap_gtc_plugin.c @@ -21,6 +21,8 @@ #include <daemon.h> +#include <linux/capability.h> + /** * Implementation of plugin_t.destroy */ @@ -42,6 +44,9 @@ plugin_t *plugin_create() this->plugin.destroy = (void(*)(plugin_t*))destroy; + /* required for PAM authentication */ + charon->keep_cap(charon, CAP_AUDIT_WRITE); + charon->eap->add_method(charon->eap, EAP_GTC, 0, EAP_SERVER, (eap_constructor_t)eap_gtc_create_server); charon->eap->add_method(charon->eap, EAP_GTC, 0, EAP_PEER, diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c index fe7498f1a..6b9043b1a 100644 --- a/src/libstrongswan/library.c +++ b/src/libstrongswan/library.c @@ -86,6 +86,8 @@ void library_init(char *settings) private_library_t *this = malloc_thing(private_library_t); lib = &this->public; + lib->leak_detective = FALSE; + #ifdef LEAK_DETECTIVE this->detective = leak_detective_create(); #endif /* LEAK_DETECTIVE */ diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h index 9d151c4cc..2ea4b624b 100644 --- a/src/libstrongswan/library.h +++ b/src/libstrongswan/library.h @@ -108,6 +108,11 @@ struct library_t { * various settings loaded from settings file */ settings_t *settings; + + /** + * is leak detective running? + */ + bool leak_detective; }; /** diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index 72da4bd37..70726da3b 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -560,6 +560,7 @@ leak_detective_t *leak_detective_create() if (getenv("LEAK_DETECTIVE_DISABLE") == NULL) { + lib->leak_detective = TRUE; install_hooks(); } return &this->public; |