From d29473ff4432822f8784d3b2142507ce7a2e8b55 Mon Sep 17 00:00:00 2001 From: Jeffrey C. Ollie Date: Thu, 8 Nov 2007 16:42:56 -0600 Subject: [PATCH] Backport patch that lets Asterisk set the TOS byte even when running as non-root. --- CHANGES | 5 +++++ configure.ac | 5 +++++ doc/security.txt | 7 +++++++ main/Makefile | 3 +++ main/asterisk.c | 30 +++++++++++++++++++++++++----- makeopts.in | 3 +++ 6 files changed, 48 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index faa1855..7825d58 100644 --- a/CHANGES +++ b/CHANGES @@ -339,3 +339,8 @@ Changes since Asterisk 1.2: 1. aelparse -- compile .ael files outside of asterisk * New manager events: 1. OriginateResponse event comes to replace OriginateSuccess and OriginateFailure + + * Ability to use libcap to set high ToS bits when non-root on + Linux. If configure is unable to find libcap then you can use + --with-cap to specify the path. + diff --git a/configure.ac b/configure.ac index 26a5735..cd4e87b 100644 --- a/configure.ac +++ b/configure.ac @@ -174,6 +174,7 @@ AC_SUBST(AST_DEVMODE) AST_EXT_LIB_SETUP([ALSA], [Advanced Linux Sound Architecture], [asound]) AST_EXT_LIB_SETUP([CURL], [cURL], [curl]) +AST_EXT_LIB_SETUP([CAP], [POSIX 1.e capabilities], [cap]) AST_EXT_LIB_SETUP([CURSES], [curses], [curses]) AST_EXT_LIB_SETUP([GNUTLS], [GNU TLS support (used for iksemel only)], [gnutls]) AST_EXT_LIB_SETUP([GSM], [GSM], [gsm], [, or 'internal']) @@ -400,6 +401,10 @@ AST_EXT_LIB_CHECK([ALSA], [asound], [snd_spcm_init], [alsa/asoundlib.h], [-lm -l AST_EXT_LIB_CHECK([CURSES], [curses], [initscr], [curses.h]) +if test "x${host_os}" = "xlinux-gnu" ; then + AST_EXT_LIB_CHECK([CAP], [cap], [cap_from_text], [sys/capability.h]) +fi + GSM_INTERNAL="yes" AC_SUBST(GSM_INTERNAL) GSM_SYSTEM="yes" diff --git a/doc/security.txt b/doc/security.txt index 0801679..3adf536 100644 --- a/doc/security.txt +++ b/doc/security.txt @@ -28,6 +28,13 @@ The IAX2 protocol supports strong RSA key authentication as well as AES encryption of voice and signalling. The SIP channel does not support encryption in this version of Asterisk. +By default, if you have libcap available, Asterisk will try to retain the +CAP_NET_ADMIN capability when running as a non-root user. If you do not need +that capability you may want to configure Asterisk with --without-cap; however, +this will prevent Asterisk from being able to mark high ToS bits under Linux. +More information on CAP_NET_ADMIN is available at: +http://www.lids.org/lids-howto/node48.html + * DIALPLAN SECURITY First and foremost remember this: diff --git a/main/Makefile b/main/Makefile index 4f405b5..cee9e13 100644 --- a/main/Makefile +++ b/main/Makefile @@ -55,6 +55,9 @@ ifneq ($(findstring $(OSARCH), linux-gnu uclinux linux-uclibc ),) ifneq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),) AST_LIBS+=-ldl endif + ifneq (x$(CAP_LIB),x) + AST_LIBS+=$(CAP_LIB) + endif AST_LIBS+=-lpthread $(EDITLINE_LIB) -lm -lresolv else AST_LIBS+=$(EDITLINE_LIB) -lm diff --git a/main/asterisk.c b/main/asterisk.c index 202a190..bd8cd9b 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -82,13 +82,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include #ifdef linux #include -#endif +#ifdef HAVE_CAP +#include +#endif /* HAVE_CAP */ +#endif /* linux */ #include -#ifdef linux -#include -#endif - #if defined(__FreeBSD__) || defined( __NetBSD__ ) || defined(SOLARIS) #include #if defined(SOLARIS) @@ -2734,6 +2733,10 @@ int main(int argc, char *argv[]) } if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) { +#ifdef HAVE_CAP + cap_t cap; + int has_cap = 1; +#endif /* HAVE_CAP */ struct passwd *pw; pw = getpwnam(runuser); if (!pw) { @@ -2744,6 +2747,12 @@ int main(int argc, char *argv[]) ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser); exit(1); } +#ifdef HAVE_CAP + if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { + ast_log(LOG_WARNING, "Unable to keep capabilities.\n"); + has_cap = 0; + } +#endif /* HAVE_CAP */ if (!rungroup) { if (setgid(pw->pw_gid)) { ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid); @@ -2760,6 +2769,17 @@ int main(int argc, char *argv[]) } if (option_verbose) ast_verbose("Running as user '%s'\n", runuser); +#ifdef HAVE_CAP + if (has_cap) { + cap = cap_from_text("cap_net_admin=ep"); + if (cap_set_proc(cap)) { + ast_log(LOG_WARNING, "Unable to install capabilities.\n"); + } + if (cap_free(cap)) { + ast_log(LOG_WARNING, "Unable to drop capabilities.\n"); + } + } +#endif /* HAVE_CAP */ } #endif /* __CYGWIN__ */ diff --git a/makeopts.in b/makeopts.in index 8138dd8..a81503c 100644 --- a/makeopts.in +++ b/makeopts.in @@ -189,3 +189,6 @@ TERMCAP_DIR=@TERMCAP_DIR@ TINFO_INCLUDE=@TINFO_INCLUDE@ TINFO_LIB=@TINFO_LIB@ TINFO_DIR=@TINFO_DIR@ + +CAP_LIB=@CAP_LIB@ +CAP_INCLUDE=@CAP_INCLUDE@ -- 1.5.3.7