142 lines
3.9 KiB
C
Executable File
142 lines
3.9 KiB
C
Executable File
#define MODULE_LOG_PREFIX "failban"
|
|
|
|
#include "globals.h"
|
|
#include "module-anticasc.h"
|
|
#include "oscam-net.h"
|
|
#include "oscam-string.h"
|
|
#include "oscam-time.h"
|
|
|
|
static int32_t cs_check_v(IN_ADDR_T ip, int32_t port, int32_t add, char *info, int32_t acosc_penalty_duration)
|
|
{
|
|
int32_t result = 0;
|
|
|
|
if(!(cfg.failbantime || acosc_enabled()))
|
|
return 0;
|
|
|
|
if(!cfg.v_list)
|
|
{ cfg.v_list = ll_create("v_list"); }
|
|
|
|
struct timeb (now);
|
|
cs_ftime(&now);
|
|
LL_ITER itr = ll_iter_create(cfg.v_list);
|
|
V_BAN *v_ban_entry;
|
|
int32_t ftime = cfg.failbantime * 60 * 1000;
|
|
|
|
// run over all banned entries to do housekeeping:
|
|
while((v_ban_entry = ll_iter_next(&itr)))
|
|
{
|
|
// housekeeping:
|
|
int64_t gone = comp_timeb(&now, &v_ban_entry->v_time);
|
|
if(((gone >= ftime) && !v_ban_entry->acosc_entry) || (v_ban_entry->acosc_entry && ((gone/1000) >= v_ban_entry->acosc_penalty_dur))) // entry out of time->remove
|
|
{
|
|
NULLFREE(v_ban_entry->info);
|
|
ll_iter_remove_data(&itr);
|
|
continue;
|
|
}
|
|
|
|
if(IP_EQUAL(ip, v_ban_entry->v_ip) && port == v_ban_entry->v_port)
|
|
{
|
|
result = 1;
|
|
if(!info)
|
|
{ info = v_ban_entry->info; }
|
|
else if(!v_ban_entry->info)
|
|
{
|
|
v_ban_entry->info = cs_strdup(info);
|
|
}
|
|
|
|
if(!add)
|
|
{
|
|
if(v_ban_entry->v_count >= cfg.failbancount)
|
|
{
|
|
if(!v_ban_entry->acosc_entry)
|
|
{
|
|
cs_log_dbg(D_TRACE, "failban: banned ip %s:%d - %"PRId64" seconds left %s%s",
|
|
cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port,
|
|
(ftime - gone) / 1000, info ? ", info: " : "", info ? info : "");
|
|
}
|
|
else
|
|
{
|
|
cs_log_dbg(D_TRACE, "failban: banned ip %s:%d - %"PRId64" seconds left %s%s",
|
|
cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port,
|
|
(v_ban_entry->acosc_penalty_dur - (gone / 1000)),
|
|
info ? ", info: " : "", info ? info : "");
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
cs_log_dbg(D_TRACE, "failban: ip %s:%d chance %d of %d%s%s",
|
|
cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port,
|
|
v_ban_entry->v_count, cfg.failbancount,
|
|
info ? ", info: " : "", info ? info : "");
|
|
|
|
v_ban_entry->v_count++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cs_log_dbg(D_TRACE, "failban: banned ip %s:%d - already exist in list %s%s",
|
|
cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port,
|
|
info ? ", info: " : "", info ? info : "");
|
|
}
|
|
}
|
|
}
|
|
|
|
if(add && !result)
|
|
{
|
|
if(cs_malloc(&v_ban_entry, sizeof(V_BAN)))
|
|
{
|
|
cs_ftime(&v_ban_entry->v_time);
|
|
v_ban_entry->v_ip = ip;
|
|
v_ban_entry->v_port = port;
|
|
v_ban_entry->v_count = 1;
|
|
v_ban_entry->acosc_entry = false;
|
|
v_ban_entry->acosc_penalty_dur = 0;
|
|
|
|
if(acosc_penalty_duration > 0)
|
|
{
|
|
v_ban_entry->v_count = cfg.failbancount +1; // set it to a higher level
|
|
v_ban_entry->acosc_entry = true;
|
|
v_ban_entry->acosc_penalty_dur = acosc_penalty_duration;
|
|
}
|
|
|
|
if(info)
|
|
{ v_ban_entry->info = cs_strdup(info); }
|
|
|
|
ll_iter_insert(&itr, v_ban_entry);
|
|
cs_log_dbg(D_TRACE, "failban: ban ip %s:%d with timestamp %" PRId64 "%s%s",
|
|
cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port, (int64_t)v_ban_entry->v_time.time,
|
|
info ? ", info: " : "", info ? info : "");
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int32_t cs_check_violation(IN_ADDR_T ip, int32_t port)
|
|
{
|
|
return cs_check_v(ip, port, 0, NULL, 0);
|
|
}
|
|
|
|
int32_t cs_add_violation_by_ip(IN_ADDR_T ip, int32_t port, char *info)
|
|
{
|
|
return cs_check_v(ip, port, 1, info, 0);
|
|
}
|
|
|
|
int32_t cs_add_violation_by_ip_acosc(IN_ADDR_T ip, int32_t port, char *info, int32_t acosc_penalty_duration)
|
|
{
|
|
return cs_check_v(ip, port, 1, info, acosc_penalty_duration);
|
|
}
|
|
|
|
void cs_add_violation(struct s_client *cl, char *info)
|
|
{
|
|
struct s_module *module = get_module(cl);
|
|
cs_add_violation_by_ip(cl->ip, module->ptab.ports[cl->port_idx].s_port, info);
|
|
}
|
|
|
|
void cs_add_violation_acosc(struct s_client *cl, char *info, int32_t acosc_penalty_duration)
|
|
{
|
|
struct s_module *module = get_module(cl);
|
|
cs_add_violation_by_ip_acosc(cl->ip, module->ptab.ports[cl->port_idx].s_port, info, acosc_penalty_duration);
|
|
}
|