oscam-2.26.01-11942-802-wit.../oscam-failban.c

142 lines
3.9 KiB
C
Raw Normal View History

#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);
}