source: trunk/oscam-emm.c@ 8294

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

Fix two harmless warnings.

File size: 14.6 KB
Line 
1#include "globals.h"
2#include "module-led.h"
3#include "oscam-client.h"
4#include "oscam-config.h"
5#include "oscam-emm.h"
6#include "oscam-string.h"
7#include "oscam-time.h"
8#include "oscam-work.h"
9#include "reader-common.h"
10
11const char *entitlement_type[] = { "", "package", "PPV-Event", "chid", "tier", "class", "PBM", "admin" };
12
13static int8_t cs_emmlen_is_blocked(struct s_reader *rdr, int16_t len)
14{
15 int i;
16 for (i = 0; i < CS_MAXEMMBLOCKBYLEN; i++) {
17 if (rdr->blockemmbylen[i] == len)
18 return 1;
19 }
20 return 0;
21}
22
23/**
24 * Function to filter emm by cardsystem.
25 * Every cardsystem can export a function "get_emm_filter"
26 *
27 * the emm is checked against it an returns 1 for a valid emm or 0 if not
28 */
29static int8_t do_simple_emm_filter(struct s_reader *rdr, struct s_cardsystem *cs, EMM_PACKET *ep)
30{
31 //copied and enhanced from module-dvbapi.c
32 //dvbapi_start_emm_filter()
33 int32_t i, j, k, match;
34 uint8_t flt, mask;
35 uint8_t dmx_filter[342]; // 10 filter + 2 byte header
36
37 memset(dmx_filter, 0, sizeof(dmx_filter));
38 dmx_filter[0] = 0xFF;
39 dmx_filter[1] = 0;
40
41 // Call cardsystems emm filter
42 cs->get_emm_filter(rdr, dmx_filter);
43
44 // Only check matching emmtypes:
45 uint8_t org_emmtype;
46 if (ep->type == UNKNOWN)
47 org_emmtype = EMM_UNKNOWN;
48 else
49 org_emmtype = 1 << (ep->type-1);
50
51 // Now check all filter values
52 // dmx_filter has 2 bytes header:
53 // first byte is always 0xFF
54 // second byte is filter count
55 // all the other datas are the filter count * 34 bytes filter
56
57 // every filter is 34 bytes
58 // 2 bytes emmtype+count
59 // 16 bytes filter data
60 // 16 bytes filter mask
61
62 int32_t filter_count = dmx_filter[1];
63 for (j = 1; j <= filter_count && j <= 10; j++) {
64 int32_t startpos = 2 + (34 * (j - 1));
65 if (dmx_filter[startpos+1] != 0x00)
66 continue;
67
68 uint8_t emmtype = dmx_filter[startpos];
69 if (emmtype != org_emmtype)
70 continue;
71
72 match = 1;
73 for (i = 0, k = 0; i < 10 && k < ep->emmlen && match; i++, k++) {
74 flt = dmx_filter[startpos + 2 + i];
75 mask = dmx_filter[startpos + 2 + 16 + i];
76 if (!mask)
77 break;
78 match = (flt == (ep->emm[k] & mask));
79 if (k == 0)
80 k += 2; //skip len
81 }
82 if (match)
83 return 1; //valid emm
84 }
85 return 0; //emm filter does not match, illegal emm, return
86}
87
88static void reader_log_emm(struct s_reader * reader, EMM_PACKET *ep, int32_t i, int32_t rc, struct timeb *tps) {
89 char *rtxt[] = {
90 "error",
91 is_cascading_reader(reader) ? "sent" : "written",
92 "skipped",
93 "blocked" };
94 char *typedesc[] = { "unknown", "unique", "shared", "global" };
95 struct s_client *cl = reader->client;
96 struct timeb tpe;
97
98 if (reader->logemm & (1 << rc)) {
99 cs_ftime(&tpe);
100 if (!tps)
101 tps = &tpe;
102
103 rdr_log(reader, "%s emmtype=%s, len=%d, idx=%d, cnt=%d: %s (%ld ms)",
104 username(ep->client), typedesc[cl->emmcache[i].type], ep->emm[2],
105 i, cl->emmcache[i].count, rtxt[rc],
106 1000 * (tpe.time - tps->time) + tpe.millitm - tps->millitm);
107 }
108
109 if (rc) {
110 cl->lastemm = time(NULL);
111 led_status_emm_ok();
112 }
113
114#if defined(WEBIF) || defined(LCDSUPPORT)
115 //counting results
116 switch (rc) {
117 case 0: reader->emmerror[ep->type]++; break;
118 case 1: reader->emmwritten[ep->type]++; break;
119 case 2: reader->emmskipped[ep->type]++; break;
120 case 3: reader->emmblocked[ep->type]++; break;
121 }
122#endif
123}
124
125static int32_t reader_store_emm(uint8_t type, uint8_t *emmd5)
126{
127 int32_t rc;
128 struct s_client *cl = cur_client();
129 memcpy(cl->emmcache[cl->rotate].emmd5, emmd5, CS_EMMSTORESIZE);
130 cl->emmcache[cl->rotate].type=type;
131 cl->emmcache[cl->rotate].count=1;
132// cs_debug_mask(D_READER, "EMM stored (index %d)", rotate);
133 rc = cl->rotate;
134 cl->rotate = (++cl->rotate < CS_EMMCACHESIZE) ? cl->rotate : 0;
135 return rc;
136}
137
138int32_t emm_reader_match(struct s_reader *reader, uint16_t caid, uint32_t provid) {
139 int32_t i;
140
141 // if physical reader a card needs to be inserted
142 if (!is_network_reader(reader) && reader->card_status != CARD_INSERTED)
143 return 0;
144
145 if (reader->audisabled)
146 return 0;
147
148 if (reader->caid != caid) {
149 int caid_found = 0;
150 for (i = 0; i < 2; i++) {
151 if (reader->csystem.caids[i] == caid) {
152 caid_found = 1;
153 break;
154 }
155 }
156 if (!caid_found) {
157 rdr_debug_mask(reader, D_EMM, "reader_caid %04X != caid %04X", reader->caid, caid);
158 return 0;
159 }
160 }
161
162 //if (!hexserialset(reader)) { There are cards without serial, they should get emm of type global and shared!
163 // rdr_debug_mask(reader, D_EMM, "no hexserial is set");
164 // return 0;
165 //}
166
167 if (!provid) {
168 rdr_debug_mask(reader, D_EMM, "caid %04X has no provider", caid);
169 return 1;
170 }
171
172 if (reader->auprovid && reader->auprovid == provid) {
173 rdr_debug_mask(reader, D_EMM, "matched auprovid %06X", reader->auprovid);
174 return 1;
175 }
176
177 if (!reader->nprov) {
178 rdr_debug_mask(reader, D_EMM, "no provider is set");
179 return 1;
180 }
181
182 for (i=0; i<reader->nprov; i++) {
183 uint32_t prid = b2i(4, reader->prid[i]);
184 if (prid == provid || ( (reader->typ == R_CAMD35 || reader->typ == R_CS378X) && (prid & 0xFFFF) == (provid & 0xFFFF) )) {
185 rdr_debug_mask(reader, D_EMM, "provider match %04X:%06X", caid, provid);
186 return 1;
187 }
188 }
189 rdr_debug_mask(reader, D_EMM, "skip provider %04X:%06X", caid, provid);
190 return 0;
191}
192
193static char *get_emmlog_filename(char *dest, size_t destlen, const char *basefilename, const char *ext) {
194 char filename[64 + 16];
195 snprintf(filename, sizeof(filename), "%s_emm.%s", basefilename, ext);
196 if (!cfg.emmlogdir) {
197 get_config_filename(dest, destlen, filename);
198 } else {
199 const char *slash = "/";
200 if (cfg.emmlogdir[strlen(cfg.emmlogdir) - 1] == '/') slash = "";
201 snprintf(dest, destlen, "%s%s%s", cfg.emmlogdir, slash, filename);
202 }
203 return dest;
204}
205
206static void saveemm(struct s_reader *aureader, EMM_PACKET *ep)
207{
208 FILE *fp;
209 char tmp[17];
210 char buf[80];
211 char token[256];
212 char *tmp2;
213 time_t rawtime;
214 uint32_t emmtype;
215 struct tm timeinfo;
216 if (ep->type == UNKNOWN)
217 emmtype = EMM_UNKNOWN;
218 else
219 emmtype = 1 << (ep->type - 1);
220 // should this nano be saved?
221 if (((1 << (ep->emm[0] % 0x80)) & aureader->s_nano) || (aureader->saveemm & emmtype))
222 {
223 time(&rawtime);
224 localtime_r(&rawtime, &timeinfo); // to access LOCAL date/time info
225 int32_t emm_length = ((ep->emm[1] & 0x0f) << 8) | ep->emm[2];
226 strftime(buf, sizeof(buf), "%Y/%m/%d %H:%M:%S", &timeinfo);
227 if (!(fp = fopen(get_emmlog_filename(token, sizeof(token), aureader->label, "log"), "a"))) {
228 rdr_log(aureader, "ERROR: Cannot open file '%s' (errno=%d: %s)\n", token, errno, strerror(errno));
229 } else if (cs_malloc(&tmp2, (emm_length + 3) * 2 + 1)) {
230 fprintf(fp, "%s %s ", buf, cs_hexdump(0, ep->hexserial, 8, tmp, sizeof(tmp)));
231 fprintf(fp, "%s\n", cs_hexdump(0, ep->emm, emm_length + 3, tmp2, (emm_length + 3) * 2 + 1));
232 free(tmp2);
233 fclose(fp);
234 rdr_log(aureader, "Successfully added EMM to %s", token);
235 }
236 if (!(fp = fopen(get_emmlog_filename(token, sizeof(token), aureader->label, "bin"), "ab"))) {
237 rdr_log(aureader, "ERROR: Cannot open file '%s' (errno=%d: %s)\n", token, errno, strerror(errno));
238 } else {
239 if ((int)fwrite(ep->emm, 1, emm_length + 3, fp) == emm_length + 3) {
240 rdr_log(aureader, "Successfully added binary EMM to %s", token);
241 } else {
242 rdr_log(aureader, "ERROR: Cannot write binary EMM to %s (errno=%d: %s)\n", token, errno, strerror(errno));
243 }
244 fclose(fp);
245 }
246 }
247}
248
249void do_emm(struct s_client * client, EMM_PACKET *ep)
250{
251 char *typtext[]={"unknown", "unique", "shared", "global"};
252 char tmp[17];
253 int32_t emmnok=0;
254
255 struct s_reader *aureader = NULL;
256 cs_ddump_mask(D_EMM, ep->emm, ep->emmlen, "emm:");
257
258 LL_ITER itr = ll_iter_create(client->aureader_list);
259 while ((aureader = ll_iter_next(&itr))) {
260 if (!aureader->enable)
261 continue;
262
263 uint16_t caid = b2i(2, ep->caid);
264 uint32_t provid = b2i(4, ep->provid);
265
266 if (aureader->audisabled) {
267 rdr_debug_mask(aureader, D_EMM, "AU is disabled");
268 /* we have to write the log for blocked EMM here because
269 this EMM never reach the reader module where the rest
270 of EMM log is done. */
271 if (aureader->logemm & 0x10) {
272 rdr_log(aureader, "%s emmtype=%s, len=%d, idx=0, cnt=1: audisabled (0 ms)",
273 client->account->usr,
274 typtext[ep->type],
275 ep->emm[2]);
276 }
277 continue;
278 }
279
280 if (!(aureader->grp & client->grp)) {
281 rdr_debug_mask(aureader, D_EMM, "skip emm, group mismatch");
282 continue;
283 }
284
285 //TODO: provider possibly not set yet, this is done in get_emm_type()
286 if (!emm_reader_match(aureader, caid, provid))
287 continue;
288
289 struct s_cardsystem *cs = NULL;
290
291 if (is_cascading_reader(aureader)) { // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM)
292 if (!aureader->ph.c_send_emm) // no emm support
293 continue;
294
295 cs = get_cardsystem_by_caid(caid);
296 if (!cs) {
297 rdr_debug_mask(aureader, D_EMM, "unable to find cardsystem for caid %04X", caid);
298 continue;
299 }
300 } else { // local reader
301 if (aureader->csystem.active)
302 cs=&aureader->csystem;
303 }
304
305 if (cs && cs->get_emm_type) {
306 if (!cs->get_emm_type(ep, aureader)) {
307 rdr_debug_mask(aureader, D_EMM, "emm skipped, get_emm_type() returns error");
308 emmnok++;
309 continue;
310 }
311 }
312
313 if (cs && cs->get_emm_filter) {
314 if (!do_simple_emm_filter(aureader, cs, ep)) {
315 rdr_debug_mask(aureader, D_EMM, "emm skipped, emm_filter() returns invalid");
316 emmnok++;
317 continue;
318 }
319 }
320
321 rdr_debug_mask_sensitive(aureader, D_EMM, "emmtype %s. Reader serial {%s}.", typtext[ep->type],
322 cs_hexdump(0, aureader->hexserial, 8, tmp, sizeof(tmp)));
323 rdr_debug_mask_sensitive(aureader, D_EMM, "emm UA/SA: {%s}.",
324 cs_hexdump(0, ep->hexserial, 8, tmp, sizeof(tmp)));
325
326 client->last = time(NULL);
327 saveemm(aureader, ep);
328
329 int32_t is_blocked = 0;
330 switch (ep->type) {
331 case UNKNOWN: is_blocked = (aureader->blockemm & EMM_UNKNOWN) == EMM_UNKNOWN; break;
332 case UNIQUE : is_blocked = (aureader->blockemm & EMM_UNIQUE ) == EMM_UNIQUE; break;
333 case SHARED : is_blocked = (aureader->blockemm & EMM_SHARED ) == EMM_SHARED; break;
334 case GLOBAL : is_blocked = (aureader->blockemm & EMM_GLOBAL ) == EMM_GLOBAL; break;
335 }
336
337 // if not already blocked we check for block by len
338 if (!is_blocked) is_blocked = cs_emmlen_is_blocked( aureader, ep->emm[2] ) ;
339
340 if (is_blocked != 0) {
341#ifdef WEBIF
342 aureader->emmblocked[ep->type]++;
343 is_blocked = aureader->emmblocked[ep->type];
344#endif
345 /* we have to write the log for blocked EMM here because
346 this EMM never reach the reader module where the rest
347 of EMM log is done. */
348 if (aureader->logemm & 0x08) {
349 rdr_log(aureader, "%s emmtype=%s, len=%d, idx=0, cnt=%d: blocked (0 ms)",
350 client->account->usr,
351 typtext[ep->type],
352 ep->emm[2],
353 is_blocked);
354 }
355 continue;
356 }
357
358 client->lastemm = time((time_t*)0);
359
360 client->emmok++;
361 if (client->account)
362 client->account->emmok++;
363 first_client->emmok++;
364
365 //Check emmcache early:
366 int32_t i;
367 unsigned char md5tmp[CS_EMMSTORESIZE];
368 struct s_client *au_cl = aureader->client;
369
370 MD5(ep->emm, ep->emm[2], md5tmp);
371 ep->client = client;
372
373 for (i=0; i<CS_EMMCACHESIZE; i++) {
374 if (!memcmp(au_cl->emmcache[i].emmd5, md5tmp, CS_EMMSTORESIZE)) {
375 rdr_debug_mask(aureader, D_EMM, "emm found in cache: count %d rewrite %d",
376 au_cl->emmcache[i].count, aureader->rewritemm);
377 if (aureader->cachemm && (au_cl->emmcache[i].count > aureader->rewritemm)) {
378 reader_log_emm(aureader, ep, i, 2, NULL);
379 return;
380 }
381 }
382 }
383
384 EMM_PACKET *emm_pack;
385 if (cs_malloc(&emm_pack, sizeof(EMM_PACKET))) {
386 rdr_debug_mask(aureader, D_EMM, "emm is being sent to reader");
387 memcpy(emm_pack, ep, sizeof(EMM_PACKET));
388 add_job(aureader->client, ACTION_READER_EMM, emm_pack, sizeof(EMM_PACKET));
389 }
390 }
391 if (emmnok > 0 && emmnok == ll_count(client->aureader_list)) {
392 client->emmnok++;
393 if (client->account)
394 client->account->emmnok++;
395 first_client->emmnok++;
396 }
397}
398
399
400int32_t reader_do_emm(struct s_reader * reader, EMM_PACKET *ep)
401{
402 int32_t i, rc, ecs;
403 unsigned char md5tmp[MD5_DIGEST_LENGTH];
404 struct timeb tps;
405 struct s_client *cl = reader->client;
406
407 if(!cl)
408 return 0;
409
410 cs_ftime(&tps);
411
412 MD5(ep->emm, ep->emm[2], md5tmp);
413
414 for (i = ecs = 0; i < CS_EMMCACHESIZE; i++) {
415 if (!memcmp(cl->emmcache[i].emmd5, md5tmp, CS_EMMSTORESIZE)) {
416 cl->emmcache[i].count++;
417 if (reader->cachemm) {
418 if (cl->emmcache[i].count > reader->rewritemm) {
419 ecs = 2; //skip emm
420 } else {
421 ecs = 1; //rewrite emm
422 }
423 }
424 break;
425 }
426 }
427
428 // Ecs=0 not found in cache
429 // Ecs=1 found in cache, rewrite emm
430 // Ecs=2 skip
431 if ((rc = ecs) < 2) {
432 if (is_cascading_reader(reader)) {
433 rdr_debug_mask(reader, D_READER, "network emm reader");
434 if (reader->ph.c_send_emm) {
435 rc = reader->ph.c_send_emm(ep);
436 } else {
437 rdr_debug_mask(reader, D_READER, "send_emm() support missing");
438 rc = 0;
439 }
440 } else {
441 rdr_debug_mask(reader, D_READER, "local emm reader");
442 rc = cardreader_do_emm(reader, ep);
443 }
444 if (!ecs)
445 i = reader_store_emm(ep->type, md5tmp);
446 }
447
448 reader_log_emm(reader, ep, i, rc, &tps);
449
450 return rc;
451}
452
453void do_emm_from_file(struct s_reader * reader)
454{
455 if (!reader->emmfile)
456 return;
457
458 char token[256];
459 FILE *fp;
460
461 if (reader->emmfile[0] == '/')
462 snprintf(token, sizeof(token), "%s", reader->emmfile); //pathname included
463 else
464 get_config_filename(token, sizeof(token), reader->emmfile); //only file specified, look in confdir for this file
465
466 if (!(fp = fopen (token, "rb"))) {
467 rdr_log(reader, "ERROR: Cannot open EMM file '%s' (errno=%d %s)\n", token, errno, strerror(errno));
468 return;
469 }
470
471 EMM_PACKET *eptmp;
472 if (!cs_malloc(&eptmp, sizeof(EMM_PACKET))) {
473 fclose (fp);
474 return;
475 }
476
477 size_t ret = fread(eptmp, sizeof(EMM_PACKET), 1, fp);
478 if (ret < 1 && ferror(fp)) {
479 rdr_log(reader, "ERROR: Can't read EMM from file '%s' (errno=%d %s)", token, errno, strerror(errno));
480 free(eptmp);
481 fclose(fp);
482 return;
483 }
484 fclose (fp);
485
486 eptmp->caid[0] = (reader->caid >> 8) & 0xFF;
487 eptmp->caid[1] = reader->caid & 0xFF;
488 if (reader->nprov > 0)
489 memcpy(eptmp->provid, reader->prid[0], sizeof(eptmp->provid));
490 eptmp->emmlen = eptmp->emm[2] + 3;
491
492 struct s_cardsystem *cs = get_cardsystem_by_caid(reader->caid);
493 if (cs && cs->get_emm_type && !cs->get_emm_type(eptmp, reader)) {
494 rdr_debug_mask(reader, D_EMM, "emm skipped, get_emm_type() returns error");
495 free(eptmp);
496 return;
497 }
498
499 //save old b_nano value
500 //clear lsb and lsb+1, so no blocking, and no saving for this nano
501 uint16_t save_s_nano = reader->s_nano;
502 uint16_t save_b_nano = reader->b_nano;
503 uint32_t save_saveemm = reader->saveemm;
504
505 reader->s_nano = reader->b_nano = 0;
506 reader->saveemm = 0;
507
508 int32_t rc = cardreader_do_emm(reader, eptmp);
509 if (rc == OK)
510 rdr_log(reader, "EMM from file %s was successful written.", token);
511 else
512 rdr_log(reader, "ERROR: EMM read from file %s NOT processed correctly! (rc=%d)", token, rc);
513
514 //restore old block/save settings
515 reader->s_nano = save_s_nano;
516 reader->b_nano = save_b_nano;
517 reader->saveemm = save_saveemm;
518
519 free(eptmp);
520}
Note: See TracBrowser for help on using the repository browser.