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(uchar
*ecm
, int32_t l
, uchar 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; }
56 j
= an
= cl_n
= l
= 0;
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
69 if(ecm_class
== clstab
->bclass
[i
])
71 cs_log_dbg(D_CLIENT
, "class %02X rejected by %s '%s' !%02X filter",
72 ecm_class
, type
, name
, ecm_class
);
77 for(i
= 0; i
< clstab
->an
; i
++) // search in allowed
78 if(ecm_class
== clstab
->aclass
[i
])
89 if(er
->prid
!= 0x11 || er
->ecm
[0] == 0) { return 1; }
92 ecm_class
= er
->ecm
[5];
93 cs_log_dbg(D_CLIENT
, "ecm class=%02X", ecm_class
);
95 for(i
= 0; i
< clstab
->bn
; i
++) // search in blocked
96 if(ecm_class
== clstab
->bclass
[i
])
98 cs_log_dbg(D_CLIENT
, "class %02X rejected by %s '%s' !%02X filter",
99 ecm_class
, type
, name
, ecm_class
);
103 for(i
= 0; i
< clstab
->an
; i
++) // search in allowed
104 if(ecm_class
== clstab
->aclass
[i
])
111 if(cl_n
&& clstab
->an
)
114 { cs_log_dbg(D_CLIENT
, "ECM classes allowed by %s '%s' filter", type
, name
); }
117 cs_log_dbg(D_CLIENT
, "ECM classes don't match %s '%s' filter, rejecting", type
, name
);
125 int32_t chk_srvid_match(ECM_REQUEST
*er
, SIDTAB
*sidtab
)
129 if(!sidtab
->num_caid
)
132 for(i
= 0; (i
< sidtab
->num_caid
) && (!(rc
& 1)); i
++)
133 if(er
->caid
== sidtab
->caid
[i
]) { rc
|= 1; }
135 if(!er
->prid
|| !sidtab
->num_provid
)
138 for(i
= 0; (i
< sidtab
->num_provid
) && (!(rc
& 2)); i
++)
139 if(er
->prid
== sidtab
->provid
[i
]) { rc
|= 2; }
141 if(!sidtab
->num_srvid
)
144 for(i
= 0; (i
< sidtab
->num_srvid
) && (!(rc
& 4)); i
++)
145 if(er
->srvid
== sidtab
->srvid
[i
]) { rc
|= 4; }
150 int32_t chk_srvid(struct s_client
*cl
, ECM_REQUEST
*er
)
157 if(!cl
->sidtabs
.no
) { return (1); }
160 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
161 if(sidtab
->num_caid
| sidtab
->num_provid
| sidtab
->num_srvid
)
163 if((cl
->sidtabs
.no
& ((SIDTABBITS
)1 << nr
)) &&
164 (chk_srvid_match(er
, sidtab
)))
166 if((cl
->sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) &&
167 (chk_srvid_match(er
, sidtab
)))
173 int32_t has_srvid(struct s_client
*cl
, ECM_REQUEST
*er
)
181 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
182 if(sidtab
->num_srvid
)
184 if((cl
->sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) &&
185 (chk_srvid_match(er
, sidtab
)))
191 int32_t has_lb_srvid(struct s_client
*cl
, ECM_REQUEST
*er
)
193 if(!cl
->lb_sidtabs
.ok
)
199 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
200 if((cl
->lb_sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) &&
201 (chk_srvid_match(er
, sidtab
)))
206 int32_t chk_srvid_match_by_caid_prov(uint16_t caid
, uint32_t provid
, SIDTAB
*sidtab
)
210 if(!sidtab
->num_caid
)
213 for(i
= 0; (i
< sidtab
->num_caid
) && (!(rc
& 1)); i
++)
214 if(caid
== sidtab
->caid
[i
]) { rc
|= 1; }
216 if(!sidtab
->num_provid
)
219 for(i
= 0; (i
< sidtab
->num_provid
) && (!(rc
& 2)); i
++)
220 if(provid
== sidtab
->provid
[i
]) { rc
|= 2; }
225 int32_t chk_srvid_by_caid_prov(struct s_client
*cl
, uint16_t caid
, uint32_t provid
)
232 if(!cl
->sidtabs
.no
) { return (1); }
235 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
236 if(sidtab
->num_caid
| sidtab
->num_provid
)
238 if((cl
->sidtabs
.no
& ((SIDTABBITS
)1 << nr
)) && !sidtab
->num_srvid
&&
239 (chk_srvid_match_by_caid_prov(caid
, provid
, sidtab
)))
241 if((cl
->sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) &&
242 (chk_srvid_match_by_caid_prov(caid
, provid
, sidtab
)))
248 int32_t chk_srvid_by_caid_prov_rdr(struct s_reader
*rdr
, uint16_t caid
, uint32_t provid
)
255 if(!rdr
->sidtabs
.no
) { return (1); }
258 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
259 if(sidtab
->num_caid
| sidtab
->num_provid
)
261 if((rdr
->sidtabs
.no
& ((SIDTABBITS
)1 << nr
)) && !sidtab
->num_srvid
&&
262 (chk_srvid_match_by_caid_prov(caid
, provid
, sidtab
)))
264 if((rdr
->sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) &&
265 (chk_srvid_match_by_caid_prov(caid
, provid
, sidtab
)))
271 int32_t chk_is_betatunnel_caid(uint16_t caid
)
273 if(caid
== 0x1702 || caid
== 0x1722) { return 1; }
274 if(caid
== 0x1801 || caid
== 0x1833 || caid
== 0x1834 || caid
== 0x1835) { return 2; }
278 uint16_t chk_on_btun(uint8_t chk_sx
, struct s_client
*cl
, ECM_REQUEST
*er
)
280 if(chk_is_betatunnel_caid(er
->caid
))
289 for(i
= 0; i
< ttab
->ttnum
; i
++)
291 if(er
->caid
== ttab
->ttdata
[i
].bt_caidfrom
)
293 if(er
->srvid
== ttab
->ttdata
[i
].bt_srvid
) { return ttab
->ttdata
[i
].bt_caidto
; }
294 if(chk_sx
&& ttab
->ttdata
[i
].bt_srvid
== 0xFFFF) { return ttab
->ttdata
[i
].bt_caidto
; }
295 if(!chk_sx
&& !ttab
->ttdata
[i
].bt_srvid
) { return ttab
->ttdata
[i
].bt_caidto
; }
300 return lb_get_betatunnel_caid_to(er
);
305 // server filter for newcamd
306 int32_t chk_sfilter(ECM_REQUEST
*er
, PTAB
*ptab
)
308 #ifdef MODULE_NEWCAMD
309 int32_t i
, j
, pi
, rc
= 1;
310 uint16_t caid
, scaid
;
311 uint32_t prid
, sprid
;
313 if(!ptab
) { return (1); }
314 struct s_client
*cur_cl
= cur_client();
318 pi
= cur_cl
->port_idx
;
323 if(ptab
->nports
&& ptab
->ports
[pi
].ncd
&& ptab
->ports
[pi
].ncd
->ncd_ftab
.nfilts
)
325 for(rc
= j
= 0; (!rc
) && (j
< ptab
->ports
[pi
].ncd
->ncd_ftab
.nfilts
); j
++)
327 scaid
= ptab
->ports
[pi
].ncd
->ncd_ftab
.filts
[j
].caid
;
328 if(caid
== 0 || (caid
!= 0 && caid
== scaid
))
330 for(i
= 0; (!rc
) && i
< ptab
->ports
[pi
].ncd
->ncd_ftab
.filts
[j
].nprids
; i
++)
332 sprid
= ptab
->ports
[pi
].ncd
->ncd_ftab
.filts
[j
].prids
[i
];
333 cs_log_dbg(D_CLIENT
, "trying server filter %04X@%06X", scaid
, sprid
);
337 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed by server filter %04X@%06X",
338 caid
, prid
, scaid
, sprid
);
345 cs_log_dbg(D_CLIENT
, "no match, %04X@%06X rejected by server filters", caid
, prid
);
346 snprintf(er
->msglog
, MSGLOGSIZE
, "no server match %04X@%06X",
347 caid
, (uint32_t) prid
);
349 if(!er
->rcEx
) { er
->rcEx
= (E1_LSERVER
<< 4) | E2_IDENT
; }
361 static int32_t chk_chid(ECM_REQUEST
*er
, FTAB
*fchid
, char *type
, char *name
)
363 int32_t rc
= 1, i
, j
, found_caid
= 0;
364 if(!fchid
->nfilts
) { return 1; }
365 if(er
->chid
== 0 && er
->ecm
[0] == 0) { return 1; } // skip empty ecm, chid 00 to avoid no matching readers in dvbapi
367 for(i
= rc
= 0; (!rc
) && i
< fchid
->nfilts
; i
++)
368 if(er
->caid
== fchid
->filts
[i
].caid
)
371 for(j
= 0; (!rc
) && j
< fchid
->filts
[i
].nprids
; j
++)
373 cs_log_dbg(D_CLIENT
, "trying %s '%s' CHID filter %04X:%04X",
374 type
, name
, fchid
->filts
[i
].caid
, fchid
->filts
[i
].prids
[j
]);
375 if(er
->chid
== fchid
->filts
[i
].prids
[j
])
377 cs_log_dbg(D_CLIENT
, "%04X:%04X allowed by %s '%s' CHID filter %04X:%04X",
378 er
->caid
, er
->chid
, type
, name
, fchid
->filts
[i
].caid
,
379 fchid
->filts
[i
].prids
[j
]);
388 cs_log_dbg(D_CLIENT
, "no match, %04X:%04X rejected by %s '%s' CHID filter(s)",
389 er
->caid
, er
->chid
, type
, name
);
393 cs_log_dbg(D_CLIENT
, "%04X:%04X allowed by %s '%s' CHID filter, CAID not spezified",
394 er
->caid
, er
->chid
, type
, name
);
400 int32_t chk_ident_filter(uint16_t rcaid
, uint32_t rprid
, FTAB
*ftab
)
408 for(rc
=i
=0; (!rc
) && (i
<ftab
->nfilts
); i
++)
410 caid
= ftab
->filts
[i
].caid
;
411 if((caid
!=0 && caid
==rcaid
) || caid
==0)
413 for(j
=0; (!rc
) && (j
<ftab
->filts
[i
].nprids
); j
++)
415 prid
= ftab
->filts
[i
].prids
[j
];
430 int32_t chk_ufilters(ECM_REQUEST
*er
)
435 struct s_client
*cur_cl
= cur_client();
438 if(cur_cl
->ftab
.nfilts
)
440 FTAB
*f
= &cur_cl
->ftab
;
441 for(i
= rc
= 0; (!rc
) && (i
< f
->nfilts
); i
++)
443 ucaid
= f
->filts
[i
].caid
;
444 if(er
->caid
== 0 || ucaid
== 0 || (er
->caid
!= 0 && er
->caid
== ucaid
))
448 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed by user '%s' filter caid %04X prid %06X",
449 er
->caid
, er
->prid
, cur_cl
->account
->usr
, ucaid
, 0);
453 for(j
= rc
= 0; (!rc
) && (j
< f
->filts
[i
].nprids
); j
++)
455 uprid
= f
->filts
[i
].prids
[j
];
456 cs_log_dbg(D_CLIENT
, "trying user '%s' filter %04X@%06X",
457 cur_cl
->account
->usr
, ucaid
, uprid
);
458 if(er
->prid
== uprid
)
461 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed by user '%s' filter %04X@%06X",
462 er
->caid
, er
->prid
, cur_cl
->account
->usr
, ucaid
, uprid
);
469 cs_log_dbg(D_CLIENT
, "no match, %04X@%06X rejected by user '%s' filters",
470 er
->caid
, er
->prid
, cur_cl
->account
->usr
);
471 snprintf(er
->msglog
, MSGLOGSIZE
, "no card support %04X@%06X",
472 er
->caid
, (uint32_t) er
->prid
);
474 if(!er
->rcEx
) { er
->rcEx
= (E1_USER
<< 4) | E2_IDENT
; }
479 if(!(rc
= chk_class(er
, &cur_cl
->cltab
, "user", cur_cl
->account
->usr
)))
481 if(!er
->rcEx
) { er
->rcEx
= (E1_USER
<< 4) | E2_CLASS
; }
483 else if(!(rc
= chk_chid(er
, &cur_cl
->fchid
, "user", cur_cl
->account
->usr
)))
484 if(!er
->rcEx
) { er
->rcEx
= (E1_USER
<< 4) | E2_CHID
; }
486 if(rc
) { er
->rcEx
= 0; }
491 int32_t chk_rsfilter(struct s_reader
*reader
, ECM_REQUEST
*er
)
497 if(reader
->ncd_disable_server_filt
)
499 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed - server filters disabled",
508 for(i
= 0; (!rc
) && (i
< reader
->nprov
); i
++)
510 prid
= (uint32_t)((reader
->prid
[i
][1] << 16) |
511 (reader
->prid
[i
][2] << 8) |
512 (reader
->prid
[i
][3]));
513 cs_log_dbg(D_CLIENT
, "trying server '%s' filter %04X@%06X",
514 reader
->device
, caid
, prid
);
515 if(prid
== er
->prid
|| !er
->prid
)
518 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed by server '%s' filter %04X@%06X",
519 er
->caid
, er
->prid
, reader
->device
, caid
, prid
);
525 cs_log_dbg(D_CLIENT
, "no match, %04X@%06X rejected by server '%s' filters",
526 er
->caid
, er
->prid
, reader
->device
);
527 if(!er
->rcEx
) { er
->rcEx
= (E1_SERVER
<< 4) | E2_IDENT
; }
534 int32_t chk_rfilter2(uint16_t rcaid
, uint32_t rprid
, struct s_reader
*rdr
)
536 int32_t i
, j
, rc
= 1;
542 for(rc
= i
= 0; (!rc
) && (i
< rdr
->ftab
.nfilts
); i
++)
544 caid
= rdr
->ftab
.filts
[i
].caid
;
545 if((caid
!= 0 && caid
== rcaid
) || caid
== 0)
547 for(j
= 0; (!rc
) && (j
< rdr
->ftab
.filts
[i
].nprids
); j
++)
549 prid
= rdr
->ftab
.filts
[i
].prids
[j
];
550 cs_log_dbg(D_CLIENT
, "trying reader '%s' filter %04X@%06X",
551 rdr
->label
, caid
, prid
);
555 cs_log_dbg(D_CLIENT
, "%04X@%06X allowed by reader '%s' filter %04X@%06X",
556 rcaid
, rprid
, rdr
->label
, caid
, prid
);
563 cs_log_dbg(D_CLIENT
, "no match, %04X@%06X rejected by reader '%s' filters",
564 rcaid
, rprid
, rdr
->label
);
572 static int32_t chk_rfilter(ECM_REQUEST
*er
, struct s_reader
*rdr
)
574 return chk_rfilter2(er
->caid
, er
->prid
, rdr
);
577 int32_t chk_ctab(uint16_t caid
, CAIDTAB
*ctab
)
579 if(!caid
|| !ctab
->ctnum
)
583 for(i
= 0; i
< ctab
->ctnum
; i
++)
585 CAIDTAB_DATA
*d
= &ctab
->ctdata
[i
];
590 if((caid
& d
->mask
) == d
->caid
)
596 int32_t chk_ctab_ex(uint16_t caid
, CAIDTAB
*ctab
)
598 if(!caid
|| !ctab
->ctnum
)
602 for(i
= 0; i
< ctab
->ctnum
; i
++)
604 CAIDTAB_DATA
*d
= &ctab
->ctdata
[i
];
609 if((caid
& d
->mask
) == d
->caid
)
615 uint8_t is_localreader(struct s_reader
*rdr
, ECM_REQUEST
*er
) //to be used for LB/reader selections checks only
619 if(!is_network_reader(rdr
)){
623 if(!rdr
->localcards
.nfilts
) { return 0; }
626 for(i
= 0; i
< rdr
->localcards
.nfilts
; i
++)
628 uint16_t tcaid
= rdr
->localcards
.filts
[i
].caid
;
629 if(tcaid
&& tcaid
== er
->caid
) //caid match
631 int32_t nprids
= rdr
->localcards
.filts
[i
].nprids
;
632 if(!nprids
) // No Provider ->Ok
635 for(k
= 0; k
< nprids
; k
++)
637 uint32_t prid
= rdr
->localcards
.filts
[i
].prids
[k
];
638 if(prid
== er
->prid
) //Provider matches
649 uint8_t chk_is_fixed_fallback(struct s_reader
*rdr
, ECM_REQUEST
*er
)
652 if(!rdr
->fallback
&& !rdr
->fallback_percaid
.nfilts
) { return 0; }
654 if(!rdr
->fallback_percaid
.nfilts
)
659 for(i
= 0; i
< rdr
->fallback_percaid
.nfilts
; i
++)
661 uint16_t tcaid
= rdr
->fallback_percaid
.filts
[i
].caid
;
662 if(tcaid
&& (tcaid
== er
->caid
|| (tcaid
< 0x0100 && (er
->caid
>> 8) == tcaid
))) //caid match
665 int32_t nprids
= rdr
->fallback_percaid
.filts
[i
].nprids
;
666 if(!nprids
) // No Provider ->Ok
669 for(k
= 0; k
< nprids
; k
++)
671 uint32_t prid
= rdr
->fallback_percaid
.filts
[i
].prids
[k
];
672 if(prid
== er
->prid
) //Provider matches
683 uint8_t chk_has_fixed_fallback(ECM_REQUEST
*er
)
685 struct s_ecm_answer
*ea
;
686 struct s_reader
*rdr
;
688 for(ea
= er
->matching_rdr
; ea
; ea
= ea
->next
)
691 if(chk_is_fixed_fallback(rdr
, er
))
697 uint8_t chk_if_ignore_checksum(ECM_REQUEST
*er
, int8_t disablecrc
, FTAB
*disablecrc_only_for
)
699 if(!disablecrc
&& !disablecrc_only_for
->nfilts
) { return 0; }
702 for(i
= 0; i
< disablecrc_only_for
->nfilts
; i
++)
704 uint16_t tcaid
= disablecrc_only_for
->filts
[i
].caid
;
705 if(tcaid
&& (tcaid
== er
->caid
|| (tcaid
< 0x0100 && (er
->caid
>> 8) == tcaid
))) //caid match
708 int32_t nprids
= disablecrc_only_for
->filts
[i
].nprids
;
709 if(!nprids
) // No Provider ->Ok
712 for(k
= 0; k
< nprids
; k
++)
714 uint32_t prid
=disablecrc_only_for
->filts
[i
].prids
[k
];
715 if(prid
== er
->prid
) //Provider matches
724 int32_t matching_reader(ECM_REQUEST
*er
, struct s_reader
*rdr
)
727 //simple checks first:
732 struct s_client
*cl
= rdr
->client
;
733 if(!cl
|| !rdr
->enable
)
736 // if physical reader a card needs to be inserted
737 if(!is_network_reader(rdr
) && rdr
->card_status
!= CARD_INSERTED
)
740 //Checking connected & group valid:
741 struct s_client
*cur_cl
= er
->client
; //cur_client();
744 //Cacheex=3 defines a Cacheex-only reader. never match them.
745 if(rdr
->cacheex
.mode
== 3)
747 if(rdr
->cacheex
.mode
== 2 && !rdr
->cacheex
.allow_request
)
751 if(!(rdr
->grp
& cur_cl
->grp
))
755 if((!er
->ocaid
|| !chk_ctab(er
->ocaid
, &rdr
->ctab
)) && !chk_ctab(er
->caid
, &rdr
->ctab
))
757 cs_log_dbg(D_TRACE
, "caid %04X not found in caidlist reader %s", er
->caid
, rdr
->label
);
761 if(!is_network_reader(rdr
) && ((rdr
->caid
>> 8) != ((er
->caid
>> 8) & 0xFF) && (rdr
->caid
>> 8) != ((er
->ocaid
>> 8) & 0xFF)))
765 int i
, caid_found
= 0;
766 for(i
= 0; rdr
->csystem
->caids
[i
]; i
++)
768 uint16_t cs_caid
= rdr
->csystem
->caids
[i
];
771 if(cs_caid
== er
->caid
|| cs_caid
== er
->ocaid
)
781 //Supports long ecms?
782 if(er
->ecmlen
> 255 && is_network_reader(rdr
) && !rdr
->ph
.large_ecm_support
)
784 cs_log_dbg(D_TRACE
, "no large ecm support (l=%d) for reader %s", er
->ecmlen
, rdr
->label
);
790 if(!chk_srvid(rdr
->client
, er
))
792 cs_log_dbg(D_TRACE
, "service %04X not matching reader %s", er
->srvid
, rdr
->label
);
797 if(!chk_rfilter(er
, rdr
))
799 cs_log_dbg(D_TRACE
, "r-filter reader %s", rdr
->label
);
804 if(!chk_class(er
, &rdr
->cltab
, "reader", rdr
->label
))
806 cs_log_dbg(D_TRACE
, "class filter reader %s", rdr
->label
);
811 // CDS NL: check for right seca type
812 if(!is_network_reader(rdr
) && er
->caid
== 0x100 && er
->prid
== 0x00006a &&
813 !(er
->ecm
[8] == 0x00 && er
->ecm
[9] == 0x00)) // no empty ecm
815 if(er
->ecm
[8] == 0x00 && rdr
->secatype
== 2)
817 cs_log_dbg(D_TRACE
, "Error: this is a nagra/mediaguard3 ECM and readertype is seca2!");
818 return 0; // we dont send a nagra/mediaguard3 ecm to a seca2 reader!
820 if((er
->ecm
[8] == 0x10) && (er
->ecm
[9] == 0x01) && rdr
->secatype
== 3)
822 cs_log_dbg(D_TRACE
, "Error: this is a seca2 ECM and readertype is nagra/mediaguard3!");
823 return 0; // we dont send a seca2 ecm to a nagra/mediaguard3 reader!
826 // CDS NL: check for right seca type by ECMPID
827 if(!is_network_reader(rdr
) && er
->caid
== 0x100 && er
->prid
== 0x00006a)
829 if(rdr
->secatype
== 2 && er
->pid
>> 8 == 7)
831 cs_log_dbg(D_TRACE
, "Error: this is a nagra/mediaguard3 ECM and readertype is seca2!");
832 return 0; // we dont send a nagra/mediaguard3 ecm to a seca2 reader!
834 if(rdr
->secatype
== 3 && er
->pid
>> 8 == 6)
836 cs_log_dbg(D_TRACE
, "Error: this is a seca2 ECM and readertype is nagra/mediaguard3!");
837 return 0; // we dont send a seca2 ecm to a nagra/mediaguard3 reader!
842 if(!chk_chid(er
, &rdr
->fchid
, "reader", rdr
->label
))
844 cs_log_dbg(D_TRACE
, "chid filter reader %s", rdr
->label
);
848 //Schlocke reader-defined function, reader-self-check
849 if(rdr
->ph
.c_available
&& !rdr
->ph
.c_available(rdr
, AVAIL_CHECK_CONNECTED
, er
))
851 cs_log_dbg(D_TRACE
, "reader unavailable %s", rdr
->label
);
855 //Checking entitlements:
856 if(ll_count(rdr
->ll_entitlements
) > 0)
858 LL_ITER itr
= ll_iter_create(rdr
->ll_entitlements
);
861 while((item
= ll_iter_next(&itr
)))
863 if(item
->caid
!= er
->caid
) continue; // skip wrong caid!
864 if(item
->type
== 7) continue; // skip seca-admin type (provid 000000) since its not used for decoding!
865 if(er
->prid
&& item
->provid
&& er
->prid
!= item
->provid
) continue; // skip non matching provid!
866 if(!er
->prid
&& caid_is_seca(er
->caid
)) continue; // dont accept requests without provid for seca cas.
867 if(!er
->prid
&& caid_is_viaccess(er
->caid
)) continue; // dont accept requests without provid for viaccess cas
868 if(!er
->prid
&& caid_is_cryptoworks(er
->caid
)) continue; // dont accept requests without provid for cryptoworks cas
872 if(!found
&& er
->ecm
[0]) // ecmrequest can get corrected provid parsed from payload in ecm
874 cs_log_dbg(D_TRACE
, "entitlements check failed on reader %s", rdr
->label
);
879 //Checking ecmlength:
880 if(rdr
->ecm_whitelist
.ewnum
&& er
->ecmlen
)
883 int8_t ok
= 0, foundident
= 0;
884 for (i
= 0; i
< rdr
->ecm_whitelist
.ewnum
; i
++)
886 ECM_WHITELIST_DATA
*d
= &rdr
->ecm_whitelist
.ewdata
[i
];
887 if ((d
->caid
== 0 || d
->caid
== er
->caid
) && (d
->ident
== 0 || d
->ident
== er
->prid
))
890 if (d
->len
== er
->ecmlen
)
897 if(foundident
== 1 && ok
== 0)
899 cs_log_dbg(D_TRACE
, "ECM is not in ecmwhitelist of reader %s.", rdr
->label
);
900 rdr
->ecmsfilteredlen
+= 1;
901 rdr
->webif_ecmsfilteredlen
+= 1;
907 if(rdr
->ecm_hdr_whitelist
.ehdata
&& er
->ecmlen
)
911 int8_t foundcaid
= 0;
912 int8_t foundprovid
= 0;
917 for(r
= 0; r
< rdr
->ecm_hdr_whitelist
.ehnum
; r
++)
919 ECM_HDR_WHITELIST_DATA
*tmp
= &rdr
->ecm_hdr_whitelist
.ehdata
[r
];
924 if(tmp
->caid
== 0 || tmp
->caid
== er
->caid
)
926 foundcaid
= 1; //-> caid was in list
927 //rdr_log_dbg(rdr, D_READER, "Headerwhitelist: found matching CAID: %04X in list", tmp->caid);
928 if(tmp
->provid
== 0 || tmp
->provid
== er
->prid
)
930 foundprovid
= 1; //-> provid was in list
931 //rdr_log_dbg(rdr, D_READER, "Headerwhitelist: found matching Provid: %06X in list", tmp->provid);
933 for(i
= 0; i
< len
/ 2; i
++)
935 if(tmp
->header
[i
] == er
->ecm
[i
])
938 //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);
943 //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);
947 if(i
== len
/ 2 - 1 && byteok
== 1)
956 //rdr_log_dbg(rdr, D_READER, "ECMHeaderwhitelist: Provid: %06X not found in List-Entry -> skipping check", er->prid);
963 //rdr_log_dbg(rdr, D_READER, "ECMHeaderwhitelist: CAID: %04X not found in List-Entry -> skipping check", er->caid);
973 if(foundcaid
== 1 && foundprovid
== 1 && byteok
== 1 && entryok
== 1)
975 //cs_log("ECM for %04X@%06X:%04X is valid for ECMHeaderwhitelist of reader %s.", er->caid, er->prid, er->srvid, rdr->label);
979 if(skip
== 0 || (foundcaid
== 1 && foundprovid
== 1 && entryok
== 0 && skip
== 1))
981 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
));
982 rdr
->ecmsfilteredhead
+= 1;
983 rdr
->webif_ecmsfilteredhead
+= 1;
989 //Simple ring connection check:
991 //Check ip source+dest:
992 if(cfg
.block_same_ip
&& IP_EQUAL(cur_cl
->ip
, rdr
->client
->ip
) && get_module(cur_cl
)->listenertype
!= LIS_DVBAPI
&& is_network_reader(rdr
))
994 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
));
998 if(cfg
.block_same_name
&& strcmp(username(cur_cl
), rdr
->label
) == 0)
1000 rdr_log_dbg(rdr
, D_TRACE
, "User (%s) has the same name as the reader, blocked because block_same_name=1!", username(cur_cl
));
1004 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
1009 //All checks done, reader is matching!
1013 int32_t chk_caid(uint16_t caid
, CAIDTAB
*ctab
)
1016 if (!ctab
->ctnum
) return caid
;
1017 for(i
= 0; i
< ctab
->ctnum
; i
++)
1019 CAIDTAB_DATA
*d
= &ctab
->ctdata
[i
];
1020 if((caid
& d
->mask
) == d
->caid
) { return d
->cmap
? d
->cmap
: caid
; }
1025 int32_t chk_caid_rdr(struct s_reader
*rdr
, uint16_t caid
)
1027 if(is_network_reader(rdr
))
1029 return 1; //reader caid is not real caid
1031 else if(rdr
->caid
== caid
)
1038 int32_t chk_bcaid(ECM_REQUEST
*er
, CAIDTAB
*ctab
)
1041 caid
= chk_caid(er
->caid
, ctab
);
1042 if(caid
< 0) { return 0; }
1048 * Check for NULL CWs
1050 int32_t chk_is_null_CW(uchar cw
[])
1053 for(i
= 0; i
< 16; i
++)
1062 * Check for ecm request that expects half cw format
1064 int8_t is_halfCW_er(ECM_REQUEST
*er
)
1066 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))
1072 * Check for wrong half CWs
1074 int8_t chk_halfCW(ECM_REQUEST
*er
, uchar
*cw
)
1076 if(is_halfCW_er(er
) && cw
)
1078 uchar cw15
= cw
[15];
1079 if(get_odd_even(er
) == 0x80 && cw
[15] == 0xF0) { cw
[15] = 0; }
1081 int8_t part1
= checkCWpart(cw
, 0);
1082 int8_t part2
= checkCWpart(cw
, 1);
1084 //check for correct half cw format
1085 if(part1
&& part2
){ cw
[15] = cw15
; return 0; }
1087 //check for correct cw position
1089 (get_odd_even(er
) == 0x80 && part1
&& !part2
) //xxxxxxxx00000000
1091 (get_odd_even(er
) == 0x81 && !part1
&& part2
) //00000000xxxxxxxx
1095 return 0; //not correct swapped cw
1101 * Check for NULL nodeid
1103 int32_t chk_is_null_nodeid(uint8_t node_id
[], uint8_t len
)
1106 for(i
= 0; i
< len
; i
++)
1108 if(node_id
[i
]) { return 0; }
1113 //check if client structure is accessible
1114 bool check_client(struct s_client
*cl
)
1116 if(cl
&& !cl
->kill
) { return true; }
1120 uint16_t caidvaluetab_get_value(CAIDVALUETAB
*cv
, uint16_t caid
, uint16_t default_value
)
1123 for(i
= 0; i
< cv
->cvnum
; i
++)
1125 CAIDVALUETAB_DATA
*cvdata
= &cv
->cvdata
[i
];
1126 if(cvdata
->caid
== caid
|| cvdata
->caid
== caid
>> 8) { return cvdata
->value
; }
1128 return default_value
;
1131 int32_t chk_is_fakecw(uint8_t *cw
)
1133 uint32_t i
, is_fakecw
= 0;
1134 uint32_t idx
= ((cw
[0]&0xF)<<4) | (cw
[8]&0xF);
1136 cs_readlock(__func__
, &config_lock
);
1137 for(i
=0; i
<cfg
.fakecws
[idx
].count
; i
++)
1139 if(memcmp(cw
, cfg
.fakecws
[idx
].data
[i
].cw
, 16) == 0)
1145 cs_readunlock(__func__
, &config_lock
);