revert breaks some stupid old compilers
[oscam.git] / oscam-chk.c
blobeec620a7032451d0a00f222e993ccf4e49c5eab8
1 #define MODULE_LOG_PREFIX "chk"
3 #include "globals.h"
4 #include "oscam-cache.h"
5 #include "oscam-chk.h"
6 #include "oscam-ecm.h"
7 #include "oscam-client.h"
8 #include "oscam-lock.h"
9 #include "oscam-net.h"
10 #include "oscam-string.h"
11 #include "module-stat.h"
12 #include "oscam-reader.h"
14 #define CS_NANO_CLASS 0xE2
15 #define OK 1
16 #define ERROR 0
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; }
27 return ftimeout;
30 static int32_t find_nano(uchar *ecm, int32_t l, uchar nano, int32_t s)
32 uchar *snano;
34 if(s >= l) { return 0; }
35 if(!s) { s = (ecm[4] == 0xD2) ? 12 : 9; } // tpsflag -> offset+3
36 snano = ecm + s;
38 while((*snano != nano) && (s < l))
40 if(*snano == 0xEA) { return 0; }
41 snano++;
42 s++;
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;
51 uchar ecm_class;
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)
62 l = er->ecm[j];
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);
73 return 0;
76 cl_n++;
77 for(i = 0; i < clstab->an; i++) // search in allowed
78 if(ecm_class == clstab->aclass[i])
80 an++;
81 break;
83 j += l;
87 else
89 if(er->prid != 0x11 || er->ecm[0] == 0) { return 1; }
91 cl_n++;
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);
100 return 0;
103 for(i = 0; i < clstab->an; i++) // search in allowed
104 if(ecm_class == clstab->aclass[i])
106 an++;
107 break;
111 if(cl_n && clstab->an)
113 if(an)
114 { cs_log_dbg(D_CLIENT, "ECM classes allowed by %s '%s' filter", type, name); }
115 else
117 cs_log_dbg(D_CLIENT, "ECM classes don't match %s '%s' filter, rejecting", type, name);
118 return 0;
122 return 1;
125 int32_t chk_srvid_match(ECM_REQUEST *er, SIDTAB *sidtab)
127 int32_t i, rc = 0;
129 if(!sidtab->num_caid)
130 { rc |= 1; }
131 else
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)
136 { rc |= 2; }
137 else
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)
142 { rc |= 4; }
143 else
144 for(i = 0; (i < sidtab->num_srvid) && (!(rc & 4)); i++)
145 if(er->srvid == sidtab->srvid[i]) { rc |= 4; }
147 return (rc == 7);
150 int32_t chk_srvid(struct s_client *cl, ECM_REQUEST *er)
152 int32_t nr, rc = 0;
153 SIDTAB *sidtab;
155 if(!cl->sidtabs.ok)
157 if(!cl->sidtabs.no) { return (1); }
158 rc = 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)))
165 { return (0); }
166 if((cl->sidtabs.ok & ((SIDTABBITS)1 << nr)) &&
167 (chk_srvid_match(er, sidtab)))
168 { rc = 1; }
170 return (rc);
173 int32_t has_srvid(struct s_client *cl, ECM_REQUEST *er)
175 if(!cl->sidtabs.ok)
176 { return 0; }
178 int32_t nr;
179 SIDTAB *sidtab;
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)))
186 { return 1; }
188 return 0;
191 int32_t has_lb_srvid(struct s_client *cl, ECM_REQUEST *er)
193 if(!cl->lb_sidtabs.ok)
194 { return 0; }
196 int32_t nr;
197 SIDTAB *sidtab;
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)))
202 { return 1; }
203 return 0;
206 int32_t chk_srvid_match_by_caid_prov(uint16_t caid, uint32_t provid, SIDTAB *sidtab)
208 int32_t i, rc = 0;
210 if(!sidtab->num_caid)
211 { rc |= 1; }
212 else
213 for(i = 0; (i < sidtab->num_caid) && (!(rc & 1)); i++)
214 if(caid == sidtab->caid[i]) { rc |= 1; }
216 if(!sidtab->num_provid)
217 { rc |= 2; }
218 else
219 for(i = 0; (i < sidtab->num_provid) && (!(rc & 2)); i++)
220 if(provid == sidtab->provid[i]) { rc |= 2; }
222 return (rc == 3);
225 int32_t chk_srvid_by_caid_prov(struct s_client *cl, uint16_t caid, uint32_t provid)
227 int32_t nr, rc = 0;
228 SIDTAB *sidtab;
230 if(!cl->sidtabs.ok)
232 if(!cl->sidtabs.no) { return (1); }
233 rc = 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)))
240 { return (0); }
241 if((cl->sidtabs.ok & ((SIDTABBITS)1 << nr)) &&
242 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
243 { rc = 1; }
245 return (rc);
248 int32_t chk_srvid_by_caid_prov_rdr(struct s_reader *rdr, uint16_t caid, uint32_t provid)
250 int32_t nr, rc = 0;
251 SIDTAB *sidtab;
253 if(!rdr->sidtabs.ok)
255 if(!rdr->sidtabs.no) { return (1); }
256 rc = 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)))
263 { return (0); }
264 if((rdr->sidtabs.ok & ((SIDTABBITS)1 << nr)) &&
265 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
266 { rc = 1; }
268 return (rc);
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; }
275 return 0;
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))
283 int32_t i;
284 TUNTAB *ttab;
285 ttab = &cl->ttab;
287 if(ttab->ttdata)
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; }
299 if(chk_sx)
300 return lb_get_betatunnel_caid_to(er);
302 return 0;
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();
316 caid = er->caid;
317 prid = er->prid;
318 pi = cur_cl->port_idx;
320 if(cfg.ncd_mgclient)
321 { return 1; }
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);
334 if(prid == sprid)
336 rc = 1;
337 cs_log_dbg(D_CLIENT, "%04X@%06X allowed by server filter %04X@%06X",
338 caid, prid, scaid, sprid);
343 if(!rc)
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; }
350 return (rc);
353 return (rc);
354 #else
355 (void)er;
356 (void)ptab;
357 return 1;
358 #endif
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)
370 found_caid = 1;
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]);
380 rc = 1;
385 if(!rc)
387 if(found_caid)
388 cs_log_dbg(D_CLIENT, "no match, %04X:%04X rejected by %s '%s' CHID filter(s)",
389 er->caid, er->chid, type, name);
390 else
392 rc = 1;
393 cs_log_dbg(D_CLIENT, "%04X:%04X allowed by %s '%s' CHID filter, CAID not spezified",
394 er->caid, er->chid, type, name);
397 return (rc);
400 int32_t chk_ident_filter(uint16_t rcaid, uint32_t rprid, FTAB *ftab)
402 int32_t i, j, rc=1;
403 uint16_t caid=0;
404 uint32_t prid=0;
406 if(ftab->nfilts)
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];
416 if(prid==rprid)
418 rc=1;
423 if(!rc)
424 { return 0; }
427 return(rc);
430 int32_t chk_ufilters(ECM_REQUEST *er)
432 int32_t i, j, rc;
433 uint16_t ucaid;
434 uint32_t uprid;
435 struct s_client *cur_cl = cur_client();
437 rc = 1;
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))
446 if (er->prid == 0)
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);
450 rc = 1;
451 break;
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)
460 rc = 1;
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);
467 if(!rc)
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; }
475 return (rc);
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; }
488 return (rc);
491 int32_t chk_rsfilter(struct s_reader *reader, ECM_REQUEST *er)
493 int32_t i, rc = 1;
494 uint16_t caid;
495 uint32_t prid;
497 if(reader->ncd_disable_server_filt)
499 cs_log_dbg(D_CLIENT, "%04X@%06X allowed - server filters disabled",
500 er->caid, er->prid);
501 return 1;
504 rc = prid = 0;
505 caid = reader->caid;
506 if(caid == er->caid)
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)
517 rc = 1;
518 cs_log_dbg(D_CLIENT, "%04X@%06X allowed by server '%s' filter %04X@%06X",
519 er->caid, er->prid, reader->device, caid, prid);
523 if(!rc)
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; }
528 return 0;
531 return (rc);
534 int32_t chk_rfilter2(uint16_t rcaid, uint32_t rprid, struct s_reader *rdr)
536 int32_t i, j, rc = 1;
537 uint16_t caid = 0;
538 uint32_t prid = 0;
540 if(rdr->ftab.nfilts)
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);
552 if(prid == rprid)
554 rc = 1;
555 cs_log_dbg(D_CLIENT, "%04X@%06X allowed by reader '%s' filter %04X@%06X",
556 rcaid, rprid, rdr->label, caid, prid);
561 if(!rc)
563 cs_log_dbg(D_CLIENT, "no match, %04X@%06X rejected by reader '%s' filters",
564 rcaid, rprid, rdr->label);
565 return 0;
569 return (rc);
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)
580 { return 1; }
582 int32_t i;
583 for(i = 0; i < ctab->ctnum; i++)
585 CAIDTAB_DATA *d = &ctab->ctdata[i];
586 if(!d->caid)
588 return 0;
590 if((caid & d->mask) == d->caid)
591 { return 1; }
593 return 0;
596 int32_t chk_ctab_ex(uint16_t caid, CAIDTAB *ctab)
598 if(!caid || !ctab->ctnum)
599 { return 0; }
601 int32_t i;
602 for(i = 0; i < ctab->ctnum; i++)
604 CAIDTAB_DATA *d = &ctab->ctdata[i];
605 if(!d->caid)
607 return 0;
609 if((caid & d->mask) == d->caid)
610 { return 1; }
612 return 0;
615 uint8_t is_localreader(struct s_reader *rdr, ECM_REQUEST *er) //to be used for LB/reader selections checks only
617 if(!rdr) return 0;
619 if(!is_network_reader(rdr)){
620 return 1;
623 if(!rdr->localcards.nfilts) { return 0; }
625 int32_t i, k;
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
633 { return 1; }
635 for(k = 0; k < nprids; k++)
637 uint32_t prid = rdr->localcards.filts[i].prids[k];
638 if(prid == er->prid) //Provider matches
640 return 1;
646 return 0;
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)
655 if(rdr->fallback)
656 { return 1; }
658 int32_t i, k;
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
667 { return 1; }
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
674 return 1;
680 return 0;
683 uint8_t chk_has_fixed_fallback(ECM_REQUEST *er)
685 struct s_ecm_answer *ea;
686 struct s_reader *rdr;
687 int32_t n_falb = 0;
688 for(ea = er->matching_rdr; ea; ea = ea->next)
690 rdr = ea->reader;
691 if(chk_is_fixed_fallback(rdr, er))
692 { n_falb++; }
694 return n_falb;
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; }
701 int32_t i, k;
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
710 { return 1; }
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
716 { return 1; }
721 return 0;
724 int32_t matching_reader(ECM_REQUEST *er, struct s_reader *rdr)
727 //simple checks first:
728 if(!er || !rdr)
729 { return (0); }
731 //reader active?
732 struct s_client *cl = rdr->client;
733 if(!cl || !rdr->enable)
734 { return (0); }
736 // if physical reader a card needs to be inserted
737 if(!is_network_reader(rdr) && rdr->card_status != CARD_INSERTED)
738 { return (0); }
740 //Checking connected & group valid:
741 struct s_client *cur_cl = er->client; //cur_client();
743 #ifdef CS_CACHEEX
744 //Cacheex=3 defines a Cacheex-only reader. never match them.
745 if(rdr->cacheex.mode == 3)
746 { return (0); }
747 if(rdr->cacheex.mode == 2 && !rdr->cacheex.allow_request)
748 { return (0); }
749 #endif
751 if(!(rdr->grp & cur_cl->grp))
752 { return (0); }
754 //Checking caids:
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);
758 return 0;
761 if(!is_network_reader(rdr) && ((rdr->caid >> 8) != ((er->caid >> 8) & 0xFF) && (rdr->caid >> 8) != ((er->ocaid >> 8) & 0xFF)))
763 if (!rdr->csystem)
764 return 0;
765 int i, caid_found = 0;
766 for(i = 0; rdr->csystem->caids[i]; i++)
768 uint16_t cs_caid = rdr->csystem->caids[i];
769 if(!cs_caid)
770 { continue; }
771 if(cs_caid == er->caid || cs_caid == er->ocaid)
773 caid_found = 1;
774 break;
777 if(!caid_found)
778 { return 0; }
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);
785 return 0;
789 //Checking services:
790 if(!chk_srvid(rdr->client, er))
792 cs_log_dbg(D_TRACE, "service %04X not matching reader %s", er->srvid, rdr->label);
793 return (0);
796 //Checking ident:
797 if(!chk_rfilter(er, rdr))
799 cs_log_dbg(D_TRACE, "r-filter reader %s", rdr->label);
800 return (0);
803 //Check ECM nanos:
804 if(!chk_class(er, &rdr->cltab, "reader", rdr->label))
806 cs_log_dbg(D_TRACE, "class filter reader %s", rdr->label);
807 return (0);
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!
841 //Checking chid:
842 if(!chk_chid(er, &rdr->fchid, "reader", rdr->label))
844 cs_log_dbg(D_TRACE, "chid filter reader %s", rdr->label);
845 return (0);
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);
852 return 0;
855 //Checking entitlements:
856 if(ll_count(rdr->ll_entitlements) > 0)
858 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
859 S_ENTITLEMENT *item;
860 int8_t found = 0;
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
869 found =1;
870 break;
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);
875 return 0;
879 //Checking ecmlength:
880 if(rdr->ecm_whitelist.ewnum && er->ecmlen)
882 int32_t i;
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))
889 foundident = 1;
890 if (d->len == er->ecmlen)
892 ok = 1;
893 break;
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;
902 return (0);
906 // ECM Header Check
907 if(rdr->ecm_hdr_whitelist.ehdata && er->ecmlen)
909 int8_t byteok = 0;
910 int8_t entryok = 0;
911 int8_t foundcaid = 0;
912 int8_t foundprovid = 0;
913 int16_t len = 0;
914 int32_t i = 0;
915 int8_t skip = 0;
916 int32_t r;
917 for(r = 0; r < rdr->ecm_hdr_whitelist.ehnum; r++)
919 ECM_HDR_WHITELIST_DATA *tmp = &rdr->ecm_hdr_whitelist.ehdata[r];
920 skip = 0;
921 byteok = 0;
922 entryok = 0;
923 len = 0;
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);
932 len = tmp->len;
933 for(i = 0; i < len / 2; i++)
935 if(tmp->header[i] == er->ecm[i])
937 byteok = 1;
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);
940 else
942 byteok = 0;
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);
944 entryok = 0;
945 break;
947 if(i == len / 2 - 1 && byteok == 1)
949 entryok = 1;
954 else
956 //rdr_log_dbg(rdr, D_READER, "ECMHeaderwhitelist: Provid: %06X not found in List-Entry -> skipping check", er->prid);
957 skip = 1;
958 continue;
961 else
963 //rdr_log_dbg(rdr, D_READER, "ECMHeaderwhitelist: CAID: %04X not found in List-Entry -> skipping check", er->caid);
964 skip = 1;
965 continue;
967 if(entryok == 1)
969 break;
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);
977 else
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;
984 return (0);
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));
995 return 0;
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));
1001 return 0;
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
1006 return 0;
1009 //All checks done, reader is matching!
1010 return (1);
1013 int32_t chk_caid(uint16_t caid, CAIDTAB *ctab)
1015 int32_t i;
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; }
1022 return -1;
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)
1033 return 1;
1035 return 0;
1038 int32_t chk_bcaid(ECM_REQUEST *er, CAIDTAB *ctab)
1040 int32_t caid;
1041 caid = chk_caid(er->caid, ctab);
1042 if(caid < 0) { return 0; }
1043 er->caid = caid;
1044 return 1;
1048 * Check for NULL CWs
1050 int32_t chk_is_null_CW(uchar cw[])
1052 int8_t i;
1053 for(i = 0; i < 16; i++)
1055 if(cw[i])
1056 { return 0; }
1058 return 1;
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))
1067 { return 1; }
1068 return 0;
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
1093 { return 1; }
1094 cw[15] = cw15;
1095 return 0; //not correct swapped cw
1096 }else
1097 return 1;
1101 * Check for NULL nodeid
1103 int32_t chk_is_null_nodeid(uint8_t node_id[], uint8_t len)
1105 int8_t i;
1106 for(i = 0; i < len; i++)
1108 if(node_id[i]) { return 0; }
1110 return 1;
1113 //check if client structure is accessible
1114 bool check_client(struct s_client *cl)
1116 if(cl && !cl->kill) { return true; }
1117 return false;
1120 uint16_t caidvaluetab_get_value(CAIDVALUETAB *cv, uint16_t caid, uint16_t default_value)
1122 int32_t i;
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)
1141 is_fakecw = 1;
1142 break;
1145 cs_readunlock(__func__, &config_lock);
1147 return is_fakecw;