source: trunk/oscam-emm.c@ 8377

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

cryptoworks/viaccess: Run EMM reassembly before writing EMM in the card.

Before this patch EMM reassembly was only run by the dvbapi client.

This means that any other client (via newcamd, cs378x, cccam) was
expected to perform its own EMM reassembly otherwise the card
was unable to write the EMMs that needed preprocessing (reassemblation).

This commit moves EMM reassembly where it belongs - just before the
EMM is written in the card. That simplifies client logic (no more
knowledge of EMM structure and types) and allows cards to be updated
via any network protocol as long as the client is not trying to be
smart and just sends us all EMM packets.

The changes were tested with SRG Swiss Viacess card and Digiturk
Cryptoworks card. In the both cards shared EMMs were written OK
while receiving them via cs378x protocol and tsdecrypt as client.

If a client sends already reassembled EMMs it also works.

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