source: trunk/oscam-chk.c@ 8469

Last change on this file since 8469 was 8469, checked in by gf, 9 years ago

Fix for regression introduces in r8465.

chk_sfilter should return true.

This should fix ticket #3207.

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