source: trunk/oscam-chk.c@ 3181

Last change on this file since 3181 was 3181, checked in by dingo35, 10 years ago

Adding threadsafety FIXMEs, feel free to join checking..

File size: 10.1 KB
Line 
1//FIXME Not checked on threadsafety yet; after checking please remove this line
2#include "globals.h"
3
4int chk_srvid_match(ECM_REQUEST *er, SIDTAB *sidtab)
5{
6 int i, rc=0;
7
8 if (!sidtab->num_caid)
9 rc|=1;
10 else
11 for (i=0; (i<sidtab->num_caid) && (!(rc&1)); i++)
12 if (er->caid==sidtab->caid[i]) rc|=1;
13
14 if (!sidtab->num_provid)
15 rc|=2;
16 else
17 for (i=0; (i<sidtab->num_provid) && (!(rc&2)); i++)
18 if (er->prid==sidtab->provid[i]) rc|=2;
19
20 if (!sidtab->num_srvid)
21 rc|=4;
22 else
23 for (i=0; (i<sidtab->num_srvid) && (!(rc&4)); i++)
24 if (er->srvid==sidtab->srvid[i]) rc|=4;
25
26 return(rc==7);
27}
28
29int chk_srvid(ECM_REQUEST *er, int idx)
30{
31 int nr, rc=0;
32 SIDTAB *sidtab;
33
34 if (!client[idx].sidtabok)
35 {
36 if (!client[idx].sidtabno) return(1);
37 rc=1;
38 }
39 for (nr=0, sidtab=cfg->sidtab; sidtab; sidtab=sidtab->next, nr++)
40 if (sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid)
41 {
42 if ((client[idx].sidtabno&(1<<nr)) &&
43 (chk_srvid_match(er, sidtab)))
44 return(0);
45 if ((client[idx].sidtabok&(1<<nr)) &&
46 (chk_srvid_match(er, sidtab)))
47 rc=1;
48 }
49 return(rc);
50}
51
52int chk_srvid_match_by_caid_prov(ushort caid, ulong provid, SIDTAB *sidtab)
53{
54 int i, rc=0;
55
56 if (!sidtab->num_caid)
57 rc|=1;
58 else
59 for (i=0; (i<sidtab->num_caid) && (!(rc&1)); i++)
60 if (caid==sidtab->caid[i]) rc|=1;
61
62 if (!sidtab->num_provid)
63 rc|=2;
64 else
65 for (i=0; (i<sidtab->num_provid) && (!(rc&2)); i++)
66 if (provid==sidtab->provid[i]) rc|=2;
67
68 return(rc==3);
69}
70
71int chk_srvid_by_caid_prov(ushort caid, ulong provid, int idx) {
72 int nr, rc=0;
73 SIDTAB *sidtab;
74
75 if (!client[idx].sidtabok)
76 {
77 if (!client[idx].sidtabno) return(1);
78 rc=1;
79 }
80 for (nr=0, sidtab=cfg->sidtab; sidtab; sidtab=sidtab->next, nr++)
81 if (sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid)
82 {
83 if ((client[idx].sidtabno&(1<<nr)) &&
84 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
85 return(0);
86 if ((client[idx].sidtabok&(1<<nr)) &&
87 (chk_srvid_match_by_caid_prov(caid, provid, sidtab)))
88 rc=1;
89 }
90 return(rc);
91
92}
93
94// server filter for newcamd
95int chk_sfilter(ECM_REQUEST *er, PTAB *ptab)
96{
97 int i, j, pi, rc=1;
98 ushort caid, scaid;
99 ulong prid, sprid;
100
101 if (!ptab) return(1);
102
103 caid = er->caid;
104 prid = er->prid;
105 pi = client[cs_idx].port_idx;
106
107 if (ptab->nports && ptab->ports[pi].ftab.nfilts)
108 {
109 for( rc=j=0; (!rc) && (j<ptab->ports[pi].ftab.nfilts); j++ )
110 {
111 scaid = ptab->ports[pi].ftab.filts[j].caid;
112 if (caid==0||(caid!=0 && caid==scaid))
113 {
114 for( i=0; (!rc) && i<ptab->ports[pi].ftab.filts[j].nprids; i++ )
115 {
116 sprid=ptab->ports[pi].ftab.filts[j].prids[i];
117 cs_debug("trying server filter %04X:%06X", scaid, sprid);
118 if (prid==sprid)
119 {
120 rc=1;
121 cs_debug("%04X:%06X allowed by server filter %04X:%06X",
122 caid, prid, scaid, sprid);
123 }
124 }
125 }
126 }
127 if(!rc)
128 {
129 cs_debug("no match, %04X:%06X rejected by server filters", caid, prid);
130 snprintf( er->msglog, MSGLOGSIZE, "no server match %04X:%06X",
131 caid, (unsigned int) prid );
132
133 if (!er->rcEx) er->rcEx=(E1_LSERVER<<4)|E2_IDENT;
134 return(rc);
135 }
136 }
137 return (rc);
138}
139
140static int chk_chid(ECM_REQUEST *er, FTAB *fchid, char *type, char *name)
141{
142 int rc=1, i, j;
143
144 if( (er->caid & 0xFF00)!=0x600 ) return 1;
145 if( !er->chid ) return 1;
146 if( !fchid->nfilts ) return 1;
147
148 for( i=rc=0; (!rc) && i<fchid->nfilts; i++ )
149 if( er->caid == fchid->filts[i].caid )
150 for( j=0; (!rc) && j<fchid->filts[i].nprids; j++ )
151 {
152 cs_debug("trying %s '%s' CHID filter %04X:%04X",
153 type, name, fchid->filts[i].caid, fchid->filts[i].prids[j]);
154 if( er->chid == fchid->filts[i].prids[j] )
155 {
156 cs_debug("%04X:%04X allowed by %s '%s' CHID filter %04X:%04X",
157 er->caid, er->chid, type, name, fchid->filts[i].caid,
158 fchid->filts[i].prids[j]);
159 rc=1;
160 }
161 }
162
163 if( !rc ) cs_debug("no match, %04X:%04X rejected by %s '%s' CHID filter(s)",
164 er->caid, er->chid, type, name);
165
166 return (rc);
167}
168
169int chk_ufilters(ECM_REQUEST *er)
170{
171 int i, j, rc;
172 ushort ucaid;
173 ulong uprid;
174
175 rc=1;
176 if( client[cs_idx].ftab.nfilts )
177 {
178 FTAB *f = &client[cs_idx].ftab;
179 for( i=rc=0; (!rc) && (i<f->nfilts); i++ )
180 {
181 ucaid = f->filts[i].caid;
182 if( er->caid==0 || ucaid==0 || (er->caid!=0 && er->caid==ucaid) )
183 {
184 for( j=rc=0; (!rc) && (j<f->filts[i].nprids); j++ )
185 {
186 uprid = f->filts[i].prids[j];
187 cs_debug("trying user '%s' filter %04X:%06X",
188 client[cs_idx].usr, ucaid, uprid);
189 if( er->prid == uprid )
190 {
191 rc=1;
192 cs_debug("%04X:%06X allowed by user '%s' filter %04X:%06X",
193 er->caid, er->prid, client[cs_idx].usr, ucaid, uprid);
194 }
195 }
196 }
197 }
198 if( !rc ) {
199 cs_debug("no match, %04X:%06X rejected by user '%s' filters",
200 er->caid, er->prid, client[cs_idx].usr);
201 snprintf( er->msglog, MSGLOGSIZE, "no card support %04X:%06X",
202 er->caid, (unsigned int) er->prid );
203
204 if( !er->rcEx ) er->rcEx=(E1_USER<<4)|E2_IDENT;
205 return (rc);
206 }
207 }
208
209 if( !(rc=chk_class(er, &client[cs_idx].cltab, "user", client[cs_idx].usr)) ) {
210 if( !er->rcEx ) er->rcEx=(E1_USER<<4)|E2_CLASS;
211 }
212 else if( !(rc=chk_chid(er, &client[cs_idx].fchid, "user", client[cs_idx].usr)) )
213 if( !er->rcEx ) er->rcEx=(E1_USER<<4)|E2_CHID;
214
215 if( rc ) er->rcEx=0;
216
217 return (rc);
218}
219
220int chk_rsfilter(struct s_reader * reader, ECM_REQUEST *er, int disable_server_filt)
221{
222 int i, rc=1;
223 ushort caid;
224 ulong prid;
225
226 if( disable_server_filt )
227 {
228 cs_debug("%04X:%06X allowed - server filters disabled",
229 er->caid, er->prid);
230 return 1;
231 }
232
233 rc=prid=0;
234 caid = reader->caid[0];
235 if( caid==er->caid )
236 {
237 for( i=0; (!rc) && (i<reader->nprov); i++ )
238 {
239 prid = (ulong)((reader->prid[i][0]<<16) |
240 (reader->prid[i][1]<<8) |
241 (reader->prid[i][2]));
242 cs_debug("trying server '%s' filter %04X:%06X",
243 reader->device, caid, prid);
244 if( prid==er->prid )
245 {
246 rc=1;
247 cs_debug("%04X:%06X allowed by server '%s' filter %04X:%06X",
248 er->caid, er->prid, reader->device, caid, prid);
249 }
250 }
251 }
252 if(!rc) {
253 cs_debug("no match, %04X:%06X rejected by server '%s' filters",
254 er->caid, er->prid, reader->device);
255 if( !er->rcEx ) er->rcEx=(E1_SERVER<<4)|E2_IDENT;
256 return 0;
257 }
258
259 return(rc);
260}
261
262int chk_rfilter(ECM_REQUEST *er, struct s_reader *rdr)
263{
264 int i, j, rc=1;
265 ushort caid=0;
266 ulong prid=0;
267
268 if( rdr->ftab.nfilts )
269 {
270 for( rc=i=0; (!rc) && (i<rdr->ftab.nfilts); i++ )
271 {
272 caid = rdr->ftab.filts[i].caid;
273 if( (caid!=0 && caid==er->caid) || caid==0 )
274 {
275 for( j=0; (!rc) && (j<rdr->ftab.filts[i].nprids); j++)
276 {
277 prid = rdr->ftab.filts[i].prids[j];
278 cs_debug("trying reader '%s' filter %04X:%06X",
279 rdr->label, caid, prid);
280 if( prid==er->prid )
281 {
282 rc=1;
283 cs_debug("%04X:%06X allowed by reader '%s' filter %04X:%06X",
284 er->caid, er->prid, rdr->label, caid, prid);
285 }
286 }
287 }
288 }
289 if(!rc) {
290 cs_debug("no match, %04X:%06X rejected by reader '%s' filters",
291 er->caid, er->prid, rdr->label);
292 return 0;
293 }
294 }
295
296 return(rc);
297}
298
299int chk_avail_reader(ECM_REQUEST *er, struct s_reader *rdr)
300{
301 if( !chk_rfilter(er, rdr) ) {
302 if( !er->rcEx ) er->rcEx=(E1_READER<<4)|E2_IDENT;
303 return 0;
304 }
305 if( !chk_class(er, &rdr->cltab, "reader", rdr->label) ) {
306 if( !er->rcEx ) er->rcEx=(E1_READER<<4)|E2_CLASS;
307 return 0;
308 }
309 if( !chk_chid(er, &rdr->fchid, "reader", rdr->label) ) {
310 if( !er->rcEx ) er->rcEx=(E1_READER<<4)|E2_CHID;
311 return 0;
312 }
313//fixme re-activated code for testing
314 if( rdr->typ=='r' )
315 {
316 if( rdr->qlen>=rdr->maxqlen )
317 {
318 cs_log("reader '%s' max. queue length(%d) reached, rejected", rdr->label, rdr->qlen);
319 if( !er->rcEx ) er->rcEx=(E1_READER<<4)|E2_QUEUE;
320 return 0;
321 }
322 else {
323 cs_log("reader '%s' qlen=%d", rdr->label, rdr->qlen);
324 rdr->qlen++;
325 }
326 }
327
328 return 1;
329}
330
331extern struct s_reader *reader;
332
333int chk_ctab(ushort caid, CAIDTAB *ctab) {
334 if (!caid || !ctab->caid[0])
335 return 1;
336
337 int i;
338 for (i=0;i<CS_MAXCAIDTAB;i++)
339 {
340 if (!ctab->caid[i]) {
341 return 0;
342 }
343 if ((caid & ctab->mask[i]) == ctab->caid[i])
344 return 1;
345 }
346 return 0;
347}
348
349int matching_reader(ECM_REQUEST *er, struct s_reader *rdr) {
350 //Checking connected & group valid:
351 if (!((rdr->fd) && (rdr->grp&client[cs_idx].grp)))
352 return(0);
353
354 //Checking enabled and not deleted:
355 if (!rdr->enable || rdr->deleted) {
356 cs_debug_mask(D_TRACE, "reader disabled/deleted %s", rdr->label);
357 return(0);
358 }
359
360 //Schlocke reader-defined function, reader-self-check:
361 if (rdr->ph.c_available && !rdr->ph.c_available(client[rdr->cidx].ridx, AVAIL_CHECK_CONNECTED)) {
362 cs_debug_mask(D_TRACE, "reader unavailable %s", rdr->label);
363 return 0;
364 }
365
366 //Checking caids:
367 if (!chk_ctab(er->ocaid, &rdr->ctab) && !chk_ctab(er->caid, &rdr->ctab)) {
368 cs_debug_mask(D_TRACE, "caid %04X not found in caidlist reader %s", er->caid, rdr->label);
369 return 0;
370 }
371
372 //Checking services:
373 if (!chk_srvid(er, rdr->cidx)) {
374 cs_debug_mask(D_TRACE, "service %04X not matching reader %s", er->srvid, rdr->label);
375 return(0);
376 }
377
378 //Checking ident:
379 if (!chk_rfilter(er, rdr)) {
380 cs_debug_mask(D_TRACE, "r-filter reader %s", rdr->label);
381 return(0);
382 }
383
384 //Check ECM nanos:
385 if (!chk_class(er, &rdr->cltab, "reader", rdr->label)) {
386 cs_debug_mask(D_TRACE, "class filter reader %s", rdr->label);
387 return(0);
388 }
389
390 //Checking chid:
391 if (!chk_chid(er, &rdr->fchid, "reader", rdr->label)) {
392 cs_debug_mask(D_TRACE, "chid filter reader %s", rdr->label);
393 return(0);
394 }
395
396 //All checks done, reader is matching!
397 return(1);
398}
Note: See TracBrowser for help on using the repository browser.