From cfdacc6969ef69eb5c5e22229df263c1a607233c Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Fri, 4 Mar 2016 20:38:04 +1000 Subject: [PATCH] * jail.c: more code in f2b_jail_process() --- src/jail.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/src/jail.c b/src/jail.c index 9776edc..ba44233 100644 --- a/src/jail.c +++ b/src/jail.c @@ -55,29 +55,94 @@ f2b_jail_set_defaults(f2b_config_section_t *config) { return; } +bool +f2b_jail_ban(f2b_jail_t *jail, f2b_ipaddr_t *addr) { + assert(jail != NULL); + assert(addr != NULL); + + addr->matches.used = 0; + addr->banned = true; + addr->bantime = addr->lastseen; + + if (f2b_backend_ban(jail->backend, addr->text)) { + f2b_log_msg(log_info, "banned ip in jail '%s': %s", jail->name, addr->text); + return true; + } + + f2b_log_msg(log_error, "can't ban ip in jail '%s': backend failure for '%s'", jail->name, addr->text); + return false; +} + +bool +f2b_jail_unban(f2b_jail_t *jail, f2b_ipaddr_t *addr) { + assert(jail != NULL); + assert(addr != NULL); + + addr->banned = false; + addr->bantime = 0; + + if (f2b_backend_unban(jail->backend, addr->text)) { + f2b_log_msg(log_info, "released ip in jail '%s': %s", jail->name, addr->text); + return true; + } + + f2b_log_msg(log_error, "can't release ip in jail '%s': backend failure for '%s'", jail->name, addr->text); + return false; +} + size_t -f2b_jail_poll(f2b_jail_t *jail) { +f2b_jail_process(f2b_jail_t *jail) { f2b_logfile_t *file = NULL; f2b_ipaddr_t *addr = NULL; size_t processed = 0; char logline[LOGLINE_MAX] = ""; char matchbuf[IPADDR_MAX] = ""; + time_t now = time(NULL); + time_t release_time = 0; assert(jail != NULL); for (file = jail->logfiles; file != NULL; file = file->next) { - if (!f2b_logfile_getline(file, logline, sizeof(logline))) - continue; - if (!f2b_regexlist_match(jail->regexps, logline, matchbuf, sizeof(matchbuf))) + while (f2b_logfile_getline(file, logline, sizeof(logline))) { + if (!f2b_regexlist_match(jail->regexps, logline, matchbuf, sizeof(matchbuf))) + continue; + /* some regex matches the line */ + addr = f2b_addrlist_lookup(jail->ipaddrs, matchbuf); + if (!addr) { + /* new ip */ + addr = f2b_ipaddr_create(matchbuf, jail->tries); + addr->lastseen = now; + f2b_matches_append(&addr->matches, now); + jail->ipaddrs = f2b_addrlist_append(jail->ipaddrs, addr); + f2b_log_msg(log_debug, "new ip found by jail '%s': %s", jail->name, matchbuf); + continue; + } + /* this ip was seen before */ + addr->lastseen = now; + if (addr->banned) { + f2b_log_msg(log_warn, "found ip that was already banned by jail '%s': %s", jail->name, matchbuf); + continue; + } + f2b_matches_expire(&addr->matches, now - jail->bantime); + f2b_matches_append(&addr->matches, now); + if (addr->matches.used < jail->tries) { + f2b_log_msg(log_debug, "new match in jail '%s': %s (%d/%d)", jail->name, matchbuf, addr->matches.used, addr->matches.max); + continue; + } + /* limit reached, ban ip */ + f2b_jail_ban(jail, addr); + } /* while(lines) */ + } /* for(files) */ + + for (addr = jail->ipaddrs; addr != NULL; addr = addr->next) { + if (!addr->banned) continue; - addr = f2b_addrlist_lookup(jail->ipaddrs, matchbuf); - if (!addr) { - addr = f2b_ipaddr_create(matchbuf, jail->tries); - jail->ipaddrs = f2b_addrlist_append(jail->ipaddrs, addr); - /* TODO: log */ + release_time = addr->bantime + jail->bantime; + if (now < release_time) { + f2b_log_msg(log_debug, "skipping banned ip in jail '%s': %s (%.1fh remains)", jail->name, addr->text, (now - release_time) / 3600); continue; } - /* TODO: find & handle */ + f2b_jail_unban(jail, addr); } return processed;