1 #define MODULE_LOG_PREFIX "chk"
4 #include "oscam-cache.h"
7 #include "oscam-client.h"
8 #include "oscam-lock.h"
10 #include "oscam-string.h"
11 #include "module-stat.h"
12 #include "oscam-reader.h"
14 #define CS_NANO_CLASS 0xE2
18 uint32_t get_fallbacktimeout(uint16_t caid
)
20 uint32_t ftimeout
= caidvaluetab_get_value(&cfg
.ftimeouttab
, caid
, 0);
22 if(ftimeout
== 0) { ftimeout
= cfg
.ftimeout
; }
24 if(ftimeout
< 100) { ftimeout
= CS_CLIENT_TIMEOUT
/ 2; }
25 if(ftimeout
>= cfg
.ctimeout
) { ftimeout
= cfg
.ctimeout
- 100; }
30 static int32_t find_nano(uint8_t *ecm
, int32_t l
, uint8_t nano
, int32_t s
)
34 if(s
>= l
) { return 0; }
35 if(!s
) { s
= (ecm
[4] == 0xD2) ? 12 : 9; } // tpsflag -> offset+3
38 while((*snano
!= nano
) && (s
< l
))
40 if(*snano
== 0xEA) { return 0; }
45 return (s
< l
) ? ++s
: 0;
48 static int32_t chk_class(ECM_REQUEST
*er
, CLASSTAB
*clstab
, const char *type
, const char *name
)
50 int32_t i
, j
, an
, cl_n
, l
;
53 if(er
->caid
!= 0x0500 && er
->caid
!= 0x4AE1) { return 1; }
54 if(!clstab
->bn
&& !clstab
->an
) { return 1; }
58 if(er
->caid
== 0x0500)
60 while((j
= find_nano(er
->ecm
, er
->ecmlen
, CS_NANO_CLASS
, j
)) > 0)
63 if(l
+ j
> er
->ecmlen
) { continue; } // skip, this is not a valid class identifier!
65 ecm_class
= er
->ecm
[j
+ l
];
66 cs_log_dbg(D_CLIENT
, "ecm class=%02X", ecm_class
);
68 for(i
= 0; i
< clstab
->bn
; i
++) // search in blocked
70 if(ecm_class
== clstab
->bclass
[i
])
72 cs_log_dbg(D_CLIENT
, "class %02X rejected by %s '%s' !%02X filter",
73 ecm_class
, type
, name
, ecm_class
);
79 for(i
= 0; i
< clstab
->an
; i
++) // search in allowed
81 if(ecm_class
== clstab
->aclass
[i
])
92 if(er
->prid
!= 0x11 || er
->ecm
[0] == 0) { return 1; }
95 ecm_class
= er
->ecm
[5];
96 cs_log_dbg(D_CLIENT
, "ecm class=%02X", ecm_class
);
98 for(i
= 0; i
< clstab
->bn
; i
++) // search in blocked
100 if(ecm_class
== clstab
->bclass
[i
])
102 cs_log_dbg(D_CLIENT
, "class %02X rejected by %s '%s' !%02X filter",
103 ecm_class
, type
, name
, ecm_class
);
108 for(i
= 0; i
< clstab
->an
; i
++) // search in allowed
110 if(ecm_class
== clstab
->aclass
[i
])
118 if(cl_n
&& clstab
->an
)
121 { cs_log_dbg(D_CLIENT
, "ECM classes allowed by %s '%s' filter", type
, name
); }
124 cs_log_dbg(D_CLIENT
, "ECM classes don't match %s '%s' filter, rejecting", type
, name
);
132 int32_t chk_srvid_match(ECM_REQUEST
*er
, SIDTAB
*sidtab
)
136 if(!sidtab
->num_caid
)
139 for(i
= 0; (i
< sidtab
->num_caid
) && (!(rc
& 1)); i
++)
140 if(er
->caid
== sidtab
->caid
[i
]) { rc
|= 1; }
142 if(!er
->prid
|| !sidtab
->num_provid
)
145 for(i
= 0; (i
< sidtab
->num_provid
) && (!(rc
& 2)); i
++)
146 if(er
->prid
== sidtab
->provid
[i
]) { rc
|= 2; }
148 if(!sidtab
->num_srvid
)
151 for(i
= 0; (i
< sidtab
->num_srvid
) && (!(rc
& 4)); i
++)
152 if(er
->srvid
== sidtab
->srvid
[i
]) { rc
|= 4; }
157 #ifdef CS_CACHEEX_AIO
158 int32_t chk_srvid_disablecrccws_only_for_exception(ECM_REQUEST
*er
)
163 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
165 if(sidtab
->disablecrccws_only_for_exception
&& (sidtab
->num_caid
| sidtab
->num_provid
| sidtab
->num_srvid
) && chk_srvid_match(er
, sidtab
))
173 int32_t chk_srvid_no_wait_time(ECM_REQUEST
*er
)
178 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
180 if(sidtab
->no_wait_time
&& (sidtab
->num_caid
| sidtab
->num_provid
| sidtab
->num_srvid
) && chk_srvid_match(er
, sidtab
))
188 int32_t chk_srvid_localgenerated_only_exception(ECM_REQUEST
*er
)
193 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
195 if(sidtab
->lg_only_exception
&& (sidtab
->num_caid
| sidtab
->num_provid
| sidtab
->num_srvid
) && chk_srvid_match(er
, sidtab
))
204 int32_t chk_srvid(struct s_client
*cl
, ECM_REQUEST
*er
)
211 if(!cl
->sidtabs
.no
) { return (1); }
215 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
217 if(sidtab
->num_caid
| sidtab
->num_provid
| sidtab
->num_srvid
)
219 if((cl
->sidtabs
.no
& ((SIDTABBITS
)1 << nr
)) && (chk_srvid_match(er
, sidtab
)))
222 if((cl
->sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) && (chk_srvid_match(er
, sidtab
)))
229 int32_t has_srvid(struct s_client
*cl
, ECM_REQUEST
*er
)
237 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
239 if(sidtab
->num_srvid
)
241 if((cl
->sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) && (chk_srvid_match(er
, sidtab
)))
248 int32_t has_lb_srvid(struct s_client
*cl
, ECM_REQUEST
*er
)
250 if(!cl
->lb_sidtabs
.ok
)
256 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
258 if((cl
->lb_sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) && (chk_srvid_match(er
, sidtab
)))
264 int32_t chk_srvid_match_by_caid_prov(uint16_t caid
, uint32_t provid
, SIDTAB
*sidtab
)
268 if(!sidtab
->num_caid
)
271 for(i
= 0; (i
< sidtab
->num_caid
) && (!(rc
& 1)); i
++)
272 if(caid
== sidtab
->caid
[i
]) { rc
|= 1; }
274 if(!sidtab
->num_provid
)
277 for(i
= 0; (i
< sidtab
->num_provid
) && (!(rc
& 2)); i
++)
278 if(provid
== sidtab
->provid
[i
]) { rc
|= 2; }
283 int32_t chk_srvid_by_caid_prov(struct s_client
*cl
, uint16_t caid
, uint32_t provid
)
290 if(!cl
->sidtabs
.no
) { return (1); }
294 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
296 if(sidtab
->num_caid
| sidtab
->num_provid
)
298 if((cl
->sidtabs
.no
& ((SIDTABBITS
)1 << nr
)) && !sidtab
->num_srvid
&&
299 (chk_srvid_match_by_caid_prov(caid
, provid
, sidtab
)))
302 if((cl
->sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) &&
303 (chk_srvid_match_by_caid_prov(caid
, provid
, sidtab
)))
310 int32_t chk_srvid_by_caid_prov_rdr(struct s_reader
*rdr
, uint16_t caid
, uint32_t provid
)
317 if(!rdr
->sidtabs
.no
) { return (1); }
321 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
323 if(sidtab
->num_caid
| sidtab
->num_provid
)
325 if((rdr
->sidtabs
.no
& ((SIDTABBITS
)1 << nr
)) && !sidtab
->num_srvid
&&
326 (chk_srvid_match_by_caid_prov(caid
, provid
, sidtab
)))
329 if((rdr
->sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) &&
330 (chk_srvid_match_by_caid_prov(caid
, provid
, sidtab
)))
337 int32_t chk_is_betatunnel_caid(uint16_t caid
)
339 if(caid
== 0x1702 || caid
== 0x1722) { return 1; }
340 if(caid
== 0x1801 || caid
== 0x1833 || caid
== 0x1834 || caid
== 0x1835) { return 2; }
344 uint16_t chk_on_btun(uint8_t chk_sx
, struct s_client
*cl
, ECM_REQUEST
*er
)
346 if(chk_is_betatunnel_caid(er
->caid
))
354 for(i
= 0; i
< ttab
->ttnum
; i
++)
356 if(er
->caid
== ttab
->ttdata
[i
].bt_caidfrom
)
358 if(er
->srvid
== ttab
->ttdata
[i
].bt_srvid
) { return ttab
->ttdata
[i
].bt_caidto
; }
359 if(chk_sx
&& ttab
->ttdata
[i
].bt_srvid
== 0xFFFF) { return ttab
->ttdata
[i
].bt_caidto
; }
360 if(!chk_sx
&& !ttab
->ttdata
[i
].bt_srvid
) { return ttab
->ttdata
[i
].bt_caidto
; }
366 return lb_get_betatunnel_caid_to(er
);
371 // server filter for newcamd
372 int32_t chk_sfilter(ECM_REQUEST
*er
, PTAB
*ptab
)
374 #ifdef MODULE_NEWCAMD
375 int32_t i
, j
, pi
, rc
= 1;
376 uint16_t caid
, scaid
;
377 uint32_t prid
, sprid
;
379 if(!ptab
) { return (1); }
380 struct s_client
*cur_cl
= cur_client();
384 pi
= cur_cl
->port_idx
;
389 if(ptab
->nports
&& ptab
->ports
[pi
].ncd
&& ptab
->ports
[pi
].ncd
->ncd_ftab
.nfilts
)
391 for(rc
= j
= 0; (!rc
) && (j
< ptab
->ports
[pi
].ncd
->ncd_ftab
.nfilts
); j
++)
393 scaid
= ptab
->ports
[pi
].ncd
->ncd_ftab
.filts
[j
].caid
;
394 if(caid
== 0 || (caid
!= 0 && caid
== scaid
))
396 for(i
= 0; (!rc
) && i
< ptab
->ports
[pi
].ncd
->ncd_ftab
.filts
[j
].nprids
; i
++)
398 sprid
= ptab
->ports
[pi
].ncd
->ncd_ftab
.filts
[j
].prids
[i
];
399 cs_log_dbg(D_CLIENT
, "trying server filter %04X@%06X", scaid
, sprid
);
403 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed by server filter %04X@%06X",
404 caid
, prid
, scaid
, sprid
);
412 cs_log_dbg(D_CLIENT
, "no match, %04X@%06X rejected by server filters", caid
, prid
);
413 snprintf(er
->msglog
, MSGLOGSIZE
, "no server match %04X@%06X", caid
, (uint32_t) prid
);
415 if(!er
->rcEx
) { er
->rcEx
= (E1_LSERVER
<< 4) | E2_IDENT
; }
427 static int32_t chk_chid(ECM_REQUEST
*er
, FTAB
*fchid
, char *type
, char *name
)
429 int32_t rc
= 1, i
, j
, found_caid
= 0;
430 if(!fchid
->nfilts
) { return 1; }
431 if(er
->chid
== 0 && er
->ecm
[0] == 0) { return 1; } // skip empty ecm, chid 00 to avoid no matching readers in dvbapi
433 for(i
= rc
= 0; (!rc
) && i
< fchid
->nfilts
; i
++)
435 if(er
->caid
== fchid
->filts
[i
].caid
)
438 for(j
= 0; (!rc
) && j
< fchid
->filts
[i
].nprids
; j
++)
440 cs_log_dbg(D_CLIENT
, "trying %s '%s' CHID filter %04X:%04X",
441 type
, name
, fchid
->filts
[i
].caid
, fchid
->filts
[i
].prids
[j
]);
443 if(er
->chid
== fchid
->filts
[i
].prids
[j
])
445 cs_log_dbg(D_CLIENT
, "%04X:%04X allowed by %s '%s' CHID filter %04X:%04X",
446 er
->caid
, er
->chid
, type
, name
, fchid
->filts
[i
].caid
, fchid
->filts
[i
].prids
[j
]);
456 cs_log_dbg(D_CLIENT
, "no match, %04X:%04X rejected by %s '%s' CHID filter(s)",
457 er
->caid
, er
->chid
, type
, name
);
461 cs_log_dbg(D_CLIENT
, "%04X:%04X allowed by %s '%s' CHID filter, CAID not spezified",
462 er
->caid
, er
->chid
, type
, name
);
468 int32_t chk_ident_filter(uint16_t rcaid
, uint32_t rprid
, FTAB
*ftab
)
470 int32_t i
, j
, rc
= 1;
476 for(rc
= i
= 0; (!rc
) && (i
< ftab
->nfilts
); i
++)
478 caid
= ftab
->filts
[i
].caid
;
479 if((caid
!= 0 && caid
== rcaid
) || caid
== 0)
481 for(j
= 0; (!rc
) && (j
< ftab
->filts
[i
].nprids
); j
++)
483 prid
= ftab
->filts
[i
].prids
[j
];
499 int32_t chk_ufilters(ECM_REQUEST
*er
)
501 int32_t i
, j
, rc
= 1;
504 struct s_client
*cur_cl
= cur_client();
506 if(cur_cl
->ftab
.nfilts
)
508 FTAB
*f
= &cur_cl
->ftab
;
509 for(i
= rc
= 0; (!rc
) && (i
< f
->nfilts
); i
++)
511 ucaid
= f
->filts
[i
].caid
;
512 if(er
->caid
== 0 || ucaid
== 0 || (er
->caid
!= 0 && er
->caid
== ucaid
))
516 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed by user '%s' filter caid %04X prid %06X",
517 er
->caid
, er
->prid
, cur_cl
->account
->usr
, ucaid
, 0);
522 for(j
= rc
= 0; (!rc
) && (j
< f
->filts
[i
].nprids
); j
++)
524 uprid
= f
->filts
[i
].prids
[j
];
525 cs_log_dbg(D_CLIENT
, "trying user '%s' filter %04X@%06X", cur_cl
->account
->usr
, ucaid
, uprid
);
527 if(er
->prid
== uprid
)
530 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed by user '%s' filter %04X@%06X",
531 er
->caid
, er
->prid
, cur_cl
->account
->usr
, ucaid
, uprid
);
539 cs_log_dbg(D_CLIENT
, "no match, %04X@%06X rejected by user '%s' filters",
540 er
->caid
, er
->prid
, cur_cl
->account
->usr
);
542 snprintf(er
->msglog
, MSGLOGSIZE
, "no card support %04X@%06X", er
->caid
, (uint32_t) er
->prid
);
544 if(!er
->rcEx
) { er
->rcEx
= (E1_USER
<< 4) | E2_IDENT
; }
549 if(!(rc
= chk_class(er
, &cur_cl
->cltab
, "user", cur_cl
->account
->usr
)))
551 if(!er
->rcEx
) { er
->rcEx
= (E1_USER
<< 4) | E2_CLASS
; }
553 else if(!(rc
= chk_chid(er
, &cur_cl
->fchid
, "user", cur_cl
->account
->usr
)))
555 if(!er
->rcEx
) { er
->rcEx
= (E1_USER
<< 4) | E2_CHID
; }
558 if(rc
) { er
->rcEx
= 0; }
563 int32_t chk_rsfilter(struct s_reader
*reader
, ECM_REQUEST
*er
)
569 if(reader
->ncd_disable_server_filt
)
571 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed - server filters disabled", er
->caid
, er
->prid
);
579 for(i
= 0; (!rc
) && (i
< reader
->nprov
); i
++)
581 prid
= (uint32_t)((reader
->prid
[i
][1] << 16) | (reader
->prid
[i
][2] << 8) | (reader
->prid
[i
][3]));
582 cs_log_dbg(D_CLIENT
, "trying server '%s' filter %04X@%06X", reader
->device
, caid
, prid
);
584 if(prid
== er
->prid
|| !er
->prid
)
587 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed by server '%s' filter %04X@%06X",
588 er
->caid
, er
->prid
, reader
->device
, caid
, prid
);
595 cs_log_dbg(D_CLIENT
, "no match, %04X@%06X rejected by server '%s' filters",
596 er
->caid
, er
->prid
, reader
->device
);
598 if(!er
->rcEx
) { er
->rcEx
= (E1_SERVER
<< 4) | E2_IDENT
; }
605 int32_t chk_rfilter2(uint16_t rcaid
, uint32_t rprid
, struct s_reader
*rdr
)
607 int32_t i
, j
, rc
= 1;
613 for(rc
= i
= 0; (!rc
) && (i
< rdr
->ftab
.nfilts
); i
++)
615 caid
= rdr
->ftab
.filts
[i
].caid
;
616 if((caid
!= 0 && caid
== rcaid
) || caid
== 0)
618 for(j
= 0; (!rc
) && (j
< rdr
->ftab
.filts
[i
].nprids
); j
++)
620 prid
= rdr
->ftab
.filts
[i
].prids
[j
];
621 cs_log_dbg(D_CLIENT
, "trying reader '%s' filter %04X@%06X", rdr
->label
, caid
, prid
);
626 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed by reader '%s' filter %04X@%06X",
627 rcaid
, rprid
, rdr
->label
, caid
, prid
);
635 cs_log_dbg(D_CLIENT
, "no match, %04X@%06X rejected by reader '%s' filters",
636 rcaid
, rprid
, rdr
->label
);
644 static int32_t chk_rfilter(ECM_REQUEST
*er
, struct s_reader
*rdr
)
646 return chk_rfilter2(er
->caid
, er
->prid
, rdr
);
649 int32_t chk_ctab(uint16_t caid
, CAIDTAB
*ctab
)
651 if(!caid
|| !ctab
->ctnum
)
655 for(i
= 0; i
< ctab
->ctnum
; i
++)
657 CAIDTAB_DATA
*d
= &ctab
->ctdata
[i
];
662 if((caid
& d
->mask
) == d
->caid
)
668 int32_t chk_ctab_ex(uint16_t caid
, CAIDTAB
*ctab
)
670 if(!caid
|| !ctab
->ctnum
)
674 for(i
= 0; i
< ctab
->ctnum
; i
++)
676 CAIDTAB_DATA
*d
= &ctab
->ctdata
[i
];
682 if((caid
& d
->mask
) == d
->caid
)
690 uint8_t is_localreader(struct s_reader
*rdr
, ECM_REQUEST
*er
) // to be used for LB/reader selections checks only
694 if(!is_network_reader(rdr
))
699 if(!rdr
->localcards
.nfilts
) { return 0; }
702 for(i
= 0; i
< rdr
->localcards
.nfilts
; i
++)
704 uint16_t tcaid
= rdr
->localcards
.filts
[i
].caid
;
705 if(tcaid
&& tcaid
== er
->caid
) // caid match
707 int32_t nprids
= rdr
->localcards
.filts
[i
].nprids
;
708 if(!nprids
) // No Provider -> Ok
711 for(k
= 0; k
< nprids
; k
++)
713 uint32_t prid
= rdr
->localcards
.filts
[i
].prids
[k
];
714 if(prid
== er
->prid
) // Provider matches
725 uint8_t chk_is_fixed_fallback(struct s_reader
*rdr
, ECM_REQUEST
*er
)
727 if(!rdr
->fallback
&& !rdr
->fallback_percaid
.nfilts
) { return 0; }
729 if(!rdr
->fallback_percaid
.nfilts
)
736 for(i
= 0; i
< rdr
->fallback_percaid
.nfilts
; i
++)
738 uint16_t tcaid
= rdr
->fallback_percaid
.filts
[i
].caid
;
739 if(tcaid
&& (tcaid
== er
->caid
|| (tcaid
< 0x0100 && (er
->caid
>> 8) == tcaid
))) // caid match
741 int32_t nprids
= rdr
->fallback_percaid
.filts
[i
].nprids
;
742 if(!nprids
) // No Provider ->Ok
745 for(k
= 0; k
< nprids
; k
++)
747 uint32_t prid
= rdr
->fallback_percaid
.filts
[i
].prids
[k
];
748 if(prid
== er
->prid
) // Provider matches
759 #ifdef CS_CACHEEX_AIO
760 uint8_t chk_lg_only(ECM_REQUEST
*er
, FTAB
*lg_only_ftab
)
764 if(!lg_only_ftab
->nfilts
)
767 for(i
= 0; i
< lg_only_ftab
->nfilts
; i
++)
769 uint16_t tcaid
= lg_only_ftab
->filts
[i
].caid
;
770 if(tcaid
&& (tcaid
== er
->caid
|| (tcaid
< 0x0100 && (er
->caid
>> 8) == tcaid
))) // caid match
772 int32_t nprids
= lg_only_ftab
->filts
[i
].nprids
;
773 if(!nprids
) // No Provider ->Ok
776 for(k
= 0; k
< nprids
; k
++)
778 uint32_t prid
= lg_only_ftab
->filts
[i
].prids
[k
];
779 if(prid
== NO_PROVID_VALUE
|| prid
== er
->prid
) // Provider matches
790 uint8_t chk_lg_only_cp(uint16_t caid
, uint32_t prid
, FTAB
*lg_only_ftab
)
794 if(!lg_only_ftab
->nfilts
)
797 for(i
= 0; i
< lg_only_ftab
->nfilts
; i
++)
799 uint16_t tcaid
= lg_only_ftab
->filts
[i
].caid
;
800 if(tcaid
&& (tcaid
== caid
|| (tcaid
< 0x0100 && (caid
>> 8) == tcaid
))) // caid match
802 int32_t nprids
= lg_only_ftab
->filts
[i
].nprids
;
803 if(!nprids
) // No Provider ->Ok
806 for(k
= 0; k
< nprids
; k
++)
808 uint32_t fprid
= lg_only_ftab
->filts
[i
].prids
[k
];
809 if(fprid
== NO_PROVID_VALUE
|| fprid
== prid
) // Provider matches
821 uint8_t chk_has_fixed_fallback(ECM_REQUEST
*er
)
823 struct s_ecm_answer
*ea
;
824 struct s_reader
*rdr
;
826 for(ea
= er
->matching_rdr
; ea
; ea
= ea
->next
)
829 if(chk_is_fixed_fallback(rdr
, er
))
835 uint8_t chk_if_ignore_checksum(ECM_REQUEST
*er
, FTAB
*disablecrc_only_for
)
837 if(!disablecrc_only_for
->nfilts
) { return 0; }
840 for(i
= 0; i
< disablecrc_only_for
->nfilts
; i
++)
842 uint16_t tcaid
= disablecrc_only_for
->filts
[i
].caid
;
843 if(tcaid
&& (tcaid
== er
->caid
|| (tcaid
< 0x0100 && (er
->caid
>> 8) == tcaid
))) // caid match
845 int32_t nprids
= disablecrc_only_for
->filts
[i
].nprids
;
846 if(!nprids
) // No Provider ->Ok
849 for(k
= 0; k
< nprids
; k
++)
851 uint32_t prid
=disablecrc_only_for
->filts
[i
].prids
[k
];
852 if(prid
== er
->prid
) // Provider matches
861 int32_t matching_reader(ECM_REQUEST
*er
, struct s_reader
*rdr
)
863 // simple checks first:
868 struct s_client
*cl
= rdr
->client
;
869 if(!cl
|| !rdr
->enable
)
872 // if physical reader a card needs to be inserted
873 if(!is_network_reader(rdr
) && rdr
->card_status
!= CARD_INSERTED
)
876 // Checking connected & group valid:
877 struct s_client
*cur_cl
= er
->client
; //cur_client();
880 // Cacheex=3 defines a Cacheex-only reader. never match them.
881 if(rdr
->cacheex
.mode
== 3)
883 if(rdr
->cacheex
.mode
== 2 && !rdr
->cacheex
.allow_request
)
887 if(!(rdr
->grp
& cur_cl
->grp
))
891 if((!er
->ocaid
|| !chk_ctab(er
->ocaid
, &rdr
->ctab
)) && !chk_ctab(er
->caid
, &rdr
->ctab
))
893 cs_log_dbg(D_TRACE
, "caid %04X not found in caidlist reader %s", er
->caid
, rdr
->label
);
897 if(!(rdr
->typ
== R_EMU
) && !is_network_reader(rdr
) && ((rdr
->caid
>> 8) != ((er
->caid
>> 8) & 0xFF) && (rdr
->caid
>> 8) != ((er
->ocaid
>> 8) & 0xFF)))
902 int i
, caid_found
= 0;
903 for(i
= 0; rdr
->csystem
->caids
[i
]; i
++)
905 uint16_t cs_caid
= rdr
->csystem
->caids
[i
];
909 if(cs_caid
== er
->caid
|| cs_caid
== er
->ocaid
)
920 // Supports long ecms?
921 if(er
->ecmlen
> 255 && is_network_reader(rdr
) && !rdr
->ph
.large_ecm_support
)
923 cs_log_dbg(D_TRACE
, "no large ecm support (l=%d) for reader %s", er
->ecmlen
, rdr
->label
);
927 // Checking services:
928 if(!chk_srvid(rdr
->client
, er
))
930 cs_log_dbg(D_TRACE
, "service %04X not matching reader %s", er
->srvid
, rdr
->label
);
935 if(!(rdr
->typ
== R_EMU
&& caid_is_biss(er
->caid
)) && !chk_rfilter(er
, rdr
))
937 cs_log_dbg(D_TRACE
, "r-filter reader %s", rdr
->label
);
942 if(!chk_class(er
, &rdr
->cltab
, "reader", rdr
->label
))
944 cs_log_dbg(D_TRACE
, "class filter reader %s", rdr
->label
);
948 // CDS NL: check for right seca type
949 if(!is_network_reader(rdr
) && er
->caid
== 0x100 && er
->prid
== 0x00006a
950 && !(er
->ecm
[8] == 0x00 && er
->ecm
[9] == 0x00)) // no empty ecm
952 if(er
->ecm
[8] == 0x00 && rdr
->secatype
== 2)
954 cs_log_dbg(D_TRACE
, "Error: this is a nagra/mediaguard3 ECM and readertype is seca2!");
955 return 0; // we dont send a nagra/mediaguard3 ecm to a seca2 reader!
958 if((er
->ecm
[8] == 0x10) && (er
->ecm
[9] == 0x01) && rdr
->secatype
== 3)
960 cs_log_dbg(D_TRACE
, "Error: this is a seca2 ECM and readertype is nagra/mediaguard3!");
961 return 0; // we dont send a seca2 ecm to a nagra/mediaguard3 reader!
965 // CDS NL: check for right seca type by ECMPID
966 if(!is_network_reader(rdr
) && er
->caid
== 0x100 && er
->prid
== 0x00006a)
968 if(rdr
->secatype
== 2 && er
->pid
>> 8 == 7)
970 cs_log_dbg(D_TRACE
, "Error: this is a nagra/mediaguard3 ECM and readertype is seca2!");
971 return 0; // we dont send a nagra/mediaguard3 ecm to a seca2 reader!
974 if(rdr
->secatype
== 3 && er
->pid
>> 8 == 6)
976 cs_log_dbg(D_TRACE
, "Error: this is a seca2 ECM and readertype is nagra/mediaguard3!");
977 return 0; // we dont send a seca2 ecm to a nagra/mediaguard3 reader!
982 if(!chk_chid(er
, &rdr
->fchid
, "reader", rdr
->label
))
984 cs_log_dbg(D_TRACE
, "chid filter reader %s", rdr
->label
);
988 // Schlocke reader-defined function, reader-self-check
989 if(rdr
->ph
.c_available
&& !rdr
->ph
.c_available(rdr
, AVAIL_CHECK_CONNECTED
, er
))
991 cs_log_dbg(D_TRACE
, "reader unavailable %s", rdr
->label
);
995 // Checking entitlements:
996 if(ll_count(rdr
->ll_entitlements
) > 0 && !(rdr
->typ
== R_EMU
))
998 LL_ITER itr
= ll_iter_create(rdr
->ll_entitlements
);
1002 while((item
= ll_iter_next(&itr
)))
1004 if(item
->caid
!= er
->caid
) continue; // skip wrong caid!
1005 if(item
->type
== 7) continue; // skip seca-admin type (provid 000000) since its not used for decoding!
1006 if(er
->prid
&& item
->provid
&& er
->prid
!= item
->provid
) continue; // skip non matching provid!
1007 if(!er
->prid
&& caid_is_seca(er
->caid
)) continue; // dont accept requests without provid for seca cas.
1008 if(!er
->prid
&& caid_is_viaccess(er
->caid
)) continue; // dont accept requests without provid for viaccess cas
1009 if(!er
->prid
&& caid_is_cryptoworks(er
->caid
)) continue; // dont accept requests without provid for cryptoworks cas
1014 if(!found
&& er
->ecm
[0]) // ecmrequest can get corrected provid parsed from payload in ecm
1016 cs_log_dbg(D_TRACE
, "entitlements check failed on reader %s", rdr
->label
);
1021 // Checking ecmlength:
1022 if(rdr
->ecm_whitelist
.ewnum
&& er
->ecmlen
)
1025 int8_t ok
= 0, foundident
= 0;
1027 for (i
= 0; i
< rdr
->ecm_whitelist
.ewnum
; i
++)
1029 ECM_WHITELIST_DATA
*d
= &rdr
->ecm_whitelist
.ewdata
[i
];
1030 if ((d
->caid
== 0 || d
->caid
== er
->caid
) && (d
->ident
== 0 || d
->ident
== er
->prid
))
1033 if (d
->len
== er
->ecmlen
)
1041 if(foundident
== 1 && ok
== 0)
1043 cs_log_dbg(D_TRACE
, "ECM is not in ecmwhitelist of reader %s.", rdr
->label
);
1044 rdr
->ecmsfilteredlen
+= 1;
1045 rdr
->webif_ecmsfilteredlen
+= 1;
1051 if(rdr
->ecm_hdr_whitelist
.ehdata
&& er
->ecmlen
)
1055 int8_t foundcaid
= 0;
1056 int8_t foundprovid
= 0;
1062 for(r
= 0; r
< rdr
->ecm_hdr_whitelist
.ehnum
; r
++)
1064 ECM_HDR_WHITELIST_DATA
*tmp
= &rdr
->ecm_hdr_whitelist
.ehdata
[r
];
1069 if(tmp
->caid
== 0 || tmp
->caid
== er
->caid
)
1071 foundcaid
= 1; //-> caid was in list
1072 //rdr_log_dbg(rdr, D_READER, "Headerwhitelist: found matching CAID: %04X in list", tmp->caid);
1074 if(tmp
->provid
== 0 || tmp
->provid
== er
->prid
)
1076 foundprovid
= 1; //-> provid was in list
1077 //rdr_log_dbg(rdr, D_READER, "Headerwhitelist: found matching Provid: %06X in list", tmp->provid);
1080 for(i
= 0; i
< len
/ 2; i
++)
1082 if(tmp
->header
[i
] == er
->ecm
[i
])
1085 //rdr_log_dbg(rdr, D_READER, "ECM Byte: %i of ECMHeaderwhitelist is correct. (%02X = %02X Headerlen: %i)", i, er->ecm[i], tmp->header[i], len/2);
1090 //rdr_log_dbg(rdr, D_READER, "ECM Byte: %i of ECMHeaderwhitelist is not valid. (%02X != %02X Headerlen: %i)", i, er->ecm[i], tmp->header[i], len/2);
1095 if(i
== len
/ 2 - 1 && byteok
== 1)
1103 //rdr_log_dbg(rdr, D_READER, "ECMHeaderwhitelist: Provid: %06X not found in List-Entry -> skipping check", er->prid);
1110 //rdr_log_dbg(rdr, D_READER, "ECMHeaderwhitelist: CAID: %04X not found in List-Entry -> skipping check", er->caid);
1121 if(foundcaid
== 1 && foundprovid
== 1 && byteok
== 1 && entryok
== 1)
1123 //cs_log("ECM for %04X@%06X:%04X is valid for ECMHeaderwhitelist of reader %s.", er->caid, er->prid, er->srvid, rdr->label);
1127 if(skip
== 0 || (foundcaid
== 1 && foundprovid
== 1 && entryok
== 0 && skip
== 1))
1129 cs_log_dump_dbg(D_TRACE
, er
->ecm
, er
->ecmlen
, "following ECM %04X@%06X:%04X was filtered by ECMHeaderwhitelist of Reader %s from User %s because of not matching Header:", er
->caid
, er
->prid
, er
->srvid
, rdr
->label
, username(er
->client
));
1130 rdr
->ecmsfilteredhead
+= 1;
1131 rdr
->webif_ecmsfilteredhead
+= 1;
1137 // Simple ring connection check:
1139 // Check ip source+dest:
1140 if(cfg
.block_same_ip
&& IP_EQUAL(cur_cl
->ip
, rdr
->client
->ip
) && get_module(cur_cl
)->listenertype
!= LIS_DVBAPI
&& is_network_reader(rdr
))
1142 rdr_log_dbg(rdr
, D_TRACE
, "User (%s) has the same ip (%s) as the reader, blocked because block_same_ip=1!", username(cur_cl
), cs_inet_ntoa(rdr
->client
->ip
));
1146 if(cfg
.block_same_name
&& strcmp(username(cur_cl
), rdr
->label
) == 0)
1148 rdr_log_dbg(rdr
, D_TRACE
, "User (%s) has the same name as the reader, blocked because block_same_name=1!", username(cur_cl
));
1152 if(!reader_slots_available(rdr
, er
)&& er
->ecmlen
> 0) // check free slots, er->ecmlen>0 trick to skip this test for matching readers in dvbapi module
1157 // All checks done, reader is matching!
1161 int32_t chk_caid(uint16_t caid
, CAIDTAB
*ctab
)
1165 if (!ctab
->ctnum
) { return caid
; }
1167 for(i
= 0; i
< ctab
->ctnum
; i
++)
1169 CAIDTAB_DATA
*d
= &ctab
->ctdata
[i
];
1170 if((caid
& d
->mask
) == d
->caid
) { return d
->cmap
? d
->cmap
: caid
; }
1175 int32_t chk_caid_rdr(struct s_reader
*rdr
, uint16_t caid
)
1177 if(is_network_reader(rdr
) || rdr
->typ
== R_EMU
)
1179 return 1; // reader caid is not real caid
1181 else if(rdr
->caid
== caid
)
1188 int32_t chk_bcaid(ECM_REQUEST
*er
, CAIDTAB
*ctab
)
1191 caid
= chk_caid(er
->caid
, ctab
);
1192 if(caid
< 0) { return 0; }
1198 * Check for NULL CWs
1200 int32_t chk_is_null_CW(uint8_t cw
[])
1203 for(i
= 0; i
< 16; i
++)
1212 * Check for ecm request that expects half cw format
1214 int8_t is_halfCW_er(ECM_REQUEST
*er
)
1216 if( caid_is_videoguard(er
->caid
) && (er
->caid
== 0x09C4 || er
->caid
== 0x098C || er
->caid
== 0x098D || er
->caid
== 0x0963 || er
->caid
== 0x09CD || er
->caid
== 0x0919 || er
->caid
== 0x093B || er
->caid
== 0x098E))
1222 * Check for wrong half CWs
1224 int8_t chk_halfCW(ECM_REQUEST
*er
, uint8_t *cw
)
1226 if(is_halfCW_er(er
) && cw
)
1228 uint8_t cw15
= cw
[15];
1229 if(get_odd_even(er
) == 0x80 && cw
[15] == 0xF0) { cw
[15] = 0; }
1231 int8_t part1
= checkCWpart(cw
, 0);
1232 int8_t part2
= checkCWpart(cw
, 1);
1234 // check for correct half cw format
1235 if(part1
&& part2
){ cw
[15] = cw15
; return 0; }
1237 // check for correct cw position
1238 if((get_odd_even(er
) == 0x80 && part1
&& !part2
) // xxxxxxxx00000000
1239 ||(get_odd_even(er
) == 0x81 && !part1
&& part2
)) // 00000000xxxxxxxx
1245 return 0; // not correct swapped cw
1254 * Check for NULL nodeid
1256 int32_t chk_is_null_nodeid(uint8_t node_id
[], uint8_t len
)
1259 for(i
= 0; i
< len
; i
++)
1261 if(node_id
[i
]) { return 0; }
1266 // check if client structure is accessible
1267 bool check_client(struct s_client
*cl
)
1269 if(cl
&& !cl
->kill
) { return true; }
1273 uint16_t caidvaluetab_get_value(CAIDVALUETAB
*cv
, uint16_t caid
, uint16_t default_value
)
1276 for(i
= 0; i
< cv
->cvnum
; i
++)
1278 CAIDVALUETAB_DATA
*cvdata
= &cv
->cvdata
[i
];
1279 if(cvdata
->caid
== caid
|| cvdata
->caid
== caid
>> 8) { return cvdata
->value
; }
1281 return default_value
;
1284 int32_t chk_is_fakecw(uint8_t *cw
)
1286 uint32_t i
, is_fakecw
= 0;
1287 uint32_t idx
= ((cw
[0] & 0xF) << 4) | (cw
[8] & 0xF);
1289 cs_readlock(__func__
, &config_lock
);
1291 for(i
= 0; i
< cfg
.fakecws
[idx
].count
; i
++)
1293 if(memcmp(cw
, cfg
.fakecws
[idx
].data
[i
].cw
, 16) == 0)
1299 cs_readunlock(__func__
, &config_lock
);
1304 #ifdef CS_CACHEEX_AIO
1305 bool chk_nopushafter(uint16_t caid
, CAIDVALUETAB
*cv
, int32_t ecm_time
)
1307 uint16_t npa_time
= caidvaluetab_get_value(cv
, caid
, 0);
1308 if(npa_time
&& (ecm_time
> npa_time
))
1310 cs_log_dbg(D_CACHEEX
, "REJECTED push: nopushafter %u < ecm_time %i", npa_time
, ecm_time
);