1 #define MODULE_LOG_PREFIX "config"
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
;
22 *tosleep
= strToIntVal(value
, cfg
.tosleep
);
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
;
37 *c35_suppresscmd08
= (int8_t)strToIntVal(value
, cfg
.c35_suppresscmd08
);
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;
49 *umaxidle = (int32_t)strToIntVal(value, cfg.umaxidle);
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
;
63 def_value
= cfg
.ncd_keepalive
;
67 *ncd_keepalive
= (int8_t)strToIntVal(value
, def_value
);
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
;
79 account
->allowedprotocols
= 0;
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
; }
104 if(account
->allowedprotocols
|| cfg
.http_full_cfg
)
106 value
= mk_t_allowedprotocols(account
);
107 fprintf_conf(f
, token
, "%s\n", value
);
112 static void account_au_fn(const char *token
, char *value
, void *setting
, FILE *f
)
114 struct s_auth
*account
= setting
;
117 // set default values for usage during runtime from Webif
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
))
130 while((rdr
= ll_iter_next(&itr
)))
132 if(streq(rdr
->label
, pch
) || account
->autoau
)
134 ll_append(account
->aureader_list
, rdr
);
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
); }
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
;
164 account
->expirationdate
= (time_t)NULL
;
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
++)
176 cstime
.tm_year
= atoi(ptr1
) - 1900;
179 cstime
.tm_mon
= atoi(ptr1
) - 1;
182 cstime
.tm_mday
= atoi(ptr1
);
189 cstime
.tm_isdst
= -1;
190 account
->expirationdate
= mktime(&cstime
);
193 if(account
->expirationdate
|| cfg
.http_full_cfg
)
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 int32_t i
, j
, t
, startt
, endt
;
212 char *ptr1
, *ptr2
, *ptr3
, *saveptr1
= NULL
, *saveptr2
= NULL
;
216 //First empty allowedtimeframe array very important otherwise new config won't be properly set
217 for(i
=0;i
<SIZE_SHORTDAY
;i
++) {
219 account
->allowedtimeframe
[i
][j
][0]=0;
220 account
->allowedtimeframe
[i
][j
][1]=0;
223 account
->allowedtimeframe_set
=0;
226 for(i
= 0, ptr1
= strtok_r(value
, ";", &saveptr1
); (ptr1
); ptr1
= strtok_r(NULL
, ";", &saveptr1
), i
++)
228 if((ptr2
= strchr(trim(ptr1
), '@')))
230 *ptr2
++ = '\0'; //clean up @ symbol
232 dest
= strstr(weekdstr
,ptr1
);
233 day_idx
= (dest
- weekdstr
)/3;
235 for(j
= 0, ptr3
= strtok_r(ptr2
, ",", &saveptr2
); (ptr3
); ptr3
= strtok_r(NULL
, ",", &saveptr2
), j
++)
237 if((sscanf(ptr3
, "%2d:%2d-%2d:%2d", &allowed
[0], &allowed
[1], &allowed
[2], &allowed
[3]) == 4) && (day_idx
<SIZE_SHORTDAY
))
239 startt
= allowed
[0] * 60 + allowed
[1];
240 endt
= allowed
[2] * 60 + allowed
[3];
241 if(startt
== endt
) { endt
++; } //end time cannot be the same as the star time
242 if((startt
<0) || (startt
> 1439)) { startt
= 0; } //could not start later than 23H59, avoid overflow
243 if((endt
<0) || (endt
> 1440)) { endt
= 1440; } //could not be higher than 24H00, avoid overflow
244 account
->allowedtimeframe_set
=1;
246 for(t
=startt
; t
<1440 ;t
++)
248 tempo
= (1 << (t
% 30));
249 account
->allowedtimeframe
[day_idx
][t
/60][(t
/30)%2]=account
->allowedtimeframe
[day_idx
][t
/60][(t
/30)%2]|tempo
;
253 for(t
=startt
; t
<endt
;t
++)
255 tempo
= (1 << (t
% 30));
256 account
->allowedtimeframe
[day_idx
][t
/60][((t
/30)%2)]=account
->allowedtimeframe
[day_idx
][t
/60][(t
/30)%2]|tempo
;
261 fprintf(stderr
, "WARNING: Value '%s' is not valid for allowedtimeframe (DAY@HH:MM-HH:MM)\n", value
);
265 else //No day specified so whole week (ALL)
267 if(sscanf(ptr1
, "%2d:%2d-%2d:%2d", &allowed
[0], &allowed
[1], &allowed
[2], &allowed
[3]) == 4)
269 startt
= allowed
[0] * 60 + allowed
[1];
270 endt
= allowed
[2] * 60 + allowed
[3];
271 if(startt
== endt
) { endt
++; } //end time cannot be the same as the star time
272 if((startt
<0) || (startt
> 1439)) { startt
= 0; } //could not start later than 23H59, avoid overflow
273 if((endt
<0) || (endt
> 1440)) { endt
= 1440; } //could not be higher than 24H00, avoid overflow
274 account
->allowedtimeframe_set
=1;
275 dest
= strstr(weekdstr
,"ALL");
276 day_idx
= (dest
- weekdstr
)/3;
279 for(t
=startt
; t
<1440 ;t
++)
281 tempo
= (1 << (t
% 30));
282 account
->allowedtimeframe
[day_idx
][t
/60][(t
/30)%2]=account
->allowedtimeframe
[7][t
/60][(t
/30)%2]|tempo
;
286 for(t
=startt
; t
<endt
;t
++)
288 tempo
= (1 << (t
% 30));
289 account
->allowedtimeframe
[day_idx
][t
/60][(t
/30)%2]=account
->allowedtimeframe
[7][t
/60][(t
/30)%2]|tempo
;
294 fprintf(stderr
, "WARNING: Value '%s' is not valid for allowedtimeframe (hh:mm-hh:mm)\n", value
);
301 if(account
->allowedtimeframe_set
)
303 value
= mk_t_allowedtimeframe(account
);
304 fprintf_conf(f
, token
, "%s\n", value
);
307 else if(cfg
.http_full_cfg
)
309 fprintf_conf(f
, token
, "%s\n", "");
313 static void account_tuntab_fn(const char *token
, char *value
, void *setting
, FILE *f
)
315 TUNTAB
*ttab
= setting
;
318 if(strlen(value
) == 0)
324 chk_tuntab(value
, ttab
);
328 if((ttab
->ttdata
&& ttab
->ttdata
[0].bt_caidfrom
) || cfg
.http_full_cfg
)
330 value
= mk_t_tuntab(ttab
);
331 fprintf_conf(f
, token
, "%s\n", value
);
336 void group_fn(const char *token
, char *value
, void *setting
, FILE *f
)
338 uint64_t *grp
= setting
;
341 char *ptr1
, *saveptr1
= NULL
;
343 for(ptr1
= strtok_r(value
, ",", &saveptr1
); ptr1
; ptr1
= strtok_r(NULL
, ",", &saveptr1
))
348 { *grp
|= (((uint64_t)1) << (g
- 1)); }
352 if(*grp
|| cfg
.http_full_cfg
)
354 value
= mk_t_group(*grp
);
355 fprintf_conf(f
, token
, "%s\n", value
);
360 void services_fn(const char *token
, char *value
, void *setting
, FILE *f
)
362 SIDTABS
*sidtabs
= setting
;
366 chk_services(value
, sidtabs
);
369 value
= mk_t_service(sidtabs
);
370 if(strlen(value
) > 0 || cfg
.http_full_cfg
)
371 { fprintf_conf(f
, token
, "%s\n", value
); }
375 void class_fn(const char *token
, char *value
, void *setting
, FILE *f
)
377 CLASSTAB
*cltab
= setting
;
381 chk_cltab(value
, cltab
);
384 value
= mk_t_cltab(cltab
);
385 if(strlen(value
) > 0 || cfg
.http_full_cfg
)
387 fprintf_conf(f
, token
, "%s\n", value
);
393 static void account_fixups_fn(void *var
)
395 struct s_auth
*account
= var
;
396 if(account
->ac_users
< -1) { account
->ac_users
= DEFAULT_AC_USERS
; }
397 if(account
->ac_penalty
< -1) { account
->ac_penalty
= DEFAULT_AC_PENALTY
; }
398 if(account
->acosc_max_active_sids
< -1) { account
->acosc_max_active_sids
= -1; }
399 if(account
->acosc_zap_limit
< -1) { account
->acosc_zap_limit
= -1; }
400 if(account
->acosc_penalty
< -1) { account
->acosc_penalty
= -1; }
401 if(account
->acosc_penalty_duration
< -1) { account
->acosc_penalty_duration
= -1; }
402 if(account
->acosc_delay
< -1) { account
->acosc_delay
= -1; }
406 #define OFS(X) offsetof(struct s_auth, X)
407 #define SIZEOF(X) sizeof(((struct s_auth *)0)->X)
409 static const struct config_list account_opts
[] =
412 DEF_OPT_FIXUP_FUNC(account_fixups_fn
),
414 DEF_OPT_INT8("disabled" , OFS(disabled
), 0),
415 DEF_OPT_SSTR("user" , OFS(usr
), "", SIZEOF(usr
)),
416 DEF_OPT_STR("pwd" , OFS(pwd
), NULL
),
418 DEF_OPT_STR("description" , OFS(description
), NULL
),
420 DEF_OPT_STR("hostname" , OFS(dyndns
), NULL
),
421 DEF_OPT_FUNC("caid" , OFS(ctab
), check_caidtab_fn
),
422 DEF_OPT_INT8("uniq" , OFS(uniq
), 0),
423 DEF_OPT_UINT8("sleepsend" , OFS(c35_sleepsend
), 0),
424 DEF_OPT_INT32("failban" , OFS(failban
), 0),
425 DEF_OPT_INT8("monlevel" , OFS(monlvl
), 0),
426 DEF_OPT_FUNC("sleep" , OFS(tosleep
), account_tosleep_fn
),
427 DEF_OPT_FUNC("suppresscmd08" , OFS(c35_suppresscmd08
), account_c35_suppresscmd08_fn
),
428 DEF_OPT_INT32("umaxidle" , OFS(umaxidle
), -1),
429 DEF_OPT_FUNC("keepalive" , OFS(ncd_keepalive
), account_ncd_keepalive_fn
),
430 DEF_OPT_FUNC("au" , 0, account_au_fn
),
431 DEF_OPT_UINT8("emmreassembly" , OFS(emm_reassembly
), 2),
432 DEF_OPT_FUNC("expdate" , 0, account_expdate_fn
),
433 DEF_OPT_FUNC("allowedprotocols" , 0, account_allowedprotocols_fn
),
434 DEF_OPT_FUNC("allowedtimeframe" , 0, account_allowedtimeframe_fn
),
435 DEF_OPT_FUNC("betatunnel" , OFS(ttab
), account_tuntab_fn
),
436 DEF_OPT_FUNC("group" , OFS(grp
), group_fn
),
437 DEF_OPT_FUNC("services" , OFS(sidtabs
), services_fn
),
438 DEF_OPT_INT8("preferlocalcards" , OFS(preferlocalcards
), -1),
439 DEF_OPT_FUNC_X("ident" , OFS(ftab
), ftab_fn
, FTAB_ACCOUNT
| FTAB_PROVID
),
440 DEF_OPT_FUNC_X("chid" , OFS(fchid
), ftab_fn
, FTAB_ACCOUNT
| FTAB_CHID
),
441 DEF_OPT_FUNC("class" , OFS(cltab
), class_fn
),
442 DEF_OPT_UINT32("max_connections" , OFS(max_connections
), 1),
444 DEF_OPT_INT8("cacheex" , OFS(cacheex
.mode
), 0),
445 DEF_OPT_INT8("cacheex_maxhop" , OFS(cacheex
.maxhop
), 0),
446 DEF_OPT_FUNC("cacheex_ecm_filter" , OFS(cacheex
.filter_caidtab
), cacheex_hitvaluetab_fn
),
447 DEF_OPT_UINT8("cacheex_drop_csp" , OFS(cacheex
.drop_csp
), 0),
448 DEF_OPT_UINT8("cacheex_allow_request" , OFS(cacheex
.allow_request
), 0),
449 DEF_OPT_UINT8("no_wait_time" , OFS(no_wait_time
), 0),
450 DEF_OPT_UINT8("cacheex_allow_filter", OFS(cacheex
.allow_filter
), 1),
451 DEF_OPT_UINT8("cacheex_block_fakecws",OFS(cacheex
.block_fakecws
), 0),
452 DEF_OPT_UINT8("disablecrccacheex" ,OFS(disablecrccacheex
), 0),
453 DEF_OPT_FUNC_X("disablecrccacheex_only_for", OFS(disablecrccacheex_only_for
), ftab_fn
, FTAB_ACCOUNT
| FTAB_IGNCRCCEX4USERONLYFOR
),
456 DEF_OPT_INT32("cccmaxhops" , OFS(cccmaxhops
), DEFAULT_CC_MAXHOPS
),
457 DEF_OPT_INT8("cccreshare" , OFS(cccreshare
), DEFAULT_CC_RESHARE
),
458 DEF_OPT_INT8("cccignorereshare" , OFS(cccignorereshare
), DEFAULT_CC_IGNRSHR
),
459 DEF_OPT_INT8("cccstealth" , OFS(cccstealth
), DEFAULT_CC_STEALTH
),
462 DEF_OPT_INT32("fakedelay" , OFS(ac_fakedelay
), -1),
463 DEF_OPT_INT32("numusers" , OFS(ac_users
), DEFAULT_AC_USERS
),
464 DEF_OPT_INT8("penalty" , OFS(ac_penalty
), DEFAULT_AC_PENALTY
),
465 DEF_OPT_INT8("acosc_max_active_sids" , OFS(acosc_max_active_sids
), -1 ),
466 DEF_OPT_INT8("acosc_zap_limit" , OFS(acosc_zap_limit
), -1 ),
467 DEF_OPT_INT8("acosc_penalty" , OFS(acosc_penalty
), -1 ),
468 DEF_OPT_INT32("acosc_penalty_duration" , OFS(acosc_penalty_duration
), -1 ),
469 DEF_OPT_INT32("acosc_delay" , OFS(acosc_delay
), -1 ),
472 DEF_OPT_INT32("lb_nbest_readers" , OFS(lb_nbest_readers
), -1),
473 DEF_OPT_INT32("lb_nfb_readers" , OFS(lb_nfb_readers
), -1),
474 DEF_OPT_FUNC("lb_nbest_percaid" , OFS(lb_nbest_readers_tab
), caidvaluetab_fn
),
476 #ifdef CW_CYCLE_CHECK
477 DEF_OPT_INT8("cwc_disable" , OFS(cwc_disable
), 0),
482 void chk_account(const char *token
, char *value
, struct s_auth
*account
)
484 if(config_list_parse(account_opts
, token
, value
, account
))
486 else if(token
[0] != '#')
487 { fprintf(stderr
, "Warning: keyword '%s' in account section not recognized\n", token
); }
490 void account_set_defaults(struct s_auth
*account
)
492 config_list_set_defaults(account_opts
, account
);
495 struct s_auth
*init_userdb(void)
497 FILE *fp
= open_config_file(cs_user
);
501 struct s_auth
*authptr
= NULL
;
502 int32_t tag
= 0, nr
= 0, expired
= 0, disabled
= 0;
504 struct s_auth
*account
= NULL
;
505 struct s_auth
*probe
= NULL
;
506 if(!cs_malloc(&token
, MAXLINESIZE
))
509 while(fgets(token
, MAXLINESIZE
, fp
))
514 if((l
= strlen(trim(token
))) < 3)
516 if(token
[0] == '[' && token
[l
- 1] == ']')
519 tag
= streq("account", strtolower(token
+ 1));
520 if(!cs_malloc(&ptr
, sizeof(struct s_auth
)))
523 { account
->next
= ptr
; }
528 account_set_defaults(account
);
536 char *value
= strchr(token
, '=');
542 // check for duplicate useraccounts and make the name unique
543 if(streq(trim(strtolower(token
)), "user"))
545 for(probe
= authptr
; probe
; probe
= probe
->next
)
547 if(!strcmp(probe
->usr
, trim(value
)))
549 fprintf(stderr
, "Warning: duplicate account '%s'\n", value
);
550 strncat(value
, "_x", sizeof(probe
->usr
) - strlen(value
) - 1);
554 chk_account(trim(strtolower(token
)), trim(value
), account
);
559 for(account
= authptr
; account
; account
= account
->next
)
561 if(account
->expirationdate
&& account
->expirationdate
< time(NULL
))
563 if(account
->disabled
)
566 cs_log("userdb reloaded: %d accounts loaded, %d expired, %d disabled", nr
, expired
, disabled
);
570 int32_t init_free_userdb(struct s_auth
*ptr
)
573 for(nro
= 0; ptr
; nro
++)
575 struct s_auth
*ptr_next
;
576 ptr_next
= ptr
->next
;
577 ll_destroy(&ptr
->aureader_list
);
579 config_list_gc_values(account_opts
, ptr
);
580 ftab_clear(&ptr
->ftab
);
581 ftab_clear(&ptr
->fchid
);
582 tuntab_clear(&ptr
->ttab
);
583 caidtab_clear(&ptr
->ctab
);
584 NULLFREE(ptr
->cltab
.aclass
);
585 NULLFREE(ptr
->cltab
.bclass
);
587 cecspvaluetab_clear(&ptr
->cacheex
.filter_caidtab
);
590 caidvaluetab_clear(&ptr
->lb_nbest_readers_tab
);
595 cs_log("userdb %d accounts freed", nro
);
599 int32_t write_userdb(void)
601 struct s_auth
*account
;
602 FILE *f
= create_config_file(cs_user
);
605 for(account
= cfg
.account
; account
; account
= account
->next
)
607 fprintf(f
, "[account]\n");
608 config_list_apply_fixups(account_opts
, account
);
609 config_list_save(f
, account_opts
, account
, cfg
.http_full_cfg
);
612 return flush_config_file(f
, cs_user
);
615 void cs_accounts_chk(void)
617 struct s_auth
*account1
, *account2
;
618 struct s_auth
*new_accounts
= init_userdb();
619 cs_writelock(__func__
, &config_lock
);
620 struct s_auth
*old_accounts
= cfg
.account
;
621 for(account1
= cfg
.account
; account1
; account1
= account1
->next
)
623 for(account2
= new_accounts
; account2
; account2
= account2
->next
)
625 if(!strcmp(account1
->usr
, account2
->usr
))
627 account2
->cwfound
= account1
->cwfound
;
628 account2
->cwcache
= account1
->cwcache
;
629 account2
->cwnot
= account1
->cwnot
;
630 account2
->cwtun
= account1
->cwtun
;
631 account2
->cwignored
= account1
->cwignored
;
632 account2
->cwtout
= account1
->cwtout
;
633 account2
->emmok
= account1
->emmok
;
634 account2
->emmnok
= account1
->emmnok
;
635 account2
->firstlogin
= account1
->firstlogin
;
636 ac_copy_vars(account1
, account2
);
640 cs_reinit_clients(new_accounts
);
641 cfg
.account
= new_accounts
;
642 init_free_userdb(old_accounts
);
644 cs_writeunlock(__func__
, &config_lock
);