source: trunk/oscam-emm.c@ 8454

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

Add emmreassembly reader setting.

Unfortunately r8441 causes too many errors for clients that do not
try to be smart (like dvbapi, see ticket #3204) so this commit reverts
r8441.

I can't see how to make non assembled and assembled emms to work both,
so I'm forced to introduce reader setting that turns off emm reassembly.

For the documentation:

emmreassembly = [0|1], Default: 1 (EMM reassembly is enabled).

emmreassembly = 0 (disable) should be set for viaccess and cryptoworks
readers if the client that you are using to send EMMs is reassembling
them instead of just sending them to OSCam for processing.

Two such clients are mgcamd and ACamd (over newcamd).

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->emm_reassembly && aureader->csystem.do_emm_reassembly) {
327 if (!aureader->csystem.do_emm_reassembly(aureader, ep))
328 return;
329 }
330
331 rdr_debug_mask_sensitive(aureader, D_EMM, "emmtype %s. Reader serial {%s}.", typtext[ep->type],
332 cs_hexdump(0, aureader->hexserial, 8, tmp, sizeof(tmp)));
333 rdr_debug_mask_sensitive(aureader, D_EMM, "emm UA/SA: {%s}.",
334 cs_hexdump(0, ep->hexserial, 8, tmp, sizeof(tmp)));
335
336 client->last = time(NULL);
337 saveemm(aureader, ep);
338
339 int32_t is_blocked = 0;
340 switch (ep->type) {
341 case UNKNOWN: is_blocked = (aureader->blockemm & EMM_UNKNOWN) == EMM_UNKNOWN; break;
342 case UNIQUE : is_blocked = (aureader->blockemm & EMM_UNIQUE ) == EMM_UNIQUE; break;
343 case SHARED : is_blocked = (aureader->blockemm & EMM_SHARED ) == EMM_SHARED; break;
344 case GLOBAL : is_blocked = (aureader->blockemm & EMM_GLOBAL ) == EMM_GLOBAL; break;
345 }
346
347 // if not already blocked we check for block by len
348 if (!is_blocked) is_blocked = cs_emmlen_is_blocked( aureader, ep->emm[2] ) ;
349
350 if (is_blocked != 0) {
351#ifdef WEBIF
352 aureader->emmblocked[ep->type]++;
353 is_blocked = aureader->emmblocked[ep->type];
354#endif
355 /* we have to write the log for blocked EMM here because
356 this EMM never reach the reader module where the rest
357 of EMM log is done. */
358 if (aureader->logemm & 0x08) {
359 rdr_log(aureader, "%s emmtype=%s, len=%d, idx=0, cnt=%d: blocked (0 ms)",
360 client->account->usr,
361 typtext[ep->type],
362 ep->emm[2],
363 is_blocked);
364 }
365 continue;
366 }
367
368 client->lastemm = time((time_t*)0);
369
370 client->emmok++;
371 if (client->account)
372 client->account->emmok++;
373 first_client->emmok++;
374
375 //Check emmcache early:
376 int32_t i;
377 unsigned char md5tmp[CS_EMMSTORESIZE];
378 struct s_client *au_cl = aureader->client;
379
380 MD5(ep->emm, ep->emm[2], md5tmp);
381 ep->client = client;
382
383 for (i=0; i<CS_EMMCACHESIZE; i++) {
384 if (!memcmp(au_cl->emmcache[i].emmd5, md5tmp, CS_EMMSTORESIZE)) {
385 rdr_debug_mask(aureader, D_EMM, "emm found in cache: count %d rewrite %d",
386 au_cl->emmcache[i].count, aureader->rewritemm);
387 if (aureader->cachemm && (au_cl->emmcache[i].count > aureader->rewritemm)) {
388 reader_log_emm(aureader, ep, i, 2, NULL);
389 return;
390 }
391 }
392 }
393
394 EMM_PACKET *emm_pack;
395 if (cs_malloc(&emm_pack, sizeof(EMM_PACKET))) {
396 rdr_debug_mask(aureader, D_EMM, "emm is being sent to reader");
397 memcpy(emm_pack, ep, sizeof(EMM_PACKET));
398 add_job(aureader->client, ACTION_READER_EMM, emm_pack, sizeof(EMM_PACKET));
399 }
400 }
401 if (emmnok > 0 && emmnok == ll_count(client->aureader_list)) {
402 client->emmnok++;
403 if (client->account)
404 client->account->emmnok++;
405 first_client->emmnok++;
406 }
407}
408
409
410int32_t reader_do_emm(struct s_reader * reader, EMM_PACKET *ep)
411{
412 int32_t i, rc, ecs;
413 unsigned char md5tmp[MD5_DIGEST_LENGTH];
414 struct timeb tps;
415 struct s_client *cl = reader->client;
416
417 if(!cl)
418 return 0;
419
420 cs_ftime(&tps);
421
422 MD5(ep->emm, ep->emm[2], md5tmp);
423
424 for (i = ecs = 0; i < CS_EMMCACHESIZE; i++) {
425 if (!memcmp(cl->emmcache[i].emmd5, md5tmp, CS_EMMSTORESIZE)) {
426 cl->emmcache[i].count++;
427 if (reader->cachemm) {
428 if (cl->emmcache[i].count > reader->rewritemm) {
429 ecs = 2; //skip emm
430 } else {
431 ecs = 1; //rewrite emm
432 }
433 }
434 break;
435 }
436 }
437
438 // Ecs=0 not found in cache
439 // Ecs=1 found in cache, rewrite emm
440 // Ecs=2 skip
441 if ((rc = ecs) < 2) {
442 if (is_cascading_reader(reader)) {
443 rdr_debug_mask(reader, D_READER, "network emm reader");
444 if (reader->ph.c_send_emm) {
445 rc = reader->ph.c_send_emm(ep);
446 } else {
447 rdr_debug_mask(reader, D_READER, "send_emm() support missing");
448 rc = 0;
449 }
450 } else {
451 rdr_debug_mask(reader, D_READER, "local emm reader");
452 rc = cardreader_do_emm(reader, ep);
453 }
454 if (!ecs)
455 i = reader_store_emm(ep->type, md5tmp);
456 }
457
458 reader_log_emm(reader, ep, i, rc, &tps);
459
460 return rc;
461}
462
463void do_emm_from_file(struct s_reader * reader)
464{
465 if (!reader->emmfile)
466 return;
467
468 char token[256];
469 FILE *fp;
470
471 if (reader->emmfile[0] == '/')
472 snprintf(token, sizeof(token), "%s", reader->emmfile); //pathname included
473 else
474 get_config_filename(token, sizeof(token), reader->emmfile); //only file specified, look in confdir for this file
475
476 if (!(fp = fopen (token, "rb"))) {
477 rdr_log(reader, "ERROR: Cannot open EMM file '%s' (errno=%d %s)\n", token, errno, strerror(errno));
478 return;
479 }
480
481 EMM_PACKET *eptmp;
482 if (!cs_malloc(&eptmp, sizeof(EMM_PACKET))) {
483 fclose (fp);
484 return;
485 }
486
487 size_t ret = fread(eptmp, sizeof(EMM_PACKET), 1, fp);
488 if (ret < 1 && ferror(fp)) {
489 rdr_log(reader, "ERROR: Can't read EMM from file '%s' (errno=%d %s)", token, errno, strerror(errno));
490 free(eptmp);
491 fclose(fp);
492 return;
493 }
494 fclose (fp);
495
496 eptmp->caid[0] = (reader->caid >> 8) & 0xFF;
497 eptmp->caid[1] = reader->caid & 0xFF;
498 if (reader->nprov > 0)
499 memcpy(eptmp->provid, reader->prid[0], sizeof(eptmp->provid));
500 eptmp->emmlen = eptmp->emm[2] + 3;
501
502 struct s_cardsystem *cs = get_cardsystem_by_caid(reader->caid);
503 if (cs && cs->get_emm_type && !cs->get_emm_type(eptmp, reader)) {
504 rdr_debug_mask(reader, D_EMM, "emm skipped, get_emm_type() returns error");
505 free(eptmp);
506 return;
507 }
508
509 //save old b_nano value
510 //clear lsb and lsb+1, so no blocking, and no saving for this nano
511 uint16_t save_s_nano = reader->s_nano;
512 uint16_t save_b_nano = reader->b_nano;
513 uint32_t save_saveemm = reader->saveemm;
514
515 reader->s_nano = reader->b_nano = 0;
516 reader->saveemm = 0;
517
518 int32_t rc = cardreader_do_emm(reader, eptmp);
519 if (rc == OK)
520 rdr_log(reader, "EMM from file %s was successful written.", token);
521 else
522 rdr_log(reader, "ERROR: EMM read from file %s NOT processed correctly! (rc=%d)", token, rc);
523
524 //restore old block/save settings
525 reader->s_nano = save_s_nano;
526 reader->b_nano = save_b_nano;
527 reader->saveemm = save_saveemm;
528
529 free(eptmp);
530}
531
532void emm_sort_nanos(unsigned char *dest, const unsigned char *src, int32_t len)
533{
534 int32_t w = 0, c = -1, j = 0;
535 while(1) {
536 int32_t n = 256;
537 for (j = 0; j < len; ) {
538 int32_t l = src[j + 1] + 2;
539 if (src[j] == c) {
540 if (w + l > len) {
541 cs_debug_mask(D_EMM, "sortnanos: sanity check failed. Exceeding memory area. Probably corrupted nanos!");
542 memset(dest, 0, len); // zero out everything
543 return;
544 }
545 memcpy(&dest[w],&src[j],l);
546 w += l;
547 } else if (src[j] > c && src[j] < n) {
548 n = src[j];
549 }
550 j += l;
551 }
552 if (n >= 256)
553 break;
554 c = n;
555 }
556}
Note: See TracBrowser for help on using the repository browser.