source: trunk.old/oscam-ac.c@ 2

Last change on this file since 2 was 1, checked in by root, 14 years ago

initial import

File size: 4.6 KB
Line 
1#include "globals.h"
2
3#ifdef CS_ANTICASC
4
5//static time_t ac_last_chk;
6static uchar ac_ecmd5[CS_ECMSTORESIZE];
7struct s_acasc ac_stat[CS_MAXPID];
8
9int ac_init_log(char *file)
10{
11 if( (!fpa) && (file[0]))
12 {
13 if( (fpa=fopen(file, "a+"))<=(FILE *)0 )
14 {
15 fpa=(FILE *)0;
16 fprintf(stderr, "can't open anti-cascading logfile: %s\n", file);
17 }
18 else
19 cs_log("anti-cascading log initialized");
20 }
21
22 return(fpa<=(FILE *)0);
23}
24
25void ac_init_stat(int i)
26{
27 memset(ac_stat, 0, sizeof(ac_stat));
28 memset(acasc, 0, sizeof(acasc));
29
30 if( fpa )
31 fclose(fpa);
32 fpa=(FILE *)0;
33 if( ac_init_log(cfg->ac_logfile) )
34 cs_exit(0);
35}
36
37int idx_from_ac_idx(int ac_idx)
38{
39 int i;
40
41 for( i=0; i<CS_MAXPID; i++ )
42 if( client[i].ac_idx==ac_idx ) return i;
43
44 return -1;
45}
46
47void ac_do_stat()
48{
49 int i, j, idx, exceeds, maxval, prev_deny;
50 int cl_idx;
51
52 for( i=0; i<CS_MAXPID; i++ )
53 {
54 idx = ac_stat[i].idx;
55 ac_stat[i].stat[idx] = acasc[i].count;
56 acasc[i].count=0;
57 cl_idx = idx_from_ac_idx(i);
58
59 if( ac_stat[i].stat[idx] )
60 {
61 if( cl_idx==-1 ) {
62 cs_log("ERROR: can't find client with ac_idx=%d", i);
63 continue;
64 }
65
66 if( client[cl_idx].ac_penalty==2 ) {// banned
67 cs_debug("user '%s' banned", client[cl_idx].usr);
68 acasc[i].deny=1;
69 }
70 else
71 {
72 for( j=exceeds=maxval=0; j<cfg->ac_samples; j++ )
73 {
74 if( ac_stat[i].stat[j] > maxval )
75 maxval=ac_stat[i].stat[j];
76 exceeds+=(ac_stat[i].stat[j]>client[cl_idx].ac_limit);
77 }
78 prev_deny=acasc[i].deny;
79 acasc[i].deny = (exceeds >= cfg->ac_denysamples);
80
81 cs_debug("%s limit=%d, max=%d, samples=%d, dsamples=%d, ac[ci=%d][si=%d]:",
82 client[cl_idx].usr, client[cl_idx].ac_limit, maxval,
83 cfg->ac_samples, cfg->ac_denysamples, i, idx);
84 cs_debug("%d %d %d %d %d %d %d %d %d %d ", ac_stat[i].stat[0],
85 ac_stat[i].stat[1], ac_stat[i].stat[2], ac_stat[i].stat[3],
86 ac_stat[i].stat[4], ac_stat[i].stat[5], ac_stat[i].stat[6],
87 ac_stat[i].stat[7], ac_stat[i].stat[8], ac_stat[i].stat[9]);
88 if( acasc[i].deny ) {
89 cs_log("user '%s' exceeds limit", client[cl_idx].usr);
90 ac_stat[i].stat[idx] = 0;
91 } else if( prev_deny )
92 cs_log("user '%s' restored access", client[cl_idx].usr);
93 }
94 }
95 else if( acasc[i].deny )
96 {
97 prev_deny=1;
98 acasc[i].deny=0;
99 if( cl_idx!=-1 )
100 cs_log("restored access for inactive user '%s'", client[cl_idx].usr);
101 else
102 cs_log("restored access for unknown user (ac_idx=%d)", i);
103 }
104
105 if( !acasc[i].deny && !prev_deny )
106 ac_stat[i].idx = (ac_stat[i].idx + 1) % cfg->ac_samples;
107 }
108}
109
110void ac_init_client(struct s_auth *account)
111{
112 client[cs_idx].ac_idx = account->ac_idx;
113 client[cs_idx].ac_limit = 0;
114 if( cfg->ac_enabled )
115 {
116 if( account->ac_users )
117 {
118 client[cs_idx].ac_limit = (account->ac_users*100+80)*cfg->ac_stime;
119 client[cs_idx].ac_penalty = account->ac_penalty;
120 cs_debug("login '%s', ac_idx=%d, users=%d, stime=%d min, dwlimit=%d per min, penalty=%d",
121 account->usr, account->ac_idx, account->ac_users, cfg->ac_stime,
122 account->ac_users*100+80, account->ac_penalty);
123 }
124 else
125 cs_debug("anti-cascading not used for login '%s'", account->usr);
126 }
127}
128
129static int ac_dw_weight(ECM_REQUEST *er)
130{
131 struct s_cpmap *cpmap;
132
133 for( cpmap=cfg->cpmap; (cpmap) ; cpmap=cpmap->next )
134 if( (cpmap->caid ==0 || cpmap->caid ==er->caid) &&
135 (cpmap->provid==0 || cpmap->provid==er->prid) &&
136 (cpmap->sid ==0 || cpmap->sid ==er->srvid) &&
137 (cpmap->chid ==0 || cpmap->chid ==er->chid) )
138 return (cpmap->dwtime*100/60);
139
140 cs_debug("WARNING: CAID %04X, PROVID %06X, SID %04X, CHID %04X not found in oscam.ac",
141 er->caid, er->prid, er->srvid, er->chid);
142 cs_debug("set DW lifetime 10 sec");
143 return 16; // 10*100/60
144}
145
146void ac_chk(ECM_REQUEST *er, int level)
147{
148 if( !client[cs_idx].ac_limit || !cfg->ac_enabled ) return;
149
150 if( level==1 )
151 {
152 if( er->rc==7 ) acasc[client[cs_idx].ac_idx].count++;
153 if( er->rc>3 ) return; // not found
154 if( memcmp(ac_ecmd5, er->ecmd5, CS_ECMSTORESIZE) != 0 )
155 {
156 acasc[client[cs_idx].ac_idx].count+=ac_dw_weight(er);
157 memcpy(ac_ecmd5, er->ecmd5, CS_ECMSTORESIZE);
158 }
159 return;
160 }
161
162 if( acasc[client[cs_idx].ac_idx].deny )
163 if( client[cs_idx].ac_penalty )
164 {
165 cs_debug("send fake dw");
166 er->rc=7; // fake
167 er->rcEx=0;
168 cs_sleepms(cfg->ac_fakedelay);
169 }
170}
171#endif
Note: See TracBrowser for help on using the repository browser.