source: trunk/oscam-emm.c@ 8452

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

Do not forget to close open file on error.

Patch by DaytonaHack.

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