Browse Source

* update f2b_jail_t struct

master
Alex 'AdUser' Z 3 years ago
parent
commit
ce7defbb13
  1. 9
      src/backend-test.c
  2. 27
      src/backend.c
  3. 21
      src/backend.h
  4. 11
      src/filter-test.c
  5. 33
      src/filter.c
  6. 20
      src/filter.h
  7. 113
      src/jail.c
  8. 31
      src/jail.h
  9. 9
      src/source-test.c
  10. 27
      src/source.c
  11. 17
      src/source.h

9
src/backend-test.c

@ -84,8 +84,13 @@ int main(int argc, char *argv[]) {
section = config.backends; section = config.backends;
} }
if ((backend = f2b_backend_create(section, argv[2])) == NULL) { if ((backend = f2b_backend_create(section->name, argv[2])) == NULL) {
f2b_log_msg(log_fatal, "can't create backend '%s' with id '%s'", section->name, argv[2]); 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; return EXIT_FAILURE;
} }

27
src/backend.c

@ -10,9 +10,21 @@
#define BACKEND_LIBRARY_PARAM "load" #define BACKEND_LIBRARY_PARAM "load"
f2b_backend_t * f2b_backend_t *
f2b_backend_create(f2b_config_section_t *config, const char *id) { f2b_backend_create(const char *name, const char *init) {
f2b_config_param_t *param = NULL;
f2b_backend_t *backend = NULL; 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; int flags = RTLD_NOW | RTLD_LOCAL;
const char *dlerr = NULL; 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); param = f2b_config_param_find(config->param, BACKEND_LIBRARY_PARAM);
if (!param) { if (!param) {
f2b_log_msg(log_error, "can't find '%s' param in backend config", BACKEND_LIBRARY_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) if ((backend->h = dlopen(param->value, flags)) == NULL)
goto cleanup; goto cleanup;
if ((*(void **) (&backend->create) = dlsym(backend->h, "create")) == NULL) 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) if ((*(void **) (&backend->destroy) = dlsym(backend->h, "destroy")) == NULL)
goto cleanup; 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"); f2b_log_msg(log_error, "backend create config failed");
goto cleanup; goto cleanup;
} }
@ -71,7 +80,7 @@ f2b_backend_create(f2b_config_section_t *config, const char *id) {
} }
if (backend->ready(backend->cfg)) if (backend->ready(backend->cfg))
return backend; return true;
/* still not ready */ /* still not ready */
f2b_log_msg(log_error, "backend '%s' not fully configured", config->name); 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); dlclose(backend->h);
} }
free(backend); free(backend);
return NULL; return false;
} }
void void

21
src/backend.h

