From ce7defbb13c4c2c3412da251c3d161b4fcfdcd41 Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Thu, 21 Jan 2021 22:25:23 +1000 Subject: [PATCH] * update f2b_jail_t struct --- src/backend-test.c | 9 +++- src/backend.c | 27 +++++++---- src/backend.h | 21 +++++++-- src/filter-test.c | 11 +++-- src/filter.c | 33 +++++++------ src/filter.h | 20 ++++++-- src/jail.c | 113 +++++++++++++++++++++++---------------------- src/jail.h | 31 +++++++------ src/source-test.c | 9 +++- src/source.c | 27 +++++++---- src/source.h | 17 +++++-- 11 files changed, 196 insertions(+), 122 deletions(-) diff --git a/src/backend-test.c b/src/backend-test.c index d2b31ed..38664f1 100644 --- a/src/backend-test.c +++ b/src/backend-test.c @@ -84,8 +84,13 @@ int main(int argc, char *argv[]) { section = config.backends; } - if ((backend = f2b_backend_create(section, argv[2])) == NULL) { - f2b_log_msg(log_fatal, "can't create backend '%s' with id '%s'", section->name, argv[2]); + if ((backend = f2b_backend_create(section->name, argv[2])) == NULL) { + f2b_log_msg(log_fatal, "can't create backend '%s'", section->name); + return EXIT_FAILURE; + } + + if (!f2b_backend_init(backend, section)) { + f2b_log_msg(log_fatal, "can't init backend '%s'", backend->name); return EXIT_FAILURE; } diff --git a/src/backend.c b/src/backend.c index fd96d9a..4b94dcd 100644 --- a/src/backend.c +++ b/src/backend.c @@ -10,9 +10,21 @@ #define BACKEND_LIBRARY_PARAM "load" f2b_backend_t * -f2b_backend_create(f2b_config_section_t *config, const char *id) { - f2b_config_param_t *param = NULL; +f2b_backend_create(const char *name, const char *init) { f2b_backend_t *backend = NULL; + + if ((backend = calloc(1, sizeof(f2b_backend_t))) == NULL) + return NULL; + + strlcpy(backend->name, name, sizeof(backend->name)); + strlcpy(backend->init, init, sizeof(backend->init)); + + return backend; +} + +bool +f2b_backend_init(f2b_backend_t *backend, f2b_config_section_t *config) { + f2b_config_param_t *param = NULL; int flags = RTLD_NOW | RTLD_LOCAL; const char *dlerr = NULL; @@ -22,12 +34,9 @@ f2b_backend_create(f2b_config_section_t *config, const char *id) { param = f2b_config_param_find(config->param, BACKEND_LIBRARY_PARAM); if (!param) { f2b_log_msg(log_error, "can't find '%s' param in backend config", BACKEND_LIBRARY_PARAM); - return NULL; + return false; } - if ((backend = calloc(1, sizeof(f2b_backend_t))) == NULL) - return NULL; - if ((backend->h = dlopen(param->value, flags)) == NULL) goto cleanup; if ((*(void **) (&backend->create) = dlsym(backend->h, "create")) == NULL) @@ -53,7 +62,7 @@ f2b_backend_create(f2b_config_section_t *config, const char *id) { if ((*(void **) (&backend->destroy) = dlsym(backend->h, "destroy")) == NULL) goto cleanup; - if ((backend->cfg = backend->create(id)) == NULL) { + if ((backend->cfg = backend->create(backend->init)) == NULL) { f2b_log_msg(log_error, "backend create config failed"); goto cleanup; } @@ -71,7 +80,7 @@ f2b_backend_create(f2b_config_section_t *config, const char *id) { } if (backend->ready(backend->cfg)) - return backend; + return true; /* still not ready */ f2b_log_msg(log_error, "backend '%s' not fully configured", config->name); @@ -86,7 +95,7 @@ f2b_backend_create(f2b_config_section_t *config, const char *id) { dlclose(backend->h); } free(backend); - return NULL; + return false; } void diff --git a/src/backend.h b/src/backend.h index 7fd6558..c5227ad 100644 --- a/src/backend.h +++ b/src/backend.h @@ -42,15 +42,26 @@ typedef struct f2b_backend_t { bool (*unban) (void *cfg, const char *ip); /** dlsym pointer to handler of @a destroy command */ void (*destroy) (void *cfg); + /* config variables */ + char name[CONFIG_KEY_MAX]; /**< backend name from config (eg [backend:$NAME] section) */ + char init[CONFIG_VAL_MAX]; /**< backend init string (eg `backend = NAME:$INIT_STRING` line from jail section) */ } f2b_backend_t; /** - * @brief Create module from config - * @param config Pointer to section of config - * @param id Backend id - * @returns Pointer to module metadata of NULL on error + * @brief Allocate new backend struct and fill name/init fields + * @param name Module name + * @param init Module init string + * @returns Pointer to allocated module struct or NULL on error */ -f2b_backend_t * f2b_backend_create (f2b_config_section_t *config, const char *id); +f2b_backend_t * f2b_backend_create (const char *name, const char *init); + +/** + * @brief Initialize and configure backend + * @param config Pointer to config section with module description + * @return true on success, false on error + */ +bool f2b_backend_init(f2b_backend_t *backend, f2b_config_section_t *config); + /** * @brief Free module metadata * @param b Pointer to module struct diff --git a/src/filter-test.c b/src/filter-test.c index a2e7518..43460dd 100644 --- a/src/filter-test.c +++ b/src/filter-test.c @@ -41,14 +41,19 @@ int main(int argc, char *argv[]) { section = config.filters; } - if ((filter = f2b_filter_create(section, argv[2])) == false) { - f2b_log_msg(log_fatal, "can't create filter '%s' with file '%s'", section->name, argv[2]); + if ((filter = f2b_filter_create(section->name, argv[2])) == false) { + f2b_log_msg(log_fatal, "can't create filter '%s'", section->name); + return EXIT_FAILURE; + } + + if (!f2b_filter_init(filter, section)) { + f2b_log_msg(log_fatal, "can't configure filter '%s' with file '%s'", filter->name, argv[2]); return EXIT_FAILURE; } if (argc > 3) { if ((file = fopen(argv[3], "r")) == NULL) { - f2b_log_msg(log_fatal, "can't open regexp file '%s': %s", argv[2], strerror(errno)); + f2b_log_msg(log_fatal, "can't open log file '%s': %s", argv[3], strerror(errno)); return EXIT_FAILURE; } } else { diff --git a/src/filter.c b/src/filter.c index 243b513..9768d7f 100644 --- a/src/filter.c +++ b/src/filter.c @@ -70,25 +70,33 @@ f2b_filter_load_file(f2b_filter_t *filter, const char *path) { } f2b_filter_t * -f2b_filter_create(f2b_config_section_t *config, const char *file) { - f2b_config_param_t *param = NULL; +f2b_filter_create(const char *name, const char *init) { f2b_filter_t *filter = NULL; + + if ((filter = calloc(1, sizeof(f2b_filter_t))) == NULL) + return NULL; + + strlcpy(filter->name, name, sizeof(filter->name)); + strlcpy(filter->init, init, sizeof(filter->init)); + + return filter; +} + +bool +f2b_filter_init(f2b_filter_t *filter, f2b_config_section_t *config) { + f2b_config_param_t *param = NULL; int flags = RTLD_NOW | RTLD_LOCAL; const char *dlerr = NULL; - assert(file != NULL); assert(config != NULL); assert(config->type == t_filter); param = f2b_config_param_find(config->param, FILTER_LIBRARY_PARAM); if (!param) { f2b_log_msg(log_error, "can't find '%s' param in filter config", FILTER_LIBRARY_PARAM); - return NULL; + return false; } - if ((filter = calloc(1, sizeof(f2b_filter_t))) == NULL) - return NULL; - if ((filter->h = dlopen(param->value, flags)) == NULL) goto cleanup; if ((*(void **) (&filter->create) = dlsym(filter->h, "create")) == NULL) @@ -110,7 +118,6 @@ f2b_filter_create(f2b_config_section_t *config, const char *file) { if ((*(void **) (&filter->destroy) = dlsym(filter->h, "destroy")) == NULL) goto cleanup; - /* TODO: do we need id? */ if ((filter->cfg = filter->create("")) == NULL) { f2b_log_msg(log_error, "filter create config failed"); goto cleanup; @@ -128,13 +135,11 @@ f2b_filter_create(f2b_config_section_t *config, const char *file) { config->name, param->name, param->value); } - strlcpy(filter->file, file, sizeof(filter->file)); - - if (!f2b_filter_load_file(filter, file)) + if (!f2b_filter_load_file(filter, filter->init)) goto cleanup; if (filter->ready(filter->cfg)) - return filter; + return true; /* still not ready */ f2b_log_msg(log_error, "filter '%s' not fully configured", config->name); @@ -149,7 +154,7 @@ f2b_filter_create(f2b_config_section_t *config, const char *file) { dlclose(filter->h); } free(filter); - return NULL; + return false; } void @@ -191,7 +196,7 @@ f2b_filter_cmd_reload(char *buf, size_t bufsize, f2b_filter_t *filter) { assert(filter != NULL); filter->flush(filter->cfg); - if (f2b_filter_load_file(filter, filter->file)) { + if (f2b_filter_load_file(filter, filter->init)) { snprintf(buf, bufsize, "can't reload filter"); } } diff --git a/src/filter.h b/src/filter.h index 2b2f4cf..9eead58 100644 --- a/src/filter.h +++ b/src/filter.h @@ -19,7 +19,6 @@ typedef struct f2b_filter_t { void *h; /**< dlopen handler */ void *cfg; /**< opaque pointer of module config */ - char file[PATH_MAX]; /**< path to file with patterns */ /* handlers */ /** dlsym pointer to handler of @a create command */ void *(*create) (const char *id); @@ -39,15 +38,26 @@ typedef struct f2b_filter_t { bool (*match) (void *cfg, const char *line, char *buf, size_t buf_size); /** dlsym pointer to handler of @a destroy command */ void (*destroy) (void *cfg); + /* config variables */ + char name[CONFIG_KEY_MAX]; /**< filter name from config (eg [filter:$NAME] section) */ + char init[CONFIG_VAL_MAX]; /**< filter init string (eg `filter = NAME:$INIT_STRING` line from jail section) */ } f2b_filter_t; /** - * @brief Create module from config - * @param config Pointer to config section with module description - * @param id Filter id + * @brief Allocate new filter struct and fill name/init fields + * @param name Module name + * @param init Module init string * @returns Pointer to allocated module struct or NULL on error */ -f2b_filter_t * f2b_filter_create (f2b_config_section_t *config, const char *id); +f2b_filter_t * f2b_filter_create (const char *name, const char *init); + +/** + * @brief Initialize and configure filter + * @param config Pointer to config section with module description + * @return true on success, false on error + */ +bool f2b_filter_init (f2b_filter_t *filter, f2b_config_section_t *config); + /** * @brief Free module metadata * @param f Pointer to module struct diff --git a/src/jail.c b/src/jail.c index 22b5e4b..9d1c98e 100644 --- a/src/jail.c +++ b/src/jail.c @@ -89,12 +89,12 @@ f2b_jail_set_param(f2b_jail_t *jail, const char *param, const char *value) { jail->maxretry = DEFAULT_MAXRETRY; return true; } - if (strcmp(param, "incr_bantime") == 0) { - jail->incr_bantime = atof(value); + if (strcmp(param, "bantime_extend") == 0) { + jail->bantime_extend = atof(value); return true; } - if (strcmp(param, "incr_findtime") == 0) { - jail->incr_findtime = atof(value); + if (strcmp(param, "findtime_extend") == 0) { + jail->findtime_extend = atof(value); return true; } return false; @@ -102,6 +102,8 @@ f2b_jail_set_param(f2b_jail_t *jail, const char *param, const char *value) { void f2b_jail_apply_config(f2b_jail_t *jail, f2b_config_section_t *section) { + char name[CONFIG_KEY_MAX]; + char init[CONFIG_KEY_MAX]; f2b_config_param_t *param = NULL; assert(jail != NULL); @@ -110,15 +112,18 @@ f2b_jail_apply_config(f2b_jail_t *jail, f2b_config_section_t *section) { for (param = section->param; param != NULL; param = param->next) { if (strcmp(param->name, "source") == 0) { - f2b_jail_parse_compound_value(param->value, jail->source_name, jail->source_init); + f2b_jail_parse_compound_value(param->value, name, init); + jail->source = f2b_source_create(name, init); continue; } if (strcmp(param->name, "filter") == 0) { - f2b_jail_parse_compound_value(param->value, jail->filter_name, jail->filter_init); + f2b_jail_parse_compound_value(param->value, name, init); + jail->filter = f2b_filter_create(name, init); continue; } if (strcmp(param->name, "backend") == 0) { - f2b_jail_parse_compound_value(param->value, jail->backend_name, jail->backend_init); + f2b_jail_parse_compound_value(param->value, name, init); + jail->backend = f2b_backend_create(name, init); continue; } if (f2b_jail_set_param(jail, param->name, param->value)) @@ -149,14 +154,14 @@ f2b_jail_ban(f2b_jail_t *jail, f2b_ipaddr_t *addr) { addr->banned = true; addr->banned_at = addr->lastseen; - if (jail->incr_bantime > 0) { - bantime = jail->bantime + (int) (addr->bancount * (jail->bantime * jail->incr_bantime)); + if (jail->bantime_extend > 0) { + bantime = jail->bantime + (int) (addr->bancount * (jail->bantime * jail->bantime_extend)); } else { bantime = jail->bantime; } addr->bancount++; addr->release_at = addr->banned_at + bantime; - jail->bancount++; + jail->stats.bans++; if (f2b_backend_check(jail->backend, addr->text)) { f2b_log_msg(log_warn, "jail '%s': ip %s was already banned", jail->name, addr->text); @@ -246,7 +251,7 @@ f2b_jail_process(f2b_jail_t *jail) { if (!f2b_filter_match(jail->filter, line, matchbuf, sizeof(matchbuf))) continue; /* some regex matches the line */ - jail->matchcount++; + jail->stats.matches++; addr = f2b_addrlist_lookup(jail->ipaddrs, matchbuf); if (!addr) { addr = f2b_ipaddr_create(matchbuf); @@ -260,10 +265,10 @@ f2b_jail_process(f2b_jail_t *jail) { continue; } match = f2b_match_create(now); - if (jail->incr_findtime > 0 && addr->matches.count > jail->maxretry) { + if (jail->findtime_extend > 0 && addr->matches.count > jail->maxretry) { findtime = now - jail->findtime; findtime -= (int) ((addr->matches.count - jail->maxretry) * - (jail->findtime * jail->incr_findtime)); + (jail->findtime * jail->findtime_extend)); } else { findtime = now - jail->findtime; } @@ -324,61 +329,55 @@ f2b_jail_process(f2b_jail_t *jail) { bool f2b_jail_init(f2b_jail_t *jail, f2b_config_t *config) { - f2b_config_section_t * s_section = NULL; - f2b_config_section_t * b_section = NULL; - f2b_config_section_t * f_section = NULL; + f2b_config_section_t *section = NULL; assert(jail != NULL); assert(config != NULL); - /* source */ - if (jail->source_name[0] == '\0') { - f2b_log_msg(log_error, "jail '%s': missing 'source' parameter", jail->name); - return false; - } - if ((s_section = f2b_config_section_find(config->sources, jail->source_name)) == NULL) { - f2b_log_msg(log_error, "jail '%s': no source with name '%s'", jail->name, jail->source_name); - return false; + if (!jail->source) { + f2b_log_msg(log_error, "jail '%s': missing 'source' option", jail->name); + goto cleanup; } - - /* filter */ - if (jail->filter_name[0] == '\0') { - f2b_log_msg(log_error, "jail '%s': missing 'filter' parameter", jail->name); - return false; + if (!jail->filter) { + f2b_log_msg(log_error, "jail '%s': missing 'filter' option", jail->name); + goto cleanup; } - if ((f_section = f2b_config_section_find(config->filters, jail->filter_name)) == NULL) { - f2b_log_msg(log_error, "jail '%s': no filter with name '%s'", jail->name, jail->filter_name); - return false; + if (!jail->backend) { + f2b_log_msg(log_error, "jail '%s': missing 'backend' option", jail->name); + goto cleanup; } - /* backend */ - if (jail->backend_name[0] == '\0') { - f2b_log_msg(log_error, "jail '%s': missing 'backend' parameter", jail->name); - return false; + if ((section = f2b_config_section_find(config->sources, jail->source->name)) == NULL) { + f2b_log_msg(log_error, "jail '%s': no source with name '%s'", jail->name, jail->source->name); + goto cleanup; } - if ((b_section = f2b_config_section_find(config->backends, jail->backend_name)) == NULL) { - f2b_log_msg(log_error, "jail '%s': no backend with name '%s'", jail->name, jail->backend_name); - return false; + if (!f2b_source_init(jail->source, section)) { + f2b_log_msg(log_error, "jail '%s': can't init source '%s' with %s", jail->name, jail->source->name, jail->source->init); + goto cleanup; } - /* init all */ - if ((jail->source = f2b_source_create(s_section, jail->source_init)) == NULL) { - f2b_log_msg(log_error, "jail '%s': can't init source '%s' with %s", jail->name, jail->source_name, jail->source_init); + if ((section = f2b_config_section_find(config->filters, jail->filter->name)) == NULL) { + f2b_log_msg(log_error, "jail '%s': no filter with name '%s'", jail->name, jail->filter->name); goto cleanup; } - if (!f2b_source_start(jail->source)) { - f2b_log_msg(log_warn, "jail '%s': source action 'start' failed", jail->name); + if (!f2b_filter_init(jail->filter, section)) { + f2b_log_msg(log_error, "jail '%s': no regexps loaded from '%s'", jail->name, jail->filter->init); goto cleanup; } - if ((jail->filter = f2b_filter_create(f_section, jail->filter_init)) == NULL) { - f2b_log_msg(log_error, "jail '%s': no regexps loaded from '%s'", jail->name, jail->filter_init); + if ((section = f2b_config_section_find(config->backends, jail->backend->name)) == NULL) { + f2b_log_msg(log_error, "jail '%s': no backend with name '%s'", jail->name, jail->backend->name); goto cleanup; } - - if ((jail->backend = f2b_backend_create(b_section, jail->backend_init)) == NULL) { + if (!f2b_backend_init(jail->backend, section)) { f2b_log_msg(log_error, "jail '%s': can't init backend '%s' with %s", - jail->name, jail->backend_name, jail->backend_init); + jail->name, jail->backend->name, jail->backend->init); + goto cleanup; + } + + /* start all */ + if (!f2b_source_start(jail->source)) { + f2b_log_msg(log_warn, "jail '%s': source action 'start' failed", jail->name); goto cleanup; } if (!f2b_backend_start(jail->backend)) { @@ -391,12 +390,18 @@ f2b_jail_init(f2b_jail_t *jail, f2b_config_t *config) { return true; cleanup: - if (jail->source) + if (jail->source) { f2b_source_destroy(jail->source); - if (jail->filter) + jail->source = NULL; + } + if (jail->filter) { f2b_filter_destroy(jail->filter); - if (jail->backend) + jail->filter = NULL; + } + if (jail->backend) { f2b_backend_destroy(jail->backend); + jail->backend = NULL; + } return false; } @@ -500,8 +505,8 @@ f2b_jail_cmd_status(char *res, size_t ressize, f2b_jail_t *jail) { jail->flags & JAIL_HAS_STATE ? "yes" : "no", jail->maxretry, jail->bantime, jail->findtime, jail->expiretime, - jail->incr_bantime, jail->incr_findtime, - jail->bancount, jail->matchcount); + jail->bantime_extend, jail->findtime_extend, + jail->stats.bans, jail->stats.matches); } void diff --git a/src/jail.h b/src/jail.h index 3c7a662..cf8e357 100644 --- a/src/jail.h +++ b/src/jail.h @@ -28,26 +28,27 @@ /** jail metadata struct */ typedef struct f2b_jail_t { struct f2b_jail_t *next; /**< pointer to next jail */ + char name[CONFIG_KEY_MAX]; /**< name of the jail */ int flags; /**< jail flags, see above */ - time_t bantime; /**< option: ban host for this time if maxretry exceeded */ - time_t findtime; /**< option: time period for counting matches */ - time_t expiretime; /**< option: forget about host after this time with on activity (not including bantime) */ size_t maxretry; /**< option: maximum count of matches before ban */ - size_t bancount; /**< stats: total number of bans for this jail */ - size_t matchcount; /**< stats: total number of matches for this jail */ - float incr_bantime; /**< option: multiplier for bantime */ - float incr_findtime; /**< option: multiplier for finetime */ - char name[CONFIG_KEY_MAX]; /**< name of the jail */ - char backend_name[CONFIG_KEY_MAX]; /**< backend name from config (eg [backend:$NAME] section) */ - char backend_init[CONFIG_VAL_MAX]; /**< backend init string (eg `backend = NAME:$INIT_STRING` line from jail section) */ - char filter_name[CONFIG_KEY_MAX]; /**< filter name from config (eg [filter:$NAME] section) */ - char filter_init[CONFIG_VAL_MAX]; /**< filter init string (eg `filter = NAME:$INIT_STRING` line from jail section) */ - char source_name[CONFIG_KEY_MAX]; /**< source name from config (eg [source:$NAME] section) */ - char source_init[CONFIG_VAL_MAX]; /**< source init string (eg `source = NAME:$INIT_STRING` line from jail section) */ - f2b_statefile_t *sfile; /**< pointer to state file description */ + /* duration of misc time periods */ + time_t findtime; /**< option: length of time period for estimating recent host activity (in seconds) */ + time_t bantime; /**< option: host ban time on excess activity (seconds) */ + time_t expiretime; /**< option: forget about host after this time with no activity (seconds, for banned hosts - after it's release, for not banned - after latest match) */ + /** time period length modifiers for already banned hosts */ + float findtime_extend; /**< findtime modifier for already banned hosts in past (float) */ + float bantime_extend; /**< bantime modifier for already banned hosts in past (float) */ + float expiretime_extend; /**< expiretime modifier for already banned hosts in past (float) */ + /* jail stats */ + struct { + unsigned int hosts; /**< number of tracked hosts */ + unsigned int bans; /**< number of ban events */ + unsigned int matches; /**< number of match events */ + } stats; f2b_source_t *source; /**< pointer to source */ f2b_filter_t *filter; /**< pointer to filter */ f2b_backend_t *backend; /**< pointer to backend */ + f2b_statefile_t *sfile; /**< pointer to state file description */ f2b_ipaddr_t *ipaddrs; /**< list of known ip addresses */ } f2b_jail_t; diff --git a/src/source-test.c b/src/source-test.c index b6eee72..42c17ff 100644 --- a/src/source-test.c +++ b/src/source-test.c @@ -37,8 +37,13 @@ int main(int argc, char *argv[]) { section = config.sources; } - if ((source = f2b_source_create(section, argv[2])) == NULL) { - f2b_log_msg(log_fatal, "can't create source '%s' with init '%s'", section->name, argv[2]); + if ((source = f2b_source_create(section->name, argv[2])) == NULL) { + f2b_log_msg(log_fatal, "can't create source '%s'", section->name); + return EXIT_FAILURE; + } + + if (!f2b_source_init(source, section)) { + f2b_log_msg(log_fatal, "can't init source '%s'", source->name); return EXIT_FAILURE; } diff --git a/src/source.c b/src/source.c index 8f03993..aded7b2 100644 --- a/src/source.c +++ b/src/source.c @@ -10,9 +10,21 @@ #define SOURCE_LIBRARY_PARAM "load" f2b_source_t * -f2b_source_create(f2b_config_section_t *config, const char *init) { - f2b_config_param_t *param = NULL; +f2b_source_create(const char *name, const char *init) { f2b_source_t *source = NULL; + + if ((source = calloc(1, sizeof(f2b_source_t))) == NULL) + return NULL; + + strlcpy(source->name, name, sizeof(source->name)); + strlcpy(source->init, init, sizeof(source->init)); + + return source; +} + +bool +f2b_source_init(f2b_source_t *source, f2b_config_section_t *config) { + f2b_config_param_t *param = NULL; int flags = RTLD_NOW | RTLD_LOCAL; const char *dlerr = NULL; @@ -22,12 +34,9 @@ f2b_source_create(f2b_config_section_t *config, const char *init) { param = f2b_config_param_find(config->param, SOURCE_LIBRARY_PARAM); if (!param) { f2b_log_msg(log_error, "can't find '%s' param in source config", SOURCE_LIBRARY_PARAM); - return NULL; + return false; } - if ((source = calloc(1, sizeof(f2b_source_t))) == NULL) - return NULL; - if ((source->h = dlopen(param->value, flags)) == NULL) goto cleanup; if ((*(void **) (&source->create) = dlsym(source->h, "create")) == NULL) @@ -49,7 +58,7 @@ f2b_source_create(f2b_config_section_t *config, const char *init) { if ((*(void **) (&source->destroy) = dlsym(source->h, "destroy")) == NULL) goto cleanup; - if ((source->cfg = source->create(init)) == NULL) { + if ((source->cfg = source->create(source->init)) == NULL) { f2b_log_msg(log_error, "source create config failed"); goto cleanup; } @@ -67,7 +76,7 @@ f2b_source_create(f2b_config_section_t *config, const char *init) { } if (source->ready(source->cfg)) - return source; + return true; /* still not ready */ f2b_log_msg(log_error, "source '%s' not fully configured", config->name); @@ -82,7 +91,7 @@ f2b_source_create(f2b_config_section_t *config, const char *init) { dlclose(source->h); } free(source); - return NULL; + return false; } void diff --git a/src/source.h b/src/source.h index b09720c..b133978 100644 --- a/src/source.h +++ b/src/source.h @@ -17,6 +17,8 @@ /** source module definition */ typedef struct f2b_source_t { + char name[CONFIG_KEY_MAX]; /**< source name from config (eg [source:$NAME] section) */ + char init[CONFIG_VAL_MAX]; /**< source init string (eg `source = NAME:$INIT_STRING` line from jail section) */ void *h; /**< dlopen handler */ void *cfg; /**< opaque pointer of module config */ /* handlers */ @@ -41,13 +43,20 @@ typedef struct f2b_source_t { } f2b_source_t; /** - * @brief Create module from config - * @param config Pointer to config section with module description + * @brief Allocate new source struct and fill name/init fields + * @param name Module name * @param init Module init string - * @param logcb Logging callback * @returns Pointer to allocated module struct or NULL on error */ -f2b_source_t * f2b_source_create (f2b_config_section_t *config, const char *init); +f2b_source_t * f2b_source_create(const char *name, const char *init); + +/** + * @brief Initialize and configure source + * @param config Pointer to config section with module description + * @return true on success, false on error + */ +bool f2b_source_init(f2b_source_t *source, f2b_config_section_t *config); + /** * @brief Free module metadata * @param s Pointer to module struct