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:
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);