- Add support of ORF P4 Irdeto mode
[oscam.git] / oscam-config-account.c
blobabf891a2ab7b013350fd9ec68e47aa25bb8c37c1
1 #define MODULE_LOG_PREFIX "config"
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"
15 #define cs_user "oscam.user"
17 static void account_tosleep_fn(const char *token, char *value, void *setting, FILE *f)
19 int32_t *tosleep = setting;
20 if(value)
22 *tosleep = strToIntVal(value, cfg.tosleep);
23 return;
25 if(*tosleep != cfg.tosleep || cfg.http_full_cfg)
26 { fprintf_conf(f, token, "%d\n", *tosleep); }
32 static void account_c35_suppresscmd08_fn(const char *token, char *value, void *setting, FILE *f)
34 int8_t *c35_suppresscmd08 = setting;
35 if(value)
37 *c35_suppresscmd08 = (int8_t)strToIntVal(value, cfg.c35_suppresscmd08);
38 return;
40 if(*c35_suppresscmd08 != cfg.c35_suppresscmd08 || cfg.http_full_cfg)
41 { fprintf_conf(f, token, "%d\n", *c35_suppresscmd08); }
44 /*static void account_umaxidle_fn(const char *token, char *value, void *setting, FILE *f)
46 int32_t *umaxidle = setting;
47 if(value)
49 *umaxidle = (int32_t)strToIntVal(value, cfg.umaxidle);
50 return;
52 if(*umaxidle != cfg.umaxidle || cfg.http_full_cfg)
53 { fprintf_conf(f, token, "%u\n", *umaxidle); }
58 static void account_ncd_keepalive_fn(const char *token, char *value, void *setting, FILE *f)
60 int8_t *ncd_keepalive = setting;
61 int8_t def_value = 0;
62 #ifdef MODULE_NEWCAMD
63 def_value = cfg.ncd_keepalive;
64 #endif
65 if(value)
67 *ncd_keepalive = (int8_t)strToIntVal(value, def_value);
68 return;
70 if(*ncd_keepalive != def_value || cfg.http_full_cfg)
71 { fprintf_conf(f, token, "%d\n", *ncd_keepalive); }
74 static void account_allowedprotocols_fn(const char *token, char *value, void *setting, FILE *f)
76 struct s_auth *account = setting;
77 if(value)
79 account->allowedprotocols = 0;
80 if(strlen(value) > 3)
82 int i;
83 char *ptr, *saveptr1 = NULL;
84 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); ptr; ptr = strtok_r(NULL, ",", &saveptr1), i++)
86 if(streq(ptr, "camd33")) { account->allowedprotocols |= LIS_CAMD33TCP; }
87 else if(streq(ptr, "camd35")) { account->allowedprotocols |= LIS_CAMD35UDP; }
88 else if(streq(ptr, "cs357x")) { account->allowedprotocols |= LIS_CAMD35UDP; }
89 else if(streq(ptr, "cs378x")) { account->allowedprotocols |= LIS_CAMD35TCP; }
90 else if(streq(ptr, "newcamd")) { account->allowedprotocols |= LIS_NEWCAMD; }
91 else if(streq(ptr, "cccam")) { account->allowedprotocols |= LIS_CCCAM; }
92 else if(streq(ptr, "csp")) { account->allowedprotocols |= LIS_CSPUDP; }
93 else if(streq(ptr, "gbox")) { account->allowedprotocols |= LIS_GBOX; }
94 else if(streq(ptr, "radegast")) { account->allowedprotocols |= LIS_RADEGAST; }
95 else if(streq(ptr, "scam")) { account->allowedprotocols |= LIS_SCAM; }
96 // these have no listener ports so it doesn't make sense
97 else if(streq(ptr, "dvbapi")) { account->allowedprotocols |= LIS_DVBAPI; }
98 else if(streq(ptr, "constcw")) { account->allowedprotocols |= LIS_CONSTCW; }
99 else if(streq(ptr, "serial")) { account->allowedprotocols |= LIS_SERIAL; }
102 return;
104 if(account->allowedprotocols || cfg.http_full_cfg)
106 value = mk_t_allowedprotocols(account);
107 fprintf_conf(f, token, "%s\n", value);
108 free_mk_t(value);
112 static void account_au_fn(const char *token, char *value, void *setting, FILE *f)
114 struct s_auth *account = setting;
115 if(value)
117 // set default values for usage during runtime from Webif
118 account->autoau = 0;
119 if(!account->aureader_list)
120 { account->aureader_list = ll_create("aureader_list"); }
121 if(streq(value, "1"))
122 { account->autoau = 1; }
123 ll_clear(account->aureader_list);
124 LL_ITER itr = ll_iter_create(configured_readers);
125 struct s_reader *rdr;
126 char *pch, *saveptr1 = NULL;
127 for(pch = strtok_r(value, ",", &saveptr1); pch != NULL; pch = strtok_r(NULL, ",", &saveptr1))
129 ll_iter_reset(&itr);
130 while((rdr = ll_iter_next(&itr)))
132 if(streq(rdr->label, pch) || account->autoau)
134 ll_append(account->aureader_list, rdr);
138 return;
140 if(account->autoau == 1)
142 fprintf_conf(f, token, "%d\n", account->autoau);
144 else if(account->aureader_list)
146 value = mk_t_aureader(account);
147 if(strlen(value) > 0)
148 { fprintf_conf(f, token, "%s\n", value); }
149 free_mk_t(value);
151 else if(cfg.http_full_cfg)
153 fprintf_conf(f, token, "%s\n", "");
157 static void account_expdate_fn(const char *token, char *value, void *setting, FILE *f)
159 struct s_auth *account = setting;
160 if(value)
162 if(!value[0])
164 account->expirationdate = (time_t)NULL;
165 return;
167 int i;
168 struct tm cstime;
169 char *ptr1, *saveptr1 = NULL;
170 memset(&cstime, 0, sizeof(cstime));
171 for(i = 0, ptr1 = strtok_r(value, "-/", &saveptr1); i < 3 && ptr1; ptr1 = strtok_r(NULL, "-/", &saveptr1), i++)
173 switch(i)
175 case 0:
176 cstime.tm_year = atoi(ptr1) - 1900;
177 break;
178 case 1:
179 cstime.tm_mon = atoi(ptr1) - 1;
180 break;
181 case 2:
182 cstime.tm_mday = atoi(ptr1);
183 break;
186 cstime.tm_hour = 23;
187 cstime.tm_min = 59;
188 cstime.tm_sec = 59;
189 cstime.tm_isdst = -1;
190 account->expirationdate = mktime(&cstime);
191 return;
193 if(account->expirationdate || cfg.http_full_cfg)
195 char buf[16];
196 struct tm timeinfo;
197 localtime_r(&account->expirationdate, &timeinfo);
198 strftime(buf, 16, "%Y-%m-%d", &timeinfo);
199 fprintf_conf(f, token, "%s\n", streq(buf, "1970-01-01") ? "" : buf);
203 static void account_allowedtimeframe_fn(const char *token, char *value, void *setting, FILE *f)
205 struct s_auth *account = setting;
206 if(value)
208 account->allowedtimeframe[0] = 0;
209 account->allowedtimeframe[1] = 0;
210 if(strlen(value))
212 int32_t allowed[4];
213 if(sscanf(value, "%2d:%2d-%2d:%2d", &allowed[0], &allowed[1], &allowed[2], &allowed[3]) == 4)
215 account->allowedtimeframe[0] = allowed[0] * 60 + allowed[1];
216 account->allowedtimeframe[1] = allowed[2] * 60 + allowed[3];
218 else
220 fprintf(stderr, "WARNING: Value '%s' is not valid for allowedtimeframe (hh:mm-hh:mm)\n", value);
223 return;
225 if(account->allowedtimeframe[0] && account->allowedtimeframe[1])
227 fprintf_conf(f, token, "%02d:%02d-%02d:%02d\n",
228 account->allowedtimeframe[0] / 60, account->allowedtimeframe[0] % 60,
229 account->allowedtimeframe[1] / 60, account->allowedtimeframe[1] % 60);
231 else if(cfg.http_full_cfg)
233 fprintf_conf(f, token, "%s\n", "");
237 static void account_tuntab_fn(const char *token, char *value, void *setting, FILE *f)
239 TUNTAB *ttab = setting;
240 if(value)
242 if(strlen(value) == 0)
244 tuntab_clear(ttab);
246 else
248 chk_tuntab(value, ttab);
250 return;
252 if((ttab->ttdata && ttab->ttdata[0].bt_caidfrom) || cfg.http_full_cfg)
254 value = mk_t_tuntab(ttab);
255 fprintf_conf(f, token, "%s\n", value);
256 free_mk_t(value);
260 void group_fn(const char *token, char *value, void *setting, FILE *f)
262 uint64_t *grp = setting;
263 if(value)
265 char *ptr1, *saveptr1 = NULL;
266 *grp = 0;
267 for(ptr1 = strtok_r(value, ",", &saveptr1); ptr1; ptr1 = strtok_r(NULL, ",", &saveptr1))
269 int32_t g;
270 g = atoi(ptr1);
271 if(g > 0 && g < 65)
272 { *grp |= (((uint64_t)1) << (g - 1)); }
274 return;
276 if(*grp || cfg.http_full_cfg)
278 value = mk_t_group(*grp);
279 fprintf_conf(f, token, "%s\n", value);
280 free_mk_t(value);
284 void services_fn(const char *token, char *value, void *setting, FILE *f)
286 SIDTABS *sidtabs = setting;
287 if(value)
289 strtolower(value);
290 chk_services(value, sidtabs);
291 return;
293 value = mk_t_service(sidtabs);
294 if(strlen(value) > 0 || cfg.http_full_cfg)
295 { fprintf_conf(f, token, "%s\n", value); }
296 free_mk_t(value);
299 void class_fn(const char *token, char *value, void *setting, FILE *f)
301 CLASSTAB *cltab = setting;
302 if(value)
304 strtolower(value);
305 chk_cltab(value, cltab);
306 return;
308 value = mk_t_cltab(cltab);
309 if(strlen(value) > 0 || cfg.http_full_cfg)
311 fprintf_conf(f, token, "%s\n", value);
312 free_mk_t(value);
316 #ifdef CS_ANTICASC
317 static void account_fixups_fn(void *var)
319 struct s_auth *account = var;
320 if(account->ac_users < -1) { account->ac_users = DEFAULT_AC_USERS; }
321 if(account->ac_penalty < -1) { account->ac_penalty = DEFAULT_AC_PENALTY; }
322 if(account->acosc_max_active_sids < -1) { account->acosc_max_active_sids = -1; }
323 if(account->acosc_zap_limit < -1) { account->acosc_zap_limit = -1; }
324 if(account->acosc_penalty < -1) { account->acosc_penalty = -1; }
325 if(account->acosc_penalty_duration < -1) { account->acosc_penalty_duration = -1; }
326 if(account->acosc_delay < -1) { account->acosc_delay = -1; }
328 #endif
330 #define OFS(X) offsetof(struct s_auth, X)
331 #define SIZEOF(X) sizeof(((struct s_auth *)0)->X)
333 static const struct config_list account_opts[] =
335 #ifdef CS_ANTICASC
336 DEF_OPT_FIXUP_FUNC(account_fixups_fn),
337 #endif
338 DEF_OPT_INT8("disabled" , OFS(disabled), 0),
339 DEF_OPT_SSTR("user" , OFS(usr), "", SIZEOF(usr)),
340 DEF_OPT_STR("pwd" , OFS(pwd), NULL),
341 #ifdef WEBIF
342 DEF_OPT_STR("description" , OFS(description), NULL),
343 #endif
344 DEF_OPT_STR("hostname" , OFS(dyndns), NULL),
345 DEF_OPT_FUNC("caid" , OFS(ctab), check_caidtab_fn),
346 DEF_OPT_INT8("uniq" , OFS(uniq), 0),
347 DEF_OPT_UINT8("sleepsend" , OFS(c35_sleepsend), 0),
348 DEF_OPT_INT32("failban" , OFS(failban), 0),
349 DEF_OPT_INT8("monlevel" , OFS(monlvl), 0),
350 DEF_OPT_FUNC("sleep" , OFS(tosleep), account_tosleep_fn),
351 DEF_OPT_FUNC("suppresscmd08" , OFS(c35_suppresscmd08), account_c35_suppresscmd08_fn),
352 DEF_OPT_INT32("umaxidle" , OFS(umaxidle), -1),
353 DEF_OPT_FUNC("keepalive" , OFS(ncd_keepalive), account_ncd_keepalive_fn),
354 DEF_OPT_FUNC("au" , 0, account_au_fn),
355 DEF_OPT_UINT8("emmreassembly" , OFS(emm_reassembly), 2),
356 DEF_OPT_FUNC("expdate" , 0, account_expdate_fn),
357 DEF_OPT_FUNC("allowedprotocols" , 0, account_allowedprotocols_fn),
358 DEF_OPT_FUNC("allowedtimeframe" , 0, account_allowedtimeframe_fn),
359 DEF_OPT_FUNC("betatunnel" , OFS(ttab), account_tuntab_fn),
360 DEF_OPT_FUNC("group" , OFS(grp), group_fn),
361 DEF_OPT_FUNC("services" , OFS(sidtabs), services_fn),
362 DEF_OPT_INT8("preferlocalcards" , OFS(preferlocalcards), -1),
363 DEF_OPT_FUNC_X("ident" , OFS(ftab), ftab_fn, FTAB_ACCOUNT | FTAB_PROVID),
364 DEF_OPT_FUNC_X("chid" , OFS(fchid), ftab_fn, FTAB_ACCOUNT | FTAB_CHID),
365 DEF_OPT_FUNC("class" , OFS(cltab), class_fn),
366 DEF_OPT_UINT32("max_connections" , OFS(max_connections), 1),
367 #ifdef CS_CACHEEX
368 DEF_OPT_INT8("cacheex" , OFS(cacheex.mode), 0),
369 DEF_OPT_INT8("cacheex_maxhop" , OFS(cacheex.maxhop), 0),
370 DEF_OPT_FUNC("cacheex_ecm_filter" , OFS(cacheex.filter_caidtab), cacheex_hitvaluetab_fn),
371 DEF_OPT_UINT8("cacheex_drop_csp" , OFS(cacheex.drop_csp), 0),
372 DEF_OPT_UINT8("cacheex_allow_request" , OFS(cacheex.allow_request), 0),
373 DEF_OPT_UINT8("no_wait_time" , OFS(no_wait_time), 0),
374 DEF_OPT_UINT8("cacheex_allow_filter", OFS(cacheex.allow_filter), 1),
375 DEF_OPT_UINT8("cacheex_block_fakecws",OFS(cacheex.block_fakecws), 0),
376 #endif
377 #ifdef MODULE_CCCAM
378 DEF_OPT_INT32("cccmaxhops" , OFS(cccmaxhops), DEFAULT_CC_MAXHOPS),
379 DEF_OPT_INT8("cccreshare" , OFS(cccreshare), DEFAULT_CC_RESHARE),
380 DEF_OPT_INT8("cccignorereshare" , OFS(cccignorereshare), DEFAULT_CC_IGNRSHR),
381 DEF_OPT_INT8("cccstealth" , OFS(cccstealth), DEFAULT_CC_STEALTH),
382 #endif
383 #ifdef CS_ANTICASC
384 DEF_OPT_INT32("fakedelay" , OFS(ac_fakedelay), -1),
385 DEF_OPT_INT32("numusers" , OFS(ac_users), DEFAULT_AC_USERS),
386 DEF_OPT_INT8("penalty" , OFS(ac_penalty), DEFAULT_AC_PENALTY),
387 DEF_OPT_INT8("acosc_max_active_sids" , OFS(acosc_max_active_sids), -1 ),
388 DEF_OPT_INT8("acosc_zap_limit" , OFS(acosc_zap_limit), -1 ),
389 DEF_OPT_INT8("acosc_penalty" , OFS(acosc_penalty), -1 ),
390 DEF_OPT_INT32("acosc_penalty_duration" , OFS(acosc_penalty_duration), -1 ),
391 DEF_OPT_INT32("acosc_delay" , OFS(acosc_delay), -1 ),
392 #endif
393 #ifdef WITH_LB
394 DEF_OPT_INT32("lb_nbest_readers" , OFS(lb_nbest_readers), -1),
395 DEF_OPT_INT32("lb_nfb_readers" , OFS(lb_nfb_readers), -1),
396 DEF_OPT_FUNC("lb_nbest_percaid" , OFS(lb_nbest_readers_tab), caidvaluetab_fn),
397 #endif
398 #ifdef CW_CYCLE_CHECK
399 DEF_OPT_INT8("cwc_disable" , OFS(cwc_disable), 0),
400 #endif
401 DEF_LAST_OPT
404 void chk_account(const char *token, char *value, struct s_auth *account)
406 if(config_list_parse(account_opts, token, value, account))
407 { return; }
408 else if(token[0] != '#')
409 { fprintf(stderr, "Warning: keyword '%s' in account section not recognized\n", token); }
412 void account_set_defaults(struct s_auth *account)
414 config_list_set_defaults(account_opts, account);
417 struct s_auth *init_userdb(void)
419 FILE *fp = open_config_file(cs_user);
420 if(!fp)
421 { return NULL; }
423 struct s_auth *authptr = NULL;
424 int32_t tag = 0, nr = 0, expired = 0, disabled = 0;
425 char *token;
426 struct s_auth *account = NULL;
427 struct s_auth *probe = NULL;
428 if(!cs_malloc(&token, MAXLINESIZE))
429 { return NULL; }
431 while(fgets(token, MAXLINESIZE, fp))
433 int32_t l;
434 void *ptr;
436 if((l = strlen(trim(token))) < 3)
437 { continue; }
438 if(token[0] == '[' && token[l - 1] == ']')
440 token[l - 1] = 0;
441 tag = streq("account", strtolower(token + 1));
442 if(!cs_malloc(&ptr, sizeof(struct s_auth)))
443 { break; }
444 if(account)
445 { account->next = ptr; }
446 else
447 { authptr = ptr; }
449 account = ptr;
450 account_set_defaults(account);
451 nr++;
453 continue;
456 if(!tag)
457 { continue; }
458 char *value = strchr(token, '=');
459 if(!value)
460 { continue; }
462 *value++ = '\0';
464 // check for duplicate useraccounts and make the name unique
465 if(streq(trim(strtolower(token)), "user"))
467 for(probe = authptr; probe; probe = probe->next)
469 if(!strcmp(probe->usr, trim(value)))
471 fprintf(stderr, "Warning: duplicate account '%s'\n", value);
472 strncat(value, "_x", sizeof(probe->usr) - strlen(value) - 1);
476 chk_account(trim(strtolower(token)), trim(value), account);
478 NULLFREE(token);
479 fclose(fp);
481 for(account = authptr; account; account = account->next)
483 if(account->expirationdate && account->expirationdate < time(NULL))
484 { ++expired; }
485 if(account->disabled)
486 { ++disabled; }
488 cs_log("userdb reloaded: %d accounts loaded, %d expired, %d disabled", nr, expired, disabled);
489 return authptr;
492 int32_t init_free_userdb(struct s_auth *ptr)
494 int32_t nro;
495 for(nro = 0; ptr; nro++)
497 struct s_auth *ptr_next;
498 ptr_next = ptr->next;
499 ll_destroy(&ptr->aureader_list);
500 ptr->next = NULL;
501 config_list_gc_values(account_opts, ptr);
502 ftab_clear(&ptr->ftab);
503 ftab_clear(&ptr->fchid);
504 tuntab_clear(&ptr->ttab);
505 caidtab_clear(&ptr->ctab);
506 NULLFREE(ptr->cltab.aclass);
507 NULLFREE(ptr->cltab.bclass);
508 #ifdef CS_CACHEEX
509 cecspvaluetab_clear(&ptr->cacheex.filter_caidtab);
510 #endif
511 #ifdef WITH_LB
512 caidvaluetab_clear(&ptr->lb_nbest_readers_tab);
513 #endif
514 add_garbage(ptr);
515 ptr = ptr_next;
517 cs_log("userdb %d accounts freed", nro);
518 return nro;
521 int32_t write_userdb(void)
523 struct s_auth *account;
524 FILE *f = create_config_file(cs_user);
525 if(!f)
526 { return 1; }
527 for(account = cfg.account; account; account = account->next)
529 fprintf(f, "[account]\n");
530 config_list_apply_fixups(account_opts, account);
531 config_list_save(f, account_opts, account, cfg.http_full_cfg);
532 fprintf(f, "\n");
534 return flush_config_file(f, cs_user);
537 void cs_accounts_chk(void)
539 struct s_auth *account1, *account2;
540 struct s_auth *new_accounts = init_userdb();
541 cs_writelock(__func__, &config_lock);
542 struct s_auth *old_accounts = cfg.account;
543 for(account1 = cfg.account; account1; account1 = account1->next)
545 for(account2 = new_accounts; account2; account2 = account2->next)
547 if(!strcmp(account1->usr, account2->usr))
549 account2->cwfound = account1->cwfound;
550 account2->cwcache = account1->cwcache;
551 account2->cwnot = account1->cwnot;
552 account2->cwtun = account1->cwtun;
553 account2->cwignored = account1->cwignored;
554 account2->cwtout = account1->cwtout;
555 account2->emmok = account1->emmok;
556 account2->emmnok = account1->emmnok;
557 account2->firstlogin = account1->firstlogin;
558 ac_copy_vars(account1, account2);
562 cs_reinit_clients(new_accounts);
563 cfg.account = new_accounts;
564 init_free_userdb(old_accounts);
565 ac_clear();
566 cs_writeunlock(__func__, &config_lock);