source: trunk/oscam-chk.c@ 8432

Last change on this file since 8432 was 8432, checked in by theparasol, 9 years ago
  • Added optional ecm unique check to ratelimiter (experimental)
  • Property svn:eol-style set to LF
File size: 28.0 KB
Line 
1#include "globals.h"
2#include "oscam-chk.h"
3#include "oscam-ecm.h"
4#include "oscam-client.h"
5#include "oscam-net.h"
6#include "oscam-string.h"
7
8#define CS_NANO_CLASS 0xE2
9#define OK 1
10#define ERROR 0
11
12#ifdef WITH_CARDREADER
13static int32_t ecm_ratelimit_findspace(struct s_reader * reader, ECM_REQUEST *er, int32_t maxloop, int32_t reader_mode)
14{
15 int32_t h, foundspace = -1;
16 time_t actualtime = time(NULL);
17 for (h = 0; h < maxloop; h++) { // always release slots with srvid that are overtime, even if not called from reader module to maximize available slots!
18 if ((actualtime - reader->rlecmh[h].last >= reader->ratelimitseconds) && (reader->rlecmh[h].last !=-1)){
19 cs_debug_mask(D_TRACE, "ratelimiter old srvid %04X released from slot #%d/%d of reader %s (%d>=%d ratelimitsec!)", reader->rlecmh[h].srvid, h+1, maxloop, reader->label, (int) (actualtime - reader->rlecmh[h].last), reader->ratelimitseconds);
20 reader->rlecmh[h].last = -1;
21 reader->rlecmh[h].srvid = -1;
22 }
23 }
24
25 for (h = 0; h < maxloop; h++) { // check if srvid is already in a slot
26 if (reader->rlecmh[h].srvid == er->srvid) {
27 cs_debug_mask(D_TRACE, "ratelimiter found srvid %04X for %d sec in slot #%d/%d of reader %s",er->srvid, (int) (actualtime - reader->rlecmh[h].last), h+1, maxloop,reader->label);
28
29 if(reader_mode && reader->ecmunique){ // allow just 1 ecm in a slot instead of a srvid
30 if (memcmp(reader->rlecmh[h].ecmd5, er->ecmd5, CS_ECMSTORESIZE)){
31 char ecmd5[17*3];
32 cs_hexdump(0, reader->rlecmh[h].ecmd5, 16, ecmd5, sizeof(ecmd5));
33 cs_debug_mask(D_TRACE, "ratelimiter ecm %s in this slot for next %d seconds -> skipping this slot!", ecmd5, (int)
34 (reader->ratelimitseconds - (actualtime - reader->rlecmh[h].last)));
35 continue;
36 }
37 }
38 if (h > 0){
39 for (foundspace = 0; foundspace < h; foundspace++) { // check for free lower slot
40 if (reader->rlecmh[foundspace].last ==- 1) {
41 reader->rlecmh[h].srvid = -1;
42 reader->rlecmh[h].last = -1;
43 cs_debug_mask(D_TRACE, "ratelimiter moving srvid %04X to slot #%d/%d of reader %s",er->srvid, foundspace+1, maxloop, reader->label);
44 return foundspace; // moving to lower free slot!
45 }
46 }
47 }
48 return h; // Found but cant move to lower slot!
49 }
50 } // srvid not found in slots!
51 if (!reader_mode) return -1; // who's calling us? reader or some stat prober? If reader then register otherwise just report!
52 for (h = 0; h < maxloop; h++) { // check for free slot
53 if (reader->rlecmh[h].last ==- 1) {
54 cs_debug_mask(D_TRACE, "ratelimiter added srvid %04X to slot #%d/%d of reader %s", er->srvid, h+1, maxloop, reader->label);
55 return h; // free slot found -> assign it!
56 }
57 else cs_debug_mask(D_TRACE, "ratelimiter srvid %04X for %d seconds present in slot #%d/%d of reader %s", reader->rlecmh[h].srvid, (int) (actualtime - reader->rlecmh[h].last), h+1, maxloop, reader->label); //occupied slots
58 }
59
60 #ifdef HAVE_DVBAPI
61 /* Overide ratelimit priority for dvbapi request */
62 foundspace = -1;
63 if ((cfg.dvbapi_enabled == 1) && streq(er->client->account->usr, cfg.dvbapi_usr)) {
64 if ((reader->lastdvbapirateoverride) < (time(NULL) - reader->ratelimitseconds)) {
65 time_t minecmtime = time(NULL);
66 for (h = 0; h < maxloop; h++) {
67 if(reader->rlecmh[h].last < minecmtime) {
68 minecmtime = reader->rlecmh[h].last;
69 foundspace = h;
70 }
71 }
72 reader->lastdvbapirateoverride = time(NULL);
73 cs_debug_mask(D_TRACE, "prioritizing DVBAPI user %s over other watching client", er->client->account->usr);
74 cs_debug_mask(D_TRACE, "ratelimiter forcing srvid %04X into slot #%d/%d of reader %s", er->srvid, foundspace+1, maxloop, reader->label);
75 return foundspace;
76 } else cs_debug_mask(D_TRACE, "DVBAPI User %s is switching too fast for ratelimit and can't be prioritized!",
77 er->client->account->usr);
78 }
79 #endif
80
81 return (-1);
82}
83
84int32_t ecm_ratelimit_check(struct s_reader * reader, ECM_REQUEST *er, int32_t reader_mode)
85{
86 int32_t foundspace = 0, maxslots = MAXECMRATELIMIT; //init slots to oscam global maximums
87
88 if (!reader->ratelimitecm) return OK; /* no rate limit set */
89
90 if (reader->cooldown[0]) { // Do we use cooldown?
91 if (reader->cooldownstate == 1) { // Cooldown in ratelimit phase
92 maxslots = reader->ratelimitecm; // use user defined ratelimitecm
93 if (time(NULL) - reader->cooldowntime >= reader->cooldown[1]) { // check if cooldowntime is elapsed
94 reader->cooldownstate = 0; // set cooldown setup phase
95 reader->cooldowntime = 0; // reset cooldowntime
96 maxslots = MAXECMRATELIMIT; //use oscam defined max slots
97 cs_log("Reader: %s ratelimiter returning to setup phase cooling down period of %d seconds is done!", reader->label, reader->cooldown[1]);
98 }
99 }
100 }
101
102 if (reader_mode){
103 char ecmd5[17*3];
104 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
105 cs_debug_mask(D_TRACE, "ratelimiter find a slot for srvid %04X ecm %s on reader %s", er->srvid, ecmd5, reader->label);
106 }
107 else {
108 cs_debug_mask(D_TRACE, "ratelimiter find a slot for srvid %04X on reader %s", er->srvid, reader->label);
109 }
110 foundspace = ecm_ratelimit_findspace(reader, er, maxslots, reader_mode);
111 if (foundspace < 0 || foundspace >= reader->ratelimitecm) { /* No space due to ratelimit */
112 if (!reader_mode) return OK; // who's calling us? reader or some stat prober? If reader then register otherwise just report!
113 if (reader->cooldown[0] && reader->cooldownstate == 0){ // we are in setup phase of cooldown
114 cs_log("Reader: %s ratelimiter detected overrun ecmratelimit of %d during setup phase!",reader->label, reader->ratelimitecm);
115 reader->cooldownstate = 2; /* Entering cooldowndelay phase */
116 reader->cooldowntime = time(NULL); // set cooldowntime to calculate delay
117 cs_debug_mask(D_TRACE, "ratelimiter cooldowndelaying %d seconds", reader->cooldown[0]);
118 if (foundspace < 0) return ERROR; //not even trowing an error... obvious reason ;)
119 reader->rlecmh[foundspace].last=time(NULL); // register new slot >ecmratelimit
120 reader->rlecmh[foundspace].srvid=er->srvid;
121 return OK;
122 }
123 if (reader->cooldown[0] && reader->cooldownstate == 2) { // check if cooldowndelay is elapsed
124 if (time(NULL) - reader->cooldowntime <= reader->cooldown[0]) { // we are in cooldowndelay!
125 if (foundspace < 0) return ERROR; //not even trowing an error... obvious reason ;)
126 if (reader_mode){ // who's calling us? reader or some stat prober? If reader then register otherwise just report!
127 reader->rlecmh[foundspace].last=time(NULL); // register new slot >ecmratelimit
128 reader->rlecmh[foundspace].srvid=er->srvid;
129 if(reader_mode) memcpy(reader->rlecmh[foundspace].ecmd5, er->ecmd5, CS_ECMSTORESIZE); // register ecmhash
130 }
131 return OK;
132 }
133 else {
134 if (!reader_mode) return ERROR; //who's calling us? reader or some stat prober? If reader then register otherwise just report!
135 reader->cooldownstate = 1; // Entering ratelimit for cooldown ratelimitseconds
136 reader->cooldowntime = time(NULL); // set time to enforce ecmratelimit for defined cooldowntime
137 cs_log("Reader: %s ratelimiter starting cooling down period of %d seconds!", reader->label, reader->cooldown[1]);
138
139 for (foundspace = reader->ratelimitecm; foundspace <= maxslots; foundspace++) { // release all slots above ratelimit
140 reader->rlecmh[foundspace].last = -1;
141 reader->rlecmh[foundspace].srvid = -1;
142 }
143 }
144 }
145 // Ratelimit and cooldown in ratelimitseconds
146 if (!reader_mode) return ERROR; //who's calling us? reader or some stat prober? If reader then register otherwise just report!
147 cs_debug_mask(D_TRACE, "ratelimiter no free slot for srvid %04X on reader %s -> dropping!", er->srvid, reader->label);
148 write_ecm_answer(reader, er, E_NOTFOUND, E2_RATELIMIT, NULL, "Ratelimiter: no slots free!");
149 return ERROR;
150 }
151 if (reader_mode) { //who's calling us? reader or some stat prober? If reader then register otherwise just report!
152 reader->rlecmh[foundspace].last=time(NULL); //we are within ecmratelimits
153 reader->rlecmh[foundspace].srvid=er->srvid;
154 memcpy(reader->rlecmh[foundspace].ecmd5, er->ecmd5, CS_ECMSTORESIZE);// register ecmhash
155 }
156 if (reader->cooldown[0] && reader->cooldownstate == 2) { // check if cooldowndelay is elapsed
157 if (time(NULL) - reader->cooldowntime > reader->cooldown[0]) {
158 reader->cooldownstate = 0; // return to cooldown setup phase
159 reader->cooldowntime = 0; // reset cooldowntime
160 maxslots = MAXECMRATELIMIT; //use oscam defined max slots
161 cs_log("Reader: %s ratelimiter returned to setup phase after %d seconds cooldowndelay!",reader->label, reader->cooldown[0]);
162 }
163 }
164 return OK;
165}
166#endif
167
168static int32_t find_nano(uchar *ecm, int32_t l, uchar nano, int32_t s)
169{
170 uchar *snano;
171
172 if( s >= l ) return 0;
173 if( !s ) s=(ecm[4]==0xD2) ? 12 : 9; // tpsflag -> offset+3
174 snano = ecm + s;
175
176 while( (*snano!=nano) && (s<l) )
177 {
178 if( *snano == 0xEA ) return 0;
179 snano++;
180 s++;
181 }
182
183 return (s<l)?++s:0;
184}
185
186static int32_t chk_class(ECM_REQUEST *er, CLASSTAB *clstab, const char *type, const char *name)
187{
188 int32_t i, j, an, cl_n, l;
189 uchar ecm_class;
190
191 if( er->caid!=0x0500 ) return 1;
192 if( !clstab->bn && !clstab->an ) return 1;
193
194 j=an=cl_n=l=0;
195 while( (j=find_nano(er->ecm, er->ecmlen, CS_NANO_CLASS, j)) > 0 )
196 {
197 l = er->ecm[j];
198 if(l+j>er->ecmlen) continue; // skip, this is not a valid class identifier!
199 ecm_class = er->ecm[j+l];
200 cs_debug_mask(D_CLIENT, "ecm class=%02X", ecm_class);
201 for( i=0; i<clstab->bn; i++ ) // search in blocked
202 if( ecm_class==clstab->bclass[i] )
203 {
204 cs_debug_mask(D_CLIENT, "class %02X rejected by %s '%s' !%02X filter",
205 ecm_class, type, name, ecm_class);
206 return 0;
207 }
208
209 cl_n++;
210 for( i=0; i<clstab->an; i++ ) // search in allowed
211 if( ecm_class==clstab->aclass[i] )
212 {
213 an++;
214 break;
215 }
216 j+=l;
217 }
218
219 if( cl_n && clstab->an )
220 {
221 if( an )
222 cs_debug_mask(D_CLIENT, "ECM classes allowed by %s '%s' filter", type, name);
223 else {
224 cs_debug_mask(D_CLIENT, "ECM classes don't match %s '%s' filter, rejecting", type, name);
225 return 0;
226 }
227 }
228
229 return 1;
230}
231
232int32_t chk_srvid_match(ECM_REQUEST *er, SIDTAB *sidtab)
233{
234 int32_t i, rc=0;
235
236 if (!sidtab->num_caid)
237 rc|=1;
238 else
239 for (i=0; (i<sidtab->num_caid) && (!(rc&1)); i++)
240 if (er->caid==sidtab->caid[i]) rc|=1;
241
242 if (!er->prid || !sidtab->num_provid)
243 rc|=2;
244 else
245 for (i=0; (i<sidtab->num_provid) && (!(rc&2)); i++)
246 if (er->prid==sidtab->provid[i]) rc|=2;
247
248 if (!sidtab->num_srvid)
249 rc|=4;
250 else
251 for (i=0; (i<sidtab->num_srvid) && (!(rc&4)); i++)
252 if (er->srvid==sidtab->srvid[i]) rc|=4;
253
254 return(rc==7);
255}
256
257int32_t chk_srvid(struct s_client *cl, ECM_REQUEST *er)
258{
259 int32_t nr, rc=0;
260 SIDTAB *sidtab;
261
262 if (!cl->sidtabs.ok)
263 {
264 if (!cl->sidtabs.no) return(1);
265 rc=1;
266 }
267 for (nr=0, sidtab=cfg.sidtab; sidtab; sidtab=sidtab->next, nr++)
268 if (sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid)
269 {
270 if ((cl->sidtabs.no&((SIDTABBITS)1<<nr)) &&
271 (chk_srvid_match(er, sidtab)))
272 return(0);
273 if ((cl->sidtabs.ok&((SIDTABBITS)1<<nr)) &&
274 (chk_srvid_match(er, sidtab)))
275 rc=1;
276 }
277 return(rc);
278}
279
280int32_t has_srvid(struct s_client *cl, ECM_REQUEST *er) {
281 if (!cl->sidtabs.ok)
282 return 0;
283
284 int32_t nr;
285 SIDTAB *sidtab;
286
287 for (nr=0, sidtab=cfg.sidtab; sidtab; sidtab=sidtab->next, nr++)
288 if (sidtab->num_srvid)
289 {
290 if ((cl->sidtabs.ok&((SIDTABBITS)1<<nr)) &&
291 (chk_srvid_match(er, sidtab)))
292 return 1;
293 }
294 return 0;
295}
296
297
298int32_t chk_srvid_match_by_caid_prov(uint16_t caid, uint32_t provid, SIDTAB *sidtab)
299{
300 int32_t i, rc=0;
301
302 if (!sidtab->num_caid)
303 rc|=1;
304 else
305 for (i=0; (i<sidtab->num_caid) && (!(rc&1)); i++)
306 if (caid==sidtab->caid[i]) rc|=1;
307
308 if (!sidtab->num_provid)
309 rc|=2;
310 else
311 for (i=0; (i<sidtab->num_provid) && (!(rc&2)); i++)
312 if (provid==sidtab->provid[i]) rc|=2;
313
314 return(rc==3);
315}
316
317int32_t chk_srvid_by_caid_prov(struct s_client *cl, uint16_t caid, uint32_t provid) {
318 int32_t nr, rc=0;
319 SIDTAB *sidtab;
320
321 if (!cl->sidtabs.ok)
322 {
323 if (!cl->sidtabs.no) return(1);
324 rc=1;
325 }
326 for (nr=0, sidtab=cfg.sidtab; sidtab; sidtab=sidtab->next, nr++)
327 if (sidtab->num_caid | sidtab->num_provid)
328 {
329 if ((cl->sidtabs.no&((SIDTABBITS)1<<nr)) && !sidtab->num_srvid &&
330 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
331 return(0);
332 if ((cl->sidtabs.ok&((SIDTABBITS)1<<nr)) &&
333 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
334 rc=1;
335 }
336 return(rc);
337}
338
339int32_t chk_srvid_by_caid_prov_rdr(struct s_reader *rdr, uint16_t caid, uint32_t provid) {
340 int32_t nr, rc=0;
341 SIDTAB *sidtab;
342
343 if (!rdr->sidtabs.ok)
344 {
345 if (!rdr->sidtabs.no) return(1);
346 rc=1;
347 }
348 for (nr=0, sidtab=cfg.sidtab; sidtab; sidtab=sidtab->next, nr++)
349 if (sidtab->num_caid | sidtab->num_provid)
350 {
351 if ((rdr->sidtabs.no&((SIDTABBITS)1<<nr)) && !sidtab->num_srvid &&
352 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
353 return(0);
354 if ((rdr->sidtabs.ok&((SIDTABBITS)1<<nr)) &&
355 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
356 rc=1;
357 }
358 return(rc);
359}
360
361
362// server filter for newcamd
363int32_t chk_sfilter(ECM_REQUEST *er, PTAB *ptab)
364{
365 int32_t i, j, pi, rc=1;
366 uint16_t caid, scaid;
367 uint32_t prid, sprid;
368
369 if (!ptab) return(1);
370 struct s_client *cur_cl = cur_client();
371
372 caid = er->caid;
373 prid = er->prid;
374 pi = cur_cl->port_idx;
375
376 if (cfg.ncd_mgclient && ptab == &cfg.ncd_ptab)
377 return 1;
378
379 if (ptab->nports && ptab->ports[pi].ftab.nfilts)
380 {
381 for( rc=j=0; (!rc) && (j<ptab->ports[pi].ftab.nfilts); j++ )
382 {
383 scaid = ptab->ports[pi].ftab.filts[j].caid;
384 if (caid==0||(caid!=0 && caid==scaid))
385 {
386 for( i=0; (!rc) && i<ptab->ports[pi].ftab.filts[j].nprids; i++ )
387 {
388 sprid=ptab->ports[pi].ftab.filts[j].prids[i];
389 cs_debug_mask(D_CLIENT, "trying server filter %04X:%06X", scaid, sprid);
390 if (prid==sprid)
391 {
392 rc=1;
393 cs_debug_mask(D_CLIENT, "%04X:%06X allowed by server filter %04X:%06X",
394 caid, prid, scaid, sprid);
395 }
396 }
397 }
398 }
399 if(!rc)
400 {
401 cs_debug_mask(D_CLIENT, "no match, %04X:%06X rejected by server filters", caid, prid);
402 snprintf( er->msglog, MSGLOGSIZE, "no server match %04X:%06X",
403 caid, (uint32_t) prid );
404
405 if (!er->rcEx) er->rcEx=(E1_LSERVER<<4)|E2_IDENT;
406 return(rc);
407 }
408 }
409 return (rc);
410}
411
412static int32_t chk_chid(ECM_REQUEST *er, FTAB *fchid, char *type, char *name)
413{
414 int32_t rc=1, i, j, found_caid=0;
415 if( !fchid->nfilts ) return 1;
416
417 for( i=rc=0; (!rc) && i<fchid->nfilts; i++ )
418 if( er->caid == fchid->filts[i].caid ) {
419 found_caid=1;
420 for( j=0; (!rc) && j<fchid->filts[i].nprids; j++ )
421 {
422 cs_debug_mask(D_CLIENT, "trying %s '%s' CHID filter %04X:%04X",
423 type, name, fchid->filts[i].caid, fchid->filts[i].prids[j]);
424 if( er->chid == fchid->filts[i].prids[j] )
425 {
426 cs_debug_mask(D_CLIENT, "%04X:%04X allowed by %s '%s' CHID filter %04X:%04X",
427 er->caid, er->chid, type, name, fchid->filts[i].caid,
428 fchid->filts[i].prids[j]);
429 rc=1;
430 }
431 }
432 }
433
434 if( !rc )
435 {
436 if (found_caid)
437 cs_debug_mask(D_CLIENT, "no match, %04X:%04X rejected by %s '%s' CHID filter(s)",
438 er->caid, er->chid, type, name);
439 else {
440 rc=1;
441 cs_debug_mask(D_CLIENT, "%04X:%04X allowed by %s '%s' CHID filter, CAID not spezified",
442 er->caid, er->chid, type, name);
443 }
444 }
445 return (rc);
446}
447
448int32_t chk_ufilters(ECM_REQUEST *er)
449{
450 int32_t i, j, rc;
451 uint16_t ucaid;
452 uint32_t uprid;
453 struct s_client *cur_cl = cur_client();
454
455 rc=1;
456 if( cur_cl->ftab.nfilts )
457 {
458 FTAB *f = &cur_cl->ftab;
459 for( i=rc=0; (!rc) && (i<f->nfilts); i++ )
460 {
461 ucaid = f->filts[i].caid;
462 if( er->caid==0 || ucaid==0 || (er->caid!=0 && er->caid==ucaid) )
463 {
464 for( j=rc=0; (!rc) && (j<f->filts[i].nprids); j++ )
465 {
466 uprid = f->filts[i].prids[j];
467 cs_debug_mask(D_CLIENT, "trying user '%s' filter %04X:%06X",
468 cur_cl->account->usr, ucaid, uprid);
469 if( er->prid == uprid )
470 {
471 rc=1;
472 cs_debug_mask(D_CLIENT, "%04X:%06X allowed by user '%s' filter %04X:%06X",
473 er->caid, er->prid, cur_cl->account->usr, ucaid, uprid);
474 }
475 }
476 }
477 }
478 if( !rc ) {
479 cs_debug_mask(D_CLIENT, "no match, %04X:%06X rejected by user '%s' filters",
480 er->caid, er->prid, cur_cl->account->usr);
481 snprintf( er->msglog, MSGLOGSIZE, "no card support %04X:%06X",
482 er->caid, (uint32_t) er->prid );
483
484 if( !er->rcEx ) er->rcEx=(E1_USER<<4)|E2_IDENT;
485 return (rc);
486 }
487 }
488
489 if( !(rc=chk_class(er, &cur_cl->cltab, "user", cur_cl->account->usr)) ) {
490 if( !er->rcEx ) er->rcEx=(E1_USER<<4)|E2_CLASS;
491 }
492 else if( !(rc=chk_chid(er, &cur_cl->fchid, "user", cur_cl->account->usr)) )
493 if( !er->rcEx ) er->rcEx=(E1_USER<<4)|E2_CHID;
494
495 if( rc ) er->rcEx=0;
496
497 return (rc);
498}
499
500int32_t chk_rsfilter(struct s_reader * reader, ECM_REQUEST *er)
501{
502 int32_t i, rc=1;
503 uint16_t caid;
504 uint32_t prid;
505
506 if( reader->ncd_disable_server_filt )
507 {
508 cs_debug_mask(D_CLIENT, "%04X:%06X allowed - server filters disabled",
509 er->caid, er->prid);
510 return 1;
511 }
512
513 rc=prid=0;
514 caid = reader->caid;
515 if( caid==er->caid )
516 {
517 for( i=0; (!rc) && (i<reader->nprov); i++ )
518 {
519 prid = (uint32_t)((reader->prid[i][1]<<16) |
520 (reader->prid[i][2]<<8) |
521 (reader->prid[i][3]));
522 cs_debug_mask(D_CLIENT, "trying server '%s' filter %04X:%06X",
523 reader->device, caid, prid);
524 if( prid==er->prid )
525 {
526 rc=1;
527 cs_debug_mask(D_CLIENT, "%04X:%06X allowed by server '%s' filter %04X:%06X",
528 er->caid, er->prid, reader->device, caid, prid);
529 }
530 }
531 }
532 if(!rc) {
533 cs_debug_mask(D_CLIENT, "no match, %04X:%06X rejected by server '%s' filters",
534 er->caid, er->prid, reader->device);
535 if( !er->rcEx ) er->rcEx=(E1_SERVER<<4)|E2_IDENT;
536 return 0;
537 }
538
539 return(rc);
540}
541
542int32_t chk_rfilter2(uint16_t rcaid, uint32_t rprid, struct s_reader *rdr)
543{
544 int32_t i, j, rc=1;
545 uint16_t caid=0;
546 uint32_t prid=0;
547
548 if( rdr->ftab.nfilts )
549 {
550 for( rc=i=0; (!rc) && (i<rdr->ftab.nfilts); i++ )
551 {
552 caid = rdr->ftab.filts[i].caid;
553 if( (caid!=0 && caid==rcaid) || caid==0 )
554 {
555 for( j=0; (!rc) && (j<rdr->ftab.filts[i].nprids); j++)
556 {
557 prid = rdr->ftab.filts[i].prids[j];
558 cs_debug_mask(D_CLIENT, "trying reader '%s' filter %04X:%06X",
559 rdr->label, caid, prid);
560 if( prid==rprid )
561 {
562 rc=1;
563 cs_debug_mask(D_CLIENT, "%04X:%06X allowed by reader '%s' filter %04X:%06X",
564 rcaid, rprid, rdr->label, caid, prid);
565 }
566 }
567 }
568 }
569 if(!rc) {
570 cs_debug_mask(D_CLIENT, "no match, %04X:%06X rejected by reader '%s' filters",
571 rcaid, rprid, rdr->label);
572 return 0;
573 }
574 }
575
576 return(rc);
577}
578
579
580static int32_t chk_rfilter(ECM_REQUEST *er, struct s_reader *rdr)
581{
582 return chk_rfilter2(er->caid, er->prid, rdr);
583}
584
585int32_t chk_ctab(uint16_t caid, CAIDTAB *ctab) {
586 if (!caid || !ctab->caid[0])
587 return 1;
588
589 int32_t i;
590 for (i=0;i<CS_MAXCAIDTAB;i++)
591 {
592 if (!ctab->caid[i]) {
593 return 0;
594 }
595 if ((caid & ctab->mask[i]) == ctab->caid[i])
596 return 1;
597 }
598 return 0;
599}
600
601int32_t chk_ctab_ex(uint16_t caid, CAIDTAB *ctab) {
602 if (!caid || !ctab->caid[0])
603 return 0;
604
605 int32_t i;
606 for (i=0;i<CS_MAXCAIDTAB;i++)
607 {
608 if (!ctab->caid[i]) {
609 return 0;
610 }
611 if ((caid & ctab->mask[i]) == ctab->caid[i])
612 return 1;
613 }
614 return 0;
615}
616
617int32_t matching_reader(ECM_REQUEST *er, struct s_reader *rdr, int32_t slot) {
618 (void)slot; // Prevent warning about unused param slot, when WITH_CARDREADER is disabled
619 //simple checks first:
620 if (!er || !rdr)
621 return(0);
622
623 //reader active?
624 struct s_client *cl = rdr->client;
625 if (!cl || !rdr->enable)
626 return(0);
627
628 // if physical reader a card needs to be inserted
629 if (!is_network_reader(rdr) && rdr->card_status != CARD_INSERTED)
630 return(0);
631
632 //Checking connected & group valid:
633 struct s_client *cur_cl = er->client; //cur_client();
634
635#ifdef CS_CACHEEX
636 //To avoid cascading, a incoming cache request should not invoke a outgoing cache request:
637 if (rdr->cacheex.mode == 1 && cur_cl->auth && cur_cl->account->cacheex.mode == 1)
638 return (0);
639
640 //Cacheex=3 defines a Cacheex-only reader. never match them.
641 if (rdr->cacheex.mode == 3)
642 return (0);
643#endif
644
645 if (!(rdr->grp&cur_cl->grp))
646 return(0);
647
648 //Checking caids:
649 if ((!er->ocaid || !chk_ctab(er->ocaid, &rdr->ctab)) && !chk_ctab(er->caid, &rdr->ctab)) {
650 cs_debug_mask(D_TRACE, "caid %04X not found in caidlist reader %s", er->caid, rdr->label);
651 return 0;
652 }
653
654 if (!is_network_reader(rdr) && ((rdr->caid >> 8) != ((er->caid >> 8) & 0xFF) && (rdr->caid >> 8) != ((er->ocaid >> 8) & 0xFF)))
655 {
656 int i, caid_found = 0;
657 for (i = 0; i < 2; i++) {
658 if (rdr->csystem.caids[i] == er->caid || rdr->csystem.caids[i] == er->ocaid) {
659 caid_found = 1;
660 break;
661 }
662 }
663 if (!caid_found)
664 return 0;
665 }
666
667 //Supports long ecms?
668 if (er->ecmlen > 255 && is_network_reader(rdr) && !rdr->ph.large_ecm_support) {
669 cs_debug_mask(D_TRACE, "no large ecm support (l=%d) for reader %s", er->ecmlen, rdr->label);
670 return 0;
671 }
672
673
674 //Checking services:
675 if (!chk_srvid(rdr->client, er)) {
676 cs_debug_mask(D_TRACE, "service %04X not matching reader %s", er->srvid, rdr->label);
677 return(0);
678 }
679
680 //Checking ident:
681 if (er->prid && !chk_rfilter(er, rdr)) {
682 cs_debug_mask(D_TRACE, "r-filter reader %s", rdr->label);
683 return(0);
684 }
685
686 //Check ECM nanos:
687 if (!chk_class(er, &rdr->cltab, "reader", rdr->label)) {
688 cs_debug_mask(D_TRACE, "class filter reader %s", rdr->label);
689 return(0);
690 }
691
692
693 // CDS NL: check for right seca type
694 if (!is_network_reader(rdr) && er->caid == 0x100 && er->prid == 0x00006a &&
695 !(er->ecm[8] == 0x00 && er->ecm[9] == 0x00)) { // no empty ecm
696 if (er->ecm[8] == 0x00 && rdr->secatype == 2) {
697 cs_debug_mask(D_TRACE,"Error: this is a nagra/mediaguard3 ECM and readertype is seca2!");
698 return 0; // we dont send a nagra/mediaguard3 ecm to a seca2 reader!
699 }
700 if ((er->ecm[8] == 0x10) && (er->ecm[9] == 0x01) && rdr->secatype == 3){
701 cs_debug_mask(D_TRACE,"Error: this is a seca2 ECM and readertype is nagra/mediaguard3!");
702 return 0; // we dont send a seca2 ecm to a nagra/mediaguard3 reader!
703 }
704 }
705
706 //Checking chid:
707 if (!chk_chid(er, &rdr->fchid, "reader", rdr->label)) {
708 cs_debug_mask(D_TRACE, "chid filter reader %s", rdr->label);
709 return(0);
710 }
711
712 //Schlocke reader-defined function, reader-self-check
713 if (rdr->ph.c_available && !rdr->ph.c_available(rdr, AVAIL_CHECK_CONNECTED, er)) {
714 cs_debug_mask(D_TRACE, "reader unavailable %s", rdr->label);
715 return 0;
716 }
717
718 //Checking entitlements:
719 if (ll_count(rdr->ll_entitlements) > 0) {
720 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
721 S_ENTITLEMENT *item;
722 int8_t found = 0;
723 while ((item=ll_iter_next(&itr))) {
724 //if (item->caid == er->caid && (!er->prid || !item->provid || item->provid == er->prid)) { //provid check causing problems?
725 if (item->caid == er->caid || item->caid == er->ocaid) { //... so check at least caid only
726 found =1;
727 break;
728 }
729 }
730 if (!found){
731 cs_debug_mask(D_TRACE, "entitlements check failed on reader %s", rdr->label);
732 return 0;
733 }
734 }
735
736 //Checking ecmlength:
737 if (rdr->ecmWhitelist && er->ecmlen) {
738 struct s_ecmWhitelist *tmp;
739 struct s_ecmWhitelistIdent *tmpIdent;
740 struct s_ecmWhitelistLen *tmpLen;
741 int8_t ok = 0, foundident = 0;
742 for(tmp = rdr->ecmWhitelist; tmp; tmp = tmp->next){
743 if(tmp->caid == 0 || tmp->caid == er->caid){
744 for(tmpIdent = tmp->idents; tmpIdent; tmpIdent = tmpIdent->next){
745 if(tmpIdent->ident == 0 || tmpIdent->ident == er->prid){
746 foundident = 1;
747 for(tmpLen = tmpIdent->lengths; tmpLen; tmpLen = tmpLen->next){
748 if (tmpLen->len == er->ecmlen) {
749 ok = 1;
750 break;
751 }
752 }
753 }
754 }
755 }
756 }
757 if(foundident == 1 && ok == 0){
758 cs_debug_mask(D_TRACE, "ECM is not in ecmwhitelist of reader %s.",rdr->label);
759 rdr->ecmsfilteredlen += 1;
760 return(0);
761 }
762 }
763
764 // ECM Header Check
765 if (rdr->ecmHeaderwhitelist && er->ecmlen) {
766 int8_t byteok = 0;
767 int8_t entryok = 0;
768 int8_t foundcaid = 0;
769 int8_t foundprovid = 0;
770 int16_t len = 0;
771 int32_t i = 0;
772 int8_t skip = 0;
773 struct s_ecmHeaderwhitelist *tmp;
774 for(tmp = rdr->ecmHeaderwhitelist; tmp; tmp = tmp->next){
775 skip = 0;
776 byteok = 0;
777 entryok = 0;
778 len = 0;
779 if (tmp->caid == 0 || tmp->caid == er->caid){
780 foundcaid = 1; //-> caid was in list
781 //rdr_debug_mask(rdr, D_READER, "Headerwhitelist: found matching CAID: %04X in list", tmp->caid);
782 if (tmp->provid == 0 || tmp->provid == er->prid) {
783 foundprovid = 1; //-> provid was in list
784 //rdr_debug_mask(rdr, D_READER, "Headerwhitelist: found matching Provid: %06X in list", tmp->provid);
785 len = tmp->len;
786 for (i=0; i < len/2; i++){
787 if (tmp->header[i] == er->ecm[i]){
788 byteok = 1;
789 //rdr_debug_mask(rdr, D_READER, "ECM Byte: %i of ECMHeaderwhitelist is correct. (%02X = %02X Headerlen: %i)", i, er->ecm[i], tmp->header[i], len/2);
790 }
791 else {
792 byteok = 0;
793 //rdr_debug_mask(rdr, D_READER, "ECM Byte: %i of ECMHeaderwhitelist is not valid. (%02X != %02X Headerlen: %i)", i, er->ecm[i], tmp->header[i], len/2);
794 entryok = 0;
795 break;
796 }
797 if (i == len/2-1 && byteok == 1){
798 entryok = 1;
799 }
800
801 }
802 } else {
803 //rdr_debug_mask(rdr, D_READER, "ECMHeaderwhitelist: Provid: %06X not found in List-Entry -> skipping check", er->prid);
804 skip = 1;
805 continue;
806 }
807 } else {
808 //rdr_debug_mask(rdr, D_READER, "ECMHeaderwhitelist: CAID: %04X not found in List-Entry -> skipping check", er->caid);
809 skip = 1;
810 continue;
811 }
812 if (entryok == 1){
813 break;
814 }
815
816 }
817 if (foundcaid == 1 && foundprovid == 1 && byteok == 1 && entryok == 1){
818 //cs_log("ECM for %04X:%06X:%04X is valid for ECMHeaderwhitelist of reader %s.", er->caid, er->prid, er->srvid, rdr->label);
819 } else {
820 if (skip == 0 || (foundcaid == 1 && foundprovid == 1 && entryok == 0 && skip == 1)) {
821 cs_ddump_mask(D_TRACE, er->ecm, er->ecmlen,
822 "following ECM %04X:%06X:%04X was filtered by ECMHeaderwhitelist of Reader %s from User %s because of not matching Header:",
823 er->caid, er->prid, er->srvid, rdr->label, username(er->client));
824 rdr->ecmsfilteredhead += 1;
825 return(0);
826 }
827 }
828 }
829
830 //Simple ring connection check:
831
832 //Check ip source+dest:
833 if (cfg.block_same_ip && IP_EQUAL(cur_cl->ip, rdr->client->ip) &&
834 get_module(cur_cl)->listenertype != LIS_DVBAPI &&
835 is_network_reader(rdr))
836 {
837 cs_debug_mask(D_TRACE, "ECMs origin %s has the same ip as reader %s, blocked!", username(cur_cl), rdr->label);
838 return 0;
839 }
840
841 if (cfg.block_same_name && strcmp(username(cur_cl), rdr->label) == 0) {
842 cs_debug_mask(D_TRACE, "ECMs origin %s has the same name as reader %s, blocked!", username(cur_cl), rdr->label);
843 return 0;
844 }
845 #ifdef WITH_CARDREADER
846 cs_debug_mask(D_TRACE, "matching_reader became slot attribute of %d", slot);
847 if (!is_network_reader(rdr) && slot == 1) {
848 // just check ratelimiter & cooldown, but no srvid assignment in slot
849 if(ecm_ratelimit_check(rdr, er, 0) != OK) return 0; //just check ratelimiter & cooldown
850 }
851 #endif
852 //All checks done, reader is matching!
853 return(1);
854}
855
856int32_t chk_caid(uint16_t caid, CAIDTAB *ctab)
857{
858 int32_t n, rc;
859 for (rc = -1, n=0; (n < CS_MAXCAIDTAB) && (rc < 0); n++)
860 if ((caid & ctab->mask[n]) == ctab->caid[n])
861 rc = ctab->cmap[n] ? ctab->cmap[n] : caid;
862 return rc;
863}
864
865int32_t chk_caid_rdr(struct s_reader *rdr,uint16_t caid) {
866 if (is_network_reader(rdr)) {
867 return 1; //reader caid is not real caid
868 } else if (rdr->caid==caid) {
869 return 1;
870 }
871 return 0;
872}
873
874int32_t chk_bcaid(ECM_REQUEST *er, CAIDTAB *ctab)
875{
876 int32_t caid;
877 caid = chk_caid(er->caid, ctab);
878 if (caid < 0)
879 return 0;
880 er->caid = caid;
881 return 1;
882}
Note: See TracBrowser for help on using the repository browser.