1 | #define MODULE_LOG_PREFIX "failban"
|
---|
2 |
|
---|
3 | #include "globals.h"
|
---|
4 | #include "module-anticasc.h"
|
---|
5 | #include "oscam-net.h"
|
---|
6 | #include "oscam-string.h"
|
---|
7 | #include "oscam-time.h"
|
---|
8 |
|
---|
9 | static int32_t cs_check_v(IN_ADDR_T ip, int32_t port, int32_t add, char *info, int32_t acosc_penalty_duration)
|
---|
10 | {
|
---|
11 | int32_t result = 0;
|
---|
12 |
|
---|
13 | if(!(cfg.failbantime || acosc_enabled()))
|
---|
14 | return 0;
|
---|
15 |
|
---|
16 | if(!cfg.v_list)
|
---|
17 | { cfg.v_list = ll_create("v_list"); }
|
---|
18 |
|
---|
19 | struct timeb (now);
|
---|
20 | cs_ftime(&now);
|
---|
21 | LL_ITER itr = ll_iter_create(cfg.v_list);
|
---|
22 | V_BAN *v_ban_entry;
|
---|
23 | int32_t ftime = cfg.failbantime * 60 * 1000;
|
---|
24 |
|
---|
25 | // run over all banned entries to do housekeeping:
|
---|
26 | while((v_ban_entry = ll_iter_next(&itr)))
|
---|
27 | {
|
---|
28 | // housekeeping:
|
---|
29 | int64_t gone = comp_timeb(&now, &v_ban_entry->v_time);
|
---|
30 | 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
|
---|
31 | {
|
---|
32 | NULLFREE(v_ban_entry->info);
|
---|
33 | ll_iter_remove_data(&itr);
|
---|
34 | continue;
|
---|
35 | }
|
---|
36 |
|
---|
37 | if(IP_EQUAL(ip, v_ban_entry->v_ip) && port == v_ban_entry->v_port)
|
---|
38 | {
|
---|
39 | result = 1;
|
---|
40 | if(!info)
|
---|
41 | { info = v_ban_entry->info; }
|
---|
42 | else if(!v_ban_entry->info)
|
---|
43 | {
|
---|
44 | v_ban_entry->info = cs_strdup(info);
|
---|
45 | }
|
---|
46 |
|
---|
47 | if(!add)
|
---|
48 | {
|
---|
49 | if(v_ban_entry->v_count >= cfg.failbancount)
|
---|
50 | {
|
---|
51 | if(!v_ban_entry->acosc_entry)
|
---|
52 | {
|
---|
53 | cs_log_dbg(D_TRACE, "failban: banned ip %s:%d - %"PRId64" seconds left %s%s",
|
---|
54 | cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port,
|
---|
55 | (ftime - gone) / 1000, info ? ", info: " : "", info ? info : "");
|
---|
56 | }
|
---|
57 | else
|
---|
58 | {
|
---|
59 | cs_log_dbg(D_TRACE, "failban: banned ip %s:%d - %"PRId64" seconds left %s%s",
|
---|
60 | cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port,
|
---|
61 | (v_ban_entry->acosc_penalty_dur - (gone / 1000)),
|
---|
62 | info ? ", info: " : "", info ? info : "");
|
---|
63 | }
|
---|
64 |
|
---|
65 | }
|
---|
66 | else
|
---|
67 | {
|
---|
68 | cs_log_dbg(D_TRACE, "failban: ip %s:%d chance %d of %d%s%s",
|
---|
69 | cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port,
|
---|
70 | v_ban_entry->v_count, cfg.failbancount,
|
---|
71 | info ? ", info: " : "", info ? info : "");
|
---|
72 |
|
---|
73 | v_ban_entry->v_count++;
|
---|
74 | }
|
---|
75 | }
|
---|
76 | else
|
---|
77 | {
|
---|
78 | cs_log_dbg(D_TRACE, "failban: banned ip %s:%d - already exist in list %s%s",
|
---|
79 | cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port,
|
---|
80 | info ? ", info: " : "", info ? info : "");
|
---|
81 | }
|
---|
82 | }
|
---|
83 | }
|
---|
84 |
|
---|
85 | if(add && !result)
|
---|
86 | {
|
---|
87 | if(cs_malloc(&v_ban_entry, sizeof(V_BAN)))
|
---|
88 | {
|
---|
89 | cs_ftime(&v_ban_entry->v_time);
|
---|
90 | v_ban_entry->v_ip = ip;
|
---|
91 | v_ban_entry->v_port = port;
|
---|
92 | v_ban_entry->v_count = 1;
|
---|
93 | v_ban_entry->acosc_entry = false;
|
---|
94 | v_ban_entry->acosc_penalty_dur = 0;
|
---|
95 |
|
---|
96 | if(acosc_penalty_duration > 0)
|
---|
97 | {
|
---|
98 | v_ban_entry->v_count = cfg.failbancount +1; // set it to a higher level
|
---|
99 | v_ban_entry->acosc_entry = true;
|
---|
100 | v_ban_entry->acosc_penalty_dur = acosc_penalty_duration;
|
---|
101 | }
|
---|
102 |
|
---|
103 | if(info)
|
---|
104 | { v_ban_entry->info = cs_strdup(info); }
|
---|
105 |
|
---|
106 | ll_iter_insert(&itr, v_ban_entry);
|
---|
107 | cs_log_dbg(D_TRACE, "failban: ban ip %s:%d with timestamp %ld%s%s",
|
---|
108 | cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port, v_ban_entry->v_time.time,
|
---|
109 | info ? ", info: " : "", info ? info : "");
|
---|
110 | }
|
---|
111 | }
|
---|
112 |
|
---|
113 | return result;
|
---|
114 | }
|
---|
115 |
|
---|
116 | int32_t cs_check_violation(IN_ADDR_T ip, int32_t port)
|
---|
117 | {
|
---|
118 | return cs_check_v(ip, port, 0, NULL, 0);
|
---|
119 | }
|
---|
120 |
|
---|
121 | int32_t cs_add_violation_by_ip(IN_ADDR_T ip, int32_t port, char *info)
|
---|
122 | {
|
---|
123 | return cs_check_v(ip, port, 1, info, 0);
|
---|
124 | }
|
---|
125 |
|
---|
126 | int32_t cs_add_violation_by_ip_acosc(IN_ADDR_T ip, int32_t port, char *info, int32_t acosc_penalty_duration)
|
---|
127 | {
|
---|
128 | return cs_check_v(ip, port, 1, info, acosc_penalty_duration);
|
---|
129 | }
|
---|
130 |
|
---|
131 | void cs_add_violation(struct s_client *cl, char *info)
|
---|
132 | {
|
---|
133 | struct s_module *module = get_module(cl);
|
---|
134 | cs_add_violation_by_ip(cl->ip, module->ptab.ports[cl->port_idx].s_port, info);
|
---|
135 | }
|
---|
136 |
|
---|
137 | void cs_add_violation_acosc(struct s_client *cl, char *info, int32_t acosc_penalty_duration)
|
---|
138 | {
|
---|
139 | struct s_module *module = get_module(cl);
|
---|
140 | cs_add_violation_by_ip_acosc(cl->ip, module->ptab.ports[cl->port_idx].s_port, info, acosc_penalty_duration);
|
---|
141 | }
|
---|