From 7287dcd5cbd97d5d8c801949c07ef19c12c8bad8 Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Thu, 21 Apr 2016 16:19:16 +1000 Subject: [PATCH] * rename file: main.c -> daemon.c --- src/{main.c => daemon.c} | 144 +++++++++++++++++++++++++++++++++++---- 1 file changed, 131 insertions(+), 13 deletions(-) rename src/{main.c => daemon.c} (60%) diff --git a/src/main.c b/src/daemon.c similarity index 60% rename from src/main.c rename to src/daemon.c index 59c6767..8ce8047 100644 --- a/src/main.c +++ b/src/daemon.c @@ -10,28 +10,36 @@ #include "config.h" #include "jail.h" #include "backend.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 config_path[PATH_MAX]; char logfile_path[PATH_MAX]; + char csocket_path[PATH_MAX]; char pidfile_path[PATH_MAX]; } opts = { false, 0, 0, + -1, "/etc/f2b/f2b.conf", "/var/log/f2b.log", - "", + DEFAULT_CSOCKET_PATH, + DEFAULT_PIDFILE_PATH, }; enum { stop = 0, run, reconfig, test } state = run; +f2b_jail_t *jails = NULL; void signal_handler(int signum) { switch (signum) { @@ -49,19 +57,123 @@ void signal_handler(int signum) { } } -#define SA_REGISTER(SIGNUM, HANDLER) \ - memset(&act, 0x0, sizeof(act)); \ - act.sa_handler = HANDLER; \ - if (sigaction(SIGNUM, &act, NULL) != 0) { \ - f2b_log_msg(log_error, "can't register handler for " #SIGNUM); \ - return EXIT_FAILURE; \ - } - void usage(int exitcode) { fprintf(stderr, "Usage: f2b [-c ] [-d] [-h]\n"); exit(exitcode); } +#ifndef WITH_CSOCKET +/* add stubs to reduce #ifdef count */ +int f2b_csocket_create (const char *path) { + UNUSED(path); + f2b_log_msg(log_warn, "control socket support was disabled at compile-time"); + return -1; +} +void f2b_csocket_destroy(int csock, const char *path) { + UNUSED(csock); UNUSED(path); return; +} +int f2b_csocket_poll(int csock, void (*cb)(const f2b_cmsg_t *msg, char *res, size_t ressize)) { + UNUSED(csock); UNUSED(cb); return 0; +} +void +f2b_cmsg_process(const f2b_cmsg_t *msg, char *res, size_t ressize) { + UNUSED(msg); UNUSED(res); UNUSED(ressize); return; +} +#else /* WITH_CSOCKET */ +void +f2b_cmsg_process(const f2b_cmsg_t *msg, char *res, size_t ressize) { + const char *args[DATA_ARGS_MAX]; + const char *fmt; + f2b_jail_t *jail = NULL; + f2b_ipaddr_t *addr = NULL; + char line[LINE_MAX]; + + assert(msg != NULL); + assert(res != NULL); + assert(msg->type < CMD_MAX_NUMBER); + + memset(args, 0x0, sizeof(args)); + f2b_cmsg_extract_args(msg, args); + + if (msg->type >= CMD_JAIL_STATUS || msg->type <= CMD_JAIL_IP_RELEASE) { + if (args[0] == NULL) { + strlcpy(res, "can't find jail: no args\n", ressize); + return; + } + if ((jail = f2b_jail_find(jails, args[0])) == NULL) { + snprintf(res, ressize, "can't find jail '%s'\n", args[0]); + return; + } + } + + if (jail && (msg->type >= CMD_JAIL_IP_SHOW || msg->type <= CMD_JAIL_IP_RELEASE)) { + if (args[1] == NULL) { + strlcpy(res, "can't find ip: no args", ressize); + return; + } + if ((addr = f2b_addrlist_lookup(jail->ipaddrs, args[1])) == NULL) { + snprintf(res, ressize, "can't find ip '%s' in jail '%s'\n", args[1], args[0]); + return; + } + } + + if (msg->type == CMD_PING) { + strlcpy(res, "ok", ressize); + } else if (msg->type == CMD_RELOAD) { + state = reconfig; + strlcpy(res, "ok", ressize); + } else if (msg->type == CMD_SHUTDOWN) { + state = stop; + strlcpy(res, "ok", ressize); + } 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); + strlcpy(res, line, ressize); + for (jail = jails; jail != NULL; jail = jail->next) { + snprintf(line, sizeof(line), "- %s\n", jail->name); + strlcat(res, line, ressize); + } + } else if (msg->type == CMD_JAIL_STATUS) { + fmt = "name: %s\n" + "enabled: %s\n" + "maxretry: %d\n" + "times:\n" + " bantime: %d\n" + " findtime: %d\n" + " expiretime: %d\n" + "incr:\n" + " bantime: %.1f\n" + " findtime: %.1f\n" + "stats:\n" + " banned: %d\n" + " matched: %d\n"; + snprintf(res, ressize, fmt, jail->name, jail->enabled ? "yes" : "no", jail->maxretry, + jail->bantime, jail->findtime, jail->expiretime, + jail->incr_bantime, jail->incr_findtime, + jail->bancount, jail->matchcount); + } else if (msg->type == CMD_JAIL_IP_SHOW) { + fmt = "ipaddr: %s\n" + "banned: %s\n" + "bancount: %d\n" + "lastseen: %d\n" + "banned_at: %d\n" + "release_at: %d\n"; + snprintf(res, ressize, fmt, addr->text, addr->banned ? "yes" : "no", + addr->bancount, addr->lastseen, addr->banned_at, addr->release_at); + } else if (msg->type == CMD_JAIL_IP_BAN) { + f2b_jail_ban(jail, addr); + strlcpy(res, "ok", ressize); + } else if (msg->type == CMD_JAIL_IP_RELEASE) { + f2b_jail_unban(jail, addr); + strlcpy(res, "ok", ressize); + } else { + strlcpy(res, "error: unsupported command type", ressize); + } + + return; +} +#endif /* WITH_CSOCKET */ + void update_opts_from_config(f2b_config_section_t *section) { f2b_config_param_t *pa, *pb; @@ -86,10 +198,11 @@ update_opts_from_config(f2b_config_section_t *section) { opts.daemon = true; } - if ((pa = f2b_config_param_find(section->param, "pidfile")) != NULL) { + if ((pa = f2b_config_param_find(section->param, "pidfile")) != NULL) strlcpy(opts.pidfile_path, pa->value, sizeof(opts.pidfile_path)); - opts.pidfile_path[sizeof(opts.pidfile_path) - 1] = '\0'; - } + + 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) @@ -120,7 +233,6 @@ int main(int argc, char *argv[]) { struct sigaction act; f2b_config_t config; f2b_config_section_t *section = NULL; - f2b_jail_t *jails = NULL; f2b_jail_t *jail = NULL; char opt = '\0'; @@ -204,6 +316,9 @@ int main(int argc, char *argv[]) { } } + if (opts.csocket_path[0] != '\0') + opts.csock = f2b_csocket_create(opts.csocket_path); + if (config.defaults) f2b_jail_set_defaults(config.defaults); @@ -236,6 +351,7 @@ int main(int argc, char *argv[]) { for (jail = jails; jail != NULL; jail = jail->next) { f2b_jail_process(jail); } + f2b_csocket_poll(opts.csock, f2b_cmsg_process); sleep(1); if (state == reconfig) { /* TODO */ @@ -243,6 +359,8 @@ int main(int argc, char *argv[]) { } } + f2b_csocket_destroy(opts.csock, opts.csocket_path); + for (jail = jails; jail != NULL; jail = jail->next) f2b_jail_stop(jail);