source: trunk/oscam-chk.c

Last change on this file was 11665, checked in by gorgone, 5 weeks ago

fix buildwarnings oscam-chk
fix buildwarnings for drecrypt

  • Property svn:eol-style set to LF
File size: 30.0 KB
Line 
1#define MODULE_LOG_PREFIX "chk"
2
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"
13
14#define CS_NANO_CLASS 0xE2
15#define OK 1
16#define ERROR 0
17
18uint32_t get_fallbacktimeout(uint16_t caid)
19{
20 uint32_t ftimeout = caidvaluetab_get_value(&cfg.ftimeouttab, caid, 0);
21
22 if(ftimeout == 0) { ftimeout = cfg.ftimeout; }
23
24 if(ftimeout < 100) { ftimeout = CS_CLIENT_TIMEOUT / 2; }
25 if(ftimeout >= cfg.ctimeout) { ftimeout = cfg.ctimeout - 100; }
26
27 return ftimeout;
28}
29
30static int32_t find_nano(uint8_t *ecm, int32_t l, uint8_t nano, int32_t s)
31{
32 uint8_t *snano;
33
34 if(s >= l) { return 0; }
35 if(!s) { s = (ecm[4] == 0xD2) ? 12 : 9; } // tpsflag -> offset+3
36 snano = ecm + s;
37
38 while((*snano != nano) && (s < l))
39 {
40 if(*snano == 0xEA) { return 0; }
41 snano++;
42 s++;
43 }
44
45 return (s < l) ? ++s : 0;
46}
47
48static int32_t chk_class(ECM_REQUEST *er, CLASSTAB *clstab, const char *type, const char *name)
49{
50 int32_t i, j, an, cl_n, l;
51 uint8_t ecm_class;
52
53 if(er->caid != 0x0500 && er->caid != 0x4AE1) { return 1; }
54 if(!clstab->bn && !clstab->an) { return 1; }
55
56 j = an = cl_n = 0;
57
58 if(er->caid == 0x0500)
59 {
60 while((j = find_nano(er->ecm, er->ecmlen, CS_NANO_CLASS, j)) > 0)
61 {
62 l = er->ecm[j];
63 if(l + j > er->ecmlen) { continue; } // skip, this is not a valid class identifier!
64
65 ecm_class = er->ecm[j + l];
66 cs_log_dbg(D_CLIENT, "ecm class=%02X", ecm_class);
67
68 for(i = 0; i < clstab->bn; i++) // search in blocked
69 {
70 if(ecm_class == clstab->bclass[i])
71 {
72 cs_log_dbg(D_CLIENT, "class %02X rejected by %s '%s' !%02X filter",
73 ecm_class, type, name, ecm_class);
74 return 0;
75 }
76 }
77 cl_n++;
78
79 for(i = 0; i < clstab->an; i++) // search in allowed
80 {
81 if(ecm_class == clstab->aclass[i])
82 {
83 an++;
84 break;
85 }
86 }
87 j += l;
88 }
89 }
90 else
91 {
92 if(er->prid != 0x11 || er->ecm[0] == 0) { return 1; }
93
94 cl_n++;
95 ecm_class = er->ecm[5];
96 cs_log_dbg(D_CLIENT, "ecm class=%02X", ecm_class);
97
98 for(i = 0; i < clstab->bn; i++) // search in blocked
99 {
100 if(ecm_class == clstab->bclass[i])
101 {
102 cs_log_dbg(D_CLIENT, "class %02X rejected by %s '%s' !%02X filter",
103 ecm_class, type, name, ecm_class);
104 return 0;
105 }
106 }
107
108 for(i = 0; i < clstab->an; i++) // search in allowed
109 {
110 if(ecm_class == clstab->aclass[i])
111 {
112 an++;
113 break;
114 }
115 }
116 }
117
118 if(cl_n && clstab->an)
119 {
120 if(an)
121 { cs_log_dbg(D_CLIENT, "ECM classes allowed by %s '%s' filter", type, name); }
122 else
123 {
124 cs_log_dbg(D_CLIENT, "ECM classes don't match %s '%s' filter, rejecting", type, name);
125 return 0;
126 }
127 }
128
129 return 1;
130}
131
132int32_t chk_srvid_match(ECM_REQUEST *er, SIDTAB *sidtab)
133{
134 int32_t i, rc = 0;
135
136 if(!sidtab->num_caid)
137 { rc |= 1; }
138 else
139 for(i = 0; (i < sidtab->num_caid) && (!(rc & 1)); i++)
140 if(er->caid == sidtab->caid[i]) { rc |= 1; }
141
142 if(!er->prid || !sidtab->num_provid)
143 { rc |= 2; }
144 else
145 for(i = 0; (i < sidtab->num_provid) && (!(rc & 2)); i++)
146 if(er->prid == sidtab->provid[i]) { rc |= 2; }
147
148 if(!sidtab->num_srvid)
149 { rc |= 4; }
150 else
151 for(i = 0; (i < sidtab->num_srvid) && (!(rc & 4)); i++)
152 if(er->srvid == sidtab->srvid[i]) { rc |= 4; }
153
154 return (rc == 7);
155}
156
157#ifdef CS_CACHEEX_AIO
158int32_t chk_srvid_disablecrccws_only_for_exception(ECM_REQUEST *er)
159{
160 int32_t nr;
161 SIDTAB *sidtab;
162
163 for(nr = 0, sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next, nr++)
164 {
165 if(sidtab->disablecrccws_only_for_exception && (sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid) && chk_srvid_match(er, sidtab))
166 {
167 return(1);
168 }
169 }
170 return(0);
171}
172
173int32_t chk_srvid_no_wait_time(ECM_REQUEST *er)
174{
175 int32_t nr;
176 SIDTAB *sidtab;
177
178 for(nr = 0, sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next, nr++)
179 {
180 if(sidtab->no_wait_time && (sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid) && chk_srvid_match(er, sidtab))
181 {
182 return(1);
183 }
184 }
185 return(0);
186}
187
188int32_t chk_srvid_localgenerated_only_exception(ECM_REQUEST *er)
189{
190 int32_t nr;
191 SIDTAB *sidtab;
192
193 for(nr = 0, sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next, nr++)
194 {
195 if(sidtab->lg_only_exception && (sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid) && chk_srvid_match(er, sidtab))
196 {
197 return(1);
198 }
199 }
200 return(0);
201}
202#endif
203
204int32_t chk_srvid(struct s_client *cl, ECM_REQUEST *er)
205{
206 int32_t nr, rc = 0;
207 SIDTAB *sidtab;
208
209 if(!cl->sidtabs.ok)
210 {
211 if(!cl->sidtabs.no) { return (1); }
212 rc = 1;
213 }
214
215 for(nr = 0, sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next, nr++)
216 {
217 if(sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid)
218 {
219 if((cl->sidtabs.no & ((SIDTABBITS)1 << nr)) && (chk_srvid_match(er, sidtab)))
220 { return (0); }
221
222 if((cl->sidtabs.ok & ((SIDTABBITS)1 << nr)) && (chk_srvid_match(er, sidtab)))
223 { rc = 1; }
224 }
225 }
226 return (rc);
227}
228
229int32_t has_srvid(struct s_client *cl, ECM_REQUEST *er)
230{
231 if(!cl->sidtabs.ok)
232 { return 0; }
233
234 int32_t nr;
235 SIDTAB *sidtab;
236
237 for(nr = 0, sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next, nr++)
238 {
239 if(sidtab->num_srvid)
240 {
241 if((cl->sidtabs.ok & ((SIDTABBITS)1 << nr)) && (chk_srvid_match(er, sidtab)))
242 { return 1; }
243 }
244 }
245 return 0;
246}
247
248int32_t has_lb_srvid(struct s_client *cl, ECM_REQUEST *er)
249{
250 if(!cl->lb_sidtabs.ok)
251 { return 0; }
252
253 int32_t nr;
254 SIDTAB *sidtab;
255
256 for(nr = 0, sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next, nr++)
257 {
258 if((cl->lb_sidtabs.ok & ((SIDTABBITS)1 << nr)) && (chk_srvid_match(er, sidtab)))
259 { return 1; }
260 }
261 return 0;
262}
263
264int32_t chk_srvid_match_by_caid_prov(uint16_t caid, uint32_t provid, SIDTAB *sidtab)
265{
266 int32_t i, rc = 0;
267
268 if(!sidtab->num_caid)
269 { rc |= 1; }
270 else
271 for(i = 0; (i < sidtab->num_caid) && (!(rc & 1)); i++)
272 if(caid == sidtab->caid[i]) { rc |= 1; }
273
274 if(!sidtab->num_provid)
275 { rc |= 2; }
276 else
277 for(i = 0; (i < sidtab->num_provid) && (!(rc & 2)); i++)
278 if(provid == sidtab->provid[i]) { rc |= 2; }
279
280 return (rc == 3);
281}
282
283int32_t chk_srvid_by_caid_prov(struct s_client *cl, uint16_t caid, uint32_t provid)
284{
285 int32_t nr, rc = 0;
286 SIDTAB *sidtab;
287
288 if(!cl->sidtabs.ok)
289 {
290 if(!cl->sidtabs.no) { return (1); }
291 rc = 1;
292 }
293
294 for(nr = 0, sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next, nr++)
295 {
296 if(sidtab->num_caid | sidtab->num_provid)
297 {
298 if((cl->sidtabs.no & ((SIDTABBITS)1 << nr)) && !sidtab->num_srvid &&
299 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
300 { return (0); }
301
302 if((cl->sidtabs.ok & ((SIDTABBITS)1 << nr)) &&
303 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
304 { rc = 1; }
305 }
306 }
307 return (rc);
308}
309
310int32_t chk_srvid_by_caid_prov_rdr(struct s_reader *rdr, uint16_t caid, uint32_t provid)
311{
312 int32_t nr, rc = 0;
313 SIDTAB *sidtab;
314
315 if(!rdr->sidtabs.ok)
316 {
317 if(!rdr->sidtabs.no) { return (1); }
318 rc = 1;
319 }
320
321 for(nr = 0, sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next, nr++)
322 {
323 if(sidtab->num_caid | sidtab->num_provid)
324 {
325 if((rdr->sidtabs.no & ((SIDTABBITS)1 << nr)) && !sidtab->num_srvid &&
326 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
327 { return (0); }
328
329 if((rdr->sidtabs.ok & ((SIDTABBITS)1 << nr)) &&
330 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
331 { rc = 1; }
332 }
333 }
334 return (rc);
335}
336
337int32_t chk_is_betatunnel_caid(uint16_t caid)
338{
339 if(caid == 0x1702 || caid == 0x1722) { return 1; }
340 if(caid == 0x1801 || caid == 0x1833 || caid == 0x1834 || caid == 0x1835) { return 2; }
341 return 0;
342}
343
344uint16_t chk_on_btun(uint8_t chk_sx, struct s_client *cl, ECM_REQUEST *er)
345{
346 if(chk_is_betatunnel_caid(er->caid))
347 {
348 int32_t i;
349 TUNTAB *ttab;
350 ttab = &cl->ttab;
351
352 if(ttab->ttdata)
353 {
354 for(i = 0; i < ttab->ttnum; i++)
355 {
356 if(er->caid == ttab->ttdata[i].bt_caidfrom)
357 {
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; }
361 }
362 }
363 }
364
365 if(chk_sx)
366 return lb_get_betatunnel_caid_to(er);
367 }
368 return 0;
369}
370
371// server filter for newcamd
372int32_t chk_sfilter(ECM_REQUEST *er, PTAB *ptab)
373{
374#ifdef MODULE_NEWCAMD
375 int32_t i, j, pi, rc = 1;
376 uint16_t caid, scaid;
377 uint32_t prid, sprid;
378
379 if(!ptab) { return (1); }
380 struct s_client *cur_cl = cur_client();
381
382 caid = er->caid;
383 prid = er->prid;
384 pi = cur_cl->port_idx;
385
386 if(cfg.ncd_mgclient)
387 { return 1; }
388
389 if(ptab->nports && ptab->ports[pi].ncd && ptab->ports[pi].ncd->ncd_ftab.nfilts)
390 {
391 for(rc = j = 0; (!rc) && (j < ptab->ports[pi].ncd->ncd_ftab.nfilts); j++)
392 {
393 scaid = ptab->ports[pi].ncd->ncd_ftab.filts[j].caid;
394 if(caid == 0 || (caid != 0 && caid == scaid))
395 {
396 for(i = 0; (!rc) && i < ptab->ports[pi].ncd->ncd_ftab.filts[j].nprids; i++)
397 {
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);
400 if(prid == sprid)
401 {
402 rc = 1;
403 cs_log_dbg(D_CLIENT, "%04X@%06X allowed by server filter %04X@%06X",
404 caid, prid, scaid, sprid);
405 }
406 }
407 }
408 }
409
410 if(!rc)
411 {
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);
414
415 if(!er->rcEx) { er->rcEx = (E1_LSERVER << 4) | E2_IDENT; }
416 return (rc);
417 }
418 }
419 return (rc);
420#else
421 (void)er;
422 (void)ptab;
423 return 1;
424#endif
425}
426
427static int32_t chk_chid(ECM_REQUEST *er, FTAB *fchid, char *type, char *name)
428{
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
432
433 for(i = rc = 0; (!rc) && i < fchid->nfilts; i++)
434 {
435 if(er->caid == fchid->filts[i].caid)
436 {
437 found_caid = 1;
438 for(j = 0; (!rc) && j < fchid->filts[i].nprids; j++)
439 {
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]);
442
443 if(er->chid == fchid->filts[i].prids[j])
444 {
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]);
447 rc = 1;
448 }
449 }
450 }
451 }
452
453 if(!rc)
454 {
455 if(found_caid)
456 cs_log_dbg(D_CLIENT, "no match, %04X:%04X rejected by %s '%s' CHID filter(s)",
457 er->caid, er->chid, type, name);
458 else
459 {
460 rc = 1;
461 cs_log_dbg(D_CLIENT, "%04X:%04X allowed by %s '%s' CHID filter, CAID not spezified",
462 er->caid, er->chid, type, name);
463 }
464 }
465 return (rc);
466}
467
468int32_t chk_ident_filter(uint16_t rcaid, uint32_t rprid, FTAB *ftab)
469{
470 int32_t i, j, rc = 1;
471 uint16_t caid = 0;
472 uint32_t prid = 0;
473
474 if(ftab->nfilts)
475 {
476 for(rc = i = 0; (!rc) && (i < ftab->nfilts); i++)
477 {
478 caid = ftab->filts[i].caid;
479 if((caid != 0 && caid == rcaid) || caid == 0)
480 {
481 for(j = 0; (!rc) && (j < ftab->filts[i].nprids); j++)
482 {
483 prid = ftab->filts[i].prids[j];
484 if(prid == rprid)
485 {
486 rc=1;
487 }
488 }
489 }
490 }
491
492 if(!rc)
493 { return 0; }
494 }
495
496 return(rc);
497}
498
499int32_t chk_ufilters(ECM_REQUEST *er)
500{
501 int32_t i, j, rc = 1;
502 uint16_t ucaid;
503 uint32_t uprid;
504 struct s_client *cur_cl = cur_client();
505
506 if(cur_cl->ftab.nfilts)
507 {
508 FTAB *f = &cur_cl->ftab;
509 for(i = rc = 0; (!rc) && (i < f->nfilts); i++)
510 {
511 ucaid = f->filts[i].caid;
512 if(er->caid == 0 || ucaid == 0 || (er->caid != 0 && er->caid == ucaid))
513 {
514 if (er->prid == 0)
515 {
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);
518 rc = 1;
519 break;
520 }
521
522 for(j = rc = 0; (!rc) && (j < f->filts[i].nprids); j++)
523 {
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);
526
527 if(er->prid == uprid)
528 {
529 rc = 1;
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);
532 }
533 }
534 }
535 }
536
537 if(!rc)
538 {
539 cs_log_dbg(D_CLIENT, "no match, %04X@%06X rejected by user '%s' filters",
540 er->caid, er->prid, cur_cl->account->usr);
541
542 snprintf(er->msglog, MSGLOGSIZE, "no card support %04X@%06X", er->caid, (uint32_t) er->prid);
543
544 if(!er->rcEx) { er->rcEx = (E1_USER << 4) | E2_IDENT; }
545 return (rc);
546 }
547 }
548
549 if(!(rc = chk_class(er, &cur_cl->cltab, "user", cur_cl->account->usr)))
550 {
551 if(!er->rcEx) { er->rcEx = (E1_USER << 4) | E2_CLASS; }
552 }
553 else if(!(rc = chk_chid(er, &cur_cl->fchid, "user", cur_cl->account->usr)))
554 {
555 if(!er->rcEx) { er->rcEx = (E1_USER << 4) | E2_CHID; }
556 }
557
558 if(rc) { er->rcEx = 0; }
559
560 return (rc);
561}
562
563int32_t chk_rsfilter(struct s_reader *reader, ECM_REQUEST *er)
564{
565 int32_t i, rc = 1;
566 uint16_t caid;
567 uint32_t prid;
568
569 if(reader->ncd_disable_server_filt)
570 {
571 cs_log_dbg(D_CLIENT, "%04X@%06X allowed - server filters disabled", er->caid, er->prid);
572 return 1;
573 }
574
575 rc = 0;
576 caid = reader->caid;
577 if(caid == er->caid)
578 {
579 for(i = 0; (!rc) && (i < reader->nprov); i++)
580 {
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);
583
584 if(prid == er->prid || !er->prid)
585 {
586 rc = 1;
587 cs_log_dbg(D_CLIENT, "%04X@%06X allowed by server '%s' filter %04X@%06X",
588 er->caid, er->prid, reader->device, caid, prid);
589 }
590 }
591 }
592
593 if(!rc)
594 {
595 cs_log_dbg(D_CLIENT, "no match, %04X@%06X rejected by server '%s' filters",
596 er->caid, er->prid, reader->device);
597
598 if(!er->rcEx) { er->rcEx = (E1_SERVER << 4) | E2_IDENT; }
599 return 0;
600 }
601
602 return (rc);
603}
604
605int32_t chk_rfilter2(uint16_t rcaid, uint32_t rprid, struct s_reader *rdr)
606{
607 int32_t i, j, rc = 1;
608 uint16_t caid = 0;
609 uint32_t prid = 0;
610
611 if(rdr->ftab.nfilts)
612 {
613 for(rc = i = 0; (!rc) && (i < rdr->ftab.nfilts); i++)
614 {
615 caid = rdr->ftab.filts[i].caid;
616 if((caid != 0 && caid == rcaid) || caid == 0)
617 {
618 for(j = 0; (!rc) && (j < rdr->ftab.filts[i].nprids); j++)
619 {
620 prid = rdr->ftab.filts[i].prids[j];
621 cs_log_dbg(D_CLIENT, "trying reader '%s' filter %04X@%06X", rdr->label, caid, prid);
622
623 if(prid == rprid)
624 {
625 rc = 1;
626 cs_log_dbg(D_CLIENT, "%04X@%06X allowed by reader '%s' filter %04X@%06X",
627 rcaid, rprid, rdr->label, caid, prid);
628 }
629 }
630 }
631 }
632
633 if(!rc)
634 {
635 cs_log_dbg(D_CLIENT, "no match, %04X@%06X rejected by reader '%s' filters",
636 rcaid, rprid, rdr->label);
637 return 0;
638 }
639 }
640
641 return (rc);
642}
643
644static int32_t chk_rfilter(ECM_REQUEST *er, struct s_reader *rdr)
645{
646 return chk_rfilter2(er->caid, er->prid, rdr);
647}
648
649int32_t chk_ctab(uint16_t caid, CAIDTAB *ctab)
650{
651 if(!caid || !ctab->ctnum)
652 { return 1; }
653
654 int32_t i;
655 for(i = 0; i < ctab->ctnum; i++)
656 {
657 CAIDTAB_DATA *d = &ctab->ctdata[i];
658 if(!d->caid)
659 {
660 return 0;
661 }
662 if((caid & d->mask) == d->caid)
663 { return 1; }
664 }
665 return 0;
666}
667
668int32_t chk_ctab_ex(uint16_t caid, CAIDTAB *ctab)
669{
670 if(!caid || !ctab->ctnum)
671 { return 0; }
672
673 int32_t i;
674 for(i = 0; i < ctab->ctnum; i++)
675 {
676 CAIDTAB_DATA *d = &ctab->ctdata[i];
677 if(!d->caid)
678 {
679 return 0;
680 }
681
682 if((caid & d->mask) == d->caid)
683 {
684 return 1;
685 }
686 }
687 return 0;
688}
689
690uint8_t is_localreader(struct s_reader *rdr, ECM_REQUEST *er) // to be used for LB/reader selections checks only
691{
692 if(!rdr) return 0;
693
694 if(!is_network_reader(rdr))
695 {
696 return 1;
697 }
698
699 if(!rdr->localcards.nfilts) { return 0; }
700
701 int32_t i, k;
702 for(i = 0; i < rdr->localcards.nfilts; i++)
703 {
704 uint16_t tcaid = rdr->localcards.filts[i].caid;
705 if(tcaid && tcaid == er->caid) // caid match
706 {
707 int32_t nprids = rdr->localcards.filts[i].nprids;
708 if(!nprids) // No Provider -> Ok
709 { return 1; }
710
711 for(k = 0; k < nprids; k++)
712 {
713 uint32_t prid = rdr->localcards.filts[i].prids[k];
714 if(prid == er->prid) // Provider matches
715 {
716 return 1;
717 }
718 }
719 }
720 }
721
722 return 0;
723}
724
725uint8_t chk_is_fixed_fallback(struct s_reader *rdr, ECM_REQUEST *er)
726{
727 if(!rdr->fallback && !rdr->fallback_percaid.nfilts) { return 0; }
728
729 if(!rdr->fallback_percaid.nfilts)
730 {
731 if(rdr->fallback)
732 { return 1; }
733 }
734
735 int32_t i, k;
736 for(i = 0; i < rdr->fallback_percaid.nfilts; i++)
737 {
738 uint16_t tcaid = rdr->fallback_percaid.filts[i].caid;
739 if(tcaid && (tcaid == er->caid || (tcaid < 0x0100 && (er->caid >> 8) == tcaid))) // caid match
740 {
741 int32_t nprids = rdr->fallback_percaid.filts[i].nprids;
742 if(!nprids) // No Provider ->Ok
743 { return 1; }
744
745 for(k = 0; k < nprids; k++)
746 {
747 uint32_t prid = rdr->fallback_percaid.filts[i].prids[k];
748 if(prid == er->prid) // Provider matches
749 {
750 return 1;
751 }
752 }
753 }
754 }
755
756 return 0;
757}
758
759#ifdef CS_CACHEEX_AIO
760uint8_t chk_lg_only(ECM_REQUEST *er, FTAB *lg_only_ftab)
761{
762 int32_t i, k;
763
764 if(!lg_only_ftab->nfilts)
765 return 0;
766
767 for(i = 0; i < lg_only_ftab->nfilts; i++)
768 {
769 uint16_t tcaid = lg_only_ftab->filts[i].caid;
770 if(tcaid && (tcaid == er->caid || (tcaid < 0x0100 && (er->caid >> 8) == tcaid))) // caid match
771 {
772 int32_t nprids = lg_only_ftab->filts[i].nprids;
773 if(!nprids) // No Provider ->Ok
774 { return 1; }
775
776 for(k = 0; k < nprids; k++)
777 {
778 uint32_t prid = lg_only_ftab->filts[i].prids[k];
779 if(prid == NO_PROVID_VALUE || prid == er->prid) // Provider matches
780 {
781 return 1;
782 }
783 }
784 }
785 }
786
787 return 0;
788}
789
790uint8_t chk_lg_only_cp(uint16_t caid, uint32_t prid, FTAB *lg_only_ftab)
791{
792 int32_t i, k;
793
794 if(!lg_only_ftab->nfilts)
795 return 0;
796
797 for(i = 0; i < lg_only_ftab->nfilts; i++)
798 {
799 uint16_t tcaid = lg_only_ftab->filts[i].caid;
800 if(tcaid && (tcaid == caid || (tcaid < 0x0100 && (caid >> 8) == tcaid))) // caid match
801 {
802 int32_t nprids = lg_only_ftab->filts[i].nprids;
803 if(!nprids) // No Provider ->Ok
804 { return 1; }
805
806 for(k = 0; k < nprids; k++)
807 {
808 uint32_t fprid = lg_only_ftab->filts[i].prids[k];
809 if(fprid == NO_PROVID_VALUE || fprid == prid) // Provider matches
810 {
811 return 1;
812 }
813 }
814 }
815 }
816
817 return 0;
818}
819#endif
820
821uint8_t chk_has_fixed_fallback(ECM_REQUEST *er)
822{
823 struct s_ecm_answer *ea;
824 struct s_reader *rdr;
825 int32_t n_falb = 0;
826 for(ea = er->matching_rdr; ea; ea = ea->next)
827 {
828 rdr = ea->reader;
829 if(chk_is_fixed_fallback(rdr, er))
830 { n_falb++; }
831 }
832 return n_falb;
833}
834
835uint8_t chk_if_ignore_checksum(ECM_REQUEST *er, FTAB *disablecrc_only_for)
836{
837 if(!disablecrc_only_for->nfilts) { return 0; }
838
839 int32_t i, k;
840 for(i = 0; i < disablecrc_only_for->nfilts; i++)
841 {
842 uint16_t tcaid = disablecrc_only_for->filts[i].caid;
843 if(tcaid && (tcaid == er->caid || (tcaid < 0x0100 && (er->caid >> 8) == tcaid))) // caid match
844 {
845 int32_t nprids = disablecrc_only_for->filts[i].nprids;
846 if(!nprids) // No Provider ->Ok
847 { return 1; }
848
849 for(k = 0; k < nprids; k++)
850 {
851 uint32_t prid =disablecrc_only_for->filts[i].prids[k];
852 if(prid == er->prid) // Provider matches
853 { return 1; }
854 }
855 }
856 }
857
858 return 0;
859}
860
861int32_t matching_reader(ECM_REQUEST *er, struct s_reader *rdr)
862{
863 // simple checks first:
864 if(!er || !rdr)
865 { return (0); }
866
867 // reader active?
868 struct s_client *cl = rdr->client;
869 if(!cl || !rdr->enable)
870 { return (0); }
871
872 // if physical reader a card needs to be inserted
873 if(!is_network_reader(rdr) && rdr->card_status != CARD_INSERTED)
874 { return (0); }
875
876 // Checking connected & group valid:
877 struct s_client *cur_cl = er->client; //cur_client();
878
879#ifdef CS_CACHEEX
880 // Cacheex=3 defines a Cacheex-only reader. never match them.
881 if(rdr->cacheex.mode == 3)
882 { return (0); }
883 if(rdr->cacheex.mode == 2 && !rdr->cacheex.allow_request)
884 { return (0); }
885#endif
886
887 if(!(rdr->grp & cur_cl->grp))
888 { return (0); }
889
890 // Checking caids:
891 if((!er->ocaid || !chk_ctab(er->ocaid, &rdr->ctab)) && !chk_ctab(er->caid, &rdr->ctab))
892 {
893 cs_log_dbg(D_TRACE, "caid %04X not found in caidlist reader %s", er->caid, rdr->label);
894 return 0;
895 }
896
897 if(!(rdr->typ == R_EMU) && !is_network_reader(rdr) && ((rdr->caid >> 8) != ((er->caid >> 8) & 0xFF) && (rdr->caid >> 8) != ((er->ocaid >> 8) & 0xFF)))
898 {
899 if (!rdr->csystem)
900 { return 0; }
901
902 int i, caid_found = 0;
903 for(i = 0; rdr->csystem->caids[i]; i++)
904 {
905 uint16_t cs_caid = rdr->csystem->caids[i];
906 if(!cs_caid)
907 { continue; }
908
909 if(cs_caid == er->caid || cs_caid == er->ocaid)
910 {
911 caid_found = 1;
912 break;
913 }
914 }
915
916 if(!caid_found)
917 { return 0; }
918 }
919
920 // Supports long ecms?
921 if(er->ecmlen > 255 && is_network_reader(rdr) && !rdr->ph.large_ecm_support)
922 {
923 cs_log_dbg(D_TRACE, "no large ecm support (l=%d) for reader %s", er->ecmlen, rdr->label);
924 return 0;
925 }
926
927 // Checking services:
928 if(!chk_srvid(rdr->client, er))
929 {
930 cs_log_dbg(D_TRACE, "service %04X not matching reader %s", er->srvid, rdr->label);
931 return (0);
932 }
933
934 // Checking ident:
935 if(!(rdr->typ == R_EMU && caid_is_biss(er->caid)) && !chk_rfilter(er, rdr))
936 {
937 cs_log_dbg(D_TRACE, "r-filter reader %s", rdr->label);
938 return (0);
939 }
940
941 // Check ECM nanos:
942 if(!chk_class(er, &rdr->cltab, "reader", rdr->label))
943 {
944 cs_log_dbg(D_TRACE, "class filter reader %s", rdr->label);
945 return (0);
946 }
947
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
951 {
952 if(er->ecm[8] == 0x00 && rdr->secatype == 2)
953 {
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!
956 }
957
958 if((er->ecm[8] == 0x10) && (er->ecm[9] == 0x01) && rdr->secatype == 3)
959 {
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!
962 }
963 }
964
965 // CDS NL: check for right seca type by ECMPID
966 if(!is_network_reader(rdr) && er->caid == 0x100 && er->prid == 0x00006a)
967 {
968 if(rdr->secatype == 2 && er->pid >> 8 == 7)
969 {
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!
972 }
973
974 if(rdr->secatype == 3 && er->pid >> 8 == 6)
975 {
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!
978 }
979 }
980
981 // Checking chid:
982 if(!chk_chid(er, &rdr->fchid, "reader", rdr->label))
983 {
984 cs_log_dbg(D_TRACE, "chid filter reader %s", rdr->label);
985 return (0);
986 }
987
988 // Schlocke reader-defined function, reader-self-check
989 if(rdr->ph.c_available && !rdr->ph.c_available(rdr, AVAIL_CHECK_CONNECTED, er))
990 {
991 cs_log_dbg(D_TRACE, "reader unavailable %s", rdr->label);
992 return 0;
993 }
994
995 // Checking entitlements:
996 if(ll_count(rdr->ll_entitlements) > 0 && !(rdr->typ == R_EMU))
997 {
998 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
999 S_ENTITLEMENT *item;
1000 int8_t found = 0;
1001
1002 while((item = ll_iter_next(&itr)))
1003 {
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
1010 found =1;
1011 break;
1012 }
1013
1014 if(!found && er->ecm[0]) // ecmrequest can get corrected provid parsed from payload in ecm
1015 {
1016 cs_log_dbg(D_TRACE, "entitlements check failed on reader %s", rdr->label);
1017 return 0;
1018 }
1019 }
1020
1021 // Checking ecmlength:
1022 if(rdr->ecm_whitelist.ewnum && er->ecmlen)
1023 {
1024 int32_t i;
1025 int8_t ok = 0, foundident = 0;
1026
1027 for (i = 0; i < rdr->ecm_whitelist.ewnum; i++)
1028 {
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))
1031 {
1032 foundident = 1;
1033 if (d->len == er->ecmlen)
1034 {
1035 ok = 1;
1036 break;
1037 }
1038 }
1039 }
1040
1041 if(foundident == 1 && ok == 0)
1042 {
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;
1046 return (0);
1047 }
1048 }
1049
1050 // ECM Header Check
1051 if(rdr->ecm_hdr_whitelist.ehdata && er->ecmlen)
1052 {
1053 int8_t byteok = 0;
1054 int8_t entryok = 0;
1055 int8_t foundcaid = 0;
1056 int8_t foundprovid = 0;
1057 int16_t len = 0;
1058 int32_t i = 0;
1059 int8_t skip = 0;
1060 int32_t r;
1061
1062 for(r = 0; r < rdr->ecm_hdr_whitelist.ehnum; r++)
1063 {
1064 ECM_HDR_WHITELIST_DATA *tmp = &rdr->ecm_hdr_whitelist.ehdata[r];
1065 skip = 0;
1066 byteok = 0;
1067 entryok = 0;
1068
1069 if(tmp->caid == 0 || tmp->caid == er->caid)
1070 {
1071 foundcaid = 1; //-> caid was in list
1072 //rdr_log_dbg(rdr, D_READER, "Headerwhitelist: found matching CAID: %04X in list", tmp->caid);
1073
1074 if(tmp->provid == 0 || tmp->provid == er->prid)
1075 {
1076 foundprovid = 1; //-> provid was in list
1077 //rdr_log_dbg(rdr, D_READER, "Headerwhitelist: found matching Provid: %06X in list", tmp->provid);
1078
1079 len = tmp->len;
1080 for(i = 0; i < len / 2; i++)
1081 {
1082 if(tmp->header[i] == er->ecm[i])
1083 {
1084 byteok = 1;
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);
1086 }
1087 else
1088 {
1089 byteok = 0;
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);
1091 entryok = 0;
1092 break;
1093 }
1094
1095 if(i == len / 2 - 1 && byteok == 1)
1096 {
1097 entryok = 1;
1098 }
1099 }
1100 }
1101 else
1102 {
1103 //rdr_log_dbg(rdr, D_READER, "ECMHeaderwhitelist: Provid: %06X not found in List-Entry -> skipping check", er->prid);
1104 skip = 1;
1105 continue;
1106 }
1107 }
1108 else
1109 {
1110 //rdr_log_dbg(rdr, D_READER, "ECMHeaderwhitelist: CAID: %04X not found in List-Entry -> skipping check", er->caid);
1111 skip = 1;
1112 continue;
1113 }
1114
1115 if(entryok == 1)
1116 {
1117 break;
1118 }
1119 }
1120
1121 if(foundcaid == 1 && foundprovid == 1 && byteok == 1 && entryok == 1)
1122 {
1123 //cs_log("ECM for %04X@%06X:%04X is valid for ECMHeaderwhitelist of reader %s.", er->caid, er->prid, er->srvid, rdr->label);
1124 }
1125 else
1126 {
1127 if(skip == 0 || (foundcaid == 1 && foundprovid == 1 && entryok == 0 && skip == 1))
1128 {
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;
1132 return (0);
1133 }
1134 }
1135 }
1136
1137 // Simple ring connection check:
1138
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))
1141 {
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));
1143 return 0;
1144 }
1145
1146 if(cfg.block_same_name && strcmp(username(cur_cl), rdr->label) == 0)
1147 {
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));
1149 return 0;
1150 }
1151
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
1153 {
1154 return 0;
1155 }
1156
1157 // All checks done, reader is matching!
1158 return (1);
1159}
1160
1161int32_t chk_caid(uint16_t caid, CAIDTAB *ctab)
1162{
1163 int32_t i;
1164
1165 if (!ctab->ctnum) { return caid; }
1166
1167 for(i = 0; i < ctab->ctnum; i++)
1168 {
1169 CAIDTAB_DATA *d = &ctab->ctdata[i];
1170 if((caid & d->mask) == d->caid) { return d->cmap ? d->cmap : caid; }
1171 }
1172 return -1;
1173}
1174
1175int32_t chk_caid_rdr(struct s_reader *rdr, uint16_t caid)
1176{
1177 if(is_network_reader(rdr) || rdr->typ == R_EMU)
1178 {
1179 return 1; // reader caid is not real caid
1180 }
1181 else if(rdr->caid == caid)
1182 {
1183 return 1;
1184 }
1185 return 0;
1186}
1187
1188int32_t chk_bcaid(ECM_REQUEST *er, CAIDTAB *ctab)
1189{
1190 int32_t caid;
1191 caid = chk_caid(er->caid, ctab);
1192 if(caid < 0) { return 0; }
1193 er->caid = caid;
1194 return 1;
1195}
1196
1197/**
1198 * Check for NULL CWs
1199 **/
1200int32_t chk_is_null_CW(uint8_t cw[])
1201{
1202 int8_t i;
1203 for(i = 0; i < 16; i++)
1204 {
1205 if(cw[i])
1206 { return 0; }
1207 }
1208 return 1;
1209}
1210
1211/**
1212 * Check for ecm request that expects half cw format
1213 **/
1214int8_t is_halfCW_er(ECM_REQUEST *er)
1215{
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))
1217 { return 1; }
1218 return 0;
1219}
1220
1221/**
1222 * Check for wrong half CWs
1223 **/
1224int8_t chk_halfCW(ECM_REQUEST *er, uint8_t *cw)
1225{
1226 if(is_halfCW_er(er) && cw)
1227 {
1228 uint8_t cw15 = cw[15];
1229 if(get_odd_even(er) == 0x80 && cw[15] == 0xF0) { cw[15] = 0; }
1230
1231 int8_t part1 = checkCWpart(cw, 0);
1232 int8_t part2 = checkCWpart(cw, 1);
1233
1234 // check for correct half cw format
1235 if(part1 && part2){ cw[15] = cw15; return 0; }
1236
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
1240 {
1241 return 1;
1242 }
1243
1244 cw[15] = cw15;
1245 return 0; // not correct swapped cw
1246 }
1247 else
1248 {
1249 return 1;
1250 }
1251}
1252
1253/**
1254 * Check for NULL nodeid
1255 **/
1256int32_t chk_is_null_nodeid(uint8_t node_id[], uint8_t len)
1257{
1258 int8_t i;
1259 for(i = 0; i < len; i++)
1260 {
1261 if(node_id[i]) { return 0; }
1262 }
1263 return 1;
1264}
1265
1266// check if client structure is accessible
1267bool check_client(struct s_client *cl)
1268{
1269 if(cl && !cl->kill) { return true; }
1270 return false;
1271}
1272
1273uint16_t caidvaluetab_get_value(CAIDVALUETAB *cv, uint16_t caid, uint16_t default_value)
1274{
1275 int32_t i;
1276 for(i = 0; i < cv->cvnum; i++)
1277 {
1278 CAIDVALUETAB_DATA *cvdata = &cv->cvdata[i];
1279 if(cvdata->caid == caid || cvdata->caid == caid >> 8) { return cvdata->value; }
1280 }
1281 return default_value;
1282}
1283
1284int32_t chk_is_fakecw(uint8_t *cw)
1285{
1286 uint32_t i, is_fakecw = 0;
1287 uint32_t idx = ((cw[0] & 0xF) << 4) | (cw[8] & 0xF);
1288
1289 cs_readlock(__func__, &config_lock);
1290
1291 for(i = 0; i < cfg.fakecws[idx].count; i++)
1292 {
1293 if(memcmp(cw, cfg.fakecws[idx].data[i].cw, 16) == 0)
1294 {
1295 is_fakecw = 1;
1296 break;
1297 }
1298 }
1299 cs_readunlock(__func__, &config_lock);
1300
1301 return is_fakecw;
1302}
1303
1304#ifdef CS_CACHEEX_AIO
1305bool chk_nopushafter(uint16_t caid, CAIDVALUETAB *cv, int32_t ecm_time)
1306{
1307 uint16_t npa_time = caidvaluetab_get_value(cv, caid, 0);
1308 if(npa_time && (ecm_time > npa_time))
1309 {
1310 cs_log_dbg(D_CACHEEX, "REJECTED push: nopushafter %u < ecm_time %i", npa_time, ecm_time);
1311 return 0;
1312 }
1313 else
1314 return 1;
1315}
1316#endif
Note: See TracBrowser for help on using the repository browser.