From b31f9c7b862ce6393341735efbb97f72648f1b8a Mon Sep 17 00:00:00 2001 From: Thomas Ries Date: Tue, 17 Sep 2002 16:54:03 +0000 Subject: [PATCH] Release 0.2.0 --- ChangeLog | 9 ++++-- RELNOTES | 50 ++++++++++++++++++++++++++++---- TODO | 1 + config.h.in | 24 ++++++++++++++++ configure.in | 8 ++++-- doc/siproxd.conf.example | 9 +++++- src/readconf.c | 5 ++-- src/register.c | 1 - src/siproxd.c | 26 ++++++++++++++++- src/siproxd.h | 3 ++ src/utils.c | 61 ++++++++++++++++++++++++++++++++++++++++ 11 files changed, 181 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9c17145..bc9410f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ -0.1.4 +0.2.0 ===== -- +- 17-Sep-2002: - Released version 0.2.0 +- 15-Sep-2002: - added functionality to change user ID (drop privs) + after startup (configurable) + - added optional chroot jail (configurable) 0.1.3 ===== @@ -22,7 +25,7 @@ 0.1.2 ===== -- 7-Sep-2002: - Releases version 0.1.2 +- 7-Sep-2002: - Released version 0.1.2 - fixed registration concept (SIP Contact header is not a *must* to be present in every frame) - Experimental RTP proxying feature (using pthreads) diff --git a/RELNOTES b/RELNOTES index 663ac64..e69440c 100644 --- a/RELNOTES +++ b/RELNOTES @@ -1,12 +1,52 @@ -Release Notes for siproxd-0.1.4 +Release Notes for siproxd-0.2.1 =============================== - - - +TO BE ADAPTED!! + - SIP Proxy for SIP based softphones hidden behind a masquerading firewall + - Includes an RTP data stream proxy for incomming audio data + - Supports running in a chroot jail (configurable) + - Supports changing user ID after startup (if started as root) + - All configuration done via config file + +Requirements: + - pthreads + - libosip 0.8.8 + + - currently tested on Linux 2.2.x (Redhat 6.0) and 2.4.x (Redhat 7.2) + however, should run on any other ----- -md5sum for siproxd-0.1.4.tar.gz: +md5sum for siproxd-0.2.1.tar.gz: -GnuPG signature for siproxd-0.1.4.tar.gz archive: +GnuPG signature for siproxd-0.2.1.tar.gz archive: + + + +Release Notes for siproxd-0.2.0 +=============================== + - SIP Proxy for SIP based softphones hidden behind a masquerading firewall + - Includes an RTP data stream proxy for incomming audio data + - Supports running in a chroot jail (configurable) + - Supports changing user ID after startup (if started as root) + - All configuration done via config file + +Requirements: + - pthreads + - libosip 0.8.8 + + - currently tested on Linux 2.2.x (Redhat 6.0) and 2.4.x (Redhat 7.2) + however, should run on any other + +----- +md5sum for siproxd-0.2.0.tar.gz: fe22245be675015a296e9b19327c4941 + +GnuPG signature for siproxd-0.2.0.tar.gz archive: +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.0.5 (GNU/Linux) + +iEYEABECAAYFAj2HXe0ACgkQPOYHDi42pIo/FACg2AiHoo6BMy93PDmW/3uFl19+ +0NoAoIpD7jROQlLtUYrB8n8elBODR1dA +=8fno +-----END PGP SIGNATURE----- diff --git a/TODO b/TODO index 75db1b9..a6397b6 100644 --- a/TODO +++ b/TODO @@ -17,3 +17,4 @@ TODOs, in random order: - portability to other platforms / operating systems first goal: other Unixes + diff --git a/config.h.in b/config.h.in index abb632d..7698c62 100644 --- a/config.h.in +++ b/config.h.in @@ -24,15 +24,30 @@ /* Define if you have the bind function. */ #undef HAVE_BIND +/* Define if you have the chroot function. */ +#undef HAVE_CHROOT + +/* Define if you have the daemon function. */ +#undef HAVE_DAEMON + /* Define if you have the fgets function. */ #undef HAVE_FGETS +/* Define if you have the getgid function. */ +#undef HAVE_GETGID + /* Define if you have the gethostbyname function. */ #undef HAVE_GETHOSTBYNAME /* Define if you have the getopt_long_only function. */ #undef HAVE_GETOPT_LONG_ONLY +/* Define if you have the getpwnam function. */ +#undef HAVE_GETPWNAM + +/* Define if you have the getuid function. */ +#undef HAVE_GETUID + /* Define if you have the read function. */ #undef HAVE_READ @@ -45,6 +60,12 @@ /* Define if you have the sendto function. */ #undef HAVE_SENDTO +/* Define if you have the setgid function. */ +#undef HAVE_SETGID + +/* Define if you have the setuid function. */ +#undef HAVE_SETUID + /* Define if you have the socket function. */ #undef HAVE_SOCKET @@ -72,6 +93,9 @@ /* Define if you have the header file. */ #undef HAVE_ERRNO_H +/* Define if you have the header file. */ +#undef HAVE_PWD_H + /* Define if you have the header file. */ #undef HAVE_STDARG_H diff --git a/configure.in b/configure.in index 01a774b..62ec6a6 100644 --- a/configure.in +++ b/configure.in @@ -14,8 +14,8 @@ AC_INIT(src/siproxd.c) dnl ****************************************************************** dnl SPD_MAJOR_VERSION=0 -SPD_MINOR_VERSION=1 -SPD_MICRO_VERSION=4 +SPD_MINOR_VERSION=2 +SPD_MICRO_VERSION=0 SPD_VERSION=$SPD_MAJOR_VERSION.$SPD_MINOR_VERSION.$SPD_MICRO_VERSION dnl ********************************************************************* @@ -38,6 +38,7 @@ dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(sys/time.h unistd.h errno.h) AC_CHECK_HEADERS(stdarg.h varargs.h) +AC_CHECK_HEADERS(pwd.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -50,8 +51,9 @@ AC_FUNC_MEMCMP AC_FUNC_VPRINTF AC_CHECK_FUNCS(strerror) AC_CHECK_FUNCS(gethostbyname) +AC_CHECK_FUNCS(getopt_long_only daemon) +AC_CHECK_FUNCS(getuid setuid getgid setgid getpwnam chroot) AC_CHECK_FUNCS(socket bind select read send sendto) -AC_CHECK_FUNCS(getopt_long_only) AC_CHECK_FUNCS(strncpy strchr strstr sprintf vfprintf fgets sscanf) diff --git a/doc/siproxd.conf.example b/doc/siproxd.conf.example index bd214ee..d197e55 100644 --- a/doc/siproxd.conf.example +++ b/doc/siproxd.conf.example @@ -31,6 +31,13 @@ sip_listen_port = 5060 # daemonize = 0 +###################################################################### +# Secure Enviroment settings: +# user: uid/gid to switch to after startup +# chrootjail: path to chroot to (chroot jail) +user = nobody +#chrootjail = /var/lib/siproxd/ + ###################################################################### # global switch to enable (1) or disable (0) the RTP proxy feature # @@ -62,5 +69,5 @@ rtp_timeout = 60 # DBCLASS_CONFIG 0x00000100 // configuration # DBCLASS_RTP 0x00000200 // RTP proxy # -debug_level = 0x00000218 +debug_level = 0x00000318 diff --git a/src/readconf.c b/src/readconf.c index 259a225..a23fcd8 100644 --- a/src/readconf.c +++ b/src/readconf.c @@ -21,6 +21,7 @@ #include "config.h" #include +#include #include #include #include @@ -33,8 +34,6 @@ static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\ BUILDSTR " $"; -extern int errno; - /* configuration storage */ extern struct siproxd_config configuration; @@ -121,6 +120,8 @@ static int parse_config (FILE *configfile) { { "rtp_port_high", TYP_INT4, &configuration.rtp_port_high }, { "rtp_timeout", TYP_INT4, &configuration.rtp_timeout }, { "rtp_proxy_enable", TYP_INT4, &configuration.rtp_proxy_enable }, + { "user", TYP_STRING, &configuration.user }, + { "chrootjail", TYP_STRING, &configuration.chrootjail }, {0, 0, 0} }; diff --git a/src/register.c b/src/register.c index 7b84d66..2e1447f 100644 --- a/src/register.c +++ b/src/register.c @@ -38,7 +38,6 @@ static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\ /* configuration storage */ extern struct siproxd_config configuration; -extern int errno; struct urlmap_s urlmap[URLMAP_SIZE]; /* URL mapping table */ extern int sip_socket; /* sending SIP datagrams */ diff --git a/src/siproxd.c b/src/siproxd.c index e1eb3e1..06c53e8 100644 --- a/src/siproxd.c +++ b/src/siproxd.c @@ -21,6 +21,7 @@ #include "config.h" #include +#include #include #include #include @@ -43,6 +44,18 @@ struct siproxd_config configuration; /* socket used for sending SIP datagrams */ int sip_socket=0; +/* -h help option text */ +static const char str_helpmsg[] = +PACKAGE"-"VERSION"-"BUILDSTR" (c) 2002 Thomas Ries\n" \ +"\nUsage: siproxd [options]\n\n" \ +"options:\n" \ +" --help (-h) help\n" \ +" --debug (-d) set initial debug-pattern\n" \ +" --config (-c) use the specified config file\n"\ +""; + + + int main (int argc, char *argv[]) { int sts; @@ -62,6 +75,7 @@ int main (int argc, char *argv[]) configuration.sip_listen_port=SIP_PORT; configuration.inboundhost=NULL; configuration.outboundhost=NULL; + configuration.user=NULL; log_set_pattern(configuration.debuglevel); @@ -82,7 +96,7 @@ int main (int argc, char *argv[]) switch (ch1) { case 'h': /* help */ DEBUGC(DBCLASS_CONFIG,"option: help"); - + fprintf(stderr,str_helpmsg); exit(0); break; @@ -114,6 +128,9 @@ int main (int argc, char *argv[]) the debug pattern is set after reading the config */ log_set_pattern(configuration.debuglevel); + /* change user and group IDs */ + secure_enviroment(); + /* init the oSIP parser */ parser_init(); @@ -134,9 +151,16 @@ int main (int argc, char *argv[]) /* daemonize if requested to */ if (configuration.daemonize) { DEBUGC(DBCLASS_CONFIG,"daemonizing"); +#if HAVE_DAEMON + if (daemon(1,0) == -1) { + ERROR("unable to daemonize: %s", strerror(errno)); + }; +# else + if (fork()!=0) exit(0); /* close STDIN, STDOUT, STDERR */ close(0);close(1);close(2); +#endif } diff --git a/src/siproxd.h b/src/siproxd.h index 505d7a3..e5a40b7 100644 --- a/src/siproxd.h +++ b/src/siproxd.h @@ -48,6 +48,7 @@ int check_vialoop (sip_t *my_msg); int is_via_local (via_t *via); int get_ip_by_host(char *hostname, struct in_addr *addr); int compare_url(url_t *url1, url_t *url2); +void secure_enviroment (void); /* config.c */ int read_config(char *name, int search); @@ -85,6 +86,8 @@ struct siproxd_config { int rtp_port_high; int rtp_timeout; int rtp_proxy_enable; + char *user; + char *chrootjail; }; diff --git a/src/utils.c b/src/utils.c index 42dbd61..255f22e 100644 --- a/src/utils.c +++ b/src/utils.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -28,6 +29,9 @@ #include #include +#include +#include + #include #include @@ -253,3 +257,60 @@ int compare_url(url_t *url1, url_t *url2) { return sts; } + + +/* + * Secure enviroment: + * If running as root,change UID/GID to user as requested in config + */ +void secure_enviroment (void) { + int sts; + struct passwd *passwd=NULL; + + DEBUGC(DBCLASS_CONFIG,"running w/uid=%i, euid=%i, gid=%i, egid=%i", + getuid(), geteuid(), getgid(), getegid()); + + if ((getuid()==0)|| (geteuid()==0)) { + /* + * preparation - after chrooting there will be NOTHING more around + */ + if (configuration.user) passwd=getpwnam(configuration.user); + + + /* + * change root directory into chroot jail + */ + if (configuration.chrootjail) { + DEBUGC(DBCLASS_CONFIG,"chrooting to %s", + configuration.chrootjail); + sts = chroot(configuration.chrootjail); + if (sts != 0) DEBUGC(DBCLASS_CONFIG,"chroot(%s) failed: %s", + configuration.chrootjail, strerror(errno)); + chdir("/"); + } + + + /* + * change user ID and group ID + */ + if (passwd) { + DEBUGC(DBCLASS_CONFIG,"changing uid/gid to %s", + configuration.user); + sts = setgid(passwd->pw_gid); + DEBUGC(DBCLASS_CONFIG,"changed gid to %i - %s", + passwd->pw_gid, (sts==0)?"Ok":"Failed"); + + sts = setegid(passwd->pw_uid); + DEBUGC(DBCLASS_CONFIG,"changed egid to %i - %s", + passwd->pw_gid, (sts==0)?"Ok":"Failed"); + + sts = setuid(passwd->pw_uid); + DEBUGC(DBCLASS_CONFIG,"changed uid to %i - %s", + passwd->pw_uid, (sts==0)?"Ok":"Failed"); + + sts = seteuid(passwd->pw_uid); + DEBUGC(DBCLASS_CONFIG,"changed euid to %i - %s", + passwd->pw_uid, (sts==0)?"Ok":"Failed"); + } + } +}