@ -42,15 +42,26 @@ typedef struct f2b_backend_t {
bool (*unban) (void *cfg, const char *ip); bool (*unban) (void *cfg, const char *ip);
/** dlsym pointer to handler of @a destroy command */ /** dlsym pointer to handler of @a destroy command */
void (*destroy) (void *cfg); 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; } f2b_backend_t;
/** /**
* @brief Create module from config * @brief Allocate new backend struct and fill name/init fields
* @param config Pointer to section of config * @param name Module name
* @param id Backend id * @param init Module init string
* @returns Pointer to module metadata of NULL on error * @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 * @brief Free module metadata
* @param b Pointer to module struct * @param b Pointer to module struct

11
src/filter-test.c

@ -41,14 +41,19 @@ int main(int argc, char *argv[]) {
section = config.filters; section = config.filters;
} }
if ((filter = f2b_filter_create(section, argv[2])) == false) { if ((filter = f2b_filter_create(section->name, argv[2])) == false) {
f2b_log_msg(log_fatal, "can't create filter '%s' with file '%s'", section->name, argv[2]); 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; return EXIT_FAILURE;
} }
if (argc > 3) { if (argc > 3) {
if ((file = fopen(argv[3], "r")) == NULL) { 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; return EXIT_FAILURE;
} }
} else { } else {

33
src/filter.c

@ -70,25 +70,33 @@ f2b_filter_load_file(f2b_filter_t *filter, const char *path) {
} }
f2b_filter_t * f2b_filter_t *
f2b_filter_create(f2b_config_section_t *config, const char *file) { f2b_filter_create(const char *name, const char *init) {
f2b_config_param_t *param = NULL;
f2b_filter_t *filter = NULL; 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; int flags = RTLD_NOW | RTLD_LOCAL;
const char *dlerr = NULL; const char *dlerr = NULL;
assert(file != NULL);
assert(config != NULL); assert(config != NULL);
assert(config->type == t_filter); assert(config->type == t_filter);
param = f2b_config_param_find(config->param, FILTER_LIBRARY_PARAM); param = f2b_config_param_find(config->param, FILTER_LIBRARY_PARAM);
if (!param) { if (!param) {
f2b_log_msg(log_error, "can't find '%s' param in filter config", FILTER_LIBRARY_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) if ((filter->h = dlopen(param->value, flags)) == NULL)
goto cleanup; goto cleanup;
if ((*(void **) (&filter->create) = dlsym(filter->h, "create")) == NULL) 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) if ((*(void **) (&filter->destroy) = dlsym(filter->h, "destroy")) == NULL)
goto cleanup; goto cleanup;
/* TODO: do we need id? */
if ((filter->cfg = filter->create("")) == NULL) { if ((filter->cfg = filter->create("")) == NULL) {
f2b_log_msg(log_error, "filter create config failed"); f2b_log_msg(log_error, "filter create config failed");
goto cleanup; goto cleanup;
@ -128,13 +135,11 @@ f2b_filter_create(f2b_config_section_t *config, const char *file) {
config->name, param->name, param->value); config->name, param->name, param->value);
} }
strlcpy(filter->file, file, sizeof(filter->file)); if (!f2b_filter_load_file(filter, filter->init))
if (!f2b_filter_load_file(filter, file))
goto cleanup; goto cleanup;
if (filter->ready(filter->cfg)) if (filter->ready(filter->cfg))
return filter; return true;
/* still not ready */ /* still not ready */
f2b_log_msg(log_error, "filter '%s' not fully configured", config->name); 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); dlclose(filter->h);
} }
free(filter); free(filter);
return NULL; return false;
} }
void void
@ -191,7 +196,7 @@ f2b_filter_cmd_reload(char *buf, size_t bufsize, f2b_filter_t *filter) {
assert(filter != NULL); assert(filter != NULL);
filter->flush(filter->cfg); 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"); snprintf(buf, bufsize, "can't reload filter");
} }
} }

20
src/filter.h

