Commit aff4f24a authored by ale's avatar ale
Browse files

Implement docroot checks

parent 8d347923
......@@ -7,13 +7,13 @@
#define _GNU_SOURCE 1
#include "config.h"
#include "sandbox.h"
#include "log.h"
#include "sandbox.h"
#include "strlist.h"
#include <ctype.h>
#include <fcntl.h>
#include <grp.h> /* for setgroups() */
#include <grp.h> /* for setgroups() */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -51,7 +51,8 @@ static int s2i(char *s, int *i) {
}
static int config_add_allowed_cmd(struct config *config, char *value) {
return strlist_append(&(config->allowed_cmds), &(config->num_allowed_cmds), value);
return strlist_append(&(config->allowed_cmds), &(config->num_allowed_cmds),
value);
}
static int config_add_docroot(struct config *config, char *value) {
......@@ -65,6 +66,13 @@ static int config_add_docroot(struct config *config, char *value) {
return -1;
}
// Strip trailing slashes.
{
int n = strlen(value);
while (n > 1 && value[n - 1] == '/')
value[n--] = '\0';
}
// Extend the docroots array.
return strlist_append(&(config->docroots), &(config->num_docroots), value);
}
......@@ -191,7 +199,8 @@ extern char **environ;
static char **saved_env;
static void save_env() {
/* Wipe the environment as soon as possible, to prevent libc function side effects. */
/* Wipe the environment as soon as possible, to prevent libc function side
* effects. */
static char *empty_ptr = NULL;
saved_env = environ;
environ = &empty_ptr;
......@@ -280,23 +289,45 @@ static int check_cmd(struct config *config, char *cmd) {
return 0;
}
static int check_cwd(struct config *config) {
struct stat dir_info;
int i, allowed = 1;
char cwd[PATH_MAX];
if (!getcwd(cwd, sizeof(cwd))) {
log_println_errno("getcwd failed");
return -1;
}
if ((lstat(cwd, &dir_info) != 0) || (!S_ISDIR(dir_info.st_mode))) {
log_printf("cannot stat cwd (%s)", cwd);
return -1;
}
if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) {
log_printf("directory is writable by others (%s)", cwd);
return -1;
}
if (config->num_docroots > 0) {
allowed = 0;
for (i = 0; i < config->num_docroots; i++) {
// Docroot must either match identically cwd, or cwd must have
// (docroot + /) as a prefix.
int n = strlen(config->docroots[i]);
if (!strcmp(cwd, config->docroots[i]) ||
(!strncmp(cwd, config->docroots[i], n) && cwd[n] == '/')) {
allowed = 1;
break;
}
}
}
if (!allowed) {
log_printf("docroot not allowed (%s)", cwd);
return -1;
}
/* static int change_user(int uid, int gid) { */
/* gid_t groups[1] = {gid}; */
/* if (setgid(gid) < 0) { */
/* log_printf_errno("setgid failed (%d)", gid); */
/* return -1; */
/* } */
/* if (setgroups(1, groups) < 0) { */
/* log_printf_errno("setgroups failed (%d)", gid); */
/* return -1; */
/* } */
/* if (setuid(uid) < 0) { */
/* log_printf_errno("setuid failed (%d)", uid); */
/* return -1; */
/* } */
/* return 0; */
/* } */
return 0;
}
int main(int argc, char **argv) {
int target_uid;
......@@ -308,7 +339,7 @@ int main(int argc, char **argv) {
struct sandbox_config sandbox_config;
save_env();
// Parse command-line arguments.
if (argc == 2 && !strcmp(argv[1], "-V")) {
fprintf(stderr, "%s (send bugs to <%s>)\n", PACKAGE_STRING,
......@@ -349,7 +380,7 @@ int main(int argc, char **argv) {
// Read configuration file.
if (read_config(SUEXEC_CONFIGURATION, &config) < 0)
exit(102);
// Clean the environment.
if (clear_env(&config) < 0)
exit(110);
......@@ -364,25 +395,28 @@ int main(int argc, char **argv) {
exit(104);
}
if (check_cwd(&config) < 0)
exit(105);
if (check_cmd(&config, real_cmd) < 0)
exit(105);
// Invoke the sandbox.
if (sandbox_config_init(&sandbox_config, target_uid, target_gid,
argc - 4, real_cmd, (argv + 3)) < 0)
if (sandbox_config_init(&sandbox_config, target_uid, target_gid, argc - 4,
real_cmd, (argv + 3)) < 0)
exit(106);
//sandbox_config.mount_dir = "/home/ale";
// sandbox_config.mount_dir = "/home/ale";
if (sandbox_start(&sandbox_config) < 0)
exit(107);
// Switch user.
//if (change_user(target_uid, target_gid) < 0)
// if (change_user(target_uid, target_gid) < 0)
// exit(105);
// Execute the command (with arguments), in our clean environment.
//execv(real_cmd, (argv + 3));
// execv(real_cmd, (argv + 3));
exit(110);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment