diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 21ede53..0858045 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(SOURCES "daemon.c" "strlcpy.c" "config.c" "log.c" "matches.c" "ipaddr.c" "source.c" "filter.c" "backend.c" "jail.c") +set(SOURCES "daemon.c" "strlcpy.c" "config.c" "log.c" "matches.c" "ipaddr.c" + "appconfig.c" "source.c" "filter.c" "backend.c" "jail.c") if (WITH_CSOCKET) list(APPEND SOURCES "commands.c" "csocket.c" "cmsg.c") diff --git a/src/daemon.c b/src/daemon.c index 2bd1dcb..d8b9b0a 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -9,36 +9,13 @@ #include "config.h" #include "jail.h" #include "backend.h" +#include "appconfig.h" #include "commands.h" #include "cmsg.h" #include "csocket.h" #include #include -#include -#include - -/** global variables */ -struct { - bool daemon; - uid_t uid; - gid_t gid; - int csock; - char logdest[CONFIG_KEY_MAX]; - char config_path[PATH_MAX]; - char logfile_path[PATH_MAX]; - char csocket_path[PATH_MAX]; - char pidfile_path[PATH_MAX]; -} opts = { - false, - 0, 0, - -1, - "file", - "/etc/f2b/f2b.conf", - "/var/log/f2b.log", - DEFAULT_CSOCKET_PATH, - DEFAULT_PIDFILE_PATH, -}; enum { stop = 0, run, reconfig, logrotate, test } state = run; @@ -124,7 +101,7 @@ f2b_cmsg_process(const f2b_cmsg_t *msg, char *res, size_t ressize) { state = stop; } else if (msg->type == CMD_STATUS) { snprintf(line, sizeof(line), "pid: %u\npidfile: %s\ncsocket: %s\njails:\n", - getpid(), opts.pidfile_path, opts.csocket_path); + getpid(), appconfig.pidfile_path, appconfig.csocket_path); strlcpy(res, line, ressize); for (jail = jails; jail != NULL; jail = jail->next) { snprintf(line, sizeof(line), "- %s\n", jail->name); @@ -152,62 +129,6 @@ f2b_cmsg_process(const f2b_cmsg_t *msg, char *res, size_t ressize) { } #endif /* WITH_CSOCKET */ -void -update_opts_from_config(f2b_config_section_t *section) { - f2b_config_param_t *pa, *pb; - - if (!section) - return; - - /* set uid & gid. note: set only once if root */ - if (opts.uid == 0 && (pa = f2b_config_param_find(section->param, "user")) != NULL) { - struct passwd *pw; - if ((pw = getpwnam(pa->value)) != NULL) - opts.uid = pw->pw_uid, opts.gid = pw->pw_gid; - } - if (opts.gid == 0 && (pa = f2b_config_param_find(section->param, "group")) != NULL) { - struct group *grp; - if ((grp = getgrnam(pa->value)) != NULL) - opts.gid = grp->gr_gid; - } - - if (opts.daemon == false && (pa = f2b_config_param_find(section->param, "daemon")) != NULL) { - if (strcmp(pa->value, "yes") == 0) - opts.daemon = true; - } - - if ((pa = f2b_config_param_find(section->param, "pidfile")) != NULL) - strlcpy(opts.pidfile_path, pa->value, sizeof(opts.pidfile_path)); - - if ((pa = f2b_config_param_find(section->param, "csocket")) != NULL) - strlcpy(opts.csocket_path, pa->value, sizeof(opts.csocket_path)); - - /* setup logging */ - if ((pa = f2b_config_param_find(section->param, "loglevel")) != NULL) - f2b_log_set_level(pa->value); - - pa = f2b_config_param_find(section->param, "logdest"); - pb = f2b_config_param_find(section->param, "logfile"); - if (pa) { - strlcpy(opts.logdest, pa->value, sizeof(opts.logdest)); - if (!opts.daemon && strcmp(pa->value, "stderr") == 0) { - f2b_log_to_stderr(); - } else if (strcmp(pa->value, "file") == 0) { - if (pb && *pb->value != '\0') { - strlcpy(opts.logfile_path, pb->value, sizeof(opts.logfile_path)); - f2b_log_to_file(opts.logfile_path); - } else { - f2b_log_msg(log_warn, "you must set 'logfile' option with 'logdest = file'"); - f2b_log_to_syslog(); - } - } else { - f2b_log_to_syslog(); - } - } - - /* TODO: */ -} - void jails_start(f2b_config_t *config) { f2b_jail_t *jail = NULL; @@ -255,10 +176,10 @@ int main(int argc, char *argv[]) { while ((opt = getopt(argc, argv, "c:dht")) != -1) { switch (opt) { case 'c': - strlcpy(opts.config_path, optarg, sizeof(opts.config_path)); + strlcpy(appconfig.config_path, optarg, sizeof(appconfig.config_path)); break; case 'd': - opts.daemon = true; + appconfig.daemon = true; break; case 'h': usage(EXIT_SUCCESS); @@ -277,20 +198,20 @@ int main(int argc, char *argv[]) { SA_REGISTER(SIGHUP, &signal_handler); SA_REGISTER(SIGUSR1, &signal_handler); - if (opts.config_path[0] == '\0') + if (appconfig.config_path[0] == '\0') usage(EXIT_FAILURE); memset(&config, 0x0, sizeof(config)); - if (f2b_config_load(&config, opts.config_path, true) != true) { - f2b_log_msg(log_error, "can't load config from '%s'", opts.config_path); + if (f2b_config_load(&config, appconfig.config_path, true) != true) { + f2b_log_msg(log_error, "can't load config from '%s'", appconfig.config_path); return EXIT_FAILURE; } if (state == test) { fprintf(stderr, "config test ok\n"); exit(EXIT_SUCCESS); } - update_opts_from_config(config.main); + f2b_appconfig_update(config.main); - if (opts.daemon) { + if (appconfig.daemon) { pid_t pid = fork(); if (pid > 0) exit(EXIT_SUCCESS); @@ -303,8 +224,8 @@ int main(int argc, char *argv[]) { /* child */ setsid(); if (getuid() == 0 && - (setuid(opts.uid) != 0 || - setgid(opts.gid) != 0)) { + (setuid(appconfig.uid) != 0 || + setgid(appconfig.gid) != 0)) { perror("child: setuid()/setgid() failed"); exit(EXIT_FAILURE); } @@ -317,9 +238,9 @@ int main(int argc, char *argv[]) { } } - if (opts.pidfile_path[0] != '\0') { + if (appconfig.pidfile_path[0] != '\0') { FILE *pidfile = NULL; - if ((pidfile = fopen(opts.pidfile_path, "w")) != NULL) { + if ((pidfile = fopen(appconfig.pidfile_path, "w")) != NULL) { if (flock(fileno(pidfile), LOCK_EX | LOCK_NB) != 0) { const char *err = (errno == EWOULDBLOCK) ? "another instance already running" @@ -334,8 +255,8 @@ int main(int argc, char *argv[]) { } } - if (opts.csocket_path[0] != '\0') - opts.csock = f2b_csocket_create(opts.csocket_path); + if (appconfig.csocket_path[0] != '\0') + appconfig.csock = f2b_csocket_create(appconfig.csocket_path); if (config.defaults) f2b_jail_set_defaults(config.defaults); @@ -352,29 +273,29 @@ int main(int argc, char *argv[]) { for (f2b_jail_t *jail = jails; jail != NULL; jail = jail->next) { f2b_jail_process(jail); } - f2b_csocket_poll(opts.csock, f2b_cmsg_process); + f2b_csocket_poll(appconfig.csock, f2b_cmsg_process); sleep(1); - if (state == logrotate && strcmp(opts.logdest, "file") == 0) { + if (state == logrotate && strcmp(appconfig.logdest, "file") == 0) { state = run; - f2b_log_to_file(opts.logfile_path); + f2b_log_to_file(appconfig.logfile_path); } if (state == reconfig) { state = run; memset(&config, 0x0, sizeof(config)); - if (f2b_config_load(&config, opts.config_path, true)) { + if (f2b_config_load(&config, appconfig.config_path, true)) { jails_stop(jails); jails = NULL; if (config.defaults) f2b_jail_set_defaults(config.defaults); jails_start(&config); } else { - f2b_log_msg(log_error, "can't load config from '%s'", opts.config_path); + f2b_log_msg(log_error, "can't load config from '%s'", appconfig.config_path); } f2b_config_free(&config); } } - f2b_csocket_destroy(opts.csock, opts.csocket_path); + f2b_csocket_destroy(appconfig.csock, appconfig.csocket_path); jails_stop(jails); jails = NULL;