source: trunk/oscam-ecm.c@ 8465

Last change on this file since 8465 was 8465, checked in by gf, 11 years ago

cfg: Remove newcamd vars from struct s_config when the module is disabled.

File size: 44.4 KB
Line 
1#include "globals.h"
2#include "cscrypt/md5.h"
3#include "module-anticasc.h"
4#include "module-cacheex.h"
5#include "module-led.h"
6#include "module-stat.h"
7#include "module-webif.h"
8#include "module-ird-guess.h"
9#include "module-cw-cycle-check.h"
10#include "oscam-chk.h"
11#include "oscam-client.h"
12#include "oscam-config.h"
13#include "oscam-ecm.h"
14#include "oscam-garbage.h"
15#include "oscam-failban.h"
16#include "oscam-net.h"
17#include "oscam-time.h"
18#include "oscam-lock.h"
19#include "oscam-string.h"
20#include "oscam-work.h"
21#include "reader-common.h"
22
23extern CS_MUTEX_LOCK ecmcache_lock;
24extern struct ecm_request_t *ecmcwcache;
25extern struct s_client *timecheck_client;
26extern uint16_t len4caid[256];
27extern uint32_t ecmcwcache_size;
28
29/**
30 * get ecm from ecmcache
31 **/
32struct ecm_request_t *check_cwcache(ECM_REQUEST *er, struct s_client *cl)
33{
34 time_t now = time(NULL);
35 //time_t timeout = now-(time_t)(cfg.ctimeout/1000)-CS_CACHE_TIMEOUT;
36 time_t timeout = now-cfg.max_cache_time;
37 struct ecm_request_t *ecm;
38 uint64_t grp = cl?cl->grp:0;
39#ifdef CS_CACHEEX
40 // precalculate for better performance
41 uint8_t ecmd5chk = checkECMD5(er);
42 bool hasMatchAlias = cacheex_is_match_alias(cl, er);
43#endif
44 cs_readlock(&ecmcache_lock);
45 for (ecm = ecmcwcache; ecm; ecm = ecm->next) {
46 if (ecm->tps.time < timeout) {
47 ecm = NULL;
48 break;
49 }
50 if (ecm->ecmcacheptr)
51 continue;
52
53 if ((grp && ecm->grp && !(grp & ecm->grp)))
54 continue;
55
56#ifdef CS_CACHEEX
57 if (!hasMatchAlias || !cacheex_match_alias(cl, er, ecm)) {
58 //CWs from csp/cacheex have no ecms, csp ecmd5 is invalid, cacheex has ecmd5
59 if (ecmd5chk && checkECMD5(ecm)) {
60 if (memcmp(ecm->ecmd5, er->ecmd5, CS_ECMSTORESIZE))
61 continue; // no match
62 } else if (ecm->csp_hash != er->csp_hash) //fallback for csp only
63 continue; // no match
64 }
65#else
66 if (memcmp(ecm->ecmd5, er->ecmd5, CS_ECMSTORESIZE))
67 continue; // no match
68#endif
69
70 if (er->caid != ecm->caid && ecm->rc >= E_NOTFOUND && !is_betatunnel_caid(er->caid))
71 continue; //CW for the cached ECM wasn't found but now the client asks on a different caid so give it another try
72
73 if (ecm->rc != E_99) {
74 cs_readunlock(&ecmcache_lock);
75 return ecm;
76 }
77 }
78 cs_readunlock(&ecmcache_lock);
79 return NULL; // nothing found so return null
80}
81
82void convert_to_beta(struct s_client *cl, ECM_REQUEST *er, uint16_t caidto)
83{
84 static uint8_t headerN3[10] = {0xc7, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x87, 0x12};
85 static uint8_t headerN2[10] = {0xc9, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x48, 0x12};
86
87 er->ocaid = er->caid;
88 er->caid = caidto;
89 er->prid = 0;
90 er->ecmlen = er->ecm[2] + 3;
91
92 memmove(er->ecm + 13, er->ecm + 3, er->ecmlen - 3);
93
94 if (er->ecmlen > 0x88) {
95 memcpy(er->ecm + 3, headerN3, 10);
96 if (er->ecm[0] == 0x81)
97 er->ecm[12] += 1;
98 er->ecm[1]=0x70;
99 } else {
100 memcpy(er->ecm + 3, headerN2, 10);
101 }
102
103 er->ecmlen += 10;
104 er->ecm[2] = er->ecmlen - 3;
105 er->btun = 1;
106
107 cl->cwtun++;
108 cl->account->cwtun++;
109 first_client->cwtun++;
110
111 cs_debug_mask(D_TRACE, "ECM converted ocaid from 0x%04X to BetaCrypt caid 0x%04X for service id 0x%04X",
112 er->ocaid, caidto, er->srvid);
113}
114
115void convert_to_nagra(struct s_client *cl, ECM_REQUEST *er, uint16_t caidto)
116{
117 cs_debug_mask(D_TRACE, "convert_to_nagra");
118 er->ocaid = er->caid;
119 er->caid = caidto;
120 er->prid = 0;
121 er->ecmlen = er->ecm[2] + 3;
122
123 //not sure
124 if (er->ecmlen < 0x52)
125 er->ecm[1] = 0x30;
126
127 memmove(er->ecm + 3, er->ecm + 13, er->ecmlen - 3);
128
129 er->ecmlen -= 10;
130 er->ecm[2] = er->ecmlen - 3;
131 er->btun = 1;
132
133 cl->cwtun++;
134 cl->account->cwtun++;
135 first_client->cwtun++;
136
137 cs_debug_mask(D_TRACE, "ECM converted ocaid from: 0x%04X to Nagra: 0x04%X for service id:0x04%X",
138 er->ocaid, caidto, er->srvid);
139}
140
141void cs_betatunnel(ECM_REQUEST *er)
142{
143 int32_t n;
144 struct s_client *cl = cur_client();
145 uint32_t mask_all = 0xFFFF;
146
147 TUNTAB *ttab;
148 ttab = &cl->ttab;
149
150 if (er->caid>>8 == 0x18)
151 cs_ddump_mask(D_TRACE, er->ecm, 13, "betatunnel? ecmlen=%d", er->ecmlen);
152
153 for (n = 0; n<ttab->n; n++) {
154 if ((er->caid==ttab->bt_caidfrom[n]) && ((er->srvid==ttab->bt_srvid[n]) || (ttab->bt_srvid[n])==mask_all)) {
155 if ((er->caid == 0x1702 || er->caid == 0x1722) && er->ocaid == 0x0000) {
156 convert_to_nagra(cl, er, ttab->bt_caidto[n]);
157 } else if (er->ocaid == 0x0000) {
158 convert_to_beta(cl, er, ttab->bt_caidto[n]);
159 }
160 return;
161 }
162 }
163}
164
165static void remove_ecm_from_reader(ECM_REQUEST *ecm)
166{
167 int32_t i;
168 struct s_ecm_answer *ea = ecm->matching_rdr;
169 while (ea) {
170 if ((ea->status & REQUEST_SENT) && !(ea->status & REQUEST_ANSWERED)) {
171 //we found a outstanding reader, clean it:
172 struct s_reader *rdr = ea->reader;
173 if (rdr) {
174 struct s_client *cl = rdr->client;
175 if (cl) {
176 ECM_REQUEST *ecmtask = cl->ecmtask;
177 if (ecmtask) {
178 for (i = 0; i < cfg.max_pending; ++i) {
179 if (ecmtask[i].parent == ecm) {
180 ecmtask[i].parent = NULL;
181 ecmtask[i].client = NULL;
182 cacheex_set_csp_lastnode(&ecmtask[i]);
183 }
184 }
185 }
186 }
187 }
188 }
189 ea = ea->next;
190 }
191}
192
193void free_ecm(ECM_REQUEST *ecm)
194{
195 struct s_ecm_answer *ea, *nxt;
196 cacheex_free_csp_lastnodes(ecm);
197 //remove this ecm from reader queue to avoid segfault on very late answers (when ecm is already disposed)
198 //first check for outstanding answers:
199 remove_ecm_from_reader(ecm);
200 //free matching_rdr list:
201 ea = ecm->matching_rdr;
202 ecm->matching_rdr = NULL;
203 while (ea) {
204 nxt = ea->next;
205 add_garbage(ea);
206 ea = nxt;
207 }
208 if (ecm->src_data)
209 add_garbage(ecm->src_data);
210 add_garbage(ecm);
211}
212
213ECM_REQUEST *get_ecmtask(void)
214{
215 ECM_REQUEST *er = NULL;
216 struct s_client *cl = cur_client();
217 if (!cl)
218 return NULL;
219 if (!cs_malloc(&er, sizeof(ECM_REQUEST)))
220 return NULL;
221 cs_ftime(&er->tps);
222#ifdef CS_CACHEEX
223 er->cacheex_wait.time = er->tps.time;
224 er->cacheex_wait.millitm = er->tps.millitm;
225 er->cacheex_wait_time = 0;
226#endif
227 er->rc = E_UNHANDLED;
228 er->client = cl;
229 er->grp = cl->grp;
230 //cs_log("client %s ECMTASK %d module %s", username(cl), n, get_module(cl)->desc);
231 return er;
232}
233
234void cleanup_ecmtasks(struct s_client *cl)
235{
236 ECM_REQUEST *ecm;
237 struct s_ecm_answer *ea_list, *ea_prev;
238
239 if (cl->ecmtask) {
240 int32_t i;
241 for (i = 0; i < cfg.max_pending; i++) {
242 ecm = &cl->ecmtask[i];
243 ecm->matching_rdr = NULL;
244 ecm->client = NULL;
245 }
246 add_garbage(cl->ecmtask);
247 cl->ecmtask = NULL;
248 }
249
250 if (cl->cascadeusers) {
251 ll_destroy_data(cl->cascadeusers);
252 cl->cascadeusers = NULL;
253 }
254
255 //remove this clients ecm from queue. because of cache, just null the client:
256 cs_readlock(&ecmcache_lock);
257 for (ecm = ecmcwcache; ecm; ecm = ecm->next) {
258 if (ecm->client == cl) {
259 ecm->client = NULL;
260 cacheex_set_cacheex_src(ecm, cl);
261 //if cl is a reader, remove from matching_rdr:
262 for (ea_list = ecm->matching_rdr, ea_prev = NULL; ea_list; ea_prev = ea_list, ea_list = ea_list->next) {
263 if (ea_list->reader->client == cl) {
264 if (ea_prev)
265 ea_prev->next = ea_list->next;
266 else
267 ecm->matching_rdr = ea_list->next;
268 add_garbage(ea_list);
269 }
270 }
271 //if cl is a client, remove ecm from reader queue:
272 remove_ecm_from_reader(ecm);
273 }
274 }
275 cs_readunlock(&ecmcache_lock);
276
277 //remove client from rdr ecm-queue:
278 cs_readlock(&readerlist_lock);
279 struct s_reader *rdr = first_active_reader;
280 while (rdr) {
281 if (rdr->client && rdr->client->ecmtask) {
282 int i;
283 for (i = 0; i < cfg.max_pending; i++) {
284 ecm = &rdr->client->ecmtask[i];
285 if (ecm->client == cl) {
286 ecm->client = NULL;
287 ecm->parent = NULL;
288 }
289 }
290 }
291 rdr = rdr->next;
292 }
293 cs_readunlock(&readerlist_lock);
294}
295
296/**
297 * removes a reader from ecm cache queue - data
298 **/
299void remove_reader_from_ecm(struct s_reader *rdr)
300{
301 ECM_REQUEST *ecm;
302 struct s_ecm_answer *ea_list, *ea_prev;
303
304 cs_readlock(&ecmcache_lock);
305 for (ecm = ecmcwcache; ecm; ecm = ecm->next) {
306 for (ea_list = ecm->matching_rdr, ea_prev = NULL; ea_list; ea_prev = ea_list, ea_list = ea_list->next) {
307 if (ea_list->reader == rdr) {
308 if (ea_prev)
309 ea_prev->next = ea_list->next;
310 else
311 ecm->matching_rdr = ea_list->next;
312 add_garbage(ea_list);
313 }
314 }
315 }
316 cs_readunlock(&ecmcache_lock);
317}
318
319
320/**
321 * Check for NULL CWs
322 * Return them as "NOT FOUND"
323 **/
324void checkCW(ECM_REQUEST *er)
325{
326 int8_t i;
327 for (i = 0; i < 16; i++) {
328 if (er->cw[i])
329 return;
330 }
331 er->rc = E_NOTFOUND;
332}
333
334static void add_cascade_data(struct s_client *client, ECM_REQUEST *er)
335{
336 if (!client->cascadeusers)
337 client->cascadeusers = ll_create("cascade_data");
338 LLIST *l = client->cascadeusers;
339 LL_ITER it = ll_iter_create(l);
340 time_t now = time(NULL);
341 struct s_cascadeuser *cu;
342 int8_t found = 0;
343 while ((cu = ll_iter_next(&it))) {
344 if (er->caid==cu->caid && er->prid==cu->prid && er->srvid==cu->srvid) { //found it
345 if (cu->time < now)
346 cu->cwrate = now-cu->time;
347 cu->time = now;
348 found = 1;
349 }
350 else if (cu->time+60 < now) // old
351 ll_iter_remove_data(&it);
352 }
353 if (!found) { //add it if not found
354 if (!cs_malloc(&cu, sizeof(struct s_cascadeuser)))
355 return;
356 cu->caid = er->caid;
357 cu->prid = er->prid;
358 cu->srvid = er->srvid;
359 cu->time = now;
360 ll_append(l, cu);
361 }
362}
363
364static int32_t is_double_check_caid(ECM_REQUEST *er)
365{
366 if (!cfg.double_check_caid.caid[0]) //no caids defined: Check all
367 return 1;
368 int32_t i;
369 for (i = 0; i < CS_MAXCAIDTAB; i++) {
370 uint16_t tcaid = cfg.double_check_caid.caid[i];
371 if (!tcaid)
372 break;
373 if (tcaid == er->caid || (tcaid < 0x0100 && (er->caid >> 8) == tcaid)) {
374 return 1;
375 }
376 }
377 return 0;
378}
379
380static int32_t send_dcw(struct s_client * client, ECM_REQUEST *er)
381{
382 if (!client || client->kill || client->typ != 'c')
383 return 0;
384
385 static const char stageTxt[]={'0','C','L','P','F','X'};
386 static const char *stxt[]={"found", "cache1", "cache2", "cache3",
387 "not found", "timeout", "sleeping",
388 "fake", "invalid", "corrupt", "no card", "expdate", "disabled", "stopped"};
389 static const char *stxtEx[16]={"", "group", "caid", "ident", "class", "chid", "queue", "peer", "sid", "", "", "", "", "", "", ""};
390 static const char *stxtWh[16]={"", "user ", "reader ", "server ", "lserver ", "", "", "", "", "", "", "", "" ,"" ,"", ""};
391 char sby[100]="", sreason[32]="", schaninfo[32]="";
392 char erEx[32]="";
393 char uname[38]="";
394 char channame[32];
395 struct timeb tpe;
396
397 snprintf(uname,sizeof(uname)-1, "%s", username(client));
398
399 if (er->rc < E_NOTFOUND)
400 checkCW(er);
401
402#ifdef WITH_DEBUG
403 if (cs_dblevel & D_CLIENTECM) {
404 char buf[ECM_FMT_LEN];
405 char ecmd5[17*3];
406 char cwstr[17*3];
407 format_ecm(er, buf, ECM_FMT_LEN);
408 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
409 cs_hexdump(0, er->cw, 16, cwstr, sizeof(cwstr));
410#ifdef CS_CACHEEX
411 char csphash[5*3];
412 cs_hexdump(0, (void*)&er->csp_hash, 4, csphash, sizeof(csphash));
413 cs_debug_mask(D_CLIENTECM, "Client %s csphash %s cw %s rc %d %s", username(client), csphash, cwstr, er->rc, buf);
414#else
415 cs_debug_mask(D_CLIENTECM, "Client %s cw %s rc %d %s", username(client), cwstr, er->rc, buf);
416#endif
417 }
418#endif
419
420 struct s_reader *er_reader = er->selected_reader; //responding reader
421
422 if (er_reader) {
423 // add marker to reader if ECM_REQUEST was betatunneled
424 if (er->ocaid)
425 snprintf(sby, sizeof(sby)-1, " by %s(btun %04X)", er_reader->label, er->ocaid);
426 else
427 snprintf(sby, sizeof(sby)-1, " by %s", er_reader->label);
428 } else if (er->rc == E_TIMEOUT) {
429 struct s_ecm_answer *ea_list;
430 int32_t ofs = 0;
431 for (ea_list = er->matching_rdr; ea_list; ea_list = ea_list->next) {
432 if (ea_list->reader && ofs < (int32_t)sizeof(sby) && (ea_list->status & (REQUEST_SENT|REQUEST_ANSWERED)) == REQUEST_SENT) { //Request send, but no answer!
433 ofs += snprintf(sby+ofs, sizeof(sby)-ofs-1, "%s%s", ofs?",":" by ", ea_list->reader->label);
434 }
435 }
436 if (er->ocaid && ofs < (int32_t)sizeof(sby))
437 ofs += snprintf(sby+ofs, sizeof(sby)-ofs-1, "(btun %04X)", er->ocaid);
438 }
439
440 if (er->rc < E_NOTFOUND)
441 er->rcEx = 0;
442
443 if (er->rcEx)
444 snprintf(erEx, sizeof(erEx)-1, "rejected %s%s", stxtWh[er->rcEx>>4], stxtEx[er->rcEx & 0xf]);
445
446 if (cfg.appendchaninfo)
447 snprintf(schaninfo, sizeof(schaninfo)-1, " - %s", get_servicename(client, er->srvid, er->caid, channame));
448
449 if (er->msglog[0])
450 snprintf(sreason, sizeof(sreason)-1, " (%s)", er->msglog);
451
452 cs_ftime(&tpe);
453
454#ifdef CS_CACHEEX
455 if (er->rc == E_FOUND && er->cacheex_wait_time)
456 snprintf(sreason, sizeof(sreason)-1, " (real %d ms)", comp_timeb(&tpe, &er->cacheex_wait));
457#endif
458
459 client->cwlastresptime = 1000 * (tpe.time-er->tps.time) + tpe.millitm-er->tps.millitm;
460
461 time_t now = time(NULL);
462 webif_client_add_lastresponsetime(client, client->cwlastresptime, now, er->rc); // add to ringbuffer
463
464 if (er_reader) {
465 struct s_client *er_cl = er_reader->client;
466 if (er_cl) {
467 er_cl->cwlastresptime = client->cwlastresptime;
468 webif_client_add_lastresponsetime(er_cl, client->cwlastresptime, now, er->rc);
469 er_cl->last_srvidptr = client->last_srvidptr;
470 }
471 }
472
473 webif_client_init_lastreader(client, er, er_reader, stxt);
474
475 client->last = now;
476
477 //cs_debug_mask(D_TRACE, "CHECK rc=%d er->cacheex_src=%s", er->rc, username(er->cacheex_src));
478 switch(er->rc) {
479 case E_FOUND: {
480 client->cwfound++;
481 client->account->cwfound++;
482 first_client->cwfound++;
483 break;
484 }
485 case E_CACHE1:
486 case E_CACHE2:
487 case E_CACHEEX: {
488 client->cwcache++;
489 client->account->cwcache++;
490 first_client->cwcache++;
491#ifdef CS_CACHEEX
492 if (er->cacheex_src) {
493 er->cacheex_src->cwcacheexhit++;
494 if (er->cacheex_src->account)
495 er->cacheex_src->account->cwcacheexhit++;
496 first_client->cwcacheexhit++;
497 }
498#endif
499 break;
500 }
501 case E_NOTFOUND:
502 case E_CORRUPT:
503 case E_NOCARD: {
504 if (er->rcEx) {
505 client->cwignored++;
506 client->account->cwignored++;
507 first_client->cwignored++;
508 } else {
509 client->cwnot++;
510 client->account->cwnot++;
511 first_client->cwnot++;
512 }
513 break;
514 }
515 case E_TIMEOUT: {
516 client->cwtout++;
517 client->account->cwtout++;
518 first_client->cwtout++;
519 break;
520 }
521 default: {
522 client->cwignored++;
523 client->account->cwignored++;
524 first_client->cwignored++;
525 } }
526
527 ac_chk(client, er, 1);
528
529 int32_t is_fake = 0;
530 if (er->rc == E_FAKE) {
531 is_fake = 1;
532 er->rc = E_FOUND;
533 }
534
535 if (cfg.double_check && er->rc == E_FOUND && er->selected_reader && is_double_check_caid(er)) {
536 if (er->checked == 0) {//First CW, save it and wait for next one
537 er->checked = 1;
538 er->origin_reader = er->selected_reader;
539 memcpy(er->cw_checked, er->cw, sizeof(er->cw));
540 cs_log("DOUBLE CHECK FIRST CW by %s idx %d cpti %d", er->origin_reader->label, er->idx, er->msgid);
541 } else if (er->origin_reader != er->selected_reader) { //Second (or third and so on) cw. We have to compare
542 if (memcmp(er->cw_checked, er->cw, sizeof(er->cw)) == 0) {
543 er->checked++;
544 cs_log("DOUBLE CHECKED! %d. CW by %s idx %d cpti %d", er->checked, er->selected_reader->label, er->idx, er->msgid);
545 } else {
546 cs_log("DOUBLE CHECKED NONMATCHING! %d. CW by %s idx %d cpti %d", er->checked, er->selected_reader->label, er->idx, er->msgid);
547 }
548 }
549 if (er->checked < 2) { //less as two same cw? mark as pending!
550 er->rc = E_UNHANDLED;
551 return 0;
552 }
553 }
554
555 get_module(client)->send_dcw(client, er);
556
557 add_cascade_data(client, er);
558
559 if (is_fake)
560 er->rc = E_FAKE;
561
562 if (!(er->rc == E_SLEEPING && client->cwlastresptime == 0)) {
563 char buf[ECM_FMT_LEN];
564 format_ecm(er, buf, ECM_FMT_LEN);
565 if (er->reader_avail == 1) {
566 cs_log("%s (%s): %s (%d ms)%s %s%s",
567 uname, buf,
568 er->rcEx?erEx:stxt[er->rc], client->cwlastresptime, sby, schaninfo, sreason);
569 } else {
570 cs_log("%s (%s): %s (%d ms)%s (%c/%d/%d/%d)%s%s",
571 uname, buf,
572 er->rcEx ? erEx : stxt[er->rc],
573 client->cwlastresptime, sby,
574 stageTxt[er->stage], er->reader_requested, er->reader_count, er->reader_avail,
575 schaninfo, sreason);
576 }
577 }
578
579 cs_ddump_mask (D_ATR, er->cw, 16, "cw:");
580 led_status_cw_not_found(er);
581
582 return 0;
583}
584
585/*
586 * write_ecm_request():
587 */
588static int32_t write_ecm_request(struct s_reader *rdr, ECM_REQUEST *er)
589{
590 add_job(rdr->client, ACTION_READER_ECM_REQUEST, (void*)er, 0);
591 return 1;
592}
593
594
595/**
596 * distributes found ecm-request to all clients with rc=99
597 **/
598static void distribute_ecm(ECM_REQUEST *er, int32_t rc)
599{
600 struct ecm_request_t *ecm;
601 cs_readlock(&ecmcache_lock);
602 for (ecm = ecmcwcache; ecm; ecm = ecm->next) {
603 if (ecm != er && ecm->rc >= E_99 && ecm->ecmcacheptr == er) {
604 cacheex_init_cacheex_src(ecm, er);
605 write_ecm_answer(er->selected_reader, ecm, rc, 0, er->cw, NULL);
606 }
607 }
608 cs_readunlock(&ecmcache_lock);
609}
610
611/**
612 * sends the ecm request to the readers
613 * ECM_REQUEST er : the ecm
614 * er->stage: 0 = no reader asked yet
615 * 2 = ask only local reader (skipped without preferlocalcards)
616 * 3 = ask any non fallback reader
617 * 4 = ask fallback reader
618 **/
619void request_cw_from_readers(ECM_REQUEST *er)
620{
621 struct s_ecm_answer *ea;
622 int8_t sent = 0;
623
624 if (er->stage >= 4) return;
625
626 while (1) {
627 er->stage++;
628
629#ifndef CS_CACHEEX
630 if (er->stage == 1)
631 er->stage++;
632#endif
633 if (er->stage == 2 && !cfg.preferlocalcards)
634 er->stage++;
635
636 for (ea = er->matching_rdr; ea; ea = ea->next) {
637 switch(er->stage) {
638#ifdef CS_CACHEEX
639 case 1: {
640 // Cache-Exchange
641 if ((ea->status & REQUEST_SENT) ||
642 (ea->status & (READER_CACHEEX|READER_ACTIVE)) != (READER_CACHEEX|READER_ACTIVE))
643 continue;
644 break;
645 }
646#endif
647 case 2: {
648 // only local reader
649 if ((ea->status & REQUEST_SENT) ||
650 (ea->status & (READER_ACTIVE|READER_FALLBACK|READER_LOCAL)) != (READER_ACTIVE|READER_LOCAL))
651 continue;
652 break;
653 }
654 case 3: {
655 // any non fallback reader not asked yet
656 if ((ea->status & REQUEST_SENT) ||
657 (ea->status & (READER_ACTIVE|READER_FALLBACK)) != READER_ACTIVE)
658 continue;
659 break;
660 }
661 default: {
662 // only fallbacks
663 if ((ea->status & (READER_ACTIVE|READER_FALLBACK)) != (READER_ACTIVE|READER_FALLBACK))
664 continue;
665 if (ea->status & REQUEST_SENT) {
666 if (ea->reader && ea->reader->client && ea->reader->client->is_udp) //Always resend on udp
667 break;
668 if (er->reader_count > 1) //do not resend to the same reader(s) if we have more than one reader
669 continue;
670 }
671 break;
672 } }
673
674 struct s_reader *rdr = ea->reader;
675 char ecmd5[17*3];
676 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
677 cs_debug_mask(D_TRACE | D_CSPCWC, "request_cw stage=%d to reader %s ecm hash=%s", er->stage, rdr?rdr->label:"", ecmd5);
678
679 ea->status |= REQUEST_SENT;
680 er->reader_requested++;
681 write_ecm_request(ea->reader, er);
682
683 //set sent=1 only if reader is active/connected. If not, switch to next stage!
684 if (!sent && rdr) {
685 struct s_client *rcl = rdr->client;
686 if (rcl) {
687 if (rcl->typ=='r' && rdr->card_status==CARD_INSERTED)
688 sent = 1;
689 else if (rcl->typ=='p' && (rdr->card_status==CARD_INSERTED ||rdr->tcp_connected))
690 sent = 1;
691 }
692 }
693 }
694 if (sent || er->stage >= 4)
695 break;
696 }
697}
698
699void chk_dcw(struct s_client *cl, struct s_ecm_answer *ea)
700{
701 if (!ea || !ea->er)
702 return;
703
704 ECM_REQUEST *ert = ea->er;
705 struct s_ecm_answer *ea_list;
706 struct s_reader *eardr = ea->reader;
707 if (!ert)
708 return;
709
710 if (eardr) {
711 char ecmd5[17*3];
712 cs_hexdump(0, ert->ecmd5, 16, ecmd5, sizeof(ecmd5));
713 rdr_debug_mask(eardr, D_TRACE, "ecm answer for ecm hash %s rc=%d", ecmd5, ea->rc);
714 //rdr_ddump_mask(eardr, D_TRACE, ea->cw, sizeof(ea->cw), "received cw caid=%04X srvid=%04X hash=%08X",
715 // ert->caid, ert->srvid, ert->csp_hash);
716 //rdr_ddump_mask(eardr, D_TRACE, ert->ecm, ert->ecmlen, "received cw for ecm caid=%04X srvid=%04X hash=%08X",
717 // ert->caid, ert->srvid, ert->csp_hash);
718 }
719
720 ea->status |= REQUEST_ANSWERED;
721
722 if (eardr) {
723 //Update reader stats:
724 if (ea->rc == E_FOUND) {
725 eardr->ecmsok++;
726#ifdef CS_CACHEEX
727 struct s_client *eacl = eardr->client;
728 if (cacheex_reader(eardr) && !ert->cacheex_done && eacl) {
729 eacl->cwcacheexgot++;
730 cacheex_add_stats(eacl, ea->er->caid, ea->er->srvid, ea->er->prid, 1);
731 first_client->cwcacheexgot++;
732 }
733#endif
734 } else if (ea->rc == E_NOTFOUND) {
735 eardr->ecmsnok++;
736 if (eardr->ecmnotfoundlimit && eardr->ecmsnok >= eardr->ecmnotfoundlimit) {
737 rdr_log(eardr,"ECM not found limit reached %u. Restarting the reader.",
738 eardr->ecmsnok);
739 eardr->ecmsnok = 0; // Reset the variable
740 eardr->ecmshealthnok = 0; // Reset the variable
741 add_job(eardr->client, ACTION_READER_RESTART, NULL, 0);
742 }
743 }
744
745 //Reader ECMs Health Try (by Pickser)
746 if (eardr->ecmsok != 0 || eardr->ecmsnok != 0) {
747 eardr->ecmshealthok = ((double) eardr->ecmsok / (eardr->ecmsok + eardr->ecmsnok)) * 100;
748 eardr->ecmshealthnok = ((double) eardr->ecmsnok / (eardr->ecmsok + eardr->ecmsnok)) * 100;
749 }
750
751 //Reader Dynamic Loadbalancer Try (by Pickser)
752 /*
753 * todo: config-option!
754 *
755#ifdef WITH_LB
756 if (eardr->ecmshealthok >= 75) {
757 eardr->lb_weight = 100;
758 } else if (eardr->ecmshealthok >= 50) {
759 eardr->lb_weight = 75;
760 } else if (eardr->ecmshealthok >= 25) {
761 eardr->lb_weight = 50;
762 } else {
763 eardr->lb_weight = 25;
764 }
765#endif
766 */
767 }
768
769 if (ert->rc < E_99) {
770 send_reader_stat(eardr, ert, ea, ea->rc);
771#ifdef CS_CACHEEX
772 if (ea && ert->rc < E_NOTFOUND && ea->rc < E_NOTFOUND && memcmp(ea->cw, ert->cw, sizeof(ert->cw)) != 0) {
773 char cw1[16*3+2], cw2[16*3+2];
774 cs_hexdump(0, ea->cw, 16, cw1, sizeof(cw1));
775 cs_hexdump(0, ert->cw, 16, cw2, sizeof(cw2));
776
777 char ip1[20]="", ip2[20]="";
778 if (ea->reader) cs_strncpy(ip1, cs_inet_ntoa(ea->reader->client->ip), sizeof(ip1));
779 if (ert->cacheex_src) cs_strncpy(ip2, cs_inet_ntoa(ert->cacheex_src->ip), sizeof(ip2));
780 else if (ert->selected_reader) cs_strncpy(ip2, cs_inet_ntoa(ert->selected_reader->client->ip), sizeof(ip2));
781
782 ECM_REQUEST *er = ert;
783 debug_ecm(D_TRACE, "WARNING2: Different CWs %s from %s(%s)<>%s(%s): %s<>%s", buf,
784 username(ea->reader ? ea->reader->client : cl), ip1,
785 er->cacheex_src ? username(er->cacheex_src) : (ea->reader ? ea->reader->label : "unknown/csp"), ip2,
786 cw1, cw2);
787 }
788#endif
789 if (ea && ea->rc < ert->rc) { //answer too late, only cache update:
790 memcpy(ert->cw, ea->cw, sizeof(ea->cw));
791 ert->rc = ea->rc;
792 }
793
794 return; // already done
795 }
796
797 int32_t reader_left = 0, local_left = 0;
798#ifdef CS_CACHEEX
799 int8_t cacheex_left = 0;
800#endif
801
802 switch (ea->rc) {
803 case E_FOUND:
804 case E_CACHE2:
805 case E_CACHE1:
806 case E_CACHEEX:
807 memcpy(ert->cw, ea->cw, 16);
808 ert->rcEx = 0;
809 ert->rc = ea->rc;
810 ert->selected_reader = eardr;
811 break;
812 case E_TIMEOUT:
813 ert->rc = E_TIMEOUT;
814 ert->rcEx = 0;
815 break;
816 case E_NOTFOUND: {
817 ert->rcEx = ea->rcEx;
818 cs_strncpy(ert->msglog, ea->msglog, sizeof(ert->msglog));
819 ert->selected_reader = eardr;
820 if (!ert->ecmcacheptr) {
821#ifdef CS_CACHEEX
822 uint8_t has_cacheex = 0;
823#endif
824 for (ea_list = ert->matching_rdr; ea_list; ea_list = ea_list->next) {
825#ifdef CS_CACHEEX
826 if (((ea_list->status & READER_CACHEEX)) == READER_CACHEEX)
827 has_cacheex = 1;
828 if (((ea_list->status & (REQUEST_SENT|REQUEST_ANSWERED|READER_CACHEEX|READER_ACTIVE)) == (REQUEST_SENT|READER_CACHEEX|READER_ACTIVE)))
829 cacheex_left++;
830#endif
831 if (((ea_list->status & (REQUEST_SENT|REQUEST_ANSWERED|READER_LOCAL|READER_ACTIVE)) == (REQUEST_SENT|READER_LOCAL|READER_ACTIVE)))
832 local_left++;
833 if (((ea_list->status & (REQUEST_ANSWERED|READER_ACTIVE)) == (READER_ACTIVE)))
834 reader_left++;
835 }
836#ifdef CS_CACHEEX
837 if (has_cacheex && !cacheex_left && !ert->cacheex_done) {
838 ert->cacheex_done = 1;
839 request_cw_from_readers(ert);
840 } else
841#endif
842 if (cfg.preferlocalcards && !local_left && !ert->locals_done) {
843 ert->locals_done = 1;
844 request_cw_from_readers(ert);
845 }
846 }
847 break;
848 }
849 default:
850 cs_log("unexpected ecm answer rc=%d.", ea->rc);
851 return;
852 break;
853 }
854
855 if (ea->rc == E_NOTFOUND && !reader_left) {
856 // no more matching reader
857 ert->rc = E_NOTFOUND; //so we set the return code
858 }
859
860 send_reader_stat(eardr, ert, ea, ea->rc);
861
862#ifdef CS_CACHEEX
863 if (ea->rc < E_NOTFOUND && !ert->ecmcacheptr)
864 cacheex_cache_push(ert);
865#endif
866
867 if (ert->rc < E_99) {
868 if (cl) send_dcw(cl, ert);
869 if (!ert->ecmcacheptr && ert->rc != E_UNHANDLED)
870 distribute_ecm(ert, (ert->rc == E_FOUND)?E_CACHE2:ert->rc);
871 }
872
873 return;
874}
875
876uint32_t chk_provid(uint8_t *ecm, uint16_t caid)
877{
878 int32_t i, len, descriptor_length = 0;
879 uint32_t provid = 0;
880
881 switch(caid >> 8) {
882 case 0x01:
883 // seca
884 provid = b2i(2, ecm+3);
885 break;
886 case 0x05:
887 // viaccess
888 i = (ecm[4] == 0xD2) ? ecm[5]+2 : 0; // skip d2 nano
889 if ((ecm[5+i] == 3) && ((ecm[4+i] == 0x90) || (ecm[4+i] == 0x40)))
890 provid = (b2i(3, ecm+6+i) & 0xFFFFF0);
891
892 i = (ecm[6] == 0xD2) ? ecm[7]+2 : 0; // skip d2 nano long ecm
893 if ((ecm[7+i] == 7) && ((ecm[6+i] == 0x90) || (ecm[6+i] == 0x40)))
894 provid = (b2i(3, ecm+8+i) & 0xFFFFF0);
895
896 break;
897 case 0x0D:
898 // cryptoworks
899 len = (((ecm[1] & 0xf) << 8) | ecm[2])+3;
900 for (i = 8; i < len; i += descriptor_length + 2) {
901 descriptor_length = ecm[i+1];
902 if (ecm[i] == 0x83) {
903 provid = (uint32_t)ecm[i+2] & 0xFE;
904 break;
905 }
906 }
907 break;
908#ifdef WITH_LB
909 default:
910 for (i = 0; i < CS_MAXCAIDTAB; i++) {
911 uint16_t tcaid = cfg.lb_noproviderforcaid.caid[i];
912 if (!tcaid) break;
913 if (tcaid == caid) {
914 provid = 0;
915 break;
916 }
917 if (tcaid < 0x0100 && (caid >> 8) == tcaid) {
918 provid = 0;
919 break;
920 }
921 }
922#endif
923 }
924 return provid;
925}
926
927void update_chid(ECM_REQUEST *er)
928{
929 if ((er->caid >> 8) == 0x06 && !er->chid && er->ecmlen > 7)
930 er->chid = (er->ecm[6] << 8) | er->ecm[7];
931}
932
933int32_t write_ecm_answer(struct s_reader * reader, ECM_REQUEST *er, int8_t rc, uint8_t rcEx, uint8_t *cw, char *msglog)
934{
935 int32_t i;
936 uint8_t c;
937 struct s_ecm_answer *ea = NULL, *ea_list, *ea_org = NULL;
938 struct timeb now;
939
940 //if (!er->parent && !er->client) //distribute also if no client is set!
941 // return 0;
942
943 cs_ftime(&now);
944
945 if (er->parent) {
946 // parent is only set on reader->client->ecmtask[], but we want client->ecmtask[]
947 // this means: reader has a ecm copy from client, so point to client
948 er->rc = rc;
949 er->idx = 0;
950 er = er->parent; //Now er is "original" ecm, before it was the reader-copy
951 er->grp |= reader->grp; // extend grp by grp of answering reader so clients in other group use cache
952
953 if (er->rc < E_99) {
954 send_reader_stat(reader, er, NULL, rc);
955 return 0; //Already done
956 }
957 }
958
959#ifdef CW_CYCLE_CHECK
960 if (!checkcwcycle(er, reader, cw, rc )) {
961 rc = E_NOTFOUND;
962 rcEx = E2_WRONG_CHKSUM;
963 }
964#endif
965
966 for (ea_list = er->matching_rdr; reader && ea_list && !ea_org; ea_list = ea_list->next) {
967 if (ea_list->reader == reader)
968 ea_org = ea_list;
969 }
970
971 if (!ea_org) {
972 if (!cs_malloc(&ea, sizeof(struct s_ecm_answer))) // Freed by ACTION_CLIENT_ECM_ANSWER
973 return 0;
974 } else {
975 ea = ea_org;
976 }
977
978 if (cw)
979 memcpy(ea->cw, cw, 16);
980
981 if (msglog)
982 memcpy(ea->msglog, msglog, MSGLOGSIZE);
983
984 ea->rc = rc;
985 ea->rcEx = rcEx;
986 ea->reader = reader;
987 ea->status |= REQUEST_ANSWERED;
988 ea->er = er;
989
990 if (reader && rc < E_NOTFOUND) {
991 if (reader->disablecrccws == 0) {
992 for (i = 0; i < 16; i += 4) {
993 c = ((ea->cw[i]+ea->cw[i+1]+ea->cw[i+2]) & 0xff);
994 if (ea->cw[i+3]!=c) {
995 if (reader->dropbadcws) {
996 ea->rc = E_NOTFOUND;
997 ea->rcEx = E2_WRONG_CHKSUM;
998 break;
999 } else {
1000 cs_debug_mask(D_TRACE, "notice: changed dcw checksum byte cw[%i] from %02x to %02x", i+3, ea->cw[i+3],c);
1001 ea->cw[i+3] = c;
1002 }
1003 }
1004 }
1005 } else {
1006 cs_debug_mask(D_TRACE, "notice: CW checksum check disabled");
1007 }
1008 }
1009
1010 if (reader && ea->rc==E_FOUND) {
1011 /* CWL logging only if cwlogdir is set in config */
1012 if (cfg.cwlogdir != NULL)
1013 logCWtoFile(er, ea->cw);
1014 }
1015
1016 int32_t res = 0;
1017 struct s_client *cl = er->client;
1018 if (cl && !cl->kill) {
1019 if (ea_org) { //duplicate for queue
1020 if (!cs_malloc(&ea, sizeof(struct s_ecm_answer)))
1021 return 0;
1022 memcpy(ea, ea_org, sizeof(struct s_ecm_answer));
1023 }
1024 add_job(cl, ACTION_CLIENT_ECM_ANSWER, ea, sizeof(struct s_ecm_answer));
1025 res = 1;
1026 } else { //client has disconnected. Distribute ecms to other waiting clients
1027 if (!er->ecmcacheptr)
1028 chk_dcw(NULL, ea);
1029 if (!ea_org)
1030 free(ea);
1031 }
1032
1033 if (reader && rc == E_FOUND && reader->resetcycle > 0) {
1034 reader->resetcounter++;
1035 if (reader->resetcounter > reader->resetcycle) {
1036 reader->resetcounter = 0;
1037 rdr_log(reader, "Resetting reader, resetcyle of %d ecms reached", reader->resetcycle);
1038 reader->card_status = CARD_NEED_INIT;
1039 cardreader_reset(cl);
1040 }
1041 }
1042
1043 return res;
1044}
1045
1046static void guess_cardsystem(ECM_REQUEST *er)
1047{
1048 uint16_t last_hope = 0;
1049
1050 // viaccess - check by provid-search
1051 if ((er->prid = chk_provid(er->ecm, 0x500)))
1052 er->caid = 0x500;
1053
1054 // nagra
1055 // is ecm[1] always 0x30 ?
1056 // is ecm[3] always 0x07 ?
1057 if ((er->ecm[6]==1) && (er->ecm[4]==er->ecm[2]-2))
1058 er->caid = 0x1801;
1059
1060 // seca2 - very poor
1061 if ((er->ecm[8]==0x10) && ((er->ecm[9]&0xF1)==1))
1062 last_hope = 0x100;
1063
1064 // is cryptoworks, but which caid ?
1065 if ((er->ecm[3]==0x81) && (er->ecm[4]==0xFF) &&
1066 (!er->ecm[5]) && (!er->ecm[6]) && (er->ecm[7]==er->ecm[2]-5))
1067 {
1068 last_hope = 0xd00;
1069 }
1070
1071 if (!er->caid && er->ecm[2] == 0x31 && er->ecm[0x0b] == 0x28)
1072 guess_irdeto(er);
1073
1074 if (!er->caid) // guess by len ..
1075 er->caid = len4caid[er->ecm[2] + 3];
1076
1077 if (!er->caid)
1078 er->caid = last_hope;
1079}
1080
1081void get_cw(struct s_client * client, ECM_REQUEST *er)
1082{
1083 int32_t i, j, m;
1084 time_t now = time((time_t*)0);
1085 uint32_t line = 0;
1086
1087 er->client = client;
1088 if (now - client->lastecm > cfg.hideclient_to) client->lastswitch = 0; // user was on freetv or didn't request for some time so we reset lastswitch to get correct stats/webif display
1089 client->lastecm = now;
1090
1091 if (client == first_client || !client ->account || client->account == first_client->account) {
1092 //DVBApi+serial is allowed to request anonymous accounts:
1093 int16_t listenertype = get_module(client)->listenertype;
1094 if (listenertype != LIS_DVBAPI && listenertype != LIS_SERIAL) {
1095 er->rc = E_INVALID;
1096 er->rcEx = E2_GLOBAL;
1097 snprintf(er->msglog, sizeof(er->msglog), "invalid user account %s", username(client));
1098 }
1099 }
1100
1101 if (er->ecmlen > MAX_ECM_SIZE) {
1102 er->rc = E_INVALID;
1103 er->rcEx = E2_GLOBAL;
1104 snprintf(er->msglog, sizeof(er->msglog), "ECM size %d > Max Ecm size %d, ignored! client %s", er->ecmlen, MAX_ECM_SIZE, username(client));
1105 }
1106
1107 if (!client->grp) {
1108 er->rc = E_INVALID;
1109 er->rcEx = E2_GROUP;
1110 snprintf(er->msglog, sizeof(er->msglog), "invalid user group %s", username(client));
1111 }
1112
1113
1114 if (!er->caid)
1115 guess_cardsystem(er);
1116
1117 /* Quickfix Area */
1118 update_chid(er);
1119
1120 // quickfix for 0100:000065
1121 if (er->caid == 0x100 && er->prid == 0x00006a) { // cds nl add fix so mismatch between ecm and secatype reader wont set channel on sid blacklist
1122 er->chid = b2i(2, er->ecm+7); // not quite right but good enough to function, its also registered this way in module-stat
1123 }
1124
1125 if (er->caid == 0x100 && er->prid == 0x65 && er->srvid == 0)
1126 er->srvid = 0x0642;
1127
1128 // Quickfixes for Opticum/Globo HD9500
1129 // Quickfix for 0500:030300
1130 if (er->caid == 0x500 && er->prid == 0x030300)
1131 er->prid = 0x030600;
1132
1133 // Quickfix for 0500:D20200
1134 if (er->caid == 0x500 && er->prid == 0xD20200)
1135 er->prid = 0x030600;
1136
1137 //betacrypt ecm with nagra header
1138 if ((er->caid == 0x1702 || er->caid == 0x1722) && (er->ecmlen == 0x89 || er->ecmlen == 0x4A) && er->ecm[3] == 0x07 && (er->ecm[4] == 0x84 || er->ecm[4] == 0x45))
1139 {
1140 //cs_debug_mask(D_TRACE, "Quickfix remap beta->nagra: 0x%X, 0x%X, 0x%X, 0x%X", er->caid, er->ecmlen, er->ecm[3], er->ecm[4]);
1141 if (er->caid == 0x1702) {
1142 er->caid = 0x1833;
1143 } else {
1144 check_lb_auto_betatunnel_mode(er);
1145 }
1146 cs_debug_mask(D_TRACE, "Quickfix remap beta->nagra: 0x%X, 0x%X, 0x%X, 0x%X", er->caid, er->ecmlen, er->ecm[3], er->ecm[4]);
1147 }
1148
1149 //nagra ecm with betacrypt header 1801, 1833, 1834, 1835
1150 if ((er->caid == 0x1801 || er->caid == 0x1833 || er->caid == 0x1834 || er->caid == 0x1835) && (er->ecmlen == 0x93 || er->ecmlen == 0x54) && er->ecm[13] == 0x07 && (er->ecm[14] == 0x84 || er->ecm[14] == 0x45))
1151 {
1152 //cs_debug_mask(D_TRACE, "Quickfix remap nagra->beta: 0x%X, 0x%X, 0x%X, 0x%X", er->caid, er->ecmlen, er->ecm[13], er->ecm[44]);
1153 if (er->caid == 0x1833) {
1154 er->caid = 0x1702;
1155 } else {
1156 er->caid = 0x1722;
1157 }
1158 cs_debug_mask(D_TRACE, "Quickfix remap nagra->beta: 0x%X, 0x%X, 0x%X, 0x%X", er->caid, er->ecmlen, er->ecm[13], er->ecm[44]);
1159 }
1160
1161 //Ariva quickfix (invalid nagra provider)
1162 if (((er->caid & 0xFF00) == 0x1800) && er->prid > 0x00FFFF)
1163 er->prid = 0;
1164
1165 //Check for invalid provider, extract provider out of ecm:
1166 uint32_t prid = chk_provid(er->ecm, er->caid);
1167 if (!er->prid) {
1168 er->prid = prid;
1169 } else {
1170 if (prid && prid != er->prid) {
1171 cs_debug_mask(D_TRACE, "provider fixed: %04X:%06X to %04X:%06X",er->caid, er->prid, er->caid, prid);
1172 er->prid = prid;
1173 }
1174 }
1175
1176#ifdef MODULE_NEWCAMD
1177 // Set providerid for newcamd clients if none is given
1178 if (!er->prid && client->ncd_server) {
1179 int32_t pi = client->port_idx;
1180 if (pi >= 0 && cfg.ncd_ptab.nports && cfg.ncd_ptab.nports >= pi && cfg.ncd_ptab.ports[pi].ncd)
1181 er->prid = cfg.ncd_ptab.ports[pi].ncd->ncd_ftab.filts[0].prids[0];
1182 }
1183#endif
1184
1185 // CAID not supported or found
1186 if (!er->caid) {
1187 er->rc = E_INVALID;
1188 er->rcEx = E2_CAID;
1189 snprintf( er->msglog, MSGLOGSIZE, "CAID not supported or found" );
1190 }
1191
1192 // user expired
1193 if (client->expirationdate && client->expirationdate < client->lastecm)
1194 er->rc = E_EXPDATE;
1195
1196 // out of timeframe
1197 if (client->allowedtimeframe[0] && client->allowedtimeframe[1]) {
1198 struct tm acttm;
1199 localtime_r(&now, &acttm);
1200 int32_t curtime = (acttm.tm_hour * 60) + acttm.tm_min;
1201 int32_t mintime = client->allowedtimeframe[0];
1202 int32_t maxtime = client->allowedtimeframe[1];
1203 if (!((mintime <= maxtime && curtime > mintime && curtime < maxtime) || (mintime > maxtime && (curtime > mintime || curtime < maxtime)))) {
1204 er->rc = E_EXPDATE;
1205 }
1206 cs_debug_mask(D_TRACE, "Check Timeframe - result: %d, start: %d, current: %d, end: %d\n",er->rc, mintime, curtime, maxtime);
1207 }
1208
1209 // user disabled
1210 if (client->disabled != 0) {
1211 if (client->failban & BAN_DISABLED) {
1212 cs_add_violation(client, client->account->usr);
1213 cs_disconnect_client(client);
1214 }
1215 er->rc = E_DISABLED;
1216 }
1217
1218 if (!chk_global_whitelist(er, &line)) {
1219 debug_ecm(D_TRACE, "whitelist filtered: %s (%s) line %d", username(client), buf, line);
1220 er->rc = E_INVALID;
1221 }
1222
1223 // rc<100 -> ecm error
1224 if (er->rc >= E_UNHANDLED) {
1225 m = er->caid;
1226 i = er->srvid;
1227
1228 if (i != client->last_srvid || !client->lastswitch) {
1229 if (cfg.usrfileflag)
1230 cs_statistics(client);
1231 client->lastswitch = now;
1232 }
1233
1234 // user sleeping
1235 if (client->tosleep && (now - client->lastswitch > client->tosleep)) {
1236 if (client->failban & BAN_SLEEPING) {
1237 cs_add_violation(client, client->account->usr);
1238 cs_disconnect_client(client);
1239 }
1240 if (client->c35_sleepsend != 0) {
1241 er->rc = E_STOPPED; // send stop command CMD08 {00 xx}
1242 } else {
1243 er->rc = E_SLEEPING;
1244 }
1245 }
1246
1247 client->last_srvid = i;
1248 client->last_caid = m;
1249
1250 int32_t ecm_len = (((er->ecm[1] & 0x0F) << 8) | er->ecm[2]) + 3;
1251
1252 for (j = 0; (j < 6) && (er->rc >= E_UNHANDLED); j++) {
1253 switch(j) {
1254 case 0:
1255 // fake (uniq)
1256 if (client->dup)
1257 er->rc = E_FAKE;
1258 break;
1259 case 1:
1260 // invalid (caid)
1261 if (!chk_bcaid(er, &client->ctab)) {
1262 er->rc = E_INVALID;
1263 er->rcEx = E2_CAID;
1264 snprintf( er->msglog, MSGLOGSIZE, "invalid caid 0x%04X", er->caid );
1265 }
1266 break;
1267 case 2:
1268 // invalid (srvid)
1269 if (!chk_srvid(client, er)) {
1270 er->rc = E_INVALID;
1271 snprintf( er->msglog, MSGLOGSIZE, "invalid SID" );
1272 }
1273 break;
1274 case 3:
1275 // invalid (ufilters)
1276 if (!chk_ufilters(er))
1277 er->rc = E_INVALID;
1278 break;
1279 case 4:
1280 // invalid (sfilter)
1281 if (!chk_sfilter(er, &get_module(client)->ptab))
1282 er->rc = E_INVALID;
1283 break;
1284 case 5:
1285 // corrupt
1286 if ((i = er->ecmlen - ecm_len)) {
1287 if (i > 0) {
1288 cs_debug_mask(D_TRACE, "warning: ecm size adjusted from %d to %d", er->ecmlen, ecm_len);
1289 er->ecmlen = ecm_len;
1290 }
1291 else
1292 er->rc = E_CORRUPT;
1293 }
1294 break;
1295 }
1296 }
1297 }
1298
1299 //Schlocke: above checks could change er->rc so
1300 if (er->rc >= E_UNHANDLED) {
1301 /*BetaCrypt tunneling
1302 *moved behind the check routines,
1303 *because newcamd ECM will fail
1304 *if ECM is converted before
1305 */
1306 if (client->ttab.n)
1307 cs_betatunnel(er);
1308
1309 // ignore ecm ...
1310 int32_t offset = 3;
1311 // ... and betacrypt header for cache md5 calculation
1312 if ((er->caid >> 8) == 0x17)
1313 offset = 13;
1314 unsigned char md5tmp[MD5_DIGEST_LENGTH];
1315 // store ECM in cache
1316 memcpy(er->ecmd5, MD5(er->ecm + offset, er->ecmlen - offset, md5tmp), CS_ECMSTORESIZE);
1317 cacheex_update_hash(er);
1318 ac_chk(client, er, 0);
1319 }
1320
1321 struct s_ecm_answer *ea, *prv = NULL;
1322 uint32_t ex1rdr = 0;
1323 if (er->rc >= E_99 && !cacheex_is_match_alias(client, er)) {
1324 er->reader_avail = 0;
1325 struct s_reader *rdr;
1326
1327 cs_readlock(&readerlist_lock);
1328 cs_readlock(&clientlist_lock);
1329
1330 for (rdr = first_active_reader; rdr; rdr = rdr->next) {
1331 int8_t match = matching_reader(er, rdr, 1); // include ratelimitercheck
1332#ifdef WITH_LB
1333 //if this reader does not match, check betatunnel for it
1334 if (!match && cfg.lb_auto_betatunnel) {
1335 uint16_t caid = get_betatunnel_caid_to(er->caid);
1336 if (caid) {
1337 uint16_t save_caid = er->caid;
1338 er->caid = caid;
1339 match = matching_reader(er, rdr, 1); //matching (including ratelimitercheck)
1340 er->caid = save_caid;
1341 }
1342 }
1343#endif
1344 if (match) {
1345 if (!cs_malloc(&ea, sizeof(struct s_ecm_answer)))
1346 goto OUT;
1347 ea->reader = rdr;
1348 if (prv)
1349 prv->next = ea;
1350 else
1351 er->matching_rdr = ea;
1352 prv = ea;
1353
1354 ea->status = READER_ACTIVE;
1355 if (!is_network_reader(rdr))
1356 ea->status |= READER_LOCAL;
1357 else if (cacheex_reader(rdr))
1358 ea->status |= READER_CACHEEX;
1359 if (rdr->fallback)
1360 ea->status |= READER_FALLBACK;
1361#ifdef WITH_LB
1362 if (cfg.lb_mode || !rdr->fallback)
1363#else
1364 if (!rdr->fallback)
1365#endif
1366 er->reader_avail++;
1367 }
1368 }
1369
1370OUT:
1371 cs_readunlock(&clientlist_lock);
1372 cs_readunlock(&readerlist_lock);
1373
1374 stat_get_best_reader(er);
1375
1376 int32_t fallback_reader_count = 0;
1377 er->reader_count = 0;
1378 for (ea = er->matching_rdr; ea; ea = ea->next) {
1379 if (cacheex_reader(ea->reader))
1380 ex1rdr++;
1381 if (ea->status & READER_ACTIVE) {
1382 if (!(ea->status & READER_FALLBACK))
1383 er->reader_count++;
1384 else
1385 fallback_reader_count++;
1386 }
1387 }
1388
1389 if ((er->reader_count + fallback_reader_count) == 0) { //no reader -> not found
1390 er->rc = E_NOTFOUND;
1391 if (!er->rcEx)
1392 er->rcEx = E2_GROUP;
1393 snprintf(er->msglog, MSGLOGSIZE, "no matching reader");
1394 }
1395 }
1396
1397 //we have to go through matching_reader() to check services!
1398 struct ecm_request_t *ecm;
1399 if (er->rc == E_UNHANDLED) {
1400 ecm = check_cwcache(er, client);
1401 if (ecm) {
1402 if (ecm->rc < E_99) {
1403 memcpy(er->cw, ecm->cw, 16);
1404 er->selected_reader = ecm->selected_reader;
1405 er->rc = (ecm->rc == E_FOUND) ? E_CACHE1 : ecm->rc;
1406 } else { //E_UNHANDLED
1407 er->ecmcacheptr = ecm;
1408 er->rc = E_99;
1409#ifdef CS_CACHEEX
1410 //to support cache without ecms we store the first client ecm request here
1411 //when we got a cache ecm from cacheex
1412 if (!ecm->ecmlen && er->ecmlen && !ecm->matching_rdr) {
1413 ecm->matching_rdr = er->matching_rdr;
1414 er->matching_rdr = NULL;
1415 ecm->ecmlen = er->ecmlen;
1416 ecm->client = er->client;
1417 er->client = NULL;
1418 memcpy(ecm->ecm, er->ecm, sizeof(ecm->ecm));
1419 memcpy(ecm->ecmd5, er->ecmd5, sizeof(ecm->ecmd5));
1420 }
1421#endif
1422 }
1423#ifdef CS_CACHEEX
1424 er->cacheex_src = ecm->cacheex_src;
1425#endif
1426 } else
1427 er->rc = E_UNHANDLED;
1428 }
1429
1430#ifdef CS_CACHEEX
1431 int8_t cacheex = client->account ? client->account->cacheex.mode : 0;
1432 uint32_t cacheex_wait_time = ex1rdr>0 ? 0 : get_cacheex_wait_time(er,client); //ex1 reader win, no wait, in time of wait for exscp we ask ex1 already
1433 uint8_t cwcycle_act = cwcycle_check_act(er->caid);
1434 if (!cwcycle_act)
1435 cs_debug_mask(D_TRACE | D_CACHEEX, "[GET_CW] wait_time %d caid %04X prov %06X srvid %04X rc %d cacheex cl mode %d ex1rdr %d", cacheex_wait_time, er->caid, er->prid, er->srvid, er->rc, cacheex, ex1rdr);
1436 if ((cacheex_wait_time && !cwcycle_act) && er->rc == E_UNHANDLED) { //not found in cache, so wait!
1437 add_ms_to_timeb(&er->cacheex_wait, cacheex_wait_time);
1438 er->cacheex_wait_time = cacheex_wait_time;
1439 int32_t max_wait = cacheex_wait_time; // uint32_t can't value <> n/50
1440 while (max_wait > 0 && !client->kill) {
1441 cs_sleepms(50);
1442 max_wait -= 50;
1443 ecm = check_cwcache(er, client);
1444 if (ecm) {
1445 if (ecm->rc < E_99) { //Found cache!
1446 memcpy(er->cw, ecm->cw, 16);
1447 er->selected_reader = ecm->selected_reader;
1448 er->rc = (ecm->rc == E_FOUND)?E_CACHE1:ecm->rc;
1449 } else { //Found request!
1450 er->ecmcacheptr = ecm;
1451 er->rc = E_99;
1452 }
1453 er->cacheex_src = ecm->cacheex_src;
1454 break;
1455 }
1456 }
1457 if (max_wait <= 0 ) {
1458 cs_debug_mask(D_TRACE | D_CACHEEX, "[GET_CW] wait_time over");
1459 snprintf(er->msglog, MSGLOGSIZE, "wait_time over");
1460 }
1461 }
1462#endif
1463
1464 if (er->rc >= E_99) {
1465#ifdef CS_CACHEEX
1466 if (cacheex != 1 || er->rc == E_99) { //Cacheex should not add to the ecmcache:
1467#endif
1468 if (er->rc == E_UNHANDLED) {
1469 ecm = check_cwcache(er, client);
1470 if (ecm && ecm != er) {
1471 er->rc = E_99;
1472 er->ecmcacheptr = ecm; //Linking ecm to first request
1473#ifdef CS_CACHEEX
1474 er->cacheex_src = ecm->cacheex_src;
1475#endif
1476 }
1477 }
1478 cs_writelock(&ecmcache_lock);
1479 er->next = ecmcwcache;
1480 ecmcwcache = er;
1481 ecmcwcache_size++;
1482 cs_writeunlock(&ecmcache_lock);
1483#ifdef CS_CACHEEX
1484 }
1485#endif
1486 }
1487
1488 if (er->rc < E_99) {
1489#ifdef CS_CACHEEX
1490 if (cfg.delay && cacheex != 1) //No delay on cacheexchange mode 1 client!
1491 cs_sleepms(cfg.delay);
1492
1493 if (cacheex == 1 && er->rc < E_NOTFOUND) {
1494 cacheex_add_stats(client, er->caid, er->srvid, er->prid, 0);
1495 client->cwcacheexpush++;
1496 if (client->account)
1497 client->account->cwcacheexpush++;
1498 first_client->cwcacheexpush++;
1499 }
1500#else
1501 if (cfg.delay)
1502 cs_sleepms(cfg.delay);
1503#endif
1504 send_dcw(client, er);
1505 free_ecm(er);
1506 return; //ECM found/not found/error/invalid
1507 }
1508
1509 if (er->rc == E_99) {
1510 er->stage = 4;
1511 if (timecheck_client) {
1512 pthread_mutex_lock(&timecheck_client->thread_lock);
1513 if (timecheck_client->thread_active == 2)
1514 pthread_kill(timecheck_client->thread, OSCAM_SIGNAL_WAKEUP);
1515 pthread_mutex_unlock(&timecheck_client->thread_lock);
1516 }
1517 return; //ECM already requested / found in ECM cache
1518 }
1519
1520#ifdef CS_CACHEEX
1521 //er->rc == E_UNHANDLED
1522 //Cache Exchange never request cws from readers!
1523 if (cacheex == 1) {
1524 er->rc = E_NOTFOUND;
1525 er->rcEx = E2_OFFLINE;
1526 send_dcw(client, er);
1527 free_ecm(er);
1528 return;
1529 }
1530#endif
1531
1532 lb_mark_last_reader(er);
1533
1534 er->rcEx = 0;
1535#if defined CS_CACHEEX && defined CW_CYCLE_CHECK
1536 if (cwcycle_act)
1537 cs_debug_mask(D_TRACE | D_CACHEEX, "[GET_CW] wait_time (cwc) %d caid %04X prov %06X srvid %04X rc %d cacheex cl mode %d ex1rdr %d", cacheex_wait_time, er->caid, er->prid, er->srvid, er->rc, cacheex, ex1rdr);
1538 if ((cacheex_wait_time && cwcycle_act) && er->rc == E_UNHANDLED) { //wait for cache answer!
1539 add_ms_to_timeb(&er->cacheex_wait, cacheex_wait_time);
1540 er->cacheex_wait_time = cacheex_wait_time;
1541 } else
1542#endif
1543 request_cw_from_readers(er);
1544
1545#ifdef WITH_DEBUG
1546 if (D_CLIENTECM & cs_dblevel) {
1547 char buf[ECM_FMT_LEN];
1548 format_ecm(er, buf, ECM_FMT_LEN);
1549 cs_ddump_mask(D_CLIENTECM, er->ecm, er->ecmlen, "Client %s ECM dump %s", username(client), buf);
1550 }
1551#endif
1552
1553 if (timecheck_client) {
1554 pthread_mutex_lock(&timecheck_client->thread_lock);
1555 if (timecheck_client->thread_active == 2)
1556 pthread_kill(timecheck_client->thread, OSCAM_SIGNAL_WAKEUP);
1557 pthread_mutex_unlock(&timecheck_client->thread_lock);
1558 }
1559}
1560
1561int32_t ecmfmt(uint16_t caid, uint32_t prid, uint16_t chid, uint16_t pid, uint16_t srvid, uint16_t l, char *ecmd5hex, char *csphash, char *cw, char *result, size_t size)
1562{
1563 if (!cfg.ecmfmt)
1564 return snprintf(result, size, "%04X&%06X/%04X/%04X/%02X:%s", caid, prid, chid, srvid, l, ecmd5hex);
1565
1566 uint32_t s = 0, zero = 0, flen = 0, value = 0;
1567 char *c = cfg.ecmfmt, fmt[5] = "%04X";
1568 while (*c) {
1569 switch(*c) {
1570 case '0': zero = 1; value = 0; break;
1571 case 'c': flen = 4; value = caid; break;
1572 case 'p': flen = 6; value = prid; break;
1573 case 'i': flen = 4; value = chid; break;
1574 case 'd': flen = 4; value = pid; break;
1575 case 's': flen = 4; value = srvid; break;
1576 case 'l': flen = 2; value = l; break;
1577 case 'h': flen = CS_ECMSTORESIZE; break;
1578 case 'e': flen = 5; break;
1579 case 'w': flen = 17; break;
1580 case '\\':
1581 c++;
1582 flen = 0;
1583 value = *c;
1584 break;
1585 default: flen = 0; value = *c; break;
1586 }
1587 if (value)
1588 zero = 0;
1589
1590 if (!zero) {
1591 //fmt[0] = '%';
1592 if (flen) { //Build %04X / %06X / %02X
1593 fmt[1] = '0';
1594 fmt[2] = flen+'0';
1595 fmt[3] = 'X';
1596 fmt[4] = 0;
1597 }
1598 else {
1599 fmt[1] = 'c';
1600 fmt[2] = 0;
1601 }
1602 if (flen == CS_ECMSTORESIZE) s += snprintf(result+s, size-s ,"%s", ecmd5hex);
1603 else if (flen == 5) s += snprintf(result+s, size-s ,"%s", csphash);
1604 else if (flen == 17) s += snprintf(result+s, size-s ,"%s", cw);
1605 else s += snprintf(result+s, size-s, fmt, value);
1606 }
1607 c++;
1608 }
1609 return s;
1610}
1611
1612int32_t format_ecm(ECM_REQUEST *ecm, char *result, size_t size)
1613{
1614 char ecmd5hex[17 * 3];
1615 char csphash[5 * 3] = { 0 };
1616 char cwhex[17 * 3];
1617 cs_hexdump(0, ecm->ecmd5, 16, ecmd5hex, sizeof(ecmd5hex));
1618#ifdef CS_CACHEEX
1619 cs_hexdump(0, (void *)&ecm->csp_hash, 4, csphash, sizeof(csphash));
1620#endif
1621 cs_hexdump(0, ecm->cw, 16, cwhex, sizeof(cwhex));
1622 return ecmfmt(ecm->caid, ecm->prid, ecm->chid, ecm->pid, ecm->srvid, ecm->ecmlen, ecmd5hex, csphash, cwhex, result, size);
1623}
Note: See TracBrowser for help on using the repository browser.