source: trunk/oscam-chk.c @ 5375

Last change on this file since 5375 was 5155, checked in by _network, 8 years ago

camd35/newcamd: do not choose reader with audisabled as aureader

File size: 13.4 KB
Line 
1#include "globals.h"
2
3#define CS_NANO_CLASS 0xE2
4
5static int32_t find_nano(uchar *ecm, int32_t l, uchar nano, int32_t s)
6{
7  uchar *snano;
8
9  if( s >= l ) return 0;
10  if( !s ) s=(ecm[4]==0xD2) ? 12 : 9;   // tpsflag -> offset+3
11  snano = ecm + s;
12
13  while( (*snano!=nano) && (s<l) )
14  {
15    if( *snano == 0xEA ) return 0;
16    snano++;
17    s++;
18  }
19
20  return (s<l)?++s:0;
21}
22
23static int32_t chk_class(ECM_REQUEST *er, CLASSTAB *clstab, const char *D_USE(type), const char *D_USE(name))
24{
25  int32_t i, j, an, cl_n, l;
26  uchar ecm_class;
27
28  if( er->caid!=0x0500 ) return 1;
29  if( !clstab->bn && !clstab->an ) return 1;
30
31  j=an=cl_n=l=0;
32  while( (j=find_nano(er->ecm, er->l, CS_NANO_CLASS, j)) > 0 )
33  {
34    l = er->ecm[j];
35    ecm_class = er->ecm[j+l];
36    cs_debug_mask(D_CLIENT, "ecm class=%02X", ecm_class);
37    for( i=0; i<clstab->bn; i++ )  // search in blocked
38      if( ecm_class==clstab->bclass[i] ) 
39      {
40        cs_debug_mask(D_CLIENT, "class %02X rejected by %s '%s' !%02X filter", 
41                 ecm_class, type, name, ecm_class);
42        return 0;
43      }
44
45    cl_n++;
46    for( i=0; i<clstab->an; i++ )  // search in allowed
47      if( ecm_class==clstab->aclass[i] ) 
48      {
49        an++;
50        break;
51      }
52    j+=l;
53  }
54
55  if( cl_n && clstab->an )
56  {
57    if( an ) 
58      cs_debug_mask(D_CLIENT, "ECM classes allowed by %s '%s' filter", type, name);
59    else {
60      cs_debug_mask(D_CLIENT, "ECM classes don't match %s '%s' filter, rejecting", type, name);
61      return 0;
62    }
63  }
64
65  return 1;
66}
67
68int32_t chk_srvid_match(ECM_REQUEST *er, SIDTAB *sidtab)
69{
70  int32_t i, rc=0;
71
72  if (!sidtab->num_caid)
73    rc|=1;
74  else
75    for (i=0; (i<sidtab->num_caid) && (!(rc&1)); i++)
76      if (er->caid==sidtab->caid[i]) rc|=1;
77
78  if (!sidtab->num_provid)
79    rc|=2;
80  else
81    for (i=0; (i<sidtab->num_provid) && (!(rc&2)); i++)
82      if (er->prid==sidtab->provid[i]) rc|=2;
83
84  if (!sidtab->num_srvid)
85    rc|=4;
86  else
87    for (i=0; (i<sidtab->num_srvid) && (!(rc&4)); i++)
88      if (er->srvid==sidtab->srvid[i]) rc|=4;
89
90  return(rc==7);
91}
92
93int32_t chk_srvid(struct s_client *cl, ECM_REQUEST *er)
94{
95  int32_t nr, rc=0;
96  SIDTAB *sidtab;
97
98  if (!cl->sidtabok)
99  {
100    if (!cl->sidtabno) return(1);
101    rc=1;
102  }
103  for (nr=0, sidtab=cfg.sidtab; sidtab; sidtab=sidtab->next, nr++)
104    if (sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid)
105    {
106      if ((cl->sidtabno&((SIDTABBITS)1<<nr)) &&
107          (chk_srvid_match(er, sidtab)))
108        return(0);
109      if ((cl->sidtabok&((SIDTABBITS)1<<nr)) &&
110          (chk_srvid_match(er, sidtab)))
111        rc=1;
112    }
113  return(rc);
114}
115
116int32_t has_srvid(struct s_client *cl, ECM_REQUEST *er) {
117  if (!cl->sidtabok)
118    return 0;
119
120  int32_t nr;
121  SIDTAB *sidtab;
122     
123  for (nr=0, sidtab=cfg.sidtab; sidtab; sidtab=sidtab->next, nr++)
124    if (sidtab->num_srvid)
125    {
126      if ((cl->sidtabok&((SIDTABBITS)1<<nr)) &&
127          (chk_srvid_match(er, sidtab)))
128        return 1;
129    }
130  return 0;
131}
132
133
134static int32_t chk_srvid_match_by_caid_prov(uint16_t caid, uint32_t provid, SIDTAB *sidtab)
135{
136  int32_t i, rc=0;
137
138  if (!sidtab->num_caid)
139    rc|=1;
140  else
141    for (i=0; (i<sidtab->num_caid) && (!(rc&1)); i++)
142      if (caid==sidtab->caid[i]) rc|=1;
143
144  if (!sidtab->num_provid)
145    rc|=2;
146  else
147    for (i=0; (i<sidtab->num_provid) && (!(rc&2)); i++)
148      if (provid==sidtab->provid[i]) rc|=2;
149
150  return(rc==3);
151}
152
153int32_t chk_srvid_by_caid_prov(struct s_client *cl, uint16_t caid, uint32_t provid) {
154  int32_t nr, rc=0;
155  SIDTAB *sidtab;
156
157  if (!cl->sidtabok)
158  {
159    if (!cl->sidtabno) return(1);
160    rc=1;
161  }
162  for (nr=0, sidtab=cfg.sidtab; sidtab; sidtab=sidtab->next, nr++)
163    if (sidtab->num_caid | sidtab->num_provid)
164    {
165      if ((cl->sidtabno&((SIDTABBITS)1<<nr)) && !sidtab->num_srvid &&
166          (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
167        return(0);
168      if ((cl->sidtabok&((SIDTABBITS)1<<nr)) &&
169          (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
170        rc=1;
171    }
172  return(rc);
173
174}
175
176// server filter for newcamd
177int32_t chk_sfilter(ECM_REQUEST *er, PTAB *ptab)
178{
179  int32_t i, j, pi, rc=1;
180  uint16_t caid, scaid;
181  uint32_t  prid, sprid;
182
183  if (!ptab) return(1);
184  struct s_client *cur_cl = cur_client();
185 
186  caid = er->caid;
187  prid = er->prid;
188  pi = cur_cl->port_idx;
189
190  if (ptab->nports && ptab->ports[pi].ftab.nfilts)
191  {
192    for( rc=j=0; (!rc) && (j<ptab->ports[pi].ftab.nfilts); j++ )
193    {
194      scaid = ptab->ports[pi].ftab.filts[j].caid;
195      if (caid==0||(caid!=0 && caid==scaid))
196      {
197        for( i=0; (!rc) && i<ptab->ports[pi].ftab.filts[j].nprids; i++ )
198        {
199          sprid=ptab->ports[pi].ftab.filts[j].prids[i];
200          cs_debug_mask(D_CLIENT, "trying server filter %04X:%06X", scaid, sprid);
201          if (prid==sprid)
202          {
203            rc=1;
204            cs_debug_mask(D_CLIENT, "%04X:%06X allowed by server filter %04X:%06X",
205                     caid, prid, scaid, sprid);
206          }
207        }
208      }
209    }
210    if(!rc)
211    {
212      cs_debug_mask(D_CLIENT, "no match, %04X:%06X rejected by server filters", caid, prid);
213      snprintf( er->msglog, MSGLOGSIZE, "no server match %04X:%06X",
214        caid, (uint32_t) prid );
215
216      if (!er->rcEx) er->rcEx=(E1_LSERVER<<4)|E2_IDENT;
217      return(rc);
218    }
219  }
220  return (rc);
221}
222
223static int32_t chk_chid(ECM_REQUEST *er, FTAB *fchid, char *D_USE(type), char *D_USE(name))
224{
225  int32_t rc=1, i, j;
226
227  if( (er->caid & 0xFF00)!=0x600 ) return 1;
228  if( !er->chid ) return 1;
229  if( !fchid->nfilts ) return 1;
230
231  for( i=rc=0; (!rc) && i<fchid->nfilts; i++ )
232    if( er->caid == fchid->filts[i].caid )
233      for( j=0; (!rc) && j<fchid->filts[i].nprids; j++ )
234      {
235        cs_debug_mask(D_CLIENT, "trying %s '%s' CHID filter %04X:%04X", 
236                 type, name, fchid->filts[i].caid, fchid->filts[i].prids[j]);
237        if( er->chid == fchid->filts[i].prids[j] )
238        {
239          cs_debug_mask(D_CLIENT, "%04X:%04X allowed by %s '%s' CHID filter %04X:%04X",
240                   er->caid, er->chid, type, name, fchid->filts[i].caid, 
241                   fchid->filts[i].prids[j]);
242          rc=1;
243        }
244      }
245
246  if( !rc )
247  {
248    cs_debug_mask(D_CLIENT, "no match, %04X:%04X rejected by %s '%s' CHID filter(s)", 
249                      er->caid, er->chid, type, name);
250  }
251  return (rc);
252}
253
254int32_t chk_ufilters(ECM_REQUEST *er)
255{
256  int32_t i, j, rc;
257  uint16_t ucaid;
258  uint32_t  uprid;
259  struct s_client *cur_cl = cur_client();
260 
261  rc=1;
262  if( cur_cl->ftab.nfilts )
263  {
264    FTAB *f = &cur_cl->ftab;
265    for( i=rc=0; (!rc) && (i<f->nfilts); i++ )
266    {
267      ucaid = f->filts[i].caid;
268      if( er->caid==0 || ucaid==0 || (er->caid!=0 && er->caid==ucaid) )
269      {
270        for( j=rc=0; (!rc) && (j<f->filts[i].nprids); j++ )
271        {
272          uprid = f->filts[i].prids[j];
273          cs_debug_mask(D_CLIENT, "trying user '%s' filter %04X:%06X",
274                   cur_cl->account->usr, ucaid, uprid);
275          if( er->prid == uprid )
276          {
277            rc=1;
278            cs_debug_mask(D_CLIENT, "%04X:%06X allowed by user '%s' filter %04X:%06X",
279                      er->caid, er->prid, cur_cl->account->usr, ucaid, uprid);
280          }
281        }
282      }
283    }
284    if( !rc ) {
285      cs_debug_mask(D_CLIENT, "no match, %04X:%06X rejected by user '%s' filters",
286                er->caid, er->prid, cur_cl->account->usr);
287        snprintf( er->msglog, MSGLOGSIZE, "no card support %04X:%06X",
288                er->caid, (uint32_t) er->prid );
289
290      if( !er->rcEx ) er->rcEx=(E1_USER<<4)|E2_IDENT;
291      return (rc);
292    }
293  }
294
295  if( !(rc=chk_class(er, &cur_cl->cltab, "user", cur_cl->account->usr)) ) {
296    if( !er->rcEx ) er->rcEx=(E1_USER<<4)|E2_CLASS;
297  }
298  else if( !(rc=chk_chid(er, &cur_cl->fchid, "user", cur_cl->account->usr)) )
299    if( !er->rcEx ) er->rcEx=(E1_USER<<4)|E2_CHID;
300
301  if( rc ) er->rcEx=0;
302
303  return (rc);
304}
305
306int32_t chk_rsfilter(struct s_reader * reader, ECM_REQUEST *er)
307{
308  int32_t i, rc=1;
309  uint16_t caid;
310  uint32_t prid;
311
312  if( reader->ncd_disable_server_filt )
313  { 
314    cs_debug_mask(D_CLIENT, "%04X:%06X allowed - server filters disabled",
315              er->caid, er->prid);
316    return 1;
317  }
318
319  rc=prid=0;
320  caid = reader->caid;
321  if( caid==er->caid )
322  {
323    for( i=0; (!rc) && (i<reader->nprov); i++ )
324    {
325      prid = (uint32_t)((reader->prid[i][1]<<16) |
326                     (reader->prid[i][2]<<8) |
327                     (reader->prid[i][3]));
328      cs_debug_mask(D_CLIENT, "trying server '%s' filter %04X:%06X", 
329                reader->device, caid, prid);
330      if( prid==er->prid )
331      {
332        rc=1;
333        cs_debug_mask(D_CLIENT, "%04X:%06X allowed by server '%s' filter %04X:%06X",
334                  er->caid, er->prid, reader->device, caid, prid);
335      }
336    }
337  }
338  if(!rc) {
339    cs_debug_mask(D_CLIENT, "no match, %04X:%06X rejected by server '%s' filters",
340            er->caid, er->prid, reader->device);
341    if( !er->rcEx ) er->rcEx=(E1_SERVER<<4)|E2_IDENT;
342    return 0;
343  }
344
345  return(rc);
346}
347
348static int32_t chk_rfilter(ECM_REQUEST *er, struct s_reader *rdr)
349{
350  int32_t i, j, rc=1;
351  uint16_t caid=0;
352  uint32_t prid=0;
353
354  if( rdr->ftab.nfilts )
355  { 
356    for( rc=i=0; (!rc) && (i<rdr->ftab.nfilts); i++ )
357    {
358      caid = rdr->ftab.filts[i].caid;
359      if( (caid!=0 && caid==er->caid) || caid==0 )
360      { 
361        for( j=0; (!rc) && (j<rdr->ftab.filts[i].nprids); j++)
362        {
363          prid = rdr->ftab.filts[i].prids[j];
364          cs_debug_mask(D_CLIENT, "trying reader '%s' filter %04X:%06X",
365                    rdr->label, caid, prid);
366          if( prid==er->prid )
367          {
368            rc=1;
369            cs_debug_mask(D_CLIENT, "%04X:%06X allowed by reader '%s' filter %04X:%06X",
370                    er->caid, er->prid, rdr->label, caid, prid);
371          }
372        }
373      }
374    }
375    if(!rc) {
376      cs_debug_mask(D_CLIENT, "no match, %04X:%06X rejected by reader '%s' filters",
377                er->caid, er->prid, rdr->label);
378      return 0;
379    }
380  }
381
382  return(rc);
383}
384
385int32_t chk_ctab(uint16_t caid, CAIDTAB *ctab) {
386  if (!caid || !ctab->caid[0])
387    return 1;
388   
389  int32_t i;
390  for (i=0;i<CS_MAXCAIDTAB;i++)
391  {
392    if (!ctab->caid[i]) {
393      return 0;
394    }
395    if ((caid & ctab->mask[i]) == ctab->caid[i])
396      return 1;
397  }
398  return 0;
399}
400
401int32_t matching_reader(ECM_REQUEST *er, struct s_reader *rdr) {
402  //simple checks first:
403  if (!er || !rdr ||!rdr->client)
404    return(0);
405
406  //Checking connected & group valid:
407  struct s_client *cur_cl = cur_client();
408 
409  if (!((rdr->fd) && (rdr->grp&cur_cl->grp)))
410    return(0);
411
412  //Schlocke reader-defined function, reader-self-check:
413  if (rdr->ph.c_available && !rdr->ph.c_available(rdr, AVAIL_CHECK_CONNECTED)) {
414    //cs_debug_mask(D_TRACE, "reader unavailable %s", rdr->label);
415    return 0;
416  }
417
418  //Checking caids:
419  if (!chk_ctab(er->ocaid, &rdr->ctab) && !chk_ctab(er->caid, &rdr->ctab)) {
420    //cs_debug_mask(D_TRACE, "caid %04X not found in caidlist reader %s", er->caid, rdr->label);
421    return 0;
422  }
423
424  if ((!(rdr->typ & R_IS_NETWORK)) && ((rdr->caid >> 8) != ((er->caid >> 8) & 0xFF) && (rdr->caid >> 8) != ((er->ocaid >> 8) & 0xFF)))
425    return 0;
426
427  //Checking services:
428  if (!chk_srvid(rdr->client, er)) {
429    //cs_debug_mask(D_TRACE, "service %04X not matching  reader %s", er->srvid, rdr->label);
430    return(0);
431  }
432
433  //Checking ident:
434  if (!chk_rfilter(er, rdr)) {
435    //cs_debug_mask(D_TRACE, "r-filter reader %s", rdr->label);
436    return(0);
437  }
438
439  //Check ECM nanos:
440  if (!chk_class(er, &rdr->cltab, "reader", rdr->label)) {
441    //cs_debug_mask(D_TRACE, "class filter reader %s", rdr->label);   
442    return(0);
443  }
444
445  //Checking chid:
446  if (!chk_chid(er, &rdr->fchid, "reader", rdr->label)) {
447    //cs_debug_mask(D_TRACE, "chid filter reader %s", rdr->label);   
448    return(0);
449  }
450 
451  //Checking ecmlength:
452  if (rdr->ecmWhitelist){
453    struct s_ecmWhitelist *tmp;
454    struct s_ecmWhitelistIdent *tmpIdent;
455    struct s_ecmWhitelistLen *tmpLen;
456    int8_t ok = 0, foundident = 0;
457    for(tmp = rdr->ecmWhitelist; tmp; tmp = tmp->next){
458        if(tmp->caid == 0 || tmp->caid == er->caid){
459            for(tmpIdent = tmp->idents; tmpIdent; tmpIdent = tmpIdent->next){
460                if(tmpIdent->ident == 0 || tmpIdent->ident == er->prid){
461                    foundident = 1;
462                    for(tmpLen = tmpIdent->lengths; tmpLen; tmpLen = tmpLen->next){
463                        if(tmpLen->len == er->l){
464                            ok = 1;
465                            break;
466                        }
467                    }
468                }
469              }
470        }       
471    }
472    if(foundident == 1 && ok == 0){
473        cs_debug_mask(D_READER, "ECM is not in ecmwhitelist of reader %s.",rdr->label);
474        return(0);
475    }
476  }
477 
478  //All checks done, reader is matching!
479  return(1);
480}
481
482int32_t emm_reader_match(struct s_reader *reader, uint16_t caid, uint32_t provid) {
483    int32_t i;
484
485    if (reader->caid != caid || reader->audisabled) {
486        return 0;
487    }
488
489    if (!hexserialset(reader)) {
490        cs_debug_mask(D_EMM, "emm reader %s has no serial set", reader->label);
491        return 0;
492    }
493
494    if (!provid) {
495        cs_debug_mask(D_EMM, "emm for reader %s (%04X) has no provider", reader->label, caid);
496        return 1;
497    }
498
499    if (reader->auprovid && reader->auprovid == provid) {
500        cs_debug_mask(D_EMM, "emm provider match reader %s auprovid %06X", reader->label, reader->auprovid);
501        return 1;
502    }
503
504    if (!reader->nprov) {
505        cs_debug_mask(D_EMM, "emm reader %s has no provider set", reader->label);
506        return 1;
507    }
508
509    for (i=0; i<reader->nprov; i++) {
510        uint32_t prid = b2i(4, reader->prid[i]);
511        if (prid == provid || ( (reader->typ == R_CAMD35 || reader->typ == R_CS378X) && (prid & 0xFFFF) == (provid & 0xFFFF) )) {
512            cs_debug_mask(D_EMM, "emm reader %s provider match %04X:%06X", reader->label, caid, provid);
513            return 1;
514        }
515    }
516    cs_debug_mask(D_EMM, "emm reader %s skip provider %04X:%06X", reader->label, caid, provid);
517    return 0;
518}
Note: See TracBrowser for help on using the repository browser.