kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit 8478d8df548310e1883f7da7ceb59830eb9698dd
parent 3b30920a60f0e420738269287c21fd9a24df8530
Author: Joris Vink <joris@coders.se>
Date:   Sat,  4 May 2013 22:18:27 +0200

add chroot and runas directives so we can chroot and drop privilegs properly

Diffstat:
Makefile | 2+-
example.conf | 4+++-
includes/kore.h | 2++
src/config.c | 34++++++++++++++++++++++++++++++++++
src/kore.c | 21+++++++++++++++++++++
5 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile @@ -10,7 +10,7 @@ S_OBJS= $(S_SRC:.c=.o) CFLAGS+=-I/usr/local/ssl/include CFLAGS+=-Wall -Wstrict-prototypes -Wmissing-prototypes CFLAGS+=-Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual -CFLAGS+=-Wsign-compare -Iincludes -g +CFLAGS+=-D_GNU_SOURCE=1 -Wsign-compare -Iincludes -g LDFLAGS=-rdynamic -Llibs -lssl -lcrypto -ldl -lz light: $(S_OBJS) diff --git a/example.conf b/example.conf @@ -1,7 +1,9 @@ # Example Kore configuration # Server configuration. -bind 10.211.55.3 443 +bind 10.211.55.3 443 +chroot /tmp +runas joris # Load our site module now (containing all the goodies). load example/example.module diff --git a/includes/kore.h b/includes/kore.h @@ -115,6 +115,8 @@ struct buf_vec { extern int server_port; extern char *server_ip; +extern char *chroot_path; +extern char *runas_user; void *kore_malloc(size_t); void *kore_calloc(size_t, size_t); diff --git a/src/config.c b/src/config.c @@ -42,6 +42,8 @@ static int configure_bind(char **); static int configure_load(char **); static int configure_handler(char **); static int configure_domain(char **); +static int configure_chroot(char **); +static int configure_runas(char **); static struct { const char *name; @@ -52,6 +54,8 @@ static struct { { "static", configure_handler }, { "dynamic", configure_handler }, { "domain", configure_domain }, + { "chroot", configure_chroot }, + { "runas", configure_runas }, { NULL, NULL }, }; @@ -175,3 +179,33 @@ configure_handler(char **argv) return (KORE_RESULT_OK); } + +static int +configure_chroot(char **argv) +{ + if (chroot_path != NULL) { + kore_log("duplicate chroot path specified"); + return (KORE_RESULT_ERROR); + } + + if (argv[1] == NULL) + return (KORE_RESULT_ERROR); + + chroot_path = kore_strdup(argv[1]); + return (KORE_RESULT_OK); +} + +static int +configure_runas(char **argv) +{ + if (runas_user != NULL) { + kore_log("duplicate runas user specified"); + return (KORE_RESULT_ERROR); + } + + if (argv[1] == NULL) + return (KORE_RESULT_ERROR); + + runas_user = kore_strdup(argv[1]); + return (KORE_RESULT_OK); +} diff --git a/src/kore.c b/src/kore.c @@ -26,7 +26,9 @@ #include <openssl/err.h> #include <openssl/ssl.h> +#include <pwd.h> #include <errno.h> +#include <grp.h> #include <fcntl.h> #include <signal.h> #include <stdio.h> @@ -36,6 +38,7 @@ #include <time.h> #include <regex.h> #include <zlib.h> +#include <unistd.h> #include "spdy.h" #include "kore.h" @@ -51,6 +54,8 @@ static TAILQ_HEAD(, connection) disconnected; int server_port = 0; char *server_ip = NULL; +char *chroot_path = NULL; +char *runas_user = NULL; static void kore_signal(int); static int kore_socket_nonblock(int); @@ -65,6 +70,7 @@ static int kore_ssl_npn_cb(SSL *, const u_char **, unsigned int *, void *); int main(int argc, char *argv[]) { + struct passwd *pw; struct listener server; struct epoll_event *events; int n, i, *fd; @@ -79,6 +85,13 @@ main(int argc, char *argv[]) if (server_ip == NULL || server_port == 0) fatal("missing a correct bind directive in configuration"); + if (chroot_path == NULL) + fatal("missing a chroot path"); + if (runas_user == NULL) + fatal("missing a username to run as"); + if ((pw = getpwnam(runas_user)) == NULL) + fatal("user '%s' does not exist"); + if (!kore_server_bind(&server, server_ip, server_port)) fatal("cannot bind to %s:%d", server_ip, server_port); if (!kore_server_sslstart()) @@ -87,6 +100,14 @@ main(int argc, char *argv[]) if ((efd = epoll_create(1000)) == -1) fatal("epoll_create(): %s", errno_s); + if (chroot(chroot_path) == -1) + fatal("chroot(%s): %s", chroot_path, errno_s); + if (chdir("/") == -1) + fatal("chdir(/): %s", errno_s); + if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, + pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) + fatal("unable to drop privileges"); + http_init(); TAILQ_INIT(&disconnected);