@ -19,7 +19,6 @@
typedef struct f2b_filter_t { typedef struct f2b_filter_t {
void *h; /**< dlopen handler */ void *h; /**< dlopen handler */
void *cfg; /**< opaque pointer of module config */ void *cfg; /**< opaque pointer of module config */
char file[PATH_MAX]; /**< path to file with patterns */
/* handlers */ /* handlers */
/** dlsym pointer to handler of @a create command */ /** dlsym pointer to handler of @a create command */
void *(*create) (const char *id); 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); bool (*match) (void *cfg, const char *line, char *buf, size_t buf_size);
/** dlsym pointer to handler of @a destroy command */ /** dlsym pointer to handler of @a destroy command */
void (*destroy) (void *cfg); 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; } f2b_filter_t;
/** /**
* @brief Create module from config * @brief Allocate new filter struct and fill name/init fields
* @param config Pointer to config section with module description * @param name Module name
* @param id Filter id * @param init Module init string
* @returns Pointer to allocated module struct or NULL on error * @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 * @brief Free module metadata
* @param f Pointer to module struct * @param f Pointer to module struct

113
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; jail->maxretry = DEFAULT_MAXRETRY;
return true; return true;
} }
if (strcmp(param, "incr_bantime") == 0) { if (strcmp(param, "bantime_extend") == 0) {
jail->incr_bantime = atof(value); jail->bantime_extend = atof(value);
return true; return true;
} }
if (strcmp(param, "incr_findtime") == 0) { if (strcmp(param, "findtime_extend") == 0) {
jail->incr_findtime = atof(value); jail->findtime_extend = atof(value);
return true; return true;
} }
return false; return false;
@ -102,6 +102,8 @@ f2b_jail_set_param(f2b_jail_t *jail, const char *param, const char *value) {
void void
f2b_jail_apply_config(f2b_jail_t *jail, f2b_config_section_t *section) { 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; f2b_config_param_t *param = NULL;
assert(jail != 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) { for (param = section->param; param != NULL; param = param->next) {
if (strcmp(param->name, "source") == 0) { 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; continue;
} }
if (strcmp(param->name, "filter") == 0) { 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; continue;
} }
if (strcmp(param->name, "backend") == 0) { 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; continue;
} }
if (f2b_jail_set_param(jail, param->name, param->value)) 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 = true;
addr->banned_at = addr->lastseen; addr->banned_at = addr->lastseen;
if (jail->incr_bantime > 0) { if (jail->bantime_extend > 0) {
bantime = jail->bantime + (int) (addr->bancount * (jail->bantime * jail->incr_bantime)); bantime = jail->bantime + (int) (addr->bancount * (jail->bantime * jail->bantime_extend));
} else { } else {
bantime = jail->bantime; bantime = jail->bantime;
} }
addr->bancount++; addr->bancount++;
addr->release_at = addr->banned_at + bantime; addr->release_at = addr->banned_at + bantime;
jail->bancount++; jail->stats.bans++;
if (f2b_backend_check(jail->backend, addr->text)) { if (f2b_backend_check(jail->backend, addr->text)) {
f2b_log_msg(log_warn, "jail '%s': ip %s was already banned", jail->name, 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))) if (!f2b_filter_match(jail->filter, line, matchbuf, sizeof(matchbuf)))
continue; continue;
/* some regex matches the line */ /* some regex matches the line */
jail->matchcount++; jail->stats.matches++;
addr = f2b_addrlist_lookup(jail->ipaddrs, matchbuf); addr = f2b_addrlist_lookup(jail->ipaddrs, matchbuf);
if (!addr) { if (!addr) {
addr = f2b_ipaddr_create(matchbuf); addr = f2b_ipaddr_create(matchbuf);
@ -260,10 +265,10 @@ f2b_jail_process(f2b_jail_t *jail) {
continue; continue;
} }
match = f2b_match_create(now); 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 = now - jail->findtime;
findtime -= (int) ((addr->matches.count - jail->maxretry) * findtime -= (int) ((addr->matches.count - jail->maxretry) *
(jail->findtime * jail->incr_findtime)); (jail->findtime * jail->findtime_extend));
} else { } else {
findtime = now - jail->findtime; findtime = now - jail->findtime;
} }
@ -324,61 +329,55 @@ f2b_jail_process(f2b_jail_t *jail) {
bool bool
f2b_jail_init(f2b_jail_t *jail, f2b_config_t *config) { f2b_jail_init(f2b_jail_t *jail, f2b_config_t *config) {
f2b_config_section_t * s_section = NULL; f2b_config_section_t *section = NULL;
f2b_config_section_t * b_section = NULL;
f2b_config_section_t * f_section = NULL;
assert(jail != NULL); assert(jail != NULL);
assert(config != NULL); assert(config != NULL);
/* source */ if (!jail->source) {
if (jail->source_name[0] == '\0') { f2b_log_msg(log_error, "jail '%s': missing 'source' option", jail->name);
f2b_log_msg(log_error, "jail '%s': missing 'source' parameter", jail->name); goto cleanup;
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->filter) {
/* filter */ f2b_log_msg(log_error, "jail '%s': missing 'filter' option", jail->name);
if (jail->filter_name[0] == '\0') { goto cleanup;
f2b_log_msg(log_error, "jail '%s': missing 'filter' parameter", jail->name);
return false;
} }
if ((f_section = f2b_config_section_find(config->filters, jail->filter_name)) == NULL) { if (!jail->backend) {
f2b_log_msg(log_error, "jail '%s': no filter with name '%s'", jail->name, jail->filter_name); f2b_log_msg(log_error, "jail '%s': missing 'backend' option", jail->name);
return false; goto cleanup;
} }
/* backend */ if ((section = f2b_config_section_find(config->sources, jail->source->name)) == NULL) {
if (jail->backend_name[0] == '\0') { f2b_log_msg(log_error, "jail '%s': no source with name '%s'", jail->name, jail->source->name);
f2b_log_msg(log_error, "jail '%s': missing 'backend' parameter", jail->name); goto cleanup;
return false;
} }
if ((b_section = f2b_config_section_find(config->backends, jail->backend_name)) == NULL) { if (!f2b_source_init(jail->source, section)) {
f2b_log_msg(log_error, "jail '%s': no backend with name '%s'", jail->name, jail->backend_name); f2b_log_msg(log_error, "jail '%s': can't init source '%s' with %s", jail->name, jail->source->name, jail->source->init);
return false; goto cleanup;
} }
/* init all */ if ((section = f2b_config_section_find(config->filters, jail->filter->name)) == NULL) {
if ((jail->source = f2b_source_create(s_section, jail->source_init)) == NULL) { f2b_log_msg(log_error, "jail '%s': no filter with name '%s'", jail->name, jail->filter->name);
f2b_log_msg(log_error, "jail '%s': can't init source '%s' with %s", jail->name, jail->source_name, jail->source_init);
goto cleanup; goto cleanup;
} }
if (!f2b_source_start(jail->source)) { if (!f2b_filter_init(jail->filter, section)) {
f2b_log_msg(log_warn, "jail '%s': source action 'start' failed", jail->name); f2b_log_msg(log_error, "jail '%s': no regexps loaded from '%s'", jail->name, jail->filter->init);
goto cleanup; goto cleanup;
} }
if ((jail->filter = f2b_filter_create(f_section, jail->filter_init)) == NULL) { if ((section = f2b_config_section_find(config->backends, jail->backend->name)) == NULL) {
f2b_log_msg(log_error, "jail '%s': no regexps loaded from '%s'", jail->name, jail->filter_init); f2b_log_msg(log_error, "jail '%s': no backend with name '%s'", jail->name, jail->backend->name);
goto cleanup; goto cleanup;
} }
if (!f2b_backend_init(jail->backend, section)) {
if ((jail->backend = f2b_backend_create(b_section, jail->backend_init)) == NULL) {
f2b_log_msg(log_error, "jail '%s': can't init backend '%s' with %s", 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; goto cleanup;
} }
if (!f2b_backend_start(jail->backend)) { if (!f2b_backend_start(jail->backend)) {
@ -391,12 +390,18 @@ f2b_jail_init(f2b_jail_t *jail, f2b_config_t *config) {
return true; return true;
cleanup: cleanup:
if (jail->source) if (jail->source) {
f2b_source_destroy(jail->source); f2b_source_destroy(jail->source);
if (jail->filter) jail->source = NULL;
}
if (jail->filter) {
f2b_filter_destroy(jail->filter); f2b_filter_destroy(jail->filter);
if (jail->backend) jail->filter = NULL;
}
if (jail->backend) {
f2b_backend_destroy(jail->backend); f2b_backend_destroy(jail->backend);
jail->backend = NULL;
}
return false; 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->flags & JAIL_HAS_STATE ? "yes" : "no",
jail->maxretry, jail->maxretry,
jail->bantime, jail->findtime, jail->expiretime, jail->bantime, jail->findtime, jail->expiretime,
jail->incr_bantime, jail->incr_findtime, jail->bantime_extend, jail->findtime_extend,
jail->bancount, jail->matchcount); jail->stats.bans, jail->stats.matches);
} }
void void

31
src/jail.h

@ -28,26 +28,27 @@
/** jail metadata struct */ /** jail metadata struct */
typedef struct f2b_jail_t { typedef struct f2b_jail_t {
struct f2b_jail_t *next; /**< pointer to next jail */ struct f2b_jail_t *next; /**< pointer to next jail */
char name[CONFIG_KEY_MAX]; /**< name of the jail */
int flags; /**< jail flags, see above */ 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 maxretry; /**< option: maximum count of matches before ban */
size_t bancount; /**< stats: total number of bans for this jail */ /* duration of misc time periods */
size_t matchcount; /**< stats: total number of matches for this jail */ time_t findtime; /**< option: length of time period for estimating recent host activity (in seconds) */
float incr_bantime; /**< option: multiplier for bantime */ time_t bantime; /**< option: host ban time on excess activity (seconds) */
float incr_findtime; /**< option: multiplier for finetime */ 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) */
char name[CONFIG_KEY_MAX]; /**< name of the jail */ /** time period length modifiers for already banned hosts */
char backend_name[CONFIG_KEY_MAX]; /**< backend name from config (eg [backend:$NAME] section) */ float findtime_extend; /**< findtime modifier for already banned hosts in past (float) */
char backend_init[CONFIG_VAL_MAX]; /**< backend init string (eg `backend = NAME:$INIT_STRING` line from jail section) */ float bantime_extend; /**< bantime modifier for already banned hosts in past (float) */
char filter_name[CONFIG_KEY_MAX]; /**< filter name from config (eg [filter:$NAME] section) */ float expiretime_extend; /**< expiretime modifier for already banned hosts in past (float) */
char filter_init[CONFIG_VAL_MAX]; /**< filter init string (eg `filter = NAME:$INIT_STRING` line from jail section) */ /* jail stats */
char source_name[CONFIG_KEY_MAX]; /**< source name from config (eg [source:$NAME] section) */ struct {
char source_init[CONFIG_VAL_MAX]; /**< source init string (eg `source = NAME:$INIT_STRING` line from jail section) */ unsigned int hosts; /**< number of tracked hosts */
f2b_statefile_t *sfile; /**< pointer to state file description */ unsigned int bans; /**< number of ban events */
unsigned int matches; /**< number of match events */
} stats;
f2b_source_t *source; /**< pointer to source */ f2b_source_t *source; /**< pointer to source */
f2b_filter_t *filter; /**< pointer to filter */ f2b_filter_t *filter; /**< pointer to filter */
f2b_backend_t *backend; /**< pointer to backend */ 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_ipaddr_t *ipaddrs; /**< list of known ip addresses */
} f2b_jail_t; } f2b_jail_t;

9
src/source-test.c

@ -37,8 +37,13 @@ int main(int argc, char *argv[]) {
section = config.sources; section = config.sources;
} }
if ((source = f2b_source_create(section, argv[2])) == NULL) { if ((source = f2b_source_create(section->name, argv[2])) == NULL) {
f2b_log_msg(log_fatal, "can't create source '%s' with init '%s'", section->name, argv[2]); 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; return EXIT_FAILURE;
} }

27
src/source.c

@ -10,9 +10,21 @@
#define SOURCE_LIBRARY_PARAM "load" #define SOURCE_LIBRARY_PARAM "load"
f2b_source_t * f2b_source_t *
f2b_source_create(f2b_config_section_t *config, const char *init) { f2b_source_create(const char *name, const char *init) {
f2b_config_param_t *param = NULL;
f2b_source_t *source = NULL; 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; int flags = RTLD_NOW | RTLD_LOCAL;
const char *dlerr = NULL; 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); param = f2b_config_param_find(config->param, SOURCE_LIBRARY_PARAM);
if (!param) { if (!param) {
f2b_log_msg(log_error, "can't find '%s' param in source config", SOURCE_LIBRARY_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) if ((source->h = dlopen(param->value, flags)) == NULL)
goto cleanup; goto cleanup;
if ((*(void **) (&source->create) = dlsym(source->h, "create")) == NULL) 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) if ((*(void **) (&source->destroy) = dlsym(source->h, "destroy")) == NULL)
goto cleanup; 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"); f2b_log_msg(log_error, "source create config failed");
goto cleanup; goto cleanup;
} }
@ -67,7 +76,7 @@ f2b_source_create(f2b_config_section_t *config, const char *init) {
} }
if (source->ready(source->cfg)) if (source->ready(source->cfg))
return source; return true;
/* still not ready */ /* still not ready */
f2b_log_msg(log_error, "source '%s' not fully configured", config->name); 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); dlclose(source->h);
} }
free(source); free(source);
return NULL; return false;
} }
void void

17
src/source.h

@ -17,6 +17,8 @@
/** source module definition */ /** source module definition */
typedef struct f2b_source_t { 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 *h; /**< dlopen handler */
void *cfg; /**< opaque pointer of module config */ void *cfg; /**< opaque pointer of module config */
/* handlers */ /* handlers */
@ -41,13 +43,20 @@ typedef struct f2b_source_t {
} f2b_source_t; } f2b_source_t;
/** /**
* @brief Create module from config * @brief Allocate new source struct and fill name/init fields
* @param config Pointer to config section with module description * @param name Module name
* @param init Module init string * @param init Module init string
* @param logcb Logging callback
* @returns Pointer to allocated module struct or NULL on error * @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 * @brief Free module metadata
* @param s Pointer to module struct * @param s Pointer to module struct

Loading…
Cancel
Save