|
|
@ -7,6 +7,23 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include <getopt.h> |
|
|
|
#include <getopt.h> |
|
|
|
#include <signal.h> |
|
|
|
#include <signal.h> |
|
|
|
|
|
|
|
#include <pwd.h> |
|
|
|
|
|
|
|
#include <grp.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct { |
|
|
|
|
|
|
|
bool daemon; |
|
|
|
|
|
|
|
uid_t uid; |
|
|
|
|
|
|
|
gid_t gid; |
|
|
|
|
|
|
|
char config_path[PATH_MAX]; |
|
|
|
|
|
|
|
char logfile_path[PATH_MAX]; |
|
|
|
|
|
|
|
char pidfile_path[PATH_MAX]; |
|
|
|
|
|
|
|
} opts = { |
|
|
|
|
|
|
|
true, |
|
|
|
|
|
|
|
0, 0, |
|
|
|
|
|
|
|
"/etc/f2b/f2b.conf", |
|
|
|
|
|
|
|
"/var/log/f2b.log", |
|
|
|
|
|
|
|
"/var/run/f2b.pid", |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
bool run = true; |
|
|
|
bool run = true; |
|
|
|
bool rcfg = false; |
|
|
|
bool rcfg = false; |
|
|
@ -31,23 +48,76 @@ void sa_hup(int signum) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void usage(int exitcode) { |
|
|
|
void usage(int exitcode) { |
|
|
|
fprintf(stderr, "Usage: f2b -c <config>\n"); |
|
|
|
fprintf(stderr, "Usage: f2b [-c <config>] [-d] [-h]\n"); |
|
|
|
exit(exitcode); |
|
|
|
exit(exitcode); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 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) { |
|
|
|
|
|
|
|
if (!opts.daemon && strcmp(pa->value, "stderr") == 0) { |
|
|
|
|
|
|
|
f2b_log_to_stderr(); |
|
|
|
|
|
|
|
} else if (strcmp(pa->value, "file") == 0) { |
|
|
|
|
|
|
|
if (pb && *pb->value != '\0') { |
|
|
|
|
|
|
|
size_t len = sizeof(opts.logfile_path); |
|
|
|
|
|
|
|
strncpy(opts.logfile_path, pb->value, len - 1); |
|
|
|
|
|
|
|
opts.logfile_path[len - 1] = '\0'; |
|
|
|
|
|
|
|
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: */ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) { |
|
|
|
int main(int argc, char *argv[]) { |
|
|
|
struct sigaction act; |
|
|
|
struct sigaction act; |
|
|
|
f2b_config_t config; |
|
|
|
f2b_config_t config; |
|
|
|
f2b_config_section_t *section = NULL; |
|
|
|
f2b_config_section_t *section = NULL; |
|
|
|
f2b_jail_t *jails = NULL; |
|
|
|
f2b_jail_t *jails = NULL; |
|
|
|
f2b_jail_t *jail = NULL; |
|
|
|
f2b_jail_t *jail = NULL; |
|
|
|
char *config_file = NULL; |
|
|
|
|
|
|
|
char opt = '\0'; |
|
|
|
char opt = '\0'; |
|
|
|
|
|
|
|
|
|
|
|
while ((opt = getopt(argc, argv, "c:h")) != -1) { |
|
|
|
while ((opt = getopt(argc, argv, "c:dh")) != -1) { |
|
|
|
switch (opt) { |
|
|
|
switch (opt) { |
|
|
|
case 'c': |
|
|
|
case 'c': |
|
|
|
config_file = optarg; |
|
|
|
strncpy(opts.config_path, optarg, sizeof(opts.config_path)); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 'd': |
|
|
|
|
|
|
|
opts.daemon = true; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 'h': |
|
|
|
case 'h': |
|
|
|
usage(EXIT_SUCCESS); |
|
|
|
usage(EXIT_SUCCESS); |
|
|
@ -61,13 +131,41 @@ int main(int argc, char *argv[]) { |
|
|
|
SA_REGISTER(SIGTERM, &sa_term); |
|
|
|
SA_REGISTER(SIGTERM, &sa_term); |
|
|
|
SA_REGISTER(SIGHUP, &sa_hup); |
|
|
|
SA_REGISTER(SIGHUP, &sa_hup); |
|
|
|
|
|
|
|
|
|
|
|
if (!config_file) |
|
|
|
if (opts.config_path[0] == '\0') |
|
|
|
usage(EXIT_FAILURE); |
|
|
|
usage(EXIT_FAILURE); |
|
|
|
memset(&config, 0x0, sizeof(config)); |
|
|
|
memset(&config, 0x0, sizeof(config)); |
|
|
|
if (f2b_config_load(&config, config_file, true) != true) { |
|
|
|
if (f2b_config_load(&config, opts.config_path, true) != true) { |
|
|
|
f2b_log_msg(log_error, "can't load config from '%s'", config_file); |
|
|
|
f2b_log_msg(log_error, "can't load config from '%s'", opts.config_path); |
|
|
|
return EXIT_FAILURE; |
|
|
|
return EXIT_FAILURE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
update_opts_from_config(config.main); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (opts.daemon) { |
|
|
|
|
|
|
|
pid_t pid = fork(); |
|
|
|
|
|
|
|
if (pid > 0) |
|
|
|
|
|
|
|
exit(EXIT_SUCCESS); |
|
|
|
|
|
|
|
/* parent */ |
|
|
|
|
|
|
|
if (pid < 0) { |
|
|
|
|
|
|
|
/* parent */ |
|
|
|
|
|
|
|
perror("child: fork() failed"); |
|
|
|
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/* child */ |
|
|
|
|
|
|
|
setsid(); |
|
|
|
|
|
|
|
if (getuid() == 0 && |
|
|
|
|
|
|
|
(setuid(opts.uid) != 0 || |
|
|
|
|
|
|
|
setgid(opts.gid) != 0)) { |
|
|
|
|
|
|
|
perror("child: setuid()/setgid() failed"); |
|
|
|
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (chdir("/") != 0 || |
|
|
|
|
|
|
|
freopen("/dev/null", "r", stdin) == NULL || |
|
|
|
|
|
|
|
freopen("/dev/null", "w", stdout) == NULL || |
|
|
|
|
|
|
|
freopen("/dev/null", "w", stderr) == NULL) { |
|
|
|
|
|
|
|
perror("child: freopen() failed"); |
|
|
|
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (config.defaults) |
|
|
|
if (config.defaults) |
|
|
|
f2b_jail_set_defaults(config.defaults); |
|
|
|
f2b_jail_set_defaults(config.defaults); |
|
|
|