1 | #define MODULE_LOG_PREFIX "config"
|
---|
2 |
|
---|
3 | #include "globals.h"
|
---|
4 | #include "module-anticasc.h"
|
---|
5 | #include "oscam-array.h"
|
---|
6 | #include "oscam-client.h"
|
---|
7 | #include "oscam-conf.h"
|
---|
8 | #include "oscam-conf-chk.h"
|
---|
9 | #include "oscam-conf-mk.h"
|
---|
10 | #include "oscam-config.h"
|
---|
11 | #include "oscam-garbage.h"
|
---|
12 | #include "oscam-lock.h"
|
---|
13 | #include "oscam-string.h"
|
---|
14 | #ifdef CS_CACHEEX_AIO
|
---|
15 | #include "module-cacheex.h"
|
---|
16 | #endif
|
---|
17 | #define cs_user "oscam.user"
|
---|
18 |
|
---|
19 | static void account_tosleep_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
20 | {
|
---|
21 | int32_t *tosleep = setting;
|
---|
22 | if(value)
|
---|
23 | {
|
---|
24 | *tosleep = strToIntVal(value, cfg.tosleep);
|
---|
25 | return;
|
---|
26 | }
|
---|
27 | if(*tosleep != cfg.tosleep || cfg.http_full_cfg)
|
---|
28 | { fprintf_conf(f, token, "%d\n", *tosleep); }
|
---|
29 | }
|
---|
30 |
|
---|
31 | static void account_c35_suppresscmd08_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
32 | {
|
---|
33 | int8_t *c35_suppresscmd08 = setting;
|
---|
34 | if(value)
|
---|
35 | {
|
---|
36 | *c35_suppresscmd08 = (int8_t)strToIntVal(value, cfg.c35_suppresscmd08);
|
---|
37 | return;
|
---|
38 | }
|
---|
39 | if(*c35_suppresscmd08 != cfg.c35_suppresscmd08 || cfg.http_full_cfg)
|
---|
40 | { fprintf_conf(f, token, "%d\n", *c35_suppresscmd08); }
|
---|
41 | }
|
---|
42 |
|
---|
43 | /*static void account_umaxidle_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
44 | {
|
---|
45 | int32_t *umaxidle = setting;
|
---|
46 | if(value)
|
---|
47 | {
|
---|
48 | *umaxidle = (int32_t)strToIntVal(value, cfg.umaxidle);
|
---|
49 | return;
|
---|
50 | }
|
---|
51 | if(*umaxidle != cfg.umaxidle || cfg.http_full_cfg)
|
---|
52 | { fprintf_conf(f, token, "%u\n", *umaxidle); }
|
---|
53 | }
|
---|
54 | */
|
---|
55 |
|
---|
56 | static void account_ncd_keepalive_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
57 | {
|
---|
58 | int8_t *ncd_keepalive = setting;
|
---|
59 | int8_t def_value = 0;
|
---|
60 | #ifdef MODULE_NEWCAMD
|
---|
61 | def_value = cfg.ncd_keepalive;
|
---|
62 | #endif
|
---|
63 | if(value)
|
---|
64 | {
|
---|
65 | *ncd_keepalive = (int8_t)strToIntVal(value, def_value);
|
---|
66 | return;
|
---|
67 | }
|
---|
68 | if(*ncd_keepalive != def_value || cfg.http_full_cfg)
|
---|
69 | { fprintf_conf(f, token, "%d\n", *ncd_keepalive); }
|
---|
70 | }
|
---|
71 |
|
---|
72 | static void account_allowedprotocols_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
73 | {
|
---|
74 | struct s_auth *account = setting;
|
---|
75 | if(value)
|
---|
76 | {
|
---|
77 | account->allowedprotocols = 0;
|
---|
78 | if(cs_strlen(value) > 3)
|
---|
79 | {
|
---|
80 | int i;
|
---|
81 | char *ptr, *saveptr1 = NULL;
|
---|
82 | for(i = 0, ptr = strtok_r(value, ",", &saveptr1); ptr; ptr = strtok_r(NULL, ",", &saveptr1), i++)
|
---|
83 | {
|
---|
84 | if(streq(ptr, "camd33")) { account->allowedprotocols |= LIS_CAMD33TCP; }
|
---|
85 | else if(streq(ptr, "camd35")) { account->allowedprotocols |= LIS_CAMD35UDP; }
|
---|
86 | else if(streq(ptr, "cs357x")) { account->allowedprotocols |= LIS_CAMD35UDP; }
|
---|
87 | else if(streq(ptr, "cs378x")) { account->allowedprotocols |= LIS_CAMD35TCP; }
|
---|
88 | else if(streq(ptr, "newcamd")) { account->allowedprotocols |= LIS_NEWCAMD; }
|
---|
89 | else if(streq(ptr, "cccam")) { account->allowedprotocols |= LIS_CCCAM; }
|
---|
90 | else if(streq(ptr, "csp")) { account->allowedprotocols |= LIS_CSPUDP; }
|
---|
91 | else if(streq(ptr, "gbox")) { account->allowedprotocols |= LIS_GBOX; }
|
---|
92 | else if(streq(ptr, "radegast")) { account->allowedprotocols |= LIS_RADEGAST; }
|
---|
93 | else if(streq(ptr, "scam")) { account->allowedprotocols |= LIS_SCAM; }
|
---|
94 | // these have no listener ports so it doesn't make sense
|
---|
95 | else if(streq(ptr, "dvbapi")) { account->allowedprotocols |= LIS_DVBAPI; }
|
---|
96 | else if(streq(ptr, "constcw")) { account->allowedprotocols |= LIS_CONSTCW; }
|
---|
97 | else if(streq(ptr, "serial")) { account->allowedprotocols |= LIS_SERIAL; }
|
---|
98 | }
|
---|
99 | }
|
---|
100 | return;
|
---|
101 | }
|
---|
102 | if(account->allowedprotocols || cfg.http_full_cfg)
|
---|
103 | {
|
---|
104 | value = mk_t_allowedprotocols(account);
|
---|
105 | fprintf_conf(f, token, "%s\n", value);
|
---|
106 | free_mk_t(value);
|
---|
107 | }
|
---|
108 | }
|
---|
109 |
|
---|
110 | static void account_au_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
111 | {
|
---|
112 | struct s_auth *account = setting;
|
---|
113 | if(value)
|
---|
114 | {
|
---|
115 | // set default values for usage during runtime from Webif
|
---|
116 | account->autoau = 0;
|
---|
117 | if(!account->aureader_list)
|
---|
118 | { account->aureader_list = ll_create("aureader_list"); }
|
---|
119 | if(streq(value, "1"))
|
---|
120 | { account->autoau = 1; }
|
---|
121 | ll_clear(account->aureader_list);
|
---|
122 | LL_ITER itr = ll_iter_create(configured_readers);
|
---|
123 | struct s_reader *rdr;
|
---|
124 | char *pch, *saveptr1 = NULL;
|
---|
125 | for(pch = strtok_r(value, ",", &saveptr1); pch != NULL; pch = strtok_r(NULL, ",", &saveptr1))
|
---|
126 | {
|
---|
127 | ll_iter_reset(&itr);
|
---|
128 | while((rdr = ll_iter_next(&itr)))
|
---|
129 | {
|
---|
130 | if(streq(rdr->label, pch) || account->autoau)
|
---|
131 | {
|
---|
132 | ll_append(account->aureader_list, rdr);
|
---|
133 | }
|
---|
134 | }
|
---|
135 | }
|
---|
136 | return;
|
---|
137 | }
|
---|
138 | if(account->autoau == 1)
|
---|
139 | {
|
---|
140 | fprintf_conf(f, token, "%d\n", account->autoau);
|
---|
141 | }
|
---|
142 | else if(account->aureader_list)
|
---|
143 | {
|
---|
144 | value = mk_t_aureader(account);
|
---|
145 | if(cs_strlen(value) > 0)
|
---|
146 | { fprintf_conf(f, token, "%s\n", value); }
|
---|
147 | free_mk_t(value);
|
---|
148 | }
|
---|
149 | else if(cfg.http_full_cfg)
|
---|
150 | {
|
---|
151 | fprintf_conf(f, token, "%s\n", "");
|
---|
152 | }
|
---|
153 | }
|
---|
154 |
|
---|
155 | static void account_expdate_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
156 | {
|
---|
157 | struct s_auth *account = setting;
|
---|
158 | if(value)
|
---|
159 | {
|
---|
160 | if(!value[0])
|
---|
161 | {
|
---|
162 | account->expirationdate = (time_t)NULL;
|
---|
163 | return;
|
---|
164 | }
|
---|
165 | int i;
|
---|
166 | struct tm cstime;
|
---|
167 | char *ptr1, *saveptr1 = NULL;
|
---|
168 | memset(&cstime, 0, sizeof(cstime));
|
---|
169 | for(i = 0, ptr1 = strtok_r(value, "-/", &saveptr1); i < 3 && ptr1; ptr1 = strtok_r(NULL, "-/", &saveptr1), i++)
|
---|
170 | {
|
---|
171 | switch(i)
|
---|
172 | {
|
---|
173 | case 0:
|
---|
174 | cstime.tm_year = atoi(ptr1) - 1900;
|
---|
175 | break;
|
---|
176 | case 1:
|
---|
177 | cstime.tm_mon = atoi(ptr1) - 1;
|
---|
178 | break;
|
---|
179 | case 2:
|
---|
180 | cstime.tm_mday = atoi(ptr1);
|
---|
181 | break;
|
---|
182 | }
|
---|
183 | }
|
---|
184 | cstime.tm_hour = 23;
|
---|
185 | cstime.tm_min = 59;
|
---|
186 | cstime.tm_sec = 59;
|
---|
187 | cstime.tm_isdst = -1;
|
---|
188 | account->expirationdate = mktime(&cstime);
|
---|
189 | return;
|
---|
190 | }
|
---|
191 | if(account->expirationdate || cfg.http_full_cfg)
|
---|
192 | {
|
---|
193 | char buf[16];
|
---|
194 | struct tm timeinfo;
|
---|
195 | localtime_r(&account->expirationdate, &timeinfo);
|
---|
196 | strftime(buf, 16, "%Y-%m-%d", &timeinfo);
|
---|
197 | fprintf_conf(f, token, "%s\n", streq(buf, "1970-01-01") ? "" : buf);
|
---|
198 | }
|
---|
199 | }
|
---|
200 |
|
---|
201 | static void account_allowedtimeframe_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
202 | {
|
---|
203 | struct s_auth *account = setting;
|
---|
204 | int32_t i, j, t, startt, endt;
|
---|
205 | char *dest;
|
---|
206 | uint8_t day_idx;
|
---|
207 | int32_t allowed[4];
|
---|
208 | uint32_t tempo = 0;
|
---|
209 |
|
---|
210 | char *ptr1, *ptr2, *ptr3, *saveptr1 = NULL, *saveptr2 = NULL;
|
---|
211 |
|
---|
212 | if(value)
|
---|
213 | {
|
---|
214 | //First empty allowedtimeframe array very important otherwise new config won't be properly set
|
---|
215 | for(i = 0; i < SIZE_SHORTDAY; i++)
|
---|
216 | {
|
---|
217 | for(j = 0; j < 24; j++)
|
---|
218 | {
|
---|
219 | account->allowedtimeframe[i][j][0] = 0;
|
---|
220 | account->allowedtimeframe[i][j][1] = 0;
|
---|
221 | }
|
---|
222 | }
|
---|
223 | account->allowedtimeframe_set=0;
|
---|
224 | strtoupper(value);
|
---|
225 |
|
---|
226 | for(i = 0, ptr1 = strtok_r(value, ";", &saveptr1); (ptr1); ptr1 = strtok_r(NULL, ";", &saveptr1), i++)
|
---|
227 | {
|
---|
228 | if((ptr2 = strchr(trim(ptr1), '@')))
|
---|
229 | {
|
---|
230 | *ptr2++ = '\0'; // clean up @ symbol
|
---|
231 | // ptr1 is the day
|
---|
232 | dest = strstr(weekdstr,ptr1);
|
---|
233 | day_idx = (dest - weekdstr) / 3;
|
---|
234 |
|
---|
235 | for(j = 0, ptr3 = strtok_r(ptr2, ",", &saveptr2); (ptr3); ptr3 = strtok_r(NULL, ",", &saveptr2), j++)
|
---|
236 | {
|
---|
237 | if((sscanf(ptr3, "%2d:%2d-%2d:%2d", &allowed[0], &allowed[1], &allowed[2], &allowed[3]) == 4) && (day_idx < SIZE_SHORTDAY))
|
---|
238 | {
|
---|
239 | startt = allowed[0] * 60 + allowed[1];
|
---|
240 | endt = allowed[2] * 60 + allowed[3];
|
---|
241 |
|
---|
242 | if(startt == endt) { endt++; } // end time cannot be the same as the star time
|
---|
243 | if((startt < 0) || (startt > 1439)) { startt = 0; } // could not start later than 23H59, avoid overflow
|
---|
244 | if((endt < 0) || (endt > 1440)) { endt = 1440; } // could not be higher than 24H00, avoid overflow
|
---|
245 |
|
---|
246 | account->allowedtimeframe_set = 1;
|
---|
247 |
|
---|
248 | if(startt > endt)
|
---|
249 | {
|
---|
250 | for(t = startt; t < 1440; t++)
|
---|
251 | {
|
---|
252 | tempo = (1 << (t % 30));
|
---|
253 | account->allowedtimeframe[day_idx][t / 60][(t / 30) % 2] = account->allowedtimeframe[day_idx][t / 60][(t / 30) % 2] | tempo;
|
---|
254 | }
|
---|
255 | startt = 0;
|
---|
256 | }
|
---|
257 |
|
---|
258 | for(t = startt; t < endt; t++)
|
---|
259 | {
|
---|
260 | tempo = (1 << (t % 30));
|
---|
261 | account->allowedtimeframe[day_idx][t / 60][((t / 30) % 2)] = account->allowedtimeframe[day_idx][t / 60][(t / 30) % 2] | tempo;
|
---|
262 | }
|
---|
263 | }
|
---|
264 | else
|
---|
265 | {
|
---|
266 | fprintf(stderr, "WARNING: Value '%s' is not valid for allowedtimeframe (DAY@HH:MM-HH:MM)\n", value);
|
---|
267 | }
|
---|
268 | }
|
---|
269 | }
|
---|
270 | else // No day specified so whole week (ALL)
|
---|
271 | {
|
---|
272 | if(sscanf(ptr1, "%2d:%2d-%2d:%2d", &allowed[0], &allowed[1], &allowed[2], &allowed[3]) == 4)
|
---|
273 | {
|
---|
274 | startt = allowed[0] * 60 + allowed[1];
|
---|
275 | endt = allowed[2] * 60 + allowed[3];
|
---|
276 |
|
---|
277 | if(startt == endt) { endt++; } // end time cannot be the same as the star time
|
---|
278 | if((startt <0) || (startt > 1439)) { startt = 0; } // could not start later than 23H59, avoid overflow
|
---|
279 | if((endt <0) || (endt > 1440)) { endt = 1440; } // could not be higher than 24H00, avoid overflow
|
---|
280 |
|
---|
281 | account->allowedtimeframe_set = 1;
|
---|
282 | dest = strstr(weekdstr,"ALL");
|
---|
283 | day_idx = (dest - weekdstr) / 3;
|
---|
284 |
|
---|
285 | if(startt > endt)
|
---|
286 | {
|
---|
287 | for(t = startt; t < 1440; t++)
|
---|
288 | {
|
---|
289 | tempo = (1 << (t % 30));
|
---|
290 | account->allowedtimeframe[day_idx][t / 60][(t / 30) % 2] = account->allowedtimeframe[7][t / 60][(t / 30) % 2] | tempo;
|
---|
291 | }
|
---|
292 | startt=0;
|
---|
293 | }
|
---|
294 |
|
---|
295 | for(t = startt; t < endt; t++)
|
---|
296 | {
|
---|
297 | tempo = (1 << (t % 30));
|
---|
298 | account->allowedtimeframe[day_idx][t / 60][(t / 30) % 2] = account->allowedtimeframe[7][t / 60][(t / 30) % 2] | tempo;
|
---|
299 | }
|
---|
300 | }
|
---|
301 | else
|
---|
302 | {
|
---|
303 | fprintf(stderr, "WARNING: Value '%s' is not valid for allowedtimeframe (hh:mm-hh:mm)\n", value);
|
---|
304 | }
|
---|
305 |
|
---|
306 | }
|
---|
307 | }
|
---|
308 | return;
|
---|
309 | }
|
---|
310 | if(account->allowedtimeframe_set)
|
---|
311 | {
|
---|
312 | value = mk_t_allowedtimeframe(account);
|
---|
313 | fprintf_conf(f, token, "%s\n", value);
|
---|
314 | free_mk_t(value);
|
---|
315 | }
|
---|
316 | else if(cfg.http_full_cfg)
|
---|
317 | {
|
---|
318 | fprintf_conf(f, token, "%s\n", "");
|
---|
319 | }
|
---|
320 | }
|
---|
321 |
|
---|
322 | static void account_tuntab_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
323 | {
|
---|
324 | TUNTAB *ttab = setting;
|
---|
325 | if(value)
|
---|
326 | {
|
---|
327 | if(cs_strlen(value) == 0)
|
---|
328 | {
|
---|
329 | tuntab_clear(ttab);
|
---|
330 | }
|
---|
331 | else
|
---|
332 | {
|
---|
333 | chk_tuntab(value, ttab);
|
---|
334 | }
|
---|
335 | return;
|
---|
336 | }
|
---|
337 | if((ttab->ttdata && ttab->ttdata[0].bt_caidfrom) || cfg.http_full_cfg)
|
---|
338 | {
|
---|
339 | value = mk_t_tuntab(ttab);
|
---|
340 | fprintf_conf(f, token, "%s\n", value);
|
---|
341 | free_mk_t(value);
|
---|
342 | }
|
---|
343 | }
|
---|
344 |
|
---|
345 | void group_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
346 | {
|
---|
347 | uint64_t *grp = setting;
|
---|
348 | if(value)
|
---|
349 | {
|
---|
350 | char *ptr1, *saveptr1 = NULL;
|
---|
351 | *grp = 0;
|
---|
352 | for(ptr1 = strtok_r(value, ",", &saveptr1); ptr1; ptr1 = strtok_r(NULL, ",", &saveptr1))
|
---|
353 | {
|
---|
354 | int32_t g;
|
---|
355 | g = atoi(ptr1);
|
---|
356 | if(g > 0 && g < 65)
|
---|
357 | { *grp |= (((uint64_t)1) << (g - 1)); }
|
---|
358 | }
|
---|
359 | return;
|
---|
360 | }
|
---|
361 | if(*grp || cfg.http_full_cfg)
|
---|
362 | {
|
---|
363 | value = mk_t_group(*grp);
|
---|
364 | fprintf_conf(f, token, "%s\n", value);
|
---|
365 | free_mk_t(value);
|
---|
366 | }
|
---|
367 | }
|
---|
368 |
|
---|
369 | void services_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
370 | {
|
---|
371 | SIDTABS *sidtabs = setting;
|
---|
372 | if(value)
|
---|
373 | {
|
---|
374 | strtolower(value);
|
---|
375 | chk_services(value, sidtabs);
|
---|
376 | return;
|
---|
377 | }
|
---|
378 | value = mk_t_service(sidtabs);
|
---|
379 | if(cs_strlen(value) > 0 || cfg.http_full_cfg)
|
---|
380 | { fprintf_conf(f, token, "%s\n", value); }
|
---|
381 | free_mk_t(value);
|
---|
382 | }
|
---|
383 |
|
---|
384 | void class_fn(const char *token, char *value, void *setting, FILE *f)
|
---|
385 | {
|
---|
386 | CLASSTAB *cltab = setting;
|
---|
387 | if(value)
|
---|
388 | {
|
---|
389 | strtolower(value);
|
---|
390 | chk_cltab(value, cltab);
|
---|
391 | return;
|
---|
392 | }
|
---|
393 | value = mk_t_cltab(cltab);
|
---|
394 | if(cs_strlen(value) > 0 || cfg.http_full_cfg)
|
---|
395 | {
|
---|
396 | fprintf_conf(f, token, "%s\n", value);
|
---|
397 | free_mk_t(value);
|
---|
398 | }
|
---|
399 | }
|
---|
400 |
|
---|
401 | #if defined(CS_ANTICASC) || defined(CS_CACHEEX_AIO)
|
---|
402 | static void account_fixups_fn(void *var)
|
---|
403 | {
|
---|
404 | struct s_auth *account = var;
|
---|
405 | #endif
|
---|
406 | #if defined(CS_ANTICASC)
|
---|
407 | if(account->ac_users < -1) { account->ac_users = DEFAULT_AC_USERS; }
|
---|
408 | if(account->ac_penalty < -1) { account->ac_penalty = DEFAULT_AC_PENALTY; }
|
---|
409 | if(account->acosc_max_ecms_per_minute < -1) { account->acosc_max_ecms_per_minute = -1; }
|
---|
410 | if(account->acosc_max_active_sids < -1) { account->acosc_max_active_sids = -1; }
|
---|
411 | if(account->acosc_zap_limit < -1) { account->acosc_zap_limit = -1; }
|
---|
412 | if(account->acosc_penalty < -1) { account->acosc_penalty = -1; }
|
---|
413 | if(account->acosc_penalty_duration < -1) { account->acosc_penalty_duration = -1; }
|
---|
414 | if(account->acosc_delay < -1) { account->acosc_delay = -1; }
|
---|
415 | if((account->acosc_penalty == 4) || ((cfg.acosc_penalty == 4) && (account->acosc_penalty == -1)))
|
---|
416 | {
|
---|
417 | account->acosc_max_active_sids = -1; // use global value
|
---|
418 | account->acosc_zap_limit = -1; // use global value
|
---|
419 | account->acosc_penalty_duration = -1; // use global value
|
---|
420 |
|
---|
421 | if((account->acosc_max_ecms_per_minute != -1) && (account->acosc_max_ecms_per_minute != 0))
|
---|
422 | {
|
---|
423 | if(account->acosc_max_ecms_per_minute < 6) { account->acosc_max_ecms_per_minute = 6; }
|
---|
424 | if(account->acosc_max_ecms_per_minute > 20) { account->acosc_max_ecms_per_minute = 20; }
|
---|
425 | account->acosc_penalty_duration = (60 / account->acosc_max_ecms_per_minute);
|
---|
426 | }
|
---|
427 | }
|
---|
428 | #endif
|
---|
429 | #if defined(CS_CACHEEX_AIO)
|
---|
430 | // lgo-ctab -> lgo-ftab port
|
---|
431 | caidtab2ftab_add(&account->cacheex.localgenerated_only_in_caidtab, &account->cacheex.lg_only_in_tab);
|
---|
432 | caidtab_clear(&account->cacheex.localgenerated_only_in_caidtab);
|
---|
433 | caidtab2ftab_add(&account->cacheex.localgenerated_only_caidtab, &account->cacheex.lg_only_tab);
|
---|
434 | caidtab_clear(&account->cacheex.localgenerated_only_caidtab);
|
---|
435 | #endif
|
---|
436 | #if defined(CS_ANTICASC) || defined(CS_CACHEEX_AIO)
|
---|
437 | }
|
---|
438 | #endif
|
---|
439 |
|
---|
440 | #define OFS(X) offsetof(struct s_auth, X)
|
---|
441 | #define SIZEOF(X) sizeof(((struct s_auth *)0)->X)
|
---|
442 |
|
---|
443 | static const struct config_list account_opts[] =
|
---|
444 | {
|
---|
445 | #if defined(CS_ANTICASC) || defined(CS_CACHEEX_AIO)
|
---|
446 | DEF_OPT_FIXUP_FUNC(account_fixups_fn),
|
---|
447 | #endif
|
---|
448 | DEF_OPT_INT8("disabled" , OFS(disabled), 0),
|
---|
449 | DEF_OPT_SSTR("user" , OFS(usr), "", SIZEOF(usr)),
|
---|
450 | DEF_OPT_STR("pwd" , OFS(pwd), NULL),
|
---|
451 | #ifdef WEBIF
|
---|
452 | DEF_OPT_STR("description" , OFS(description), NULL),
|
---|
453 | #endif
|
---|
454 | DEF_OPT_STR("hostname" , OFS(dyndns), NULL),
|
---|
455 | DEF_OPT_FUNC("caid" , OFS(ctab), check_caidtab_fn),
|
---|
456 | DEF_OPT_INT8("uniq" , OFS(uniq), 0),
|
---|
457 | DEF_OPT_UINT8("sleepsend" , OFS(c35_sleepsend), 0),
|
---|
458 | DEF_OPT_INT32("failban" , OFS(failban), 0),
|
---|
459 | DEF_OPT_INT8("monlevel" , OFS(monlvl), 0),
|
---|
460 | DEF_OPT_FUNC("sleep" , OFS(tosleep), account_tosleep_fn),
|
---|
461 | DEF_OPT_FUNC("suppresscmd08" , OFS(c35_suppresscmd08), account_c35_suppresscmd08_fn),
|
---|
462 | DEF_OPT_INT32("umaxidle" , OFS(umaxidle), -1),
|
---|
463 | DEF_OPT_FUNC("keepalive" , OFS(ncd_keepalive), account_ncd_keepalive_fn),
|
---|
464 | DEF_OPT_FUNC("au" , 0, account_au_fn),
|
---|
465 | DEF_OPT_UINT8("emmreassembly" , OFS(emm_reassembly), 2),
|
---|
466 | DEF_OPT_FUNC("expdate" , 0, account_expdate_fn),
|
---|
467 | DEF_OPT_FUNC("allowedprotocols" , 0, account_allowedprotocols_fn),
|
---|
468 | DEF_OPT_FUNC("allowedtimeframe" , 0, account_allowedtimeframe_fn),
|
---|
469 | DEF_OPT_FUNC("betatunnel" , OFS(ttab), account_tuntab_fn),
|
---|
470 | DEF_OPT_FUNC("group" , OFS(grp), group_fn),
|
---|
471 | DEF_OPT_FUNC("services" , OFS(sidtabs), services_fn),
|
---|
472 | DEF_OPT_INT8("preferlocalcards" , OFS(preferlocalcards), -1),
|
---|
473 | DEF_OPT_FUNC_X("ident" , OFS(ftab), ftab_fn, FTAB_ACCOUNT | FTAB_PROVID),
|
---|
474 | DEF_OPT_FUNC_X("chid" , OFS(fchid), ftab_fn, FTAB_ACCOUNT | FTAB_CHID),
|
---|
475 | DEF_OPT_FUNC("class" , OFS(cltab), class_fn),
|
---|
476 | DEF_OPT_UINT32("max_connections" , OFS(max_connections), 1),
|
---|
477 | #ifdef CS_CACHEEX
|
---|
478 | DEF_OPT_INT8("cacheex" , OFS(cacheex.mode), 0),
|
---|
479 | DEF_OPT_INT8("cacheex_maxhop" , OFS(cacheex.maxhop), 0),
|
---|
480 | #ifdef CS_CACHEEX_AIO
|
---|
481 | DEF_OPT_INT8("cacheex_maxhop_lg" , OFS(cacheex.maxhop_lg), 0),
|
---|
482 | #endif
|
---|
483 | DEF_OPT_FUNC("cacheex_ecm_filter" , OFS(cacheex.filter_caidtab), cacheex_hitvaluetab_fn),
|
---|
484 | DEF_OPT_UINT8("cacheex_drop_csp" , OFS(cacheex.drop_csp), 0),
|
---|
485 | DEF_OPT_UINT8("cacheex_allow_request" , OFS(cacheex.allow_request), 0),
|
---|
486 | DEF_OPT_UINT8("no_wait_time" , OFS(no_wait_time), 0),
|
---|
487 | DEF_OPT_UINT8("cacheex_allow_filter" , OFS(cacheex.allow_filter), 1),
|
---|
488 | #ifdef CS_CACHEEX_AIO
|
---|
489 | DEF_OPT_UINT8("cacheex_allow_maxhop" , OFS(cacheex.allow_maxhop), 0),
|
---|
490 | #endif
|
---|
491 | DEF_OPT_UINT8("cacheex_block_fakecws" , OFS(cacheex.block_fakecws), 0),
|
---|
492 | DEF_OPT_UINT8("disablecrccacheex" , OFS(disablecrccacheex), 0),
|
---|
493 | DEF_OPT_FUNC_X("disablecrccacheex_only_for", OFS(disablecrccacheex_only_for), ftab_fn, FTAB_ACCOUNT | FTAB_IGNCRCCEX4USERONLYFOR),
|
---|
494 | #ifdef CS_CACHEEX_AIO
|
---|
495 | DEF_OPT_UINT8("cacheex_cw_check_for_push" , OFS(cacheex.cw_check_for_push), 0),
|
---|
496 | DEF_OPT_UINT8("cacheex_lg_only_remote_settings", OFS(cacheex.lg_only_remote_settings), 1),
|
---|
497 | DEF_OPT_UINT8("cacheex_localgenerated_only", OFS(cacheex.localgenerated_only), 0),
|
---|
498 | DEF_OPT_FUNC("cacheex_localgenerated_only_caid", OFS(cacheex.localgenerated_only_caidtab), check_caidtab_fn),
|
---|
499 | DEF_OPT_FUNC_X("cacheex_lg_only_tab" , OFS(cacheex.lg_only_tab), ftab_fn, 0),
|
---|
500 | DEF_OPT_UINT8("cacheex_lg_only_in_aio_only", OFS(cacheex.lg_only_in_aio_only), 0),
|
---|
501 | DEF_OPT_UINT8("cacheex_localgenerated_only_in", OFS(cacheex.localgenerated_only_in), 0),
|
---|
502 | DEF_OPT_FUNC("cacheex_localgenerated_only_in_caid", OFS(cacheex.localgenerated_only_in_caidtab), check_caidtab_fn),
|
---|
503 | DEF_OPT_FUNC_X("cacheex_lg_only_in_tab" , OFS(cacheex.lg_only_in_tab), ftab_fn, 0),
|
---|
504 | DEF_OPT_FUNC("cacheex_nopushafter" , OFS(cacheex.cacheex_nopushafter_tab), caidvaluetab_fn),
|
---|
505 | #endif
|
---|
506 | #endif
|
---|
507 | #ifdef MODULE_CCCAM
|
---|
508 | DEF_OPT_INT32("cccmaxhops" , OFS(cccmaxhops), DEFAULT_CC_MAXHOPS),
|
---|
509 | DEF_OPT_INT8("cccreshare" , OFS(cccreshare), DEFAULT_CC_RESHARE),
|
---|
510 | DEF_OPT_INT8("cccignorereshare" , OFS(cccignorereshare), DEFAULT_CC_IGNRSHR),
|
---|
511 | DEF_OPT_INT8("cccstealth" , OFS(cccstealth), DEFAULT_CC_STEALTH),
|
---|
512 | #endif
|
---|
513 | #ifdef CS_ANTICASC
|
---|
514 | DEF_OPT_INT32("fakedelay" , OFS(ac_fakedelay), -1),
|
---|
515 | DEF_OPT_INT32("numusers" , OFS(ac_users), DEFAULT_AC_USERS),
|
---|
516 | DEF_OPT_INT8("penalty" , OFS(ac_penalty), DEFAULT_AC_PENALTY),
|
---|
517 | DEF_OPT_INT8("acosc_max_ecms_per_minute" , OFS(acosc_max_ecms_per_minute), -1 ),
|
---|
518 | DEF_OPT_INT8("acosc_max_active_sids" , OFS(acosc_max_active_sids), -1 ),
|
---|
519 | DEF_OPT_INT8("acosc_zap_limit" , OFS(acosc_zap_limit), -1 ),
|
---|
520 | DEF_OPT_INT8("acosc_penalty" , OFS(acosc_penalty), -1 ),
|
---|
521 | DEF_OPT_INT32("acosc_penalty_duration" , OFS(acosc_penalty_duration), -1 ),
|
---|
522 | DEF_OPT_INT32("acosc_delay" , OFS(acosc_delay), -1 ),
|
---|
523 | #endif
|
---|
524 | #ifdef WITH_LB
|
---|
525 | DEF_OPT_INT32("lb_nbest_readers" , OFS(lb_nbest_readers), -1),
|
---|
526 | DEF_OPT_INT32("lb_nfb_readers" , OFS(lb_nfb_readers), -1),
|
---|
527 | DEF_OPT_FUNC("lb_nbest_percaid" , OFS(lb_nbest_readers_tab), caidvaluetab_fn),
|
---|
528 | #endif
|
---|
529 | #ifdef CW_CYCLE_CHECK
|
---|
530 | DEF_OPT_INT8("cwc_disable" , OFS(cwc_disable), 0),
|
---|
531 | #endif
|
---|
532 | DEF_LAST_OPT
|
---|
533 | };
|
---|
534 |
|
---|
535 | void chk_account(const char *token, char *value, struct s_auth *account)
|
---|
536 | {
|
---|
537 | if(config_list_parse(account_opts, token, value, account))
|
---|
538 | { return; }
|
---|
539 | else if(token[0] != '#')
|
---|
540 | { fprintf(stderr, "Warning: keyword '%s' in account section not recognized\n", token); }
|
---|
541 | }
|
---|
542 |
|
---|
543 | void account_set_defaults(struct s_auth *account)
|
---|
544 | {
|
---|
545 | config_list_set_defaults(account_opts, account);
|
---|
546 | }
|
---|
547 |
|
---|
548 | struct s_auth *init_userdb(void)
|
---|
549 | {
|
---|
550 | FILE *fp = open_config_file(cs_user);
|
---|
551 | if(!fp)
|
---|
552 | { return NULL; }
|
---|
553 |
|
---|
554 | struct s_auth *authptr = NULL;
|
---|
555 | int32_t tag = 0, nr = 0, expired = 0, disabled = 0;
|
---|
556 | char *token;
|
---|
557 | struct s_auth *account = NULL;
|
---|
558 | struct s_auth *probe = NULL;
|
---|
559 | if(!cs_malloc(&token, MAXLINESIZE))
|
---|
560 | { return NULL; }
|
---|
561 |
|
---|
562 | while(fgets(token, MAXLINESIZE, fp))
|
---|
563 | {
|
---|
564 | int32_t l;
|
---|
565 | void *ptr;
|
---|
566 |
|
---|
567 | if((l = cs_strlen(trim(token))) < 3)
|
---|
568 | { continue; }
|
---|
569 | if(token[0] == '[' && token[l - 1] == ']')
|
---|
570 | {
|
---|
571 | token[l - 1] = 0;
|
---|
572 | tag = streq("account", strtolower(token + 1));
|
---|
573 | if(!cs_malloc(&ptr, sizeof(struct s_auth)))
|
---|
574 | { break; }
|
---|
575 | if(account)
|
---|
576 | { account->next = ptr; }
|
---|
577 | else
|
---|
578 | { authptr = ptr; }
|
---|
579 |
|
---|
580 | account = ptr;
|
---|
581 | account_set_defaults(account);
|
---|
582 | nr++;
|
---|
583 |
|
---|
584 | continue;
|
---|
585 | }
|
---|
586 |
|
---|
587 | if(!tag)
|
---|
588 | { continue; }
|
---|
589 | char *value = strchr(token, '=');
|
---|
590 | if(!value)
|
---|
591 | { continue; }
|
---|
592 |
|
---|
593 | *value++ = '\0';
|
---|
594 |
|
---|
595 | // check for duplicate useraccounts and make the name unique
|
---|
596 | if(streq(trim(strtolower(token)), "user"))
|
---|
597 | {
|
---|
598 | for(probe = authptr; probe; probe = probe->next)
|
---|
599 | {
|
---|
600 | if(!strcmp(probe->usr, trim(value)))
|
---|
601 | {
|
---|
602 | fprintf(stderr, "Warning: duplicate account '%s'\n", value);
|
---|
603 | if (!cs_strncat(value, "_x", sizeof(probe->usr))) {
|
---|
604 | cs_log("WARNING, bug here!");
|
---|
605 | }
|
---|
606 | }
|
---|
607 | }
|
---|
608 | }
|
---|
609 | chk_account(trim(strtolower(token)), trim(value), account);
|
---|
610 | }
|
---|
611 | NULLFREE(token);
|
---|
612 | fclose(fp);
|
---|
613 |
|
---|
614 | for(account = authptr; account; account = account->next)
|
---|
615 | {
|
---|
616 | if(account->expirationdate && account->expirationdate < time(NULL))
|
---|
617 | { ++expired; }
|
---|
618 | if(account->disabled)
|
---|
619 | { ++disabled; }
|
---|
620 | }
|
---|
621 | cs_log("userdb reloaded: %d accounts loaded, %d expired, %d disabled", nr, expired, disabled);
|
---|
622 | return authptr;
|
---|
623 | }
|
---|
624 |
|
---|
625 | int32_t init_free_userdb(struct s_auth *ptr)
|
---|
626 | {
|
---|
627 | int32_t nro;
|
---|
628 | for(nro = 0; ptr; nro++)
|
---|
629 | {
|
---|
630 | struct s_auth *ptr_next;
|
---|
631 | ptr_next = ptr->next;
|
---|
632 | ll_destroy(&ptr->aureader_list);
|
---|
633 | ptr->next = NULL;
|
---|
634 | config_list_gc_values(account_opts, ptr);
|
---|
635 | ftab_clear(&ptr->ftab);
|
---|
636 | ftab_clear(&ptr->fchid);
|
---|
637 | tuntab_clear(&ptr->ttab);
|
---|
638 | caidtab_clear(&ptr->ctab);
|
---|
639 | NULLFREE(ptr->cltab.aclass);
|
---|
640 | NULLFREE(ptr->cltab.bclass);
|
---|
641 | #ifdef CS_CACHEEX
|
---|
642 | cecspvaluetab_clear(&ptr->cacheex.filter_caidtab);
|
---|
643 | ftab_clear(&ptr->disablecrccacheex_only_for);
|
---|
644 | #ifdef CS_CACHEEX_AIO
|
---|
645 | caidtab_clear(&ptr->cacheex.localgenerated_only_caidtab);
|
---|
646 | caidtab_clear(&ptr->cacheex.localgenerated_only_in_caidtab);
|
---|
647 | ftab_clear(&ptr->cacheex.lg_only_tab);
|
---|
648 | ftab_clear(&ptr->cacheex.lg_only_in_tab);
|
---|
649 | caidvaluetab_clear(&ptr->cacheex.cacheex_nopushafter_tab);
|
---|
650 | #endif
|
---|
651 | #endif
|
---|
652 | #ifdef WITH_LB
|
---|
653 | caidvaluetab_clear(&ptr->lb_nbest_readers_tab);
|
---|
654 | #endif
|
---|
655 | add_garbage(ptr);
|
---|
656 | ptr = ptr_next;
|
---|
657 | }
|
---|
658 | cs_log("userdb %d accounts freed", nro);
|
---|
659 | return nro;
|
---|
660 | }
|
---|
661 |
|
---|
662 | int32_t write_userdb(void)
|
---|
663 | {
|
---|
664 | struct s_auth *account;
|
---|
665 | FILE *f = create_config_file(cs_user);
|
---|
666 | if(!f)
|
---|
667 | { return 1; }
|
---|
668 | for(account = cfg.account; account; account = account->next)
|
---|
669 | {
|
---|
670 | fprintf(f, "[account]\n");
|
---|
671 | config_list_apply_fixups(account_opts, account);
|
---|
672 | config_list_save(f, account_opts, account, cfg.http_full_cfg);
|
---|
673 | fprintf(f, "\n");
|
---|
674 | }
|
---|
675 | return flush_config_file(f, cs_user);
|
---|
676 | }
|
---|
677 |
|
---|
678 | void cs_accounts_chk(void)
|
---|
679 | {
|
---|
680 | struct s_auth *account1, *account2;
|
---|
681 | struct s_auth *new_accounts = init_userdb();
|
---|
682 | cs_writelock(__func__, &config_lock);
|
---|
683 | struct s_auth *old_accounts = cfg.account;
|
---|
684 | for(account1 = cfg.account; account1; account1 = account1->next)
|
---|
685 | {
|
---|
686 | for(account2 = new_accounts; account2; account2 = account2->next)
|
---|
687 | {
|
---|
688 | if(!strcmp(account1->usr, account2->usr))
|
---|
689 | {
|
---|
690 | account2->cwfound = account1->cwfound;
|
---|
691 | account2->cwcache = account1->cwcache;
|
---|
692 | account2->cwnot = account1->cwnot;
|
---|
693 | account2->cwtun = account1->cwtun;
|
---|
694 | account2->cwignored = account1->cwignored;
|
---|
695 | account2->cwtout = account1->cwtout;
|
---|
696 | account2->emmok = account1->emmok;
|
---|
697 | account2->emmnok = account1->emmnok;
|
---|
698 | account2->firstlogin = account1->firstlogin;
|
---|
699 | ac_copy_vars(account1, account2);
|
---|
700 | }
|
---|
701 | }
|
---|
702 | }
|
---|
703 | cs_reinit_clients(new_accounts);
|
---|
704 | cfg.account = new_accounts;
|
---|
705 | init_free_userdb(old_accounts);
|
---|
706 | ac_clear();
|
---|
707 | cs_writeunlock(__func__, &config_lock);
|
---|
708 | }
|
---|