source: trunk/module-cccam.c@ 8455

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

Make ptab in struct s_module embedded not a pointer.

This blows up bss (static) memory nearly twice but we'll get that
back and lots more once we slim down struct s_port in the next
commit.

  • Property svn:eol-style set to LF
  • Property svn:mime-type set to text/plain
File size: 100.0 KB
Line 
1#include "globals.h"
2
3#ifdef MODULE_CCCAM
4
5#include "cscrypt/md5.h"
6#include "cscrypt/sha1.h"
7#include "module-cacheex.h"
8#include "module-cccam.h"
9#include "module-cccam-data.h"
10#include "module-cccshare.h"
11#include "oscam-chk.h"
12#include "oscam-client.h"
13#include "oscam-ecm.h"
14#include "oscam-emm.h"
15#include "oscam-failban.h"
16#include "oscam-garbage.h"
17#include "oscam-lock.h"
18#include "oscam-net.h"
19#include "oscam-reader.h"
20#include "oscam-string.h"
21#include "oscam-time.h"
22#include "oscam-work.h"
23
24//Mode names for CMD_05 command:
25const char *cmd05_mode_name[] = { "UNKNOWN", "PLAIN", "AES", "CC_CRYPT", "RC4",
26 "LEN=0" };
27
28//Mode names for CMD_0C command:
29const char *cmd0c_mode_name[] = { "NONE", "RC6", "RC4", "CC_CRYPT", "AES", "IDEA" };
30
31uint8_t cc_node_id[8];
32
33int32_t cc_cli_connect(struct s_client *cl);
34int32_t cc_send_pending_emms(struct s_client *cl);
35
36#define getprefix() (!cl?"":(!cl->cc?"":(((struct cc_data *)(cl->cc))->prefix)))
37
38void cc_init_crypt(struct cc_crypt_block *block, uint8_t *key, int32_t len) {
39 int32_t i = 0;
40 uint8_t j = 0;
41
42 for (i = 0; i < 256; i++) {
43 block->keytable[i] = i;
44 }
45
46 for (i = 0; i < 256; i++) {
47 j += key[i % len] + block->keytable[i];
48 SWAPC(&block->keytable[i], &block->keytable[j]);
49 }
50
51 block->state = *key;
52 block->counter = 0;
53 block->sum = 0;
54}
55
56void cc_crypt(struct cc_crypt_block *block, uint8_t *data, int32_t len,
57 cc_crypt_mode_t mode) {
58 int32_t i;
59 uint8_t z;
60
61 for (i = 0; i < len; i++) {
62 block->counter++;
63 block->sum += block->keytable[block->counter];
64 SWAPC(&block->keytable[block->counter], &block->keytable[block->sum]);
65 z = data[i];
66 data[i] = z ^ block->keytable[(block->keytable[block->counter]
67 + block->keytable[block->sum]) & 0xff];
68 data[i] ^= block->state;
69 if (!mode)
70 z = data[i];
71 block->state = block->state ^ z;
72 }
73}
74
75void cc_rc4_crypt(struct cc_crypt_block *block, uint8_t *data, int32_t len,
76 cc_crypt_mode_t mode) {
77 int32_t i;
78 uint8_t z;
79
80 for (i = 0; i < len; i++) {
81 block->counter++;
82 block->sum += block->keytable[block->counter];
83 SWAPC(&block->keytable[block->counter], &block->keytable[block->sum]);
84 z = data[i];
85 data[i] = z ^ block->keytable[(block->keytable[block->counter]
86 + block->keytable[block->sum]) & 0xff];
87 if (!mode)
88 z = data[i];
89 block->state = block->state ^ z;
90 }
91}
92
93void cc_xor(uint8_t *buf) {
94 const char cccam[] = "CCcam";
95 uint8_t i;
96
97 for (i = 0; i < 8; i++) {
98 buf[8 + i] = i * buf[i];
99 if (i <= 5) {
100 buf[i] ^= cccam[i];
101 }
102 }
103}
104
105void cc_cw_crypt(struct s_client *cl, uint8_t *cws, uint32_t cardid) {
106 struct cc_data *cc = cl->cc;
107 int64_t node_id;
108 uint8_t tmp;
109 int32_t i;
110
111 if (cl->typ != 'c') {
112 node_id = b2ll(8, cc->node_id);
113 } else {
114 node_id = b2ll(8, cc->peer_node_id);
115 }
116
117 for (i = 0; i < 16; i++) {
118 tmp = cws[i] ^ (node_id >> (4 * i));
119 if (i & 1)
120 tmp = ~tmp;
121 cws[i] = (cardid >> (2 * i)) ^ tmp;
122 }
123}
124
125/** swap endianness (int) */
126static void SwapLBi(unsigned char *buff, int32_t len)
127{
128#if __BYTE_ORDER != __BIG_ENDIAN
129 return;
130#endif
131
132 int32_t i;
133 unsigned char swap[4];
134 for (i = 0; i < len / 4; i++) {
135 memcpy(swap, buff, 4);
136 buff[0] = swap[3];
137 buff[1] = swap[2];
138 buff[2] = swap[1];
139 buff[3] = swap[0];
140 buff += 4;
141 }
142}
143
144void cc_crypt_cmd0c(struct s_client *cl, uint8_t *buf, int32_t len) {
145 struct cc_data *cc = cl->cc;
146 uint8_t *out;
147 if (!cs_malloc(&out, len))
148 return;
149
150 switch (cc->cmd0c_mode) {
151 case MODE_CMD_0x0C_NONE: { // none additional encryption
152 memcpy(out, buf, len);
153 break;
154 }
155 case MODE_CMD_0x0C_RC6 : { //RC6
156 int32_t i;
157 SwapLBi(buf, len);
158 for (i = 0; i < len / 16; i++)
159 rc6_block_decrypt((uint32_t*)(buf+i*16), (uint32_t*)(out+i*16), 1, cc->cmd0c_RC6_cryptkey);
160 SwapLBi(out, len);
161 break;
162 }
163 case MODE_CMD_0x0C_RC4: { // RC4
164 cc_rc4_crypt(&cc->cmd0c_cryptkey, buf, len, ENCRYPT);
165 memcpy(out, buf, len);
166 break;
167 }
168 case MODE_CMD_0x0C_CC_CRYPT: { // cc_crypt
169 cc_crypt(&cc->cmd0c_cryptkey, buf, len, DECRYPT);
170 memcpy(out, buf, len);
171 break;
172 }
173 case MODE_CMD_0x0C_AES: { // AES
174 int32_t i;
175 for (i = 0; i<len / 16; i++)
176 AES_decrypt((unsigned char *) buf + i * 16,
177 (unsigned char *) out + i * 16, &cc->cmd0c_AES_key);
178 break;
179 }
180 case MODE_CMD_0x0C_IDEA : { //IDEA
181 int32_t i=0;
182 int32_t j;
183
184 while (i < len) {
185 idea_ecb_encrypt(buf + i, out + i, &cc->cmd0c_IDEA_dkey);
186 i += 8;
187 }
188
189 i = 8;
190 while (i < len) {
191 for (j=0; j < 8; j++)
192 out[j+i] ^= buf[j+i-8];
193 i += 8;
194 }
195
196 break;
197 }
198 }
199 memcpy(buf, out, len);
200 free(out);
201}
202
203
204
205void set_cmd0c_cryptkey(struct s_client *cl, uint8_t *key, uint8_t len) {
206 struct cc_data *cc = cl->cc;
207 uint8_t key_buf[32];
208
209 memset(&key_buf, 0, sizeof(key_buf));
210
211 if (len > 32)
212 len = 32;
213
214 memcpy(key_buf, key, len);
215
216 switch (cc->cmd0c_mode) {
217
218 case MODE_CMD_0x0C_NONE : { //NONE
219 break;
220 }
221
222 case MODE_CMD_0x0C_RC6 : { //RC6
223 rc6_key_setup(key_buf, 32, cc->cmd0c_RC6_cryptkey);
224 break;
225 }
226
227 case MODE_CMD_0x0C_RC4: //RC4
228 case MODE_CMD_0x0C_CC_CRYPT: { //CC_CRYPT
229 cc_init_crypt(&cc->cmd0c_cryptkey, key_buf, 32);
230 break;
231 }
232
233 case MODE_CMD_0x0C_AES: { //AES
234 memset(&cc->cmd0c_AES_key, 0, sizeof(cc->cmd0c_AES_key));
235 AES_set_decrypt_key((unsigned char *) key_buf, 256, &cc->cmd0c_AES_key);
236 break;
237 }
238
239 case MODE_CMD_0x0C_IDEA : { //IDEA
240 uint8_t key_buf_idea[16];
241 memcpy(key_buf_idea, key_buf, 16);
242 IDEA_KEY_SCHEDULE ekey;
243
244 idea_set_encrypt_key(key_buf_idea, &ekey);
245 idea_set_decrypt_key(&ekey,&cc->cmd0c_IDEA_dkey);
246 break;
247 }
248 }
249}
250
251int32_t sid_eq(struct cc_srvid *srvid1, struct cc_srvid *srvid2) {
252 return (srvid1->sid == srvid2->sid && (srvid1->chid == srvid2->chid || !srvid1->chid || !srvid2->chid) && (srvid1->ecmlen == srvid2->ecmlen || !srvid1->ecmlen || !srvid2->ecmlen));
253}
254
255struct cc_srvid * is_sid_blocked(struct cc_card *card, struct cc_srvid *srvid_blocked) {
256 LL_ITER it = ll_iter_create(card->badsids);
257 struct cc_srvid *srvid;
258 while ((srvid = ll_iter_next(&it))) {
259 if (sid_eq(srvid, srvid_blocked)) {
260 break;
261 }
262 }
263 return srvid;
264}
265
266struct cc_srvid * is_good_sid(struct cc_card *card, struct cc_srvid *srvid_good) {
267 LL_ITER it = ll_iter_create(card->goodsids);
268 struct cc_srvid *srvid;
269 while ((srvid = ll_iter_next(&it))) {
270 if (sid_eq(srvid, srvid_good)) {
271 break;
272 }
273 }
274 return srvid;
275}
276
277#define BLOCKING_SECONDS 60
278
279void add_sid_block(struct s_client *cl __attribute__((unused)), struct cc_card *card,
280 struct cc_srvid *srvid_blocked) {
281 if (is_sid_blocked(card, srvid_blocked))
282 return;
283
284 struct cc_srvid_block *srvid;
285 if (!cs_malloc(&srvid, sizeof(struct cc_srvid_block)))
286 return;
287 memcpy(srvid, srvid_blocked, sizeof(struct cc_srvid));
288 srvid->blocked_till = time(NULL)+BLOCKING_SECONDS;
289 ll_append(card->badsids, srvid);
290 cs_debug_mask(D_READER, "%s added sid block %04X(CHID %04X, length %d) for card %08x",
291 getprefix(), srvid_blocked->sid, srvid_blocked->chid, srvid_blocked->ecmlen,
292 card->id);
293}
294
295void remove_sid_block(struct cc_card *card, struct cc_srvid *srvid_blocked) {
296 LL_ITER it = ll_iter_create(card->badsids);
297 struct cc_srvid *srvid;
298 while ((srvid = ll_iter_next(&it)))
299 if (sid_eq(srvid, srvid_blocked))
300 ll_iter_remove_data(&it);
301}
302
303void remove_good_sid(struct cc_card *card, struct cc_srvid *srvid_good) {
304 LL_ITER it = ll_iter_create(card->goodsids);
305 struct cc_srvid *srvid;
306 while ((srvid = ll_iter_next(&it)))
307 if (sid_eq(srvid, srvid_good))
308 ll_iter_remove_data(&it);
309}
310
311void add_good_sid(struct s_client *cl __attribute__((unused)), struct cc_card *card,
312 struct cc_srvid *srvid_good) {
313 if (is_good_sid(card, srvid_good))
314 return;
315
316 remove_sid_block(card, srvid_good);
317 struct cc_srvid *srvid;
318 if (!cs_malloc(&srvid, sizeof(struct cc_srvid)))
319 return;
320 memcpy(srvid, srvid_good, sizeof(struct cc_srvid));
321 ll_append(card->goodsids, srvid);
322 cs_debug_mask(D_READER, "%s added good sid %04X(%d) for card %08x",
323 getprefix(), srvid_good->sid, srvid_good->ecmlen, card->id);
324}
325
326/**
327 * reader
328 * clears and frees values for reinit
329 */
330void cc_cli_close(struct s_client *cl, int32_t call_conclose) {
331 struct s_reader *rdr = cl->reader;
332 struct cc_data *cc = cl->cc;
333 if (!rdr || !cc)
334 return;
335
336 if(rdr) rdr->tcp_connected = 0;
337 if(rdr) rdr->card_status = NO_CARD;
338 if(rdr) rdr->last_s = rdr->last_g = 0;
339 if(cl) cl->last = 0;
340
341 if (call_conclose) //clears also pending ecms!
342 network_tcp_connection_close(rdr, "close");
343 else
344 {
345 if (cl->udp_fd) {
346 close(cl->udp_fd);
347 cl->udp_fd = 0;
348 cl->pfd = 0;
349 }
350 }
351
352 cc->ecm_busy = 0;
353 cc->just_logged_in = 0;
354}
355
356struct cc_extended_ecm_idx *add_extended_ecm_idx(struct s_client *cl,
357 uint8_t send_idx, uint16_t ecm_idx, struct cc_card *card,
358 struct cc_srvid srvid, int8_t free_card) {
359 struct cc_data *cc = cl->cc;
360 struct cc_extended_ecm_idx *eei;
361 if (!cs_malloc(&eei, sizeof(struct cc_extended_ecm_idx)))
362 return NULL;
363 eei->send_idx = send_idx;
364 eei->ecm_idx = ecm_idx;
365 eei->card = card;
366 eei->cccam_id = card->id;
367 eei->srvid = srvid;
368 eei->free_card = free_card;
369 cs_ftime(&eei->tps);
370 ll_append(cc->extended_ecm_idx, eei);
371 //cs_debug_mask(D_TRACE, "%s add extended ecm-idx: %d:%d", getprefix(), send_idx, ecm_idx);
372 return eei;
373}
374
375struct cc_extended_ecm_idx *get_extended_ecm_idx(struct s_client *cl,
376 uint8_t send_idx, int32_t remove_item) {
377 struct cc_data *cc = cl->cc;
378 struct cc_extended_ecm_idx *eei;
379 LL_ITER it = ll_iter_create(cc->extended_ecm_idx);
380 while ((eei = ll_iter_next(&it))) {
381 if (eei->send_idx == send_idx) {
382 if (remove_item)
383 ll_iter_remove(&it);
384 //cs_debug_mask(D_TRACE, "%s get by send-idx: %d FOUND: %d",
385 // getprefix(), send_idx, eei->ecm_idx);
386 return eei;
387 }
388 }
389#ifdef WITH_DEBUG
390 if (remove_item)
391 cs_debug_mask(cl->typ=='c'?D_CLIENT:D_READER, "%s get by send-idx: %d NOT FOUND", getprefix(),
392 send_idx);
393#endif
394 return NULL;
395}
396
397struct cc_extended_ecm_idx *get_extended_ecm_idx_by_idx(struct s_client *cl,
398 uint16_t ecm_idx, int32_t remove_item) {
399 struct cc_data *cc = cl->cc;
400 struct cc_extended_ecm_idx *eei;
401 LL_ITER it = ll_iter_create(cc->extended_ecm_idx);
402 while ((eei = ll_iter_next(&it))) {
403 if (eei->ecm_idx == ecm_idx) {
404 if (remove_item)
405 ll_iter_remove(&it);
406 //cs_debug_mask(D_TRACE, "%s get by ecm-idx: %d FOUND: %d",
407 // getprefix(), ecm_idx, eei->send_idx);
408 return eei;
409 }
410 }
411#ifdef WITH_DEBUG
412 if (remove_item)
413 cs_debug_mask(cl->typ=='c'?D_CLIENT:D_READER, "%s get by ecm-idx: %d NOT FOUND", getprefix(),
414 ecm_idx);
415#endif
416 return NULL;
417}
418
419void cc_reset_pending(struct s_client *cl, int32_t ecm_idx) {
420 int32_t i = 0;
421 for (i = 0; i < cfg.max_pending; i++) {
422 if (cl->ecmtask[i].idx == ecm_idx && cl->ecmtask[i].rc == 101)
423 cl->ecmtask[i].rc = 100; //Mark unused
424 }
425}
426
427void free_extended_ecm_idx_by_card(struct s_client *cl, struct cc_card *card, int8_t null_only) {
428 struct cc_data *cc = cl->cc;
429 struct cc_extended_ecm_idx *eei;
430 LL_ITER it = ll_iter_create(cc->extended_ecm_idx);
431 while ((eei = ll_iter_next(&it))) {
432 if (eei->card == card) {
433 if (null_only) {
434 cc_reset_pending(cl, eei->ecm_idx);
435 if (eei->free_card)
436 free(eei->card);
437 ll_iter_remove_data(&it);
438 }
439 else {
440 if (eei->free_card)
441 free(eei->card);
442 eei->card = NULL;
443 }
444 }
445 }
446}
447
448void free_extended_ecm_idx(struct cc_data *cc) {
449 struct cc_extended_ecm_idx *eei;
450 LL_ITER it = ll_iter_create(cc->extended_ecm_idx);
451 while ((eei = ll_iter_next(&it))) {
452 if (eei->free_card)
453 free(eei->card);
454 ll_iter_remove_data(&it);
455 }
456}
457
458int32_t cc_recv_to(struct s_client *cl, uint8_t *buf, int32_t len) {
459 int32_t rc;
460 struct pollfd pfd;
461
462 while (1) {
463 pfd.fd = cl->udp_fd;
464 pfd.events = POLLIN | POLLPRI;
465
466 rc = poll(&pfd, 1, cfg.cc_recv_timeout);
467
468 if (rc < 0) {
469 if (errno==EINTR) continue;
470 return(-1); //error!!
471 }
472
473 if (rc == 1){
474 if(pfd.revents & POLLHUP)
475 return(-1); //hangup = error!!
476 else
477 break;
478 } else
479 return (-2); //timeout!!
480 }
481 return recv(cl->udp_fd, buf, len, MSG_WAITALL);
482}
483
484/**
485 * reader
486 * closes the connection and reopens it.
487 */
488static int8_t cc_cycle_connection(struct s_client *cl)
489{
490 if (!cl || cl->kill)
491 return 0;
492
493 cs_debug_mask(D_TRACE, "%s unlocked-cycleconnection! timeout %dms",
494 getprefix(), cl->reader->cc_reconnect);
495
496 cc_cli_close(cl, 0);
497 cs_sleepms(50);
498 cc_cli_connect(cl);
499
500 return cl->reader->tcp_connected;
501}
502
503/**
504 * reader+server:
505 * receive a message
506 */
507int32_t cc_msg_recv(struct s_client *cl, uint8_t *buf, int32_t maxlen) {
508 struct s_reader *rdr = (cl->typ == 'c') ? NULL : cl->reader;
509
510 int32_t len;
511 struct cc_data *cc = cl->cc;
512
513 int32_t handle = cl->udp_fd;
514
515 if (handle <= 0 || maxlen < 4)
516 return -1;
517
518 if (!cl->cc) return -1;
519 cs_writelock(&cc->lockcmd);
520 if (!cl->cc) {
521 cs_writeunlock(&cc->lockcmd);
522 return -1;
523 }
524
525 len = recv(handle, buf, 4, MSG_WAITALL);
526
527 if (len != 4) { // invalid header length read
528 if (len <= 0)
529 cs_debug_mask(cl->typ=='c'?D_CLIENT:D_READER, "%s disconnected by remote server", getprefix());
530 else
531 cs_debug_mask(cl->typ=='c'?D_CLIENT:D_READER, "%s invalid header length (expected 4, read %d)", getprefix(), len);
532 cs_writeunlock(&cc->lockcmd);
533 return -1;
534 }
535
536 cc_crypt(&cc->block[DECRYPT], buf, 4, DECRYPT);
537 //cs_ddump_mask(D_CLIENT, buf, 4, "cccam: decrypted header:");
538
539 cc->g_flag = buf[0];
540
541 int32_t size = (buf[2] << 8) | buf[3];
542 if (size) { // check if any data is expected in msg
543 if (size > maxlen) {
544 cs_writeunlock(&cc->lockcmd);
545 cs_debug_mask(cl->typ=='c'?D_CLIENT:D_READER, "%s message too big (size=%d max=%d)", getprefix(), size, maxlen);
546 return 0;
547 }
548
549 len = recv(handle, buf + 4, size, MSG_WAITALL);
550 if (rdr && buf[1] == MSG_CW_ECM)
551 rdr->last_g = time(NULL);
552
553 if (len != size) {
554 cs_writeunlock(&cc->lockcmd);
555 if (len <= 0)
556 cs_debug_mask(cl->typ=='c'?D_CLIENT:D_READER, "%s disconnected by remote", getprefix());
557 else
558 cs_debug_mask(cl->typ=='c'?D_CLIENT:D_READER, "%s invalid message length read (expected %d, read %d)",
559 getprefix(), size, len);
560 return -1;
561 }
562
563 cc_crypt(&cc->block[DECRYPT], buf + 4, len, DECRYPT);
564 len += 4;
565 }
566
567 cs_writeunlock(&cc->lockcmd);
568
569 //cs_ddump_mask(cl->typ=='c'?D_CLIENT:D_READER, buf, len, "cccam: full decrypted msg, len=%d:", len);
570
571 return len;
572}
573
574/**
575 * reader+server
576 * send a message
577 */
578int32_t cc_cmd_send(struct s_client *cl, uint8_t *buf, int32_t len, cc_msg_type_t cmd) {
579 if (!cl->udp_fd) //disconnected
580 return -1;
581
582 struct s_reader *rdr = (cl->typ == 'c') ? NULL : cl->reader;
583
584 int32_t n;
585 struct cc_data *cc = cl->cc;
586
587 if (!cl->cc || cl->kill) return -1;
588 cs_writelock(&cc->lockcmd);
589 if (!cl->cc || cl->kill) {
590 cs_writeunlock(&cc->lockcmd);
591 return -1;
592 }
593
594 uint8_t *netbuf;
595 if (!cs_malloc(&netbuf, len + 4))
596 return -1;
597
598 if (cmd == MSG_NO_HEADER) {
599 memcpy(netbuf, buf, len);
600 } else {
601 // build command message
602 netbuf[0] = cc->g_flag; // flags??
603 netbuf[1] = cmd & 0xff;
604 netbuf[2] = len >> 8;
605 netbuf[3] = len & 0xff;
606 if (buf)
607 memcpy(netbuf + 4, buf, len);
608 len += 4;
609 }
610
611 //cs_ddump_mask(D_CLIENT, netbuf, len, "cccam: send:");
612 cc_crypt(&cc->block[ENCRYPT], netbuf, len, ENCRYPT);
613
614 n = send(cl->udp_fd, netbuf, len, 0);
615 if(rdr) rdr->last_s = time(NULL);
616 if(cl) cl->last = time(NULL);
617
618 cs_writeunlock(&cc->lockcmd);
619
620 free(netbuf);
621
622 if (n != len) {
623 if (rdr)
624 cc_cli_close(cl, 1);
625 else {
626 cs_writeunlock(&cc->cards_busy);
627 cs_disconnect_client(cl);
628 }
629 n = -1;
630 }
631
632 return n;
633}
634
635#define CC_DEFAULT_VERSION 1
636#define CC_VERSIONS 8
637char *version[CC_VERSIONS] = { "2.0.11", "2.1.1", "2.1.2", "2.1.3", "2.1.4", "2.2.0", "2.2.1", "2.3.0"};
638char *build[CC_VERSIONS] = { "2892", "2971", "3094", "3165", "3191", "3290", "3316", "3367"};
639char extcompat[CC_VERSIONS] = { 0, 0, 0, 0, 0, 1, 1, 1}; //Supporting new card format starting with 2.2.0
640
641/**
642 * reader+server
643 * checks the cccam-version in the configuration
644 */
645void cc_check_version(char *cc_version, char *cc_build) {
646 int32_t i;
647 for (i = 0; i < CC_VERSIONS; i++) {
648 if (!memcmp(cc_version, version[i], strlen(version[i]))) {
649 memcpy(cc_build, build[i], strlen(build[i]) + 1);
650 cs_debug_mask(D_CLIENT, "cccam: auto build set for version: %s build: %s",
651 cc_version, cc_build);
652 return;
653 }
654 }
655 memcpy(cc_version, version[CC_DEFAULT_VERSION], strlen(
656 version[CC_DEFAULT_VERSION]));
657 memcpy(cc_build, build[CC_DEFAULT_VERSION], strlen(
658 build[CC_DEFAULT_VERSION]));
659
660 cs_debug_mask(D_CLIENT, "cccam: auto version set: %s build: %s", cc_version, cc_build);
661
662 return;
663}
664
665int32_t check_cccam_compat(struct cc_data *cc) {
666 int32_t res = 0;
667 int32_t i = 0;
668 for (i = 0; i < CC_VERSIONS; i++) {
669 if (!strcmp(cfg.cc_version, version[i])) {
670 res += extcompat[i];
671 break;
672 }
673 }
674 if (!res)
675 return 0;
676
677 for (i = 0; i < CC_VERSIONS; i++) {
678 if (!strcmp(cc->remote_version, version[i])) {
679 res += extcompat[i];
680 break;
681 }
682 }
683 return res == 2;
684}
685
686
687/**
688 * reader
689 * sends own version information to the CCCam server
690 */
691int32_t cc_send_cli_data(struct s_client *cl) {
692 struct s_reader *rdr = cl->reader;
693 struct cc_data *cc = cl->cc;
694 const int32_t size = 20 + 8 + 6 + 26 + 4 + 28 + 1;
695 uint8_t buf[size];
696
697 cs_debug_mask(D_READER, "cccam: send client data");
698
699 memcpy(cc->node_id, cc_node_id, sizeof(cc_node_id));
700
701 memcpy(buf, rdr->r_usr, sizeof(rdr->r_usr));
702 memcpy(buf + 20, cc->node_id, 8);
703 buf[28] = rdr->cc_want_emu; // <-- Client want to have EMUs, 0 - NO; 1 - YES
704 memcpy(buf + 29, rdr->cc_version, sizeof(rdr->cc_version)); // cccam version (ascii)
705 memcpy(buf + 61, rdr->cc_build, sizeof(rdr->cc_build)); // build number (ascii)
706
707 cs_debug_mask(D_READER, "%s sending own version: %s, build: %s", getprefix(),
708 rdr->cc_version, rdr->cc_build);
709
710 return cc_cmd_send(cl, buf, size, MSG_CLI_DATA);
711}
712
713/**
714 * server
715 * sends version information to the client
716 */
717int32_t cc_send_srv_data(struct s_client *cl) {
718 struct cc_data *cc = cl->cc;
719
720 cs_debug_mask(D_CLIENT, "cccam: send server data");
721
722 memcpy(cc->node_id, cc_node_id, sizeof(cc_node_id));
723
724 uint8_t buf[0x48];
725 memset(buf, 0, 0x48);
726
727 int32_t stealth = cl->account->cccstealth;
728 if (stealth == -1)
729 stealth = cfg.cc_stealth;
730 if (stealth) cc->node_id[7]++;
731
732 memcpy(buf, cc->node_id, 8);
733
734 char cc_build[7], tmp_dbg[17];
735 memset(cc_build, 0, sizeof(cc_build));
736 cc_check_version((char *) cfg.cc_version, cc_build);
737 memcpy(buf + 8, cfg.cc_version, sizeof(cfg.cc_version)); // cccam version (ascii)
738 memcpy(buf + 40, cc_build, sizeof(cc_build)); // build number (ascii)
739
740 cs_debug_mask(D_CLIENT, "%s version: %s, build: %s nodeid: %s", getprefix(),
741 cfg.cc_version, cc_build, cs_hexdump(0, cc->peer_node_id, 8, tmp_dbg, sizeof(tmp_dbg)));
742
743 return cc_cmd_send(cl, buf, 0x48, MSG_SRV_DATA);
744}
745
746int32_t loop_check(uint8_t *myid, struct s_client *cl) {
747 if (!cl)
748 return 0;
749
750 struct cc_data *cc = cl->cc;
751 if (!cc)
752 return 0;
753
754 return !memcmp(myid, cc->peer_node_id, sizeof(cc->peer_node_id)); // same nodeid? ignore
755}
756
757/**
758 * reader
759 * retrieves the next waiting ecm request
760 */
761int32_t cc_get_nxt_ecm(struct s_client *cl) {
762 struct cc_data *cc = cl->cc;
763 ECM_REQUEST *er, *ern = NULL;
764 int32_t n, i, pending=0;
765 struct timeb t;
766
767 cs_ftime(&t);
768 int32_t diff = (int32_t)cfg.ctimeout+500;
769
770 n = -1;
771 for (i = 0; i < cfg.max_pending; i++) {
772 er = &cl->ecmtask[i];
773 if ((comp_timeb(&t, &er->tps) >= diff) && (er->rc >= 10)) // drop timeouts
774 {
775 er->rc = E_TIMEOUT;
776 write_ecm_answer(cl->reader, er, E_TIMEOUT, 0, NULL, NULL);
777 }
778
779 else if (er->rc >= 10 && er->rc <= 100) { // stil active and waiting
780 pending++;
781 if (loop_check(cc->peer_node_id, er->client)) {
782 cs_debug_mask(D_READER, "%s ecm loop detected! client %s (%8lX)",
783 getprefix(), er->client->account->usr, (unsigned long)er->client->thread);
784 er->rc = E_NOTFOUND;
785 er->rcEx = E2_CCCAM_LOOP;
786 write_ecm_answer(cl->reader, er, E_NOTFOUND, E2_CCCAM_LOOP, NULL, NULL);
787 }
788 else
789 // search for the ecm with the lowest time, this should be the next to go
790 if (n < 0 || (ern->tps.time - er->tps.time < 0)) {
791
792 //check for already pending:
793 if (cc && cc->extended_mode) {
794 int32_t j,found;
795 ECM_REQUEST *erx;
796 for (found = j = 0; j < cfg.max_pending; j++) {
797 erx = &cl->ecmtask[j];
798 if (i!=j && erx->rc == 101 &&
799 er->caid==erx->caid &&
800 er->ecmd5==erx->ecmd5) {
801 found=1;
802 break;
803 }
804 }
805 if (!found) {
806 n = i;
807 ern = er;
808 }
809 }
810 else {
811 n = i;
812 ern = er;
813 }
814 }
815 }
816 }
817 cl->pending=pending;
818 return n;
819}
820
821/**
822 * sends the secret cmd05 answer to the server
823 */
824int32_t send_cmd05_answer(struct s_client *cl) {
825 struct cc_data *cc = cl->cc;
826 if (!cc->cmd05_active || cc->ecm_busy) //exit if not in cmd05 or waiting for ECM answer
827 return 0;
828
829 cc->cmd05_active--;
830 if (cc->cmd05_active)
831 return 0;
832
833 uint8_t *data = cc->cmd05_data;
834 cc_cmd05_mode cmd05_mode = MODE_UNKNOWN;
835
836 // by Project:Keynation
837 switch (cc->cmd05_data_len) {
838 case 0: { //payload 0, return with payload 0!
839 cc_cmd_send(cl, NULL, 0, MSG_CMD_05);
840 cmd05_mode = MODE_LEN0;
841 break;
842 }
843 case 256: {
844 cmd05_mode = cc->cmd05_mode;
845 switch (cmd05_mode) {
846 case MODE_PLAIN: { //Send plain unencrypted back
847 cc_cmd_send(cl, data, 256, MSG_CMD_05);
848 break;
849 }
850 case MODE_AES: { //encrypt with received aes128 key:
851 AES_KEY key;
852 uint8_t aeskey[16];
853 uint8_t out[256];
854
855 memcpy(aeskey, cc->cmd05_aeskey, 16);
856 memset(&key, 0, sizeof(key));
857
858 AES_set_encrypt_key((unsigned char *) &aeskey, 128, &key);
859 int32_t i;
860 for (i = 0; i < 256; i += 16)
861 AES_encrypt((unsigned char *) data + i, (unsigned char *) &out
862 + i, &key);
863
864 cc_cmd_send(cl, out, 256, MSG_CMD_05);
865 break;
866 }
867 case MODE_CC_CRYPT: { //encrypt with cc_crypt:
868 cc_crypt(&cc->cmd05_cryptkey, data, 256, ENCRYPT);
869 cc_cmd_send(cl, data, 256, MSG_CMD_05);
870 break;
871 }
872 case MODE_RC4_CRYPT: {//special xor crypt:
873 cc_rc4_crypt(&cc->cmd05_cryptkey, data, 256, DECRYPT);
874 cc_cmd_send(cl, data, 256, MSG_CMD_05);
875 break;
876 }
877 default:
878 cmd05_mode = MODE_UNKNOWN;
879 }
880 break;
881 }
882 default:
883 cmd05_mode = MODE_UNKNOWN;
884 }
885
886 //unhandled types always needs cycle connection after 50 ECMs!!
887 if (cmd05_mode == MODE_UNKNOWN) {
888 cc_cmd_send(cl, NULL, 0, MSG_CMD_05);
889 if (!cc->max_ecms) { //max_ecms already set?
890 cc->max_ecms = 50;
891 cc->ecm_counter = 0;
892 }
893 }
894 cs_debug_mask(D_READER, "%s sending CMD_05 back! MODE: %s len=%d",
895 getprefix(), cmd05_mode_name[cmd05_mode], cc->cmd05_data_len);
896
897 cc->cmd05NOK = 1;
898 return 1;
899}
900
901int32_t get_UA_ofs(uint16_t caid) {
902 int32_t ofs = 0;
903 switch (caid >> 8) {
904 case 0x05: //VIACCESS:
905 case 0x0D: //CRYPTOWORKS:
906 ofs = 1;
907 break;
908 case 0x4B: //TONGFANG:
909 case 0x09: //VIDEOGUARD:
910 case 0x0B: //CONAX:
911 case 0x18: //NAGRA:
912 case 0x01: //SECA:
913 case 0x00: //SECAMANAGMENT:
914 case 0x17: //BETACRYPT
915 case 0x06: //IRDETO:
916 ofs = 2;
917 break;
918 }
919 if (caid == 0x5581 || caid == 0x4AEE) //BULCRYPT:
920 ofs = 0;
921 return ofs;
922}
923
924int32_t UA_len(uint8_t *ua) {
925 int32_t i, len=0;
926 for (i=0;i<8;i++)
927 if (ua[i]) len++;
928 return len;
929}
930void UA_left(uint8_t *in, uint8_t *out, int32_t ofs) {
931 memset(out, 0, 8);
932 memcpy(out, in+ofs, 8-ofs);
933}
934
935void UA_right(uint8_t *in, uint8_t *out, int32_t len) {
936 int32_t ofs = 0;
937 while (len) {
938 memcpy(out+ofs, in, len);
939 len--;
940 if (out[len]) break;
941 ofs++;
942 out[0]=0;
943 }
944}
945
946/**
947 * cccam uses UA right justified
948 **/
949void cc_UA_oscam2cccam(uint8_t *in, uint8_t *out, uint16_t caid) {
950 uint8_t tmp[8];
951 memset(out, 0, 8);
952 memset(tmp, 0, 8);
953 //switch (caid>>8) {
954 // case 0x17: //IRDETO/Betacrypt:
955 // //oscam: AA BB CC DD 00 00 00 00
956 // //cccam: 00 00 00 00 DD AA BB CC
957 // out[4] = in[3]; //Hexbase
958 // out[5] = in[0];
959 // out[6] = in[1];
960 // out[7] = in[2];
961 // return;
962 //
963 // //Place here your own adjustments!
964 //}
965 hexserial_to_newcamd(in, tmp+2, caid);
966 UA_right(tmp, out, 8);
967}
968
969/**
970 * oscam has a special format, depends on offset or type:
971 **/
972void cc_UA_cccam2oscam(uint8_t *in, uint8_t *out, uint16_t caid) {
973 uint8_t tmp[8];
974 memset(out, 0, 8);
975 memset(tmp, 0, 8);
976 //switch(caid>>8) {
977 // case 0x17: //IRDETO/Betacrypt:
978 // //cccam: 00 00 00 00 DD AA BB CC
979 // //oscam: AA BB CC DD 00 00 00 00
980 // out[0] = in[5];
981 // out[1] = in[6];
982 // out[2] = in[7];
983 // out[3] = in[4]; //Hexbase
984 // return;
985
986 // //Place here your own adjustments!
987 //}
988 int32_t ofs = get_UA_ofs(caid);
989 UA_left(in, tmp, ofs);
990 newcamd_to_hexserial(tmp, out, caid);
991}
992
993void cc_SA_oscam2cccam(uint8_t *in, uint8_t *out) {
994 memcpy(out, in, 4);
995}
996
997void cc_SA_cccam2oscam(uint8_t *in, uint8_t *out) {
998 memcpy(out, in, 4);
999}
1000
1001int32_t cc_UA_valid(uint8_t *ua) {
1002 int32_t i;
1003 for (i = 0; i < 8; i++)
1004 if (ua[i])
1005 return 1;
1006 return 0;
1007}
1008
1009/**
1010 * Updates AU Data: UA (Unique ID / Hexserial) und SA (Shared ID - Provider)
1011 */
1012void set_au_data(struct s_client *cl, struct s_reader *rdr, struct cc_card *card, ECM_REQUEST *cur_er) {
1013 if (rdr->audisabled || !cc_UA_valid(card->hexserial))
1014 return;
1015
1016 struct cc_data *cc = cl->cc;
1017 char tmp_dbg[17];
1018 cc->last_emm_card = card;
1019
1020 cc_UA_cccam2oscam(card->hexserial, rdr->hexserial, rdr->caid);
1021
1022 cs_debug_mask(D_EMM,
1023 "%s au info: caid %04X UA: %s",
1024 getprefix(), card->caid, cs_hexdump(0, rdr->hexserial, 8, tmp_dbg, sizeof(tmp_dbg)));
1025
1026 rdr->nprov = 0;
1027 LL_ITER it2 = ll_iter_create(card->providers);
1028 struct cc_provider *provider;
1029 int32_t p = 0;
1030 while ((provider = ll_iter_next(&it2))) {
1031 if (!cur_er || provider->prov == cur_er->prid || !provider->prov || !cur_er->prid) {
1032 rdr->prid[p][0] = provider->prov >> 24;
1033 rdr->prid[p][1] = provider->prov >> 16;
1034 rdr->prid[p][2] = provider->prov >> 8;
1035 rdr->prid[p][3] = provider->prov & 0xFF;
1036 cc_SA_cccam2oscam(provider->sa, rdr->sa[p]);
1037
1038 cs_debug_mask(D_EMM, "%s au info: provider: %06X:%02X%02X%02X%02X", getprefix(),
1039 provider->prov,
1040 provider->sa[0], provider->sa[1], provider->sa[2], provider->sa[3]);
1041
1042 p++;
1043 rdr->nprov = p;
1044 if (p >= CS_MAXPROV) break;
1045 }
1046 }
1047
1048 if (!rdr->nprov) { //No Providers? Add null-provider:
1049 memset(rdr->prid[0], 0, sizeof(rdr->prid[0]));
1050 rdr->nprov = 1;
1051 }
1052
1053 rdr->caid = card->caid;
1054 if (cur_er)
1055 rdr->auprovid = cur_er->prid;
1056}
1057
1058int32_t same_first_node(struct cc_card *card1, struct cc_card *card2) {
1059 uint8_t * node1 = ll_has_elements(card1->remote_nodes);
1060 uint8_t * node2 = ll_has_elements(card2->remote_nodes);
1061
1062 if (!node1 && !node2) return 1; //both NULL, same!
1063
1064 if (!node1 || !node2) return 0; //one NULL, not same!
1065
1066 return !memcmp(node1, node2, 8); //same?
1067}
1068
1069int32_t same_card2(struct cc_card *card1, struct cc_card *card2, int8_t compare_grp) {
1070 return (card1->caid == card2->caid &&
1071 card1->card_type == card2->card_type &&
1072 card1->sidtab == card2->sidtab &&
1073 (!compare_grp || card1->grp == card2->grp) &&
1074 !memcmp(card1->hexserial, card2->hexserial, sizeof(card1->hexserial)));
1075}
1076
1077int32_t same_card(struct cc_card *card1, struct cc_card *card2) {
1078 return (card1->remote_id == card2->remote_id &&
1079 same_card2(card1, card2, 1) &&
1080 same_first_node(card1, card2));
1081}
1082
1083struct cc_card *get_matching_card(struct s_client *cl, ECM_REQUEST *cur_er, int8_t chk_only)
1084{
1085 struct cc_data *cc = cl->cc;
1086 struct s_reader *rdr = cl->reader;
1087 if (cl->kill || !rdr)
1088 return NULL;
1089
1090 struct cc_srvid cur_srvid;
1091 cur_srvid.sid = cur_er->srvid;
1092 cur_srvid.chid = cur_er->chid;
1093 cur_srvid.ecmlen = cur_er->ecmlen;
1094
1095 int32_t best_rating = MIN_RATING-1, rating;
1096
1097 LL_ITER it = ll_iter_create(cc->cards);
1098 struct cc_card *card = NULL, *ncard, *xcard = NULL;
1099 while ((ncard = ll_iter_next(&it))) {
1100 if ((ncard->caid == cur_er->caid // caid matches
1101 || (rdr->cc_want_emu && (ncard->caid == (cur_er->caid & 0xFF00))))
1102 // or system matches if caid ends with 00
1103 // needed for wantemu
1104#ifdef WITH_LB
1105 ||(chk_only && cfg.lb_mode && cfg.lb_auto_betatunnel && ((cur_er->caid>>8==0x18 && ncard->caid>>8==0x17 && cfg.lb_auto_betatunnel_mode <= 3) || (cur_er->caid>>8==0x17 && ncard->caid>>8==0x18 && cfg.lb_auto_betatunnel_mode >=1))) //accept beta card when beta-tunnel is on
1106#endif
1107 ) {
1108 struct cc_srvid *blocked_sid = is_sid_blocked(ncard, &cur_srvid);
1109 if (blocked_sid && (!chk_only || blocked_sid->ecmlen == 0))
1110 continue;
1111
1112 if (!(rdr->cc_want_emu) && (ncard->caid>>8==0x18) && (!xcard || ncard->hop < xcard->hop))
1113 xcard = ncard; //remember card (D+ / 1810 fix) if request has no provider, but card has
1114
1115 rating = ncard->rating - ncard->hop * HOP_RATING;
1116 if (rating < MIN_RATING)
1117 rating = MIN_RATING;
1118 else if (rating > MAX_RATING)
1119 rating = MAX_RATING;
1120
1121 if (!ll_count(ncard->providers)) { //card has no providers:
1122 if (rating > best_rating) {
1123 // ncard is closer
1124 card = ncard;
1125 best_rating = rating; // ncard has been matched
1126 }
1127
1128 }
1129 else { //card has providers
1130 LL_ITER it2 = ll_iter_create(ncard->providers);
1131 struct cc_provider *provider;
1132 while ((provider = ll_iter_next(&it2))) {
1133 if (!cur_er->prid || (provider->prov == cur_er->prid)) { // provid matches
1134 if (rating > best_rating) {
1135 // ncard is closer
1136 card = ncard;
1137 best_rating = rating; // ncard has been matched
1138 }
1139 }
1140 }
1141 }
1142 }
1143 }
1144 if (!card)
1145 card = xcard; //18xx: if request has no provider and we have no card, we try this card
1146
1147 return card;
1148}
1149
1150//reopen all blocked sids for this srvid:
1151static void reopen_sids(struct cc_data *cc, int8_t ignore_time, ECM_REQUEST *cur_er, struct cc_srvid *cur_srvid)
1152{
1153 time_t utime = time(NULL);
1154 struct cc_card *card;
1155 LL_ITER it = ll_iter_create(cc->cards);
1156 while ((card = ll_iter_next(&it))) {
1157 if (card->caid == cur_er->caid) { // caid matches
1158 LL_ITER it2 = ll_iter_create(card->badsids);
1159 struct cc_srvid_block *srvid;
1160 while ((srvid = ll_iter_next(&it2)))
1161 if (srvid->ecmlen > 0 && sid_eq((struct cc_srvid*)srvid, cur_srvid)) { //ecmlen==0: From remote peer, so do not remove
1162 if (ignore_time || srvid->blocked_till <= utime)
1163 ll_iter_remove_data(&it2);
1164 }
1165 }
1166 }
1167
1168}
1169
1170static int8_t cc_request_timeout(struct s_client *cl)
1171{
1172 struct s_reader *rdr = cl->reader;
1173 struct cc_data *cc = cl->cc;
1174 struct timeb timeout;
1175 struct timeb cur_time;
1176
1177 if (!cc || !cc->ecm_busy)
1178 return 0;
1179
1180 cs_ftime(&cur_time);
1181
1182 timeout = cc->ecm_time;
1183 int32_t tt = rdr->cc_reconnect;
1184 if (tt<=0)
1185 tt = DEFAULT_CC_RECONNECT;
1186
1187 timeout.time += tt / 1000;
1188 timeout.millitm += tt % 1000;
1189 if (timeout.millitm >= 1000) {
1190 timeout.time++;
1191 timeout.millitm -= 1000;
1192 }
1193
1194 return (comp_timeb(&cur_time, &timeout) >= 0);
1195}
1196
1197/**
1198 * reader
1199 * sends a ecm request to the connected CCCam Server
1200 */
1201int32_t cc_send_ecm(struct s_client *cl, ECM_REQUEST *er, uchar *buf) {
1202 struct s_reader *rdr = cl->reader;
1203
1204 //cs_debug_mask(D_TRACE, "%s cc_send_ecm", getprefix());
1205 if (!rdr->tcp_connected)
1206 cc_cli_connect(cl);
1207
1208 int32_t n;
1209 struct cc_data *cc = cl->cc;
1210 struct cc_card *card = NULL;
1211 LL_ITER it;
1212 ECM_REQUEST *cur_er;
1213 struct timeb cur_time;
1214 cs_ftime(&cur_time);
1215
1216 if (!cc || (cl->pfd < 1) || !rdr->tcp_connected) {
1217 if (er) {
1218 cs_debug_mask(D_READER, "%s server not init! ccinit=%d pfd=%d",
1219 rdr->label, cc ? 1 : 0, cl->pfd);
1220 er->rc = E_NOTFOUND;
1221 er->rcEx = E2_CCCAM_NOCARD;
1222 write_ecm_answer(rdr, er, E_NOTFOUND, E2_CCCAM_NOCARD, NULL, NULL);
1223 }
1224 //cc_cli_close(cl);
1225 return 0;
1226 }
1227
1228 if (rdr->tcp_connected != 2) {
1229 cs_debug_mask(D_READER, "%s Waiting for CARDS", getprefix());
1230 return 0;
1231 }
1232
1233 //No Card? Waiting for shares
1234 if (!ll_has_elements(cc->cards)) {
1235 rdr->fd_error++;
1236 cs_debug_mask(D_READER, "%s NO CARDS!", getprefix());
1237 return 0;
1238 }
1239
1240 cc->just_logged_in = 0;
1241
1242 if (!cc->extended_mode) {
1243 //Without extended mode, only one ecm at a time could be send
1244 //this is a limitation of "O" CCCam
1245 if (cc->ecm_busy>0) { //Unlock by NOK or ECM ACK
1246 cs_debug_mask(D_READER,
1247 "%s ecm trylock: ecm busy, retrying later after msg-receive",
1248 getprefix());
1249
1250 if (!cc_request_timeout(cl))
1251 return 0; //pending send...
1252 if (!cc_cycle_connection(cl))
1253 return 0;
1254 }
1255 cc->ecm_busy = 1;
1256 cs_debug_mask(D_READER, "cccam: ecm trylock: got lock");
1257 }
1258 int32_t processed_ecms = 0;
1259 do {
1260 cc->ecm_time = cur_time;
1261
1262 //Search next ECM to send:
1263 if ((n = cc_get_nxt_ecm(cl)) < 0) {
1264 if (!cc->extended_mode) {
1265 cc->ecm_busy = 0;
1266 }cs_debug_mask(D_READER, "%s no ecm pending!", getprefix());
1267 if (!cc_send_pending_emms(cl))
1268 send_cmd05_answer(cl);
1269 return 0; // no queued ecms
1270 }
1271 cur_er = &cl->ecmtask[n];
1272 cur_er->rc = 101; //mark ECM as already send
1273 cs_debug_mask(D_READER, "cccam: ecm-task %d", cur_er->idx);
1274
1275 //sleepsend support:
1276 static const char *typtext[] = { "ok", "invalid", "sleeping" };
1277
1278 if (cc->sleepsend && cl->stopped) {
1279 if (cur_er->srvid == cl->lastsrvid && cur_er->caid == cl->lastcaid
1280 && cur_er->pid == cl->lastpid) {
1281 cs_log(
1282 "%s is stopped - requested by server (%s)", cl->reader->label, typtext[cl->stopped]);
1283 if (!cc->extended_mode) {
1284 cc->ecm_busy = 0;
1285 }
1286 cur_er->rc = E_STOPPED;
1287 write_ecm_answer(rdr, cur_er, E_STOPPED, 0, NULL, NULL);
1288 return 0;
1289 } else {
1290 cl->stopped = 0;
1291 }
1292 }
1293
1294 cl->lastsrvid = cur_er->srvid;
1295 cl->lastcaid = cur_er->caid;
1296 cl->lastpid = cur_er->pid;
1297 //sleepsend support end
1298
1299 if (buf)
1300 memcpy(buf, cur_er->ecm, cur_er->ecmlen);
1301
1302 struct cc_srvid cur_srvid;
1303 cur_srvid.sid = cur_er->srvid;
1304 cur_srvid.chid = cur_er->chid;
1305 cur_srvid.ecmlen = cur_er->ecmlen;
1306
1307 cs_readlock(&cc->cards_busy);
1308
1309 //forward_origin:
1310 if (cfg.cc_forward_origin_card && cur_er->origin_reader == rdr
1311 && cur_er->origin_card) {
1312 it = ll_iter_create(cc->cards);
1313 struct cc_card *ncard;
1314 while ((ncard = ll_iter_next(&it))) {
1315 if (ncard == cur_er->origin_card) { //Search the origin card
1316 card = ncard; //found it, use it!
1317 break;
1318 }
1319 }
1320 }
1321
1322 if (!card)
1323 card = get_matching_card(cl, cur_er, 0);
1324
1325 if (!card && has_srvid(rdr->client, cur_er)) {
1326 reopen_sids(cc, 1, cur_er, &cur_srvid);
1327 card = get_matching_card(cl, cur_er, 0);
1328 }
1329
1330 if (card) {
1331 uint8_t *ecmbuf;
1332 if (!cs_malloc(&ecmbuf, cur_er->ecmlen + 13))
1333 break;
1334
1335 // build ecm message
1336 ecmbuf[0] = cur_er->caid >> 8;
1337 ecmbuf[1] = cur_er->caid & 0xff;
1338 ecmbuf[2] = cur_er->prid >> 24;
1339 ecmbuf[3] = cur_er->prid >> 16;
1340 ecmbuf[4] = cur_er->prid >> 8;
1341 ecmbuf[5] = cur_er->prid & 0xff;
1342 ecmbuf[6] = card->id >> 24;
1343 ecmbuf[7] = card->id >> 16;
1344 ecmbuf[8] = card->id >> 8;
1345 ecmbuf[9] = card->id & 0xff;
1346 ecmbuf[10] = cur_er->srvid >> 8;
1347 ecmbuf[11] = cur_er->srvid & 0xff;
1348 ecmbuf[12] = cur_er->ecmlen & 0xff;
1349 memcpy(ecmbuf + 13, cur_er->ecm, cur_er->ecmlen);
1350
1351 uint8_t send_idx = 1;
1352 if (cc->extended_mode) {
1353 cc->server_ecm_idx++;
1354 if (cc->server_ecm_idx >= 256)
1355 cc->server_ecm_idx = 1;
1356 cc->g_flag = cc->server_ecm_idx; //Flag is used as index!
1357 send_idx = cc->g_flag;
1358 }
1359
1360 struct cc_extended_ecm_idx *eei = get_extended_ecm_idx(cl, send_idx, 0);
1361 if (eei) {
1362 eei->ecm_idx = cur_er->idx;
1363 eei->card = card;
1364 eei->cccam_id = card->id;
1365 eei->srvid = cur_srvid;
1366 } else {
1367 eei = add_extended_ecm_idx(cl, send_idx, cur_er->idx, card, cur_srvid, 0);
1368 if (!eei) {
1369 cs_readunlock(&cc->cards_busy);
1370 break;
1371 }
1372 }
1373 eei->tps = cur_er->tps;
1374
1375 rdr->currenthops = card->hop;
1376 rdr->card_status = CARD_INSERTED;
1377
1378 cs_debug_mask(
1379 D_READER,
1380 "%s sending ecm for sid %04X(%d) to card %08x, hop %d, ecmtask %d", getprefix(), cur_er->srvid, cur_er->ecmlen, card->id, card->hop, cur_er->idx);
1381 cc_cmd_send(cl, ecmbuf, cur_er->ecmlen + 13, MSG_CW_ECM); // send ecm
1382
1383 free(ecmbuf);
1384
1385 //For EMM
1386 set_au_data(cl, rdr, card, cur_er);
1387 cs_readunlock(&cc->cards_busy);
1388
1389 processed_ecms++;
1390 if (cc->extended_mode)
1391 continue; //process next pending ecm!
1392 return 0;
1393 } else {
1394 //When connecting, it could happen than ecm requests come before all cards are received.
1395 //So if the last Message was a MSG_NEW_CARD, this "card receiving" is not already done
1396 //if this happens, we do not autoblock it and do not set rc status
1397 //So fallback could resolve it
1398 if (cc->last_msg != MSG_NEW_CARD
1399 && cc->last_msg != MSG_NEW_CARD_SIDINFO
1400 && cc->last_msg != MSG_CARD_REMOVED
1401 && !cc->just_logged_in) {
1402 cs_debug_mask(D_READER,
1403 "%s no suitable card on server", getprefix());
1404
1405 cur_er->rc = E_NOTFOUND;
1406 cur_er->rcEx = E2_CCCAM_NOCARD;
1407 write_ecm_answer(rdr, cur_er, E_NOTFOUND, E2_CCCAM_NOCARD, NULL, NULL);
1408 //cur_er->rc = 1;
1409 //cur_er->rcEx = 0;
1410 //cs_sleepms(300);
1411 rdr->last_s = rdr->last_g;
1412
1413 reopen_sids(cc, 0, cur_er, &cur_srvid);
1414 } else {
1415 //We didn't find a card and the last message was MSG_CARD_REMOVED - so we wait for a new card and process die ecm later
1416 cur_er->rc = 102; //mark as waiting
1417 }
1418 }
1419 cs_readunlock(&cc->cards_busy);
1420
1421 //process next pending ecm!
1422 } while (cc->extended_mode || processed_ecms == 0);
1423
1424 //Now mark all waiting as unprocessed:
1425 int8_t i;
1426 for (i = 0; i < cfg.max_pending; i++) {
1427 er = &cl->ecmtask[i];
1428 if (er->rc == 102)
1429 er->rc = 100;
1430 }
1431
1432 if (!cc->extended_mode) {
1433 cc->ecm_busy = 0;
1434 }
1435
1436 return 0;
1437}
1438
1439/*
1440 int32_t cc_abort_user_ecms(){
1441 int32_t n, i;
1442 time_t t;//, tls;
1443 struct cc_data *cc = rdr->cc;
1444
1445 t=time((time_t *)0);
1446 for (i = 1, n = 1; i < cfg.max_pending; i++)
1447 {
1448 if ((t-cl->ecmtask[i].tps.time > ((cfg.ctimeout + 500) / 1000) + 1) &&
1449 (cl->ecmtask[i].rc>=10)) // drop timeouts
1450 {
1451 cl->ecmtask[i].rc=0;
1452 }
1453 int32_t td=abs(1000*(ecmtask[i].tps.time-cc->found->tps.time)+ecmtask[i].tps.millitm-cc->found->tps.millitm);
1454 if (ecmtask[i].rc>=10 && ecmtask[i].cidx==cc->found->cidx && &ecmtask[i]!=cc->found){
1455 cs_log("aborting idx:%d caid:%04x client:%d timedelta:%d",ecmtask[i].idx,ecmtask[i].caid,ecmtask[i].cidx,td);
1456 ecmtask[i].rc=0;
1457 ecmtask[i].rcEx=7;
1458 write_ecm_answer(rdr, fd_c2m, &ecmtask[i]);
1459 }
1460 }
1461 return n;
1462
1463 }
1464 */
1465
1466int32_t cc_send_pending_emms(struct s_client *cl) {
1467 struct cc_data *cc = cl->cc;
1468
1469 LL_ITER it = ll_iter_create(cc->pending_emms);
1470 uint8_t *emmbuf;
1471 int32_t size = 0;
1472 if ((emmbuf = ll_iter_next(&it))) {
1473 if (!cc->extended_mode) {
1474 if (cc->ecm_busy>0) { //Unlock by NOK or ECM ACK
1475 return 0; //send later with cc_send_ecm
1476 }
1477 cc->ecm_busy = 1;
1478 }
1479 //Support for emmsize>256 bytes:
1480 size = (emmbuf[11] | (emmbuf[2]<<8)) + 12;
1481 emmbuf[2] = 0;
1482
1483 cc->just_logged_in = 0;
1484 cs_ftime(&cc->ecm_time);
1485
1486 cs_debug_mask(D_EMM, "%s emm send for card %08X", getprefix(), b2i(4,
1487 emmbuf + 7));
1488
1489 cc_cmd_send(cl, emmbuf, size, MSG_EMM_ACK); // send emm
1490
1491 ll_iter_remove_data(&it);
1492 }
1493
1494 return size;
1495}
1496
1497/**
1498 * READER only:
1499 * find card by hexserial
1500 * */
1501struct cc_card *get_card_by_hexserial(struct s_client *cl, uint8_t *hexserial,
1502 uint16_t caid) {
1503 struct cc_data *cc = cl->cc;
1504 LL_ITER it = ll_iter_create(cc->cards);
1505 struct cc_card *card;
1506 while ((card = ll_iter_next(&it)))
1507 if (card->caid == caid && memcmp(card->hexserial, hexserial, 8) == 0) { //found it!
1508 break;
1509 }
1510 return card;
1511}
1512
1513/**
1514 * EMM Procession
1515 * Copied from http://85.17.209.13:6100/file/8ec3c0c5d257/systems/cardclient/cccam2.c
1516 * ProcessEmm
1517 * */
1518int32_t cc_send_emm(EMM_PACKET *ep) {
1519 struct s_client *cl = cur_client();
1520 struct s_reader *rdr = cl->reader;
1521
1522 if (!rdr->tcp_connected)
1523 cc_cli_connect(cl);
1524
1525 struct cc_data *cc = cl->cc;
1526
1527 if (!cc || (cl->pfd < 1) || !rdr->tcp_connected) {
1528 cs_debug_mask(D_READER, "%s server not init! ccinit=%d pfd=%d", getprefix(), cc ? 1 : 0,
1529 cl->pfd);
1530 return 0;
1531 }
1532 if (rdr->audisabled) {
1533 cs_debug_mask(D_READER, "%s au is disabled", getprefix());
1534 return 0;
1535 }
1536
1537 uint16_t caid = b2i(2, ep->caid);
1538
1539 //Last used card is first card of current_cards:
1540 cs_readlock(&cc->cards_busy);
1541
1542 struct cc_card *emm_card = cc->last_emm_card;
1543
1544 if (!emm_card) {
1545 uint8_t hs[8];
1546 char tmp_dbg[17];
1547 cc_UA_oscam2cccam(ep->hexserial, hs, caid);
1548 cs_debug_mask(D_EMM,
1549 "%s au info: searching card for caid %04X oscam-UA: %s",
1550 getprefix(), b2i(2, ep->caid), cs_hexdump(0, ep->hexserial, 8, tmp_dbg, sizeof(tmp_dbg)));
1551 cs_debug_mask(D_EMM,
1552 "%s au info: searching card for caid %04X cccam-UA: %s",
1553 getprefix(), b2i(2, ep->caid), cs_hexdump(0, hs, 8, tmp_dbg, sizeof(tmp_dbg)));
1554
1555 emm_card = get_card_by_hexserial(cl, hs, caid);
1556 }
1557
1558 if (!emm_card) { //Card for emm not found!
1559 cs_debug_mask(D_EMM, "%s emm for client %8lX not possible, no card found!",
1560 getprefix(), (unsigned long)ep->client->thread);
1561 cs_readunlock(&cc->cards_busy);
1562 return 0;
1563 }
1564
1565 cs_debug_mask(D_EMM,
1566 "%s emm received for client %8lX caid %04X for card %08X",
1567 getprefix(), (unsigned long)ep->client->thread, caid, emm_card->id);
1568
1569 int32_t size = ep->emmlen + 12;
1570 uint8_t *emmbuf;
1571 if (!cs_malloc(&emmbuf, size))
1572 return 0;
1573
1574 // build ecm message
1575 emmbuf[0] = ep->caid[0];
1576 emmbuf[1] = ep->caid[1];
1577 emmbuf[2] = ep->emmlen>>8; //Support for emm len > 256bytes
1578 emmbuf[3] = ep->provid[0];
1579 emmbuf[4] = ep->provid[1];
1580 emmbuf[5] = ep->provid[2];
1581 emmbuf[6] = ep->provid[3];
1582 emmbuf[7] = emm_card->id >> 24;
1583 emmbuf[8] = emm_card->id >> 16;
1584 emmbuf[9] = emm_card->id >> 8;
1585 emmbuf[10] = emm_card->id & 0xff;
1586 emmbuf[11] = ep->emmlen & 0xff;
1587 memcpy(emmbuf + 12, ep->emm, ep->emmlen);
1588
1589 cs_readunlock(&cc->cards_busy);
1590
1591 ll_append(cc->pending_emms, emmbuf);
1592 cc_send_pending_emms(cl);
1593
1594#if defined(WEBIF) || defined(LCDSUPPORT)
1595 rdr->emmwritten[ep->type]++;
1596#endif
1597 return 1;
1598}
1599
1600void cc_free_card(struct cc_card *card) {
1601 if (!card)
1602 return;
1603
1604 ll_destroy_data_NULL(card->providers);
1605 ll_destroy_data_NULL(card->badsids);
1606 ll_destroy_data_NULL(card->goodsids);
1607 ll_destroy_data_NULL(card->remote_nodes);
1608
1609 add_garbage(card);
1610}
1611
1612struct cc_card *cc_get_card_by_id(uint32_t card_id, LLIST *cards) {
1613 if (!cards)
1614 return NULL;
1615 LL_ITER it = ll_iter_create(cards);
1616 struct cc_card *card;
1617 while ((card=ll_iter_next(&it))) {
1618 if (card->id==card_id) {
1619 break;
1620 }
1621 }
1622 return card;
1623}
1624
1625void cc_free_cardlist(LLIST *card_list, int32_t destroy_list) {
1626 if (card_list) {
1627 LL_ITER it = ll_iter_create(card_list);
1628 struct cc_card *card;
1629 while ((card = ll_iter_next_remove(&it))) {
1630 cc_free_card(card);
1631 }
1632 if (destroy_list)
1633 ll_destroy_NULL(card_list);
1634 }
1635}
1636
1637/**
1638 * Clears and free the cc datas
1639 */
1640void cc_free(struct s_client *cl) {
1641 struct cc_data *cc = cl->cc;
1642 if (!cc) return;
1643
1644 cl->cc=NULL;
1645
1646 cs_writelock(&cc->lockcmd);
1647
1648 cs_debug_mask(D_TRACE, "exit cccam1/3");
1649 cc_free_cardlist(cc->cards, 1);
1650 ll_destroy_data_NULL(cc->pending_emms);
1651 free_extended_ecm_idx(cc);
1652 ll_destroy_data_NULL(cc->extended_ecm_idx);
1653
1654 cs_writeunlock(&cc->lockcmd);
1655
1656 cs_debug_mask(D_TRACE, "exit cccam2/3");
1657
1658 add_garbage(cc->prefix);
1659 add_garbage(cc);
1660
1661 cs_debug_mask(D_TRACE, "exit cccam3/3");
1662}
1663
1664int32_t is_null_dcw(uint8_t *dcw) {
1665 int32_t i;
1666 for (i = 0; i < 15; i++)
1667 if (dcw[i])
1668 return 0;
1669 return 1;
1670}
1671
1672/*int32_t is_dcw_corrupted(uchar *dcw)
1673 {
1674 int32_t i;
1675 int32_t c, cs;
1676
1677 for (i=0; i<16; i+=4)
1678 {
1679 c = (dcw[i] + dcw[i+1] + dcw[i+2]) & 0xFF;
1680 cs = dcw[i+3];
1681 if (cs!=c) return (1);
1682 }
1683 return 0;
1684 }
1685*/
1686
1687int32_t check_extended_mode(struct s_client *cl, char *msg) {
1688 //Extended mode: if PARTNER String is ending with [PARAM], extended mode is activated
1689 //For future compatibilty the syntax should be compatible with
1690 //[PARAM1,PARAM2...PARAMn]
1691 //
1692 // EXT: Extended ECM Mode: Multiple ECMs could be send and received
1693 // ECMs are numbered, Flag (byte[0] is the index
1694 //
1695 // SID: Exchange of good sids/bad sids activated (like cccam 2.2.x)
1696 // card exchange command MSG_NEW_CARD_SIDINFO instead MSG_NEW_CARD is used
1697 //
1698 // SLP: Sleepsend supported, like camd35
1699 //
1700
1701 struct cc_data *cc = cl->cc;
1702 char *saveptr1 = NULL;
1703 int32_t has_param = 0;
1704 char *p = strtok_r(msg, "[", &saveptr1);
1705 while (p) {
1706 p = strtok_r(NULL, ",]", &saveptr1);
1707 if (p && strncmp(p, "EXT", 3) == 0) {
1708 cc->extended_mode = 1;
1709 cs_debug_mask(D_CLIENT, "%s extended ECM mode", getprefix());
1710 has_param = 1;
1711 }
1712 else if (p && strncmp(p, "SID", 3)==0) {
1713 cc->cccam220 = 1;
1714 cs_debug_mask(D_CLIENT, "%s extra SID mode", getprefix());
1715 has_param = 1;
1716 }
1717 else if (p && strncmp(p, "SLP", 3)==0) {
1718 cc->sleepsend = 1;
1719 cs_debug_mask(D_CLIENT, "%s sleepsend", getprefix());
1720 has_param = 1;
1721 }
1722 }
1723 return has_param;
1724}
1725
1726void cc_idle(void) {
1727 struct s_client *cl = cur_client();
1728 struct s_reader *rdr = cl->reader;
1729 struct cc_data *cc = cl->cc;
1730
1731 if (!cl->udp_fd)
1732 cc_cli_close(cl, 0);
1733
1734 if (rdr && rdr->cc_keepalive && !rdr->tcp_connected) {
1735 cc_cli_connect(cl);
1736 }
1737
1738 if (!rdr || !rdr->tcp_connected || !cl || !cc)
1739 return;
1740
1741 time_t now = time(NULL);
1742 if (rdr->cc_keepalive) {
1743 if (cc->answer_on_keepalive + 55 <= now) {
1744 if (cc_cmd_send(cl, NULL, 0, MSG_KEEPALIVE) > 0) {
1745 cs_debug_mask(D_READER, "cccam: keepalive");
1746 cc->answer_on_keepalive = now;
1747 }
1748 return;
1749 }
1750 }
1751 else
1752 {
1753 //cs_log("last_s - now = %d, last_g - now = %d, tcp_ito=%d", abs(rdr->last_s - now), abs(rdr->last_g - now), rdr->tcp_ito);
1754 //check inactivity timeout:
1755 if ((abs(rdr->last_s - now) > rdr->tcp_ito) && (abs(rdr->last_g -now) > rdr->tcp_ito)) { // inactivity timeout is entered in seconds in webif!
1756 cs_debug_mask(D_READER, "%s inactive_timeout, close connection (fd=%d)", rdr->ph.desc, rdr->client->pfd);
1757 network_tcp_connection_close(rdr, "inactivity");
1758 return;
1759 }
1760
1761 //check read timeout:
1762 int32_t rto = abs(rdr->last_g - now);
1763 //cs_log("last_g - now = %d, rto=%d", rto, rdr->tcp_rto);
1764 if (rto > (rdr->tcp_rto)) { // this is also entered in seconds, actually its an receive timeout!
1765 cs_debug_mask(D_READER, "%s read timeout, close connection (fd=%d)", rdr->ph.desc, rdr->client->pfd);
1766 network_tcp_connection_close(rdr, "rto");
1767 return;
1768 }
1769 }
1770}
1771
1772struct cc_card *read_card(uint8_t *buf, int32_t ext) {
1773 struct cc_card *card;
1774 if (!cs_malloc(&card, sizeof(struct cc_card)))
1775 return NULL;
1776
1777 int32_t nprov, nassign = 0, nreject = 0, offset = 21;
1778
1779 card->providers = ll_create("providers");
1780 card->badsids = ll_create("badsids");
1781 card->goodsids = ll_create("goodsids");
1782 card->remote_nodes = ll_create("remote_nodes");
1783 card->id = b2i(4, buf);
1784 card->remote_id = b2i(4, buf + 4);
1785 card->caid = b2i(2, buf + 8);
1786 card->hop = buf[10];
1787 card->reshare = buf[11];
1788 card->is_ext = ext;
1789 card->card_type = CT_REMOTECARD;
1790 memcpy(card->hexserial, buf + 12, 8); //HEXSERIAL!!
1791
1792 //cs_debug_mask(D_CLIENT, "cccam: card %08x added, caid %04X, hop %d, key %s, count %d",
1793 // card->id, card->caid, card->hop, cs_hexdump(0, card->hexserial, 8, tmp_dbg, sizeof(tmp_dbg)),
1794 // ll_count(cc->cards));
1795
1796 nprov = buf[20];
1797
1798 if (ext) {
1799 nassign = buf[21];
1800 nreject = buf[22];
1801
1802 offset += 2;
1803 }
1804
1805 int32_t i;
1806 for (i = 0; i < nprov; i++) { // providers
1807 struct cc_provider *prov;
1808 if (!cs_malloc(&prov, sizeof(struct cc_provider)))
1809 break;
1810 prov->prov = b2i(3, buf + offset);
1811 if (prov->prov == 0xFFFFFF && (card->caid >> 8) == 0x17)
1812 prov->prov = i;
1813 memcpy(prov->sa, buf + offset + 3, 4);
1814 //cs_debug_mask(D_CLIENT, " prov %d, %06x, sa %08x", i + 1, prov->prov, b2i(4,
1815 // prov->sa));
1816
1817 ll_append(card->providers, prov);
1818 offset+=7;
1819 }
1820
1821 uint8_t *ptr = buf + offset;
1822
1823 if (ext) {
1824 for (i = 0; i < nassign; i++) {
1825 uint16_t sid = b2i(2, ptr);
1826 //cs_debug_mask(D_CLIENT, " assigned sid = %04X, added to good sid list", sid);
1827
1828 struct cc_srvid *srvid;
1829 if (!cs_malloc(&srvid, sizeof(struct cc_srvid)))
1830 break;
1831 srvid->sid = sid;
1832 srvid->chid = 0;
1833 srvid->ecmlen = 0;
1834 ll_append(card->goodsids, srvid);
1835 ptr+=2;
1836 }
1837
1838 for (i = 0; i < nreject; i++) {
1839 uint16_t sid = b2i(2, ptr);
1840 //cs_debug_mask(D_CLIENT, " rejected sid = %04X, added to sid block list", sid);
1841
1842 struct cc_srvid_block *srvid;
1843 if (!cs_malloc(&srvid, sizeof(struct cc_srvid_block)))
1844 break;
1845 srvid->sid = sid;
1846 srvid->chid = 0;
1847 srvid->ecmlen = 0;
1848 srvid->blocked_till = 0;
1849 ll_append(card->badsids, srvid);
1850 ptr+=2;
1851 }
1852 }
1853
1854 int32_t remote_count = ptr[0];
1855 ptr++;
1856 for (i = 0; i < remote_count; i++) {
1857 uint8_t *remote_node;
1858 if (!cs_malloc(&remote_node, 8))
1859 break;
1860 memcpy(remote_node, ptr, 8);
1861 ll_append(card->remote_nodes, remote_node);
1862 ptr+=8;
1863 }
1864 return card;
1865}
1866
1867void cc_card_removed(struct s_client *cl, uint32_t shareid) {
1868 struct cc_data *cc = cl->cc;
1869 struct cc_card *card;
1870 LL_ITER it = ll_iter_create(cc->cards);
1871
1872 while ((card = ll_iter_next(&it))) {
1873 if (card->id == shareid) {// && card->sub_id == b2i (3, buf + 9)) {
1874 //cs_debug_mask(D_CLIENT, "cccam: card %08x removed, caid %04X, count %d",
1875 // card->id, card->caid, ll_count(cc->cards));
1876 ll_iter_remove(&it);
1877 if (cc->last_emm_card == card) {
1878 cc->last_emm_card = NULL;
1879 cs_debug_mask(D_READER, "%s current card %08x removed!",
1880 getprefix(), card->id);
1881 }
1882 free_extended_ecm_idx_by_card(cl, card, 1);
1883 if (card->hop == 1) cc->num_hop1--;
1884 else if (card->hop == 2) cc->num_hop2--;
1885 else cc->num_hopx--;
1886
1887 if (card->reshare == 0) cc->num_reshare0--;
1888 else if (card->reshare == 1) cc->num_reshare1--;
1889 else if (card->reshare == 2) cc->num_reshare2--;
1890 else cc->num_resharex--;
1891
1892 cs_debug_mask(D_TRACE, "%s card removed: id %8X remoteid %8X caid %4X hop %d reshare %d originid %8X cardtype %d",
1893 getprefix(), card->id, card->remote_id, card->caid, card->hop, card->reshare, card->origin_id, card->card_type);
1894
1895 cc_free_card(card);
1896 cc->card_removed_count++;
1897 //break;
1898 }
1899 }
1900}
1901
1902void move_card_to_end(struct s_client * cl, struct cc_card *card_to_move) {
1903
1904 struct cc_data *cc = cl->cc;
1905
1906 LL_ITER it = ll_iter_create(cc->cards);
1907 struct cc_card *card;
1908 while ((card = ll_iter_next(&it))) {
1909 if (card == card_to_move) {
1910 ll_iter_remove(&it);
1911 break;
1912 }
1913 }
1914 if (card) {
1915 cs_debug_mask(D_READER, "%s Moving card %08X to the end...", getprefix(), card_to_move->id);
1916 free_extended_ecm_idx_by_card(cl, card, 0);
1917 ll_append(cc->cards, card_to_move);
1918 }
1919}
1920
1921
1922
1923/*void fix_dcw(uchar *dcw)
1924{
1925 int32_t i;
1926 for (i=0; i<16; i+=4)
1927 {
1928 dcw[i+3] = (dcw[i] + dcw[i+1] + dcw[i+2]) & 0xFF;
1929 }
1930}*/
1931
1932void addParam(char *param, char *value)
1933{
1934 if (strlen(param) < 4)
1935 strcat(param, value);
1936 else {
1937 strcat(param, ",");
1938 strcat(param, value);
1939 }
1940}
1941
1942static void chk_peer_node_for_oscam(struct cc_data *cc)
1943{
1944 if (!cc->is_oscam_cccam) {//Allready discovered oscam-cccam:
1945 uint16_t sum = 0x1234;
1946 uint16_t recv_sum = (cc->peer_node_id[6] << 8)
1947 | cc->peer_node_id[7];
1948 int32_t i;
1949 for (i = 0; i < 6; i++) {
1950 sum += cc->peer_node_id[i];
1951 }
1952 //Create special data to detect oscam-cccam:
1953 cc->is_oscam_cccam = sum == recv_sum;
1954 }
1955}
1956
1957#ifdef CS_CACHEEX
1958
1959int32_t cc_cache_push_chk(struct s_client *cl, struct ecm_request_t *er)
1960{
1961 struct cc_data *cc = cl->cc;
1962 //check max 10 nodes to push:
1963 if (ll_count(er->csp_lastnodes) >= cacheex_maxhop(cl)) {
1964 cs_debug_mask(D_CACHEEX, "cacheex: nodelist reached %d nodes, no push", cacheex_maxhop(cl));
1965 return 0;
1966 }
1967
1968 //search existing peer nodes:
1969 LL_LOCKITER *li = ll_li_create(er->csp_lastnodes, 0);
1970 uint8_t *node;
1971 while ((node = ll_li_next(li))) {
1972 cs_debug_mask(D_CACHEEX, "cacheex: check node %" PRIu64 "X == %" PRIu64 "X ?", cacheex_node_id(node), cacheex_node_id(cc->peer_node_id));
1973 if (memcmp(node, cc->peer_node_id, 8) == 0) {
1974 break;
1975 }
1976 }
1977 ll_li_destroy(li);
1978
1979 //node found, so we got it from there, do not push:
1980 if (node) {
1981 cs_debug_mask(D_CACHEEX,
1982 "cacheex: node %" PRIu64 "X found in list => skip push!", cacheex_node_id(node));
1983 return 0;
1984 }
1985
1986 if (!cl->cc) {
1987 if (cl->reader && !cl->reader->tcp_connected) {
1988 cc_cli_connect(cl);
1989 }
1990 }
1991
1992 if (!cc || !cl->udp_fd){
1993 cs_debug_mask(D_CACHEEX, "cacheex: not connected %s -> no push", username(cl));
1994 return 0;
1995 }
1996 return 1;
1997}
1998
1999int32_t cc_cache_push_out(struct s_client *cl, struct ecm_request_t *er)
2000{
2001 int8_t rc = (er->rc<E_NOTFOUND)?E_FOUND:er->rc;
2002 if (rc != E_FOUND && rc != E_UNHANDLED) return -1; //Maybe later we could support other rcs
2003
2004 if (cl->reader) {
2005 if (!cl->reader->tcp_connected)
2006 cc_cli_connect(cl);
2007 }
2008
2009 struct cc_data *cc = cl->cc;
2010 if (!cc || !cl->udp_fd){
2011 cs_debug_mask(D_CACHEEX, "cacheex: not connected %s -> no push", username(cl));
2012 return(-1);
2013 }
2014
2015 int32_t size = 20 + sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw) + sizeof(uint8_t) +
2016 (ll_count(er->csp_lastnodes)+1)*8; //lastnodes+ownnode
2017
2018 unsigned char *ecmbuf;
2019 if (!cs_malloc(&ecmbuf, size))
2020 return -1;
2021
2022 // build ecm message
2023 //ecmbuf[0] = er->caid >> 8;
2024 //ecmbuf[1] = er->caid & 0xff;
2025 //ecmbuf[2] = er->prid >> 24;
2026 //ecmbuf[3] = er->prid >> 16;
2027 //ecmbuf[4] = er->prid >> 8;
2028 //ecmbuf[5] = er->prid & 0xff;
2029 //ecmbuf[10] = er->srvid >> 8;
2030 //ecmbuf[11] = er->srvid & 0xff;
2031 ecmbuf[12]=(sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) & 0xff;
2032 ecmbuf[13]=(sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) >> 8;
2033 //ecmbuf[12] = 0;
2034 //ecmbuf[13] = 0;
2035 ecmbuf[14] = rc;
2036
2037 i2b_buf(2, er->caid, ecmbuf + 0);
2038 i2b_buf(4, er->prid, ecmbuf + 2);
2039 i2b_buf(2, er->srvid, ecmbuf + 10);
2040
2041 uint8_t *ofs = ecmbuf + 20;
2042
2043 //Write oscam ecmd5 hash:
2044 memcpy(ofs, er->ecmd5, sizeof(er->ecmd5)); //16
2045 ofs += sizeof(er->ecmd5);
2046
2047 //Write CSP hashcode:
2048 memcpy(ofs, &er->csp_hash, sizeof(er->csp_hash)); //4
2049 ofs += sizeof(er->csp_hash);
2050
2051 //Write cw:
2052 memcpy(ofs, er->cw, sizeof(er->cw)); //16
2053 ofs += sizeof(er->cw);
2054
2055 //Write count of lastnodes:
2056 *ofs = ll_count(er->csp_lastnodes)+1;
2057 ofs++;
2058
2059 //Write own node:
2060 memcpy(ofs, cc->node_id, 8);
2061 ofs+=8;
2062
2063 //Write lastnodes:
2064 LL_LOCKITER *li = ll_li_create(er->csp_lastnodes, 0);
2065 uint8_t *node;
2066 while ((node=ll_li_next(li))) {
2067 memcpy(ofs, node, 8);
2068 ofs+=8;
2069 }
2070 ll_li_destroy(li);
2071
2072 int32_t res = cc_cmd_send(cl, ecmbuf, size, MSG_CACHE_PUSH);
2073 if (res > 0){ // cache-ex is pushing out, so no receive but last_g should be updated otherwise disconnect!
2074 if (cl->reader)
2075 cl->reader->last_s = cl->reader->last_g = time((time_t *)0); // correct
2076 if (cl) cl->last = time(NULL);
2077 }
2078 free(ecmbuf);
2079 return res;
2080}
2081
2082void cc_cache_push_in(struct s_client *cl, uchar *buf)
2083{
2084 struct cc_data *cc = cl->cc;
2085 ECM_REQUEST *er;
2086 if (!cc) return;
2087
2088 if (cl->reader)
2089 cl->reader->last_s = cl->reader->last_g = time((time_t *)0);
2090 if (cl) cl->last = time(NULL);
2091
2092 int8_t rc = buf[14];
2093 if (rc != E_FOUND && rc != E_UNHANDLED) //Maybe later we could support other rcs
2094 return;
2095 uint16_t size = buf[12] | (buf[13] << 8);
2096 if (size != sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) {
2097 cs_debug_mask(D_CACHEEX,"%s received wrong cache-push format! data ignored!", username(cl));
2098 return;
2099 }
2100 if (!(er = get_ecmtask()))
2101 return;
2102
2103 er->caid = b2i(2, buf+0);
2104 er->prid = b2i(4, buf+2);
2105 er->srvid = b2i(2, buf+ 10);
2106 er->rc = rc;
2107
2108 er->ecmlen = 0;
2109
2110 uint8_t *ofs = buf+20;
2111
2112 //Read oscam ecmd:
2113 memcpy(er->ecmd5, ofs, sizeof(er->ecmd5));
2114 ofs += sizeof(er->ecmd5);
2115
2116 if (!check_cacheex_filter(cl, er))
2117 return;
2118
2119 //Read CSP hashcode:
2120 memcpy(&er->csp_hash, ofs, sizeof(er->csp_hash));
2121 ofs += sizeof(er->csp_hash);
2122
2123 //Read cw:
2124 memcpy(er->cw, ofs, sizeof(er->cw));
2125 ofs += sizeof(er->cw);
2126
2127 //Read lastnode count:
2128 uint8_t count = *ofs;
2129 ofs++;
2130
2131 //check max nodes:
2132 if (count > cacheex_maxhop(cl)) {
2133 cs_debug_mask(D_CACHEEX, "cacheex: received %d nodes (max=%d), ignored!", (int32_t)count, cacheex_maxhop(cl));
2134 free(er);
2135 return;
2136 }
2137 cs_debug_mask(D_CACHEEX, "cacheex: received %d nodes %s", (int32_t)count, username(cl));
2138 //Read lastnodes:
2139 uint8_t *data;
2140 er->csp_lastnodes = ll_create("csp_lastnodes");
2141 while (count) {
2142 if (!cs_malloc(&data, 8))
2143 break;
2144 memcpy(data, ofs, 8);
2145 ofs+=8;
2146 ll_append(er->csp_lastnodes, data);
2147 count--;
2148 cs_debug_mask(D_CACHEEX, "cacheex: received node %" PRIu64 "X %s", cacheex_node_id(data), username(cl));
2149 }
2150
2151 //for compatibility: add peer node if no node received:
2152 if (!ll_count(er->csp_lastnodes)) {
2153 if (!cs_malloc(&data, 8))
2154 return;
2155 memcpy(data, cc->peer_node_id, 8);
2156 ll_append(er->csp_lastnodes, data);
2157 cs_debug_mask(D_CACHEEX, "cacheex: added missing remote node id %" PRIu64 "X", cacheex_node_id(data));
2158 }
2159
2160 cacheex_add_to_cache(cl, er);
2161}
2162#endif
2163
2164int32_t cc_parse_msg(struct s_client *cl, uint8_t *buf, int32_t l) {
2165 struct s_reader *rdr = (cl->typ == 'c') ? NULL : cl->reader;
2166 int32_t ret = buf[1];
2167 struct cc_data *cc = cl->cc;
2168 char tmp_dbg[33];
2169 if (!cc || cl->kill)
2170 return -1;
2171
2172 cs_debug_mask(cl->typ=='c'?D_CLIENT:D_READER, "%s parse_msg=%d", getprefix(), buf[1]);
2173
2174 uint8_t *data = buf + 4;
2175 memcpy(&cc->receive_buffer, data, l - 4);
2176 cc->last_msg = buf[1];
2177 switch (buf[1]) {
2178 case MSG_CLI_DATA:
2179 cs_debug_mask(D_CLIENT, "cccam: client data ack");
2180 break;
2181 case MSG_SRV_DATA:
2182 l -= 4;
2183 cs_debug_mask(D_READER, "%s MSG_SRV_DATA (payload=%d, hex=%02X)", getprefix(), l, l);
2184 data = cc->receive_buffer;
2185
2186 if (l == 0x48) { //72 bytes: normal server data
2187 cs_writelock(&cc->cards_busy);
2188 cc_free_cardlist(cc->cards, 0);
2189 free_extended_ecm_idx(cc);
2190 cc->last_emm_card = NULL;
2191 cc->num_hop1 = 0;
2192 cc->num_hop2 = 0;
2193 cc->num_hopx = 0;
2194 cc->num_reshare0 = 0;
2195 cc->num_reshare1 = 0;
2196 cc->num_reshare2 = 0;
2197 cc->num_resharex = 0;
2198 cs_writeunlock(&cc->cards_busy);
2199
2200 memcpy(cc->peer_node_id, data, 8);
2201 memcpy(cc->peer_version, data + 8, 8);
2202
2203 memcpy(cc->cmd0b_aeskey, cc->peer_node_id, 8);
2204 memcpy(cc->cmd0b_aeskey + 8, cc->peer_version, 8);
2205
2206 strncpy(cc->remote_version, (char*)data+8, sizeof(cc->remote_version)-1);
2207 strncpy(cc->remote_build, (char*)data+40, sizeof(cc->remote_build)-1);
2208 cc->remote_build_nr = atoi(cc->remote_build);
2209
2210 cs_debug_mask(D_READER, "%s remove server %s running v%s (%s)", getprefix(), cs_hexdump(0,
2211 cc->peer_node_id, 8, tmp_dbg, sizeof(tmp_dbg)), cc->remote_version, cc->remote_build);
2212
2213 chk_peer_node_for_oscam(cc);
2214 //Trick: when discovered partner is an Oscam Client, then we send him our version string:
2215 if (cc->is_oscam_cccam) {
2216 uint8_t token[256];
2217 snprintf((char *)token, sizeof(token),
2218 "PARTNER: OSCam v%s, build r%s (%s) [EXT,SID,SLP]", CS_VERSION,
2219 CS_SVN_VERSION, CS_TARGET);
2220 cc_cmd_send(cl, token, strlen((char *)token) + 1, MSG_CW_NOK1);
2221 }
2222
2223 cc->cmd05_mode = MODE_PLAIN;
2224 //
2225 //Keyoffset is payload-size:
2226 //
2227 } else if (l >= 0x00 && l <= 0x0F) {
2228 cc->cmd05_offset = l;
2229 //
2230 //16..43 bytes: RC4 encryption:
2231 //
2232 } else if ((l >= 0x10 && l <= 0x1f) || (l >= 0x24 && l <= 0x2b)) {
2233 cc_init_crypt(&cc->cmd05_cryptkey, data, l);
2234 cc->cmd05_mode = MODE_RC4_CRYPT;
2235 //
2236 //32 bytes: set AES128 key for CMD_05, Key=16 bytes offset keyoffset
2237 //
2238 } else if (l == 0x20) {
2239 memcpy(cc->cmd05_aeskey, data + cc->cmd05_offset, 16);
2240 cc->cmd05_mode = MODE_AES;
2241 //
2242 //33 bytes: xor-algo mit payload-bytes, offset keyoffset
2243 //
2244 } else if (l == 0x21) {
2245 cc_init_crypt(&cc->cmd05_cryptkey, data + cc->cmd05_offset, l);
2246 cc->cmd05_mode = MODE_CC_CRYPT;
2247 //
2248 //34 bytes: cmd_05 plain back
2249 //
2250 } else if (l == 0x22) {
2251 cc->cmd05_mode = MODE_PLAIN;
2252 //
2253 //35 bytes: Unknown!! 2 256 byte keys exchange
2254 //
2255 } else if (l == 0x23) {
2256 cc->cmd05_mode = MODE_UNKNOWN;
2257 cc_cycle_connection(cl);
2258 //
2259 //44 bytes: set aes128 key, Key=16 bytes [Offset=len(password)]
2260 //
2261 } else if (l == 0x2c) {
2262 memcpy(cc->cmd05_aeskey, data + strlen(rdr->r_pwd), 16);
2263 cc->cmd05_mode = MODE_AES;
2264 //
2265 //45 bytes: set aes128 key, Key=16 bytes [Offset=len(username)]
2266 //
2267 } else if (l == 0x2d) {
2268 memcpy(cc->cmd05_aeskey, data + strlen(rdr->r_usr), 16);
2269 cc->cmd05_mode = MODE_AES;
2270 //
2271 //Unknown!!
2272 //
2273 } else {
2274 cs_debug_mask(D_READER,
2275 "%s received improper MSG_SRV_DATA! No change to current mode, mode=%d",
2276 getprefix(), cc->cmd05_mode);
2277 break;
2278 }
2279 cs_debug_mask(D_READER, "%s MSG_SRV_DATA MODE=%s, len=%d", getprefix(),
2280 cmd05_mode_name[cc->cmd05_mode], l);
2281 break;
2282
2283 case MSG_NEW_CARD_SIDINFO:
2284 case MSG_NEW_CARD: {
2285 uint16_t caid = b2i(2, buf + 12);
2286 //filter caid==0 and maxhop:
2287 if (!caid || buf[14] >= rdr->cc_maxhops + 1)
2288 break;
2289
2290 //filter mindown:
2291 if (buf[15] < rdr->cc_mindown)
2292 break;
2293
2294 //caid check
2295 if (!chk_ctab(caid, &rdr->ctab))
2296 break;
2297
2298 rdr->tcp_connected = 2; //we have card
2299 rdr->card_status = CARD_INSERTED;
2300
2301 cs_writelock(&cc->cards_busy);
2302 struct cc_card *card = read_card(data, buf[1]==MSG_NEW_CARD_SIDINFO);
2303 if (!card)
2304 break;
2305 card->origin_reader = rdr;
2306 card->origin_id = card->id;
2307 card->grp = rdr->grp;
2308 card->rdr_reshare = rdr->cc_reshare > -1 ? rdr->cc_reshare : cfg.cc_reshare;
2309
2310 //Check if this card is from us:
2311 LL_ITER it = ll_iter_create(card->remote_nodes);
2312 uint8_t *node_id;
2313 while ((node_id = ll_iter_next(&it))) {
2314 if (memcmp(node_id, cc_node_id, sizeof(cc_node_id)) == 0) { //this card is from us!
2315 cs_debug_mask(D_READER, "filtered card because of recursive nodeid: id=%08X, caid=%04X", card->id, card->caid);
2316 cc_free_card(card);
2317 card=NULL;
2318 break;
2319 }
2320 }
2321#ifdef MODULE_CCCSHARE
2322 //Check Ident filter:
2323 if (card) {
2324 if (!chk_ident(&rdr->ftab, card)) {
2325 cc_free_card(card);
2326 card=NULL;
2327 }
2328 }
2329#endif
2330 if (card) {
2331 //Check if we already have this card:
2332 it = ll_iter_create(cc->cards);
2333 struct cc_card *old_card;
2334 while ((old_card = ll_iter_next(&it))) {
2335 if (old_card->id == card->id || same_card(old_card, card)) //We already have this card, delete it.
2336 {
2337 cc_free_card(card);
2338 card = old_card;
2339 break;
2340 }
2341 }
2342
2343 if (!old_card) {
2344 card->card_type = CT_REMOTECARD;
2345 ll_append(cc->cards, card);
2346 set_au_data(cl, rdr, card, NULL);
2347 cc->card_added_count++;
2348 card->hop++;
2349 if (card->hop == 1) cc->num_hop1++;
2350 else if (card->hop == 2) cc->num_hop2++;
2351 else cc->num_hopx++;
2352
2353 if (card->reshare == 0) cc->num_reshare0++;
2354 else if (card->reshare == 1) cc->num_reshare1++;
2355 else if (card->reshare == 2) cc->num_reshare2++;
2356 else cc->num_resharex++;
2357
2358 cs_debug_mask(D_TRACE, "%s card added: id %8X remoteid %8X caid %4X hop %d reshare %d originid %8X cardtype %d",
2359 getprefix(), card->id, card->remote_id, card->caid, card->hop, card->reshare, card->origin_id, card->card_type);
2360 }
2361 }
2362
2363 cs_writeunlock(&cc->cards_busy);
2364
2365 break;
2366 }
2367
2368 case MSG_CARD_REMOVED: {
2369 cs_writelock(&cc->cards_busy);
2370 cc_card_removed(cl, b2i(4, buf + 4));
2371 cs_writeunlock(&cc->cards_busy);
2372 break;
2373 }
2374
2375 case MSG_SLEEPSEND:
2376 //Server sends SLEEPSEND:
2377 if (!cfg.c35_suppresscmd08) {
2378 if(buf[4] == 0xFF) {
2379 cl->stopped = 2; // server says sleep
2380 //rdr->card_status = NO_CARD;
2381 } else {
2382#ifdef WITH_LB
2383 if (!cfg.lb_mode) {
2384#endif
2385 cl->stopped = 1; // server says invalid
2386 rdr->card_status = CARD_FAILURE;
2387#ifdef WITH_LB
2388 }
2389#endif
2390 }
2391 }
2392 //NO BREAK!! NOK Handling needed!
2393
2394#ifdef CS_CACHEEX
2395 case MSG_CACHE_PUSH:
2396 {
2397 cc_cache_push_in(cl, data);
2398 break;
2399 }
2400#endif
2401
2402 case MSG_CW_NOK1:
2403 case MSG_CW_NOK2:
2404 if (l > 5) {
2405 //Received NOK with payload:
2406 char *msg = (char*) buf + 4;
2407
2408 //Check for PARTNER connection:
2409 if (strncmp(msg, "PARTNER:", 8) == 0) {
2410 //When Data starts with "PARTNER:" we have an Oscam-cccam-compatible client/server!
2411
2412 strncpy(cc->remote_oscam, msg+9, sizeof(cc->remote_oscam)-1);
2413 int32_t has_param = check_extended_mode(cl, msg);
2414 if (!cc->is_oscam_cccam) {
2415 cc->is_oscam_cccam = 1;
2416
2417 //send params back. At the moment there is only "EXT"
2418 char param[20];
2419 if (!has_param)
2420 param[0] = 0;
2421 else {
2422 cs_strncpy(param, " [", sizeof(param));
2423 if (cc->extended_mode)
2424 addParam(param, "EXT");
2425 if (cc->cccam220)
2426 addParam(param, "SID");
2427 if (cc->sleepsend)
2428 addParam(param, "SLP");
2429 strcat(param, "]");
2430 }
2431
2432 uchar token[256];
2433 snprintf((char *)token, sizeof(token),
2434 "PARTNER: OSCam v%s, build r%s (%s)%s",
2435 CS_VERSION, CS_SVN_VERSION, CS_TARGET, param);
2436 cc_cmd_send(cl, token, strlen((char *)token) + 1, MSG_CW_NOK1);
2437 }
2438 } else {
2439 size_t msg_size = l-4;
2440 char last_char = msg[msg_size-1];
2441 if (last_char == 0) { // verify if the payload is a null terminated string
2442 if (cs_realloc(&cc->nok_message, msg_size))
2443 memcpy(cc->nok_message, msg, msg_size);
2444 } else
2445 NULLFREE(cc->nok_message);
2446 }
2447
2448 return ret;
2449 }
2450
2451 if (cl->typ == 'c')
2452 return ret;
2453
2454 //for reader only
2455
2456 cc->recv_ecmtask = -1;
2457
2458 if (cc->just_logged_in)
2459 return -1; // reader restart needed
2460
2461 cs_readlock(&cc->cards_busy);
2462
2463 struct cc_extended_ecm_idx *eei = get_extended_ecm_idx(cl,
2464 cc->extended_mode ? cc->g_flag : 1, 1);
2465 if (!eei) {
2466 cs_debug_mask(D_READER, "%s received extended ecm NOK id %d but not found!",
2467 getprefix(), cc->g_flag);
2468 }
2469 else
2470 {
2471 uint16_t ecm_idx = eei->ecm_idx;
2472 cc->recv_ecmtask = ecm_idx;
2473 struct cc_card *card = eei->card;
2474// uint32_t cccam_id = eei->cccam_id;
2475 struct cc_srvid srvid = eei->srvid;
2476 int8_t retry = 1;
2477 struct timeb tpe;
2478 cs_ftime(&tpe);
2479 int32_t cwlastresptime = 1000*(tpe.time-eei->tps.time)+tpe.millitm-eei->tps.millitm;
2480
2481 add_garbage(eei);
2482
2483 if (card) {
2484 if (buf[1] == MSG_CW_NOK1){ //MSG_CW_NOK1: share no more available
2485 cs_debug_mask(D_TRACE, "NOK1: share no more available %d %04X ecm %d %d!", card->id, card->caid, eei->send_idx, eei->ecm_idx);
2486 //cc_card_removed(cl, card->id);
2487 move_card_to_end(cl, card);
2488 add_sid_block(cl, card, &srvid);
2489 }
2490 //else MSG_CW_NOK2: can't decode
2491 else if (cc->cmd05NOK)
2492 {
2493 move_card_to_end(cl, card);
2494 if (cwlastresptime < 5000)
2495 add_sid_block(cl, card, &srvid);
2496 else
2497 card->rating--;
2498 }
2499#ifdef CS_CACHEEX
2500 else if (rdr->cacheex.mode!=1) {
2501#else
2502 else {
2503#endif
2504 if (!is_good_sid(card, &srvid))
2505 {
2506 move_card_to_end(cl, card);
2507 if (cwlastresptime < 5000)
2508 add_sid_block(cl, card, &srvid);
2509 else
2510 card->rating--;
2511 } else {
2512 move_card_to_end(cl, card);
2513 remove_good_sid(card, &srvid);
2514 }
2515
2516 if (card->rating < MIN_RATING)
2517 card->rating = MIN_RATING;
2518
2519 if (cfg.cc_forward_origin_card && card->origin_reader == rdr) {
2520 //this card is from us but it can't decode this ecm
2521 //also origin card is only set on cccam clients
2522 //so wie send back the nok to the client
2523 cs_debug_mask(D_TRACE, "%s forward card: %s", getprefix(), (buf[1]==MSG_CW_NOK1)?"NOK1":"NOK2");
2524 retry = 0;
2525 }
2526 }
2527 } else {
2528 cs_debug_mask(D_READER, "%s NOK: NO CARD!", getprefix());
2529 //try next card...
2530 }
2531
2532 //A "NOK" in extended mode means, NOTHING found, regardless of the requested card. So do not retry
2533 if (cc->extended_mode) {
2534 cl->pending--;
2535 retry = 0;
2536 }
2537
2538 if (retry) {
2539 cc_reset_pending(cl, ecm_idx);
2540 }
2541 else {
2542 int32_t i = 0;
2543 for (i = 0; i < cfg.max_pending; i++) {
2544 if (cl->ecmtask[i].idx == ecm_idx) {
2545 cs_debug_mask(D_TRACE,
2546 "%s ext NOK %s", getprefix(), (buf[1]==MSG_CW_NOK1)?"NOK1":"NOK2");
2547 ECM_REQUEST *er = &cl->ecmtask[i];
2548 cl->pending--;
2549 er->rc = E_NOTFOUND;
2550 write_ecm_answer(rdr, er, E_NOTFOUND, 0, NULL, NULL);
2551 break;
2552 }
2553 }
2554 }
2555 }
2556 cc->cmd05NOK = 0;
2557 cs_readunlock(&cc->cards_busy);
2558
2559 if (!cc->extended_mode) {
2560 cc->ecm_busy = 0;
2561 }
2562
2563 cc_send_ecm(cl, NULL, NULL);
2564 break;
2565
2566 case MSG_CW_ECM:
2567 cc->just_logged_in = 0;
2568 if (cl->typ == 'c') { //SERVER:
2569 ECM_REQUEST *er;
2570
2571 struct cc_card *server_card;
2572 if (!cs_malloc(&server_card, sizeof(struct cc_card)))
2573 break;
2574 server_card->id = buf[10] << 24 | buf[11] << 16 | buf[12] << 8
2575 | buf[13];
2576 server_card->caid = b2i(2, data);
2577#define CCMSG_HEADER_LEN 17
2578 if ((er = get_ecmtask()) && l > CCMSG_HEADER_LEN && MAX_ECM_SIZE > l - CCMSG_HEADER_LEN) {
2579 er->caid = b2i(2, buf + 4);
2580 er->prid = b2i(4, buf + 6);
2581 er->srvid = b2i(2, buf + 14);
2582 er->ecmlen = l - CCMSG_HEADER_LEN;
2583 memcpy(er->ecm, buf + CCMSG_HEADER_LEN, er->ecmlen);
2584 cc->server_ecm_pending++;
2585 er->idx = ++cc->server_ecm_idx;
2586
2587#ifdef MODULE_CCCSHARE
2588
2589 if (cfg.cc_forward_origin_card) { //search my shares for this card:
2590 cs_debug_mask(D_TRACE, "%s forward card: %04X:%04x search share %d", getprefix(), er->caid, er->srvid, server_card->id);
2591 LLIST **sharelist = get_and_lock_sharelist();
2592 LL_ITER itr = ll_iter_create(get_cardlist(er->caid, sharelist));
2593 struct cc_card *card;
2594 struct cc_card *rcard = NULL;
2595 while ((card=ll_iter_next(&itr))) {
2596 if (card->id == server_card->id) { //found it
2597 break;
2598 }
2599 }
2600 cs_debug_mask(D_TRACE, "%s forward card: share %d found: %d", getprefix(), server_card->id, card?1:0);
2601
2602 struct s_reader *ordr = NULL;
2603 if (card && card->origin_reader) { // found own card, now search reader card:
2604 //Search reader in list, because it is maybe offline?
2605 for (ordr=first_active_reader; ordr; ordr=ordr->next) {
2606 if (ordr == card->origin_reader) break;
2607 }
2608
2609 if (!ordr)
2610 cs_debug_mask(D_TRACE, "%s origin reader not found!", getprefix());
2611 else {
2612 cs_debug_mask(D_TRACE, "%s forward card: share %d origin reader %s origin id %d", getprefix(), card->id, ordr->label, card->origin_id);
2613 struct s_client *cl2 = ordr->client;
2614 if (card->origin_id && cl2 && cl2->cc) { //only if we have a origin from a cccam reader
2615 struct cc_data *rcc = cl2->cc;
2616
2617 if(rcc){
2618 itr = ll_iter_create(rcc->cards);
2619 while ((rcard=ll_iter_next(&itr))) {
2620 if (rcard->id == card->origin_id) //found it!
2621 break;
2622 }
2623 }
2624 }
2625 else
2626 rcard = card;
2627 }
2628 er->origin_reader = ordr;
2629 }
2630
2631 er->origin_card = rcard;
2632 if (!rcard || !ordr) {
2633 cs_debug_mask(D_TRACE, "%s forward card: share %d not found!", getprefix(), server_card->id);
2634 er->rc = E_NOTFOUND;
2635 er->rcEx = E2_CCCAM_NOK1; //share not found!
2636 }
2637 else
2638 cs_debug_mask(D_TRACE, "%s forward card: share %d forwarded to %s origin as id %d", getprefix(),
2639 card->id, ordr->label, rcard->id);
2640 unlock_sharelist();
2641 }
2642#endif
2643
2644 cs_debug_mask(
2645 D_CLIENT,
2646 "%s ECM request from client: caid %04x srvid %04x(%d) prid %06x",
2647 getprefix(), er->caid, er->srvid, er->ecmlen, er->prid);
2648
2649 struct cc_srvid srvid;
2650 srvid.sid = er->srvid;
2651 srvid.chid = er->chid;
2652 srvid.ecmlen = er->ecmlen;
2653 add_extended_ecm_idx(cl, cc->extended_mode ? cc->g_flag : 1,
2654 er->idx, server_card, srvid, 1);
2655
2656 get_cw(cl, er);
2657
2658 } else {
2659 cs_debug_mask(D_CLIENT, "%s NO ECMTASK!!!! l=%d", getprefix(), l);
2660 free(server_card);
2661 }
2662
2663 } else { //READER:
2664 cs_readlock(&cc->cards_busy);
2665 cc->recv_ecmtask = -1;
2666 eei = get_extended_ecm_idx(cl,
2667 cc->extended_mode ? cc->g_flag : 1, 1);
2668 if (!eei) {
2669 cs_debug_mask(D_READER, "%s received extended ecm id %d but not found!",
2670 getprefix(), cc->g_flag);
2671 if (!cc->extended_mode)
2672 cc_cli_close(cl, 0);
2673 }
2674 else
2675 {
2676 uint16_t ecm_idx = eei->ecm_idx;
2677 cc->recv_ecmtask = ecm_idx;
2678 struct cc_card *card = eei->card;
2679 uint32_t cccam_id = eei->cccam_id;
2680 struct cc_srvid srvid = eei->srvid;
2681 free(eei);
2682
2683 if (card) {
2684
2685 if (!cc->extended_mode) {
2686 cc_cw_crypt(cl, buf + 4, card->id);
2687 cc_crypt_cmd0c(cl, buf + 4, 16);
2688 }
2689
2690 memcpy(cc->dcw, buf + 4, 16);
2691 //fix_dcw(cc->dcw);
2692 if (!cc->extended_mode)
2693 cc_crypt(&cc->block[DECRYPT], buf + 4, l - 4, ENCRYPT); // additional crypto step
2694
2695 if (is_null_dcw(cc->dcw)) {
2696 cs_debug_mask(D_READER, "%s null dcw received! sid=%04X(%d)", getprefix(),
2697 srvid.sid, srvid.ecmlen);
2698 move_card_to_end(cl, card);
2699 add_sid_block(cl, card, &srvid);
2700 //ecm retry:
2701 cc_reset_pending(cl, ecm_idx);
2702 buf[1] = MSG_CW_NOK2; //So it's really handled like a nok!
2703 } else {
2704 cs_debug_mask(D_READER, "%s cws: %d %s", getprefix(),
2705 ecm_idx, cs_hexdump(0, cc->dcw, 16, tmp_dbg, sizeof(tmp_dbg)));
2706 add_good_sid(cl, card, &srvid);
2707
2708 //check response time, if > fallbacktime, switch cards!
2709 struct timeb tpe;
2710 cs_ftime(&tpe);
2711 uint32_t cwlastresptime = 1000*(tpe.time-cc->ecm_time.time)+tpe.millitm-cc->ecm_time.millitm;
2712 if (cwlastresptime > cfg.ftimeout && !cc->extended_mode) {
2713 cs_debug_mask(D_READER, "%s card %04X is too slow, moving to the end...", getprefix(), card->id);
2714 move_card_to_end(cl, card);
2715 card->rating--;
2716 if (card->rating < MIN_RATING)
2717 card->rating = MIN_RATING;
2718 }
2719 else
2720 {
2721 card->rating++;
2722 if (card->rating > MAX_RATING)
2723 card->rating = MAX_RATING;
2724 }
2725 }
2726 } else {
2727 // Card removed...
2728 cs_debug_mask(D_READER,
2729 "%s warning: ECM-CWS respond by CCCam server without current card!",
2730 getprefix());
2731
2732 if (!cc->extended_mode) {
2733 cc_cw_crypt(cl, buf + 4, cccam_id);
2734 cc_crypt_cmd0c(cl, buf + 4, 16);
2735 }
2736 memcpy(cc->dcw, buf + 4, 16);
2737 //fix_dcw(cc->dcw);
2738 if (!cc->extended_mode)
2739 cc_crypt(&cc->block[DECRYPT], buf + 4, l - 4, ENCRYPT); // additional crypto step
2740
2741 cs_debug_mask(D_READER, "%s cws: %d %s", getprefix(),
2742 ecm_idx, cs_hexdump(0, cc->dcw, 16, tmp_dbg, sizeof(tmp_dbg)));
2743 }
2744 }
2745 cs_readunlock(&cc->cards_busy);
2746
2747 if (!cc->extended_mode) {
2748 cc->ecm_busy = 0;
2749 }
2750
2751 //cc_abort_user_ecms();
2752
2753 cc_send_ecm(cl, NULL, NULL);
2754
2755 if (cc->max_ecms)
2756 cc->ecm_counter++;
2757 }
2758 break;
2759
2760 case MSG_KEEPALIVE:
2761 cl->last = time(NULL);
2762 if (rdr){
2763 rdr->last_g = time(NULL);
2764 rdr->last_s = time(NULL);
2765 }
2766 if (cl->typ != 'c') {
2767 cs_debug_mask(D_READER, "cccam: keepalive ack");
2768 } else {
2769 //Checking if last answer is one minute ago:
2770 if (cc->just_logged_in || cc->answer_on_keepalive + 55 <= time(NULL)) {
2771 cc_cmd_send(cl, NULL, 0, MSG_KEEPALIVE);
2772 cs_debug_mask(D_CLIENT, "cccam: keepalive");
2773 cc->answer_on_keepalive = time(NULL);
2774 }
2775 }
2776 cc->just_logged_in = 0;
2777 break;
2778
2779 case MSG_CMD_05:
2780 if (cl->typ != 'c') {
2781 cc->just_logged_in = 0;
2782 l = l - 4;//Header Length=4 Byte
2783
2784 cs_debug_mask(D_READER, "%s MSG_CMD_05 recvd, payload length=%d mode=%d",
2785 getprefix(), l, cc->cmd05_mode);
2786 cc->cmd05_active = 1;
2787 cc->cmd05_data_len = l;
2788 memcpy(&cc->cmd05_data, buf + 4, l);
2789 if (!cc->ecm_busy && ll_has_elements(cc->cards))
2790 send_cmd05_answer(cl);
2791 }
2792 break;
2793 case MSG_CMD_0B: {
2794 // by Project:Keynation
2795 cs_debug_mask(D_READER, "%s MSG_CMD_0B received (payload=%d)!",
2796 getprefix(), l - 4);
2797
2798 AES_KEY key;
2799 uint8_t aeskey[16];
2800 uint8_t out[16];
2801
2802 memcpy(aeskey, cc->cmd0b_aeskey, 16);
2803 memset(&key, 0, sizeof(key));
2804
2805 //cs_ddump_mask(D_READER, aeskey, 16, "%s CMD_0B AES key:", getprefix());
2806 //cs_ddump_mask(D_READER, data, 16, "%s CMD_0B received data:", getprefix());
2807
2808 AES_set_encrypt_key((unsigned char *) &aeskey, 128, &key);
2809 AES_encrypt((unsigned char *) data, (unsigned char *) &out, &key);
2810
2811 cs_debug_mask(D_TRACE, "%s sending CMD_0B! ", getprefix());
2812 //cs_ddump_mask(D_READER, out, 16, "%s CMD_0B out:", getprefix());
2813 cc_cmd_send(cl, out, 16, MSG_CMD_0B);
2814
2815 break;
2816 }
2817
2818 case MSG_CMD_0C: { //New CCCAM 2.2.0 Server/Client fake check!
2819 int32_t len = l-4;
2820
2821 if (cl->typ == 'c') { //Only im comming from "client"
2822 cs_debug_mask(D_CLIENT, "%s MSG_CMD_0C received (payload=%d)!", getprefix(), len);
2823
2824 uint8_t bytes[0x20];
2825 if (len < 0x20) //if less then 0x20 bytes, clear others:
2826 memset(data+len, 0, 0x20-len);
2827
2828 //change first 0x10 bytes to the second:
2829 memcpy(bytes, data+0x10, 0x10);
2830 memcpy(bytes+0x10, data, 0x10);
2831
2832 //xor data:
2833 int32_t i;
2834 for (i=0;i<0x20;i++)
2835 bytes[i] ^= (data[i] & 0x7F);
2836
2837 //key is now the 16bit hash of md5:
2838 uint8_t md5hash[0x10];
2839 MD5(data, 0x20, md5hash);
2840 memcpy(bytes, md5hash, 0x10);
2841
2842 cs_debug_mask(D_CLIENT, "%s sending CMD_0C! ", getprefix());
2843 //cs_ddump_mask(D_CLIENT, bytes, 0x20, "%s CMD_0C out:", getprefix());
2844 cc_cmd_send(cl, bytes, 0x20, MSG_CMD_0C);
2845 }
2846 else //reader
2847 {
2848 // by Project:Keynation + Oscam team
2849 cc_crypt_cmd0c(cl, data, len);
2850
2851 uint8_t CMD_0x0C_Command = data[0];
2852
2853 switch (CMD_0x0C_Command) {
2854
2855 case 0 : { //RC6
2856 cc->cmd0c_mode = MODE_CMD_0x0C_RC6;
2857 break;
2858 }
2859
2860 case 1: { //RC4
2861 cc->cmd0c_mode = MODE_CMD_0x0C_RC4;
2862 break;
2863 }
2864
2865 case 2: { //CC_CRYPT
2866 cc->cmd0c_mode = MODE_CMD_0x0C_CC_CRYPT;
2867 break;
2868 }
2869
2870 case 3: { //AES
2871 cc->cmd0c_mode = MODE_CMD_0x0C_AES;
2872 break;
2873 }
2874
2875 case 4 : { //IDEA
2876 cc->cmd0c_mode = MODE_CMD_0x0C_IDEA;
2877 break;
2878 }
2879
2880 default: {
2881 cc->cmd0c_mode = MODE_CMD_0x0C_NONE;
2882 }
2883 }
2884
2885 set_cmd0c_cryptkey(cl, data, len);
2886
2887 cs_debug_mask(D_READER, "%s received MSG_CMD_0C from server! CMD_0x0C_CMD=%d, MODE=%s",
2888 getprefix(), CMD_0x0C_Command, cmd0c_mode_name[cc->cmd0c_mode]);
2889 }
2890 break;
2891 }
2892
2893 case MSG_CMD_0D: { //key update for the active cmd0x0c algo
2894 int32_t len = l-4;
2895 if (cc->cmd0c_mode == MODE_CMD_0x0C_NONE)
2896 break;
2897
2898 cc_crypt_cmd0c(cl, data, len);
2899 set_cmd0c_cryptkey(cl, data, len);
2900
2901 cs_debug_mask(D_READER, "%s received MSG_CMD_0D from server! MODE=%s",
2902 getprefix(), cmd0c_mode_name[cc->cmd0c_mode]);
2903 break;
2904 }
2905
2906 case MSG_CMD_0E: {
2907 cs_debug_mask(D_READER, "cccam 2.2.x commands not implemented: 0x%02X", buf[1]);
2908 //Unkwon commands...need workout algo
2909 if (cl->typ == 'c') //client connection
2910 {
2911 //switching to an oder version and then disconnect...
2912 cs_strncpy(cfg.cc_version, version[0], sizeof(cfg.cc_version));
2913 ret = -1;
2914 }
2915 else //reader connection
2916 {
2917 cs_strncpy(cl->reader->cc_version, version[0], sizeof(cl->reader->cc_version));
2918 cs_strncpy(cl->reader->cc_build, build[0], sizeof(cl->reader->cc_build));
2919 cc_cycle_connection(cl);
2920 }
2921 break;
2922 }
2923
2924 case MSG_EMM_ACK: {
2925 cc->just_logged_in = 0;
2926 if (cl->typ == 'c') { //EMM Request received
2927 cc_cmd_send(cl, NULL, 0, MSG_EMM_ACK); //Send back ACK
2928 if (l > 4) {
2929 cs_debug_mask(D_EMM, "%s EMM Request received!", getprefix());
2930
2931 if (!ll_count(cl->aureader_list)) {
2932 cs_debug_mask(
2933 D_EMM,
2934 "%s EMM Request discarded because au is not assigned to an reader!",
2935 getprefix());
2936 return MSG_EMM_ACK;
2937 }
2938
2939 EMM_PACKET *emm;
2940 if (!cs_malloc(&emm, sizeof(EMM_PACKET)))
2941 break;
2942 emm->caid[0] = buf[4];
2943 emm->caid[1] = buf[5];
2944 emm->provid[0] = buf[7];
2945 emm->provid[1] = buf[8];
2946 emm->provid[2] = buf[9];
2947 emm->provid[3] = buf[10];
2948 //emm->hexserial[0] = buf[11];
2949 //emm->hexserial[1] = buf[12];
2950 //emm->hexserial[2] = buf[13];
2951 //emm->hexserial[3] = buf[14];
2952 if (l <= 0xFF)
2953 emm->emmlen = buf[15];
2954 else
2955 emm->emmlen = MIN(l - 16, (int32_t)sizeof(emm->emm));
2956 memcpy(emm->emm, buf + 16, emm->emmlen);
2957 //emm->type = UNKNOWN;
2958 //emm->cidx = cs_idx;
2959 do_emm(cl, emm);
2960 free(emm);
2961 }
2962 } else { //Our EMM Request Ack!
2963 cs_debug_mask(D_EMM, "%s EMM ACK!", getprefix());
2964 if (!cc->extended_mode) {
2965 cc->ecm_busy = 0;
2966 }
2967 cc_send_ecm(cl, NULL, NULL);
2968 }
2969 break;
2970 }
2971 default:
2972 //cs_ddump_mask(D_CLIENT, buf, l, "%s unhandled msg: %d len=%d", getprefix(), buf[1], l);
2973 break;
2974 }
2975
2976 if (cc->max_ecms && (cc->ecm_counter > cc->max_ecms)) {
2977 cs_debug_mask(D_READER, "%s max ecms (%d) reached, cycle connection!", getprefix(),
2978 cc->max_ecms);
2979 cc_cycle_connection(cl);
2980 }
2981 return ret;
2982}
2983
2984/**
2985 * Reader: write dcw to receive
2986 */
2987int32_t cc_recv_chk(struct s_client *cl, uchar *dcw, int32_t *rc, uchar *buf, int32_t UNUSED(n)) {
2988 struct cc_data *cc = cl->cc;
2989
2990 if (buf[1] == MSG_CW_ECM) {
2991 memcpy(dcw, cc->dcw, 16);
2992 //cs_debug_mask(D_CLIENT, "cccam: recv chk - MSG_CW %d - %s", cc->recv_ecmtask,
2993 // cs_hexdump(0, dcw, 16, tmp_dbg, sizeof(tmp_dbg)));
2994 *rc = 1;
2995 return (cc->recv_ecmtask);
2996 } else if ((buf[1] == (MSG_CW_NOK1)) || (buf[1] == (MSG_CW_NOK2))) {
2997 *rc = 0;
2998 //if (cc->is_oscam_cccam)
2999 if (cfg.cc_forward_origin_card)
3000 return (cc->recv_ecmtask);
3001 else
3002 return -1;
3003 }
3004
3005 return (-1);
3006}
3007
3008//int32_t is_softfail(int32_t rc)
3009//{
3010// //see oscam.c send_dcw() for a full list
3011// switch(rc)
3012// {
3013// case 5: // 5 = timeout
3014// case 6: // 6 = sleeping
3015// case 7: // 7 = fake
3016// case 10:// 10= no card
3017// case 11:// 11= expdate
3018// case 12:// 12= disabled
3019// case 13:// 13= stopped
3020// case 14:// 100= unhandled
3021// return 1;
3022// }
3023// return 0;
3024//}
3025
3026
3027/**
3028 * Server: send DCW to client
3029 */
3030void cc_send_dcw(struct s_client *cl, ECM_REQUEST *er) {
3031 uchar buf[16];
3032 struct cc_data *cc = cl->cc;
3033
3034 memset(buf, 0, sizeof(buf));
3035
3036 struct cc_extended_ecm_idx *eei = get_extended_ecm_idx_by_idx(cl, er->idx,
3037 1);
3038
3039 if (er->rc < E_NOTFOUND && eei) { //found:
3040 memcpy(buf, er->cw, sizeof(buf));
3041 //fix_dcw(buf);
3042 //cs_debug_mask(D_TRACE, "%s send cw: %s cpti: %d", getprefix(),
3043 // cs_hexdump(0, buf, 16, tmp_dbg, sizeof(tmp_dbg)), er->cpti);
3044 if (!cc->extended_mode)
3045 cc_cw_crypt(cl, buf, eei->cccam_id);
3046 else
3047 cc->g_flag = eei->send_idx;
3048 cc_cmd_send(cl, buf, 16, MSG_CW_ECM);
3049 if (!cc->extended_mode)
3050 cc_crypt(&cc->block[ENCRYPT], buf, 16, ENCRYPT); // additional crypto step
3051
3052 } else { //NOT found:
3053 //cs_debug_mask(D_TRACE, "%s send cw: NOK cpti: %d", getprefix(),
3054 // er->cpti);
3055
3056 if (eei && cc->extended_mode)
3057 cc->g_flag = eei->send_idx;
3058
3059 int32_t nok, bufsize = 0;
3060 if (cc->sleepsend && er->rc == E_STOPPED) {
3061 buf[0] = cl->c35_sleepsend;
3062 bufsize=1;
3063 nok = MSG_SLEEPSEND;
3064 }
3065 else if (!eei || !eei->card)
3066 nok = MSG_CW_NOK1; //share no more available
3067 else {
3068 if (cfg.cc_forward_origin_card && er->origin_card == eei->card)
3069 nok = (er->rcEx==E2_CCCAM_NOK1)?MSG_CW_NOK1:MSG_CW_NOK2;
3070 else
3071 nok = MSG_CW_NOK2; //can't decode
3072 }
3073 cc_cmd_send(cl, buf, bufsize, nok);
3074 }
3075 cc->server_ecm_pending--;
3076 if (eei) {
3077 free(eei->card);
3078 free(eei);
3079 }
3080}
3081
3082int32_t cc_recv(struct s_client *cl, uchar *buf, int32_t l) {
3083 int32_t n;
3084 struct s_reader *rdr = (cl->typ == 'c') ? NULL : cl->reader;
3085
3086 if (buf == NULL || l <= 0)
3087 return -1;
3088
3089 n = cc_msg_recv(cl, buf, l); // recv and decrypt msg
3090 //cs_ddump_mask(D_CLIENT, buf, n, "cccam: received %d bytes from %s", n, remote_txt());
3091
3092
3093 if (n <= 0) {
3094 struct cc_data *cc = cl->cc;
3095 if (cc && cc->nok_message)
3096 cs_debug_mask(D_CLIENT, "%s connection closed by %s. n=%d, Reason: %s", getprefix(), remote_txt(), n, cc->nok_message);
3097 else {
3098 cs_debug_mask(D_CLIENT, "%s connection closed by %s, n=%d.", getprefix(), remote_txt(), n);
3099 if (rdr) {
3100 cc_cli_close(cl, 1);
3101 } else {
3102 //cs_writelock(&cc->cards_busy); maybe uninitialized
3103 cs_disconnect_client(cl);
3104 //cs_writeunlock(&cc->cards_busy);
3105 }
3106 cs_sleepms(150);
3107 n = -1;
3108 return n;
3109 }
3110 n = -1;
3111 } else if (n < 4) {
3112 cs_log("%s packet is too small (%d bytes)", getprefix(), n);
3113 n = -1;
3114 } else if (n > CC_MAXMSGSIZE) {
3115 cs_log("%s packet is too big (%d bytes, max: %d)", getprefix(), n, CC_MAXMSGSIZE);
3116 n = -1;
3117 } else {
3118 // parse it and write it back, if we have received something of value
3119 n = cc_parse_msg(cl, buf, n);
3120 if (n == MSG_CW_ECM || n == MSG_EMM_ACK){
3121 cl->last = time(NULL); // last client action is now
3122 if(rdr) rdr->last_g = time(NULL); // last reader receive is now
3123 }
3124 }
3125
3126 if (n == -1) {
3127 if (cl->typ != 'c')
3128 cc_cli_close(cl, 1);
3129 }
3130 return n;
3131}
3132
3133void cc_init_locks(struct cc_data *cc) {
3134 cs_lock_create(&cc->lockcmd, 5, "lockcmd");
3135 cs_lock_create(&cc->cards_busy, 10, "cards_busy");
3136}
3137
3138#ifdef MODULE_CCCSHARE
3139/**
3140 * Starting readers to get cards:
3141 **/
3142int32_t cc_srv_wakeup_readers(struct s_client *cl) {
3143 int32_t wakeup = 0;
3144 struct s_reader *rdr;
3145 struct s_client *client;
3146 struct cc_data *cc;
3147 for (rdr = first_active_reader; rdr; rdr = rdr->next) {
3148 if (rdr->typ != R_CCCAM)
3149 continue;
3150 if (rdr->tcp_connected == 2)
3151 continue;
3152 if (!(rdr->grp & cl->grp))
3153 continue;
3154 if (rdr->cc_keepalive) //if reader has keepalive but is NOT connected, reader can't connect. so don't ask him
3155 continue;
3156 if((client = rdr->client) == NULL || (cc = client->cc) == NULL || client->kill) //reader is in shutdown
3157 continue;
3158 if(is_connect_blocked(rdr)) //reader cannot be waked up currently because its blocked
3159 continue;
3160
3161 //This wakeups the reader:
3162 add_job(rdr->client, ACTION_READER_CARDINFO, NULL, 0);
3163 wakeup++;
3164 }
3165 return wakeup;
3166}
3167
3168
3169int32_t cc_srv_connect(struct s_client *cl) {
3170 int32_t i;
3171 uint8_t data[16];
3172 char usr[21], pwd[65], tmp_dbg[17];
3173 struct s_auth *account;
3174 struct cc_data *cc;
3175
3176 if (!cs_malloc(&cc, sizeof(struct cc_data)))
3177 return -1;
3178
3179 memset(usr, 0, sizeof(usr));
3180 memset(pwd, 0, sizeof(pwd));
3181
3182 // init internals data struct
3183 cl->cc = cc;
3184 cc->extended_ecm_idx = ll_create("extended_ecm_idx");
3185
3186 cc_init_locks(cc);
3187 uint8_t *buf = cc->send_buffer;
3188
3189 cc->server_ecm_pending = 0;
3190 cc->extended_mode = 0;
3191 cc->ecm_busy = 0;
3192
3193 int32_t keep_alive = 1;
3194 setsockopt(cl->udp_fd, SOL_SOCKET, SO_KEEPALIVE,
3195 (void *)&keep_alive, sizeof(keep_alive));
3196
3197 //Create checksum for "O" cccam:
3198 get_random_bytes(data, 12);
3199 for (i = 0; i < 4; i++) {
3200 data[12 + i] = (data[i] + data[4 + i] + data[8 + i]) & 0xff;
3201 }
3202
3203 cs_debug_mask(D_TRACE, "send ccc checksum");
3204
3205 send(cl->udp_fd, data, 16, 0);
3206
3207 cc_xor(data); // XOR init bytes with 'CCcam'
3208
3209 SHA_CTX ctx;
3210 SHA1_Init(&ctx);
3211 SHA1_Update(&ctx, data, 16);
3212 SHA1_Final(buf, &ctx);
3213
3214 cc_init_crypt(&cc->block[ENCRYPT], buf, 20);
3215 cc_crypt(&cc->block[ENCRYPT], data, 16, DECRYPT);
3216 cc_init_crypt(&cc->block[DECRYPT], data, 16);
3217 cc_crypt(&cc->block[DECRYPT], buf, 20, DECRYPT);
3218
3219 cs_debug_mask(D_TRACE, "receive ccc checksum");
3220
3221 if ((i = cc_recv_to(cl, buf, 20)) == 20) {
3222 //cs_ddump_mask(D_CLIENT, buf, 20, "cccam: recv:");
3223 cc_crypt(&cc->block[DECRYPT], buf, 20, DECRYPT);
3224 //cs_ddump_mask(D_CLIENT, buf, 20, "cccam: hash:");
3225 } else
3226 return -1;
3227
3228 // receive username
3229 memset(buf, 0, CC_MAXMSGSIZE);
3230 if ((i = cc_recv_to(cl, buf, 20)) == 20) {
3231 cc_crypt(&cc->block[DECRYPT], buf, 20, DECRYPT);
3232
3233 strncpy(usr, (char *) buf, sizeof(usr));
3234
3235 //test for nonprintable characters:
3236 for (i = 0; i < 20; i++) {
3237 if (usr[i] > 0 && usr[i] < 0x20) { //found nonprintable char
3238 cs_log("illegal username received");
3239 return -3;
3240 }
3241 }
3242 //cs_ddump_mask(D_CLIENT, buf, 20, "cccam: username '%s':", usr);
3243 } else {
3244 cs_add_violation(cl, NULL);
3245 return -2;
3246 }
3247 cs_debug_mask(D_TRACE, "ccc username received %s", usr);
3248
3249 cl->crypted = 1;
3250
3251 //CCCam only supports len=20 usr/pass. So we could have more than one user that matches the first 20 chars.
3252
3253 //receive password-CCCam encrypted Hash:
3254 if (cc_recv_to(cl, buf, 6) != 6) {
3255 cs_add_violation(cl, usr);
3256 return -2;
3257 }
3258
3259 cs_debug_mask(D_TRACE, "ccc passwdhash received %s", usr);
3260
3261 account = cfg.account;
3262 struct cc_crypt_block *save_block;
3263 if (!cs_malloc(&save_block, sizeof(struct cc_crypt_block)))
3264 return -1;
3265 memcpy(save_block, cc->block, sizeof(struct cc_crypt_block));
3266 int32_t found = 0;
3267 while (1) {
3268 while (account) {
3269 if (strncmp(usr, account->usr, 20) == 0) {
3270 memset(pwd, 0, sizeof(pwd));
3271 cs_strncpy(pwd, account->pwd, sizeof(pwd));
3272 found=1;
3273 break;
3274 }
3275 account = account->next;
3276 }
3277
3278 if (!account)
3279 break;
3280
3281 // receive passwd / 'CCcam'
3282 memcpy(cc->block, save_block, sizeof(struct cc_crypt_block));
3283 cc_crypt(&cc->block[DECRYPT], (uint8_t *) pwd, strlen(pwd), ENCRYPT);
3284 cc_crypt(&cc->block[DECRYPT], buf, 6, DECRYPT);
3285 //cs_ddump_mask(D_CLIENT, buf, 6, "cccam: pwd check '%s':", buf); //illegal buf-bytes could kill the logger!
3286 if (memcmp(buf, "CCcam\0", 6) == 0) //Password Hash OK!
3287 break; //account is set
3288
3289 account = account->next;
3290 }
3291 free(save_block);
3292
3293 if (cs_auth_client(cl, account, NULL)) { //cs_auth_client returns 0 if account is valid/active/accessible
3294 if (!found)
3295 cs_log("account '%s' not found!", usr);
3296 else
3297 cs_log("password for '%s' invalid!", usr);
3298 cs_add_violation(cl, usr);
3299 return -2;
3300 }
3301 if (cl->dup) {
3302 cs_log("account '%s' duplicate login, disconnect!", usr);
3303 return -3;
3304 }
3305 if (cl->disabled) {
3306 cs_log("account '%s' disabled, blocking+disconnect!", usr);
3307 cs_add_violation(cl, usr);
3308 return -2;
3309 }
3310 if (account->cccmaxhops < -1) {
3311 cs_log("account '%s' has cccmaxhops < -1, cccam can't handle this, disconnect!", usr);
3312 return -3;
3313 }
3314
3315 cs_debug_mask(D_TRACE, "ccc user authenticated %s", usr);
3316
3317 if (account->cccmaxhops == -1)
3318 cs_log("account '%s' has cccmaxhops = -1: user will not see any card!", usr);
3319
3320 if (!cs_malloc(&cc->prefix, strlen(cl->account->usr) + 20))
3321 return -1;
3322 snprintf(cc->prefix, strlen(cl->account->usr)+20, "cccam(s) %s:", cl->account->usr);
3323
3324 //Starting readers to get cards:
3325 cc_srv_wakeup_readers(cl);
3326
3327 // send passwd ack
3328 memset(buf, 0, 20);
3329 memcpy(buf, "CCcam\0", 6);
3330 cs_ddump_mask(D_CLIENT, buf, 20, "cccam: send ack:");
3331 cc_crypt(&cc->block[ENCRYPT], buf, 20, ENCRYPT);
3332 send(cl->pfd, buf, 20, 0);
3333
3334 // recv cli data
3335 memset(buf, 0, CC_MAXMSGSIZE);
3336 i = cc_msg_recv(cl, buf, CC_MAXMSGSIZE);
3337 if (i < 0)
3338 return -1;
3339 cs_ddump_mask(D_CLIENT, buf, i, "cccam: cli data:");
3340 memcpy(cc->peer_node_id, buf + 24, 8);
3341 //chk_peer_node_for_oscam(cc);
3342
3343 strncpy(cc->remote_version, (char*)buf+33, sizeof(cc->remote_version)-1);
3344 strncpy(cc->remote_build, (char*)buf+65, sizeof(cc->remote_build)-1);
3345
3346 cs_debug_mask(D_CLIENT, "%s client '%s' (%s) running v%s (%s)", getprefix(), buf + 4,
3347 cs_hexdump(0, cc->peer_node_id, 8, tmp_dbg, sizeof(tmp_dbg)), cc->remote_version, cc->remote_build);
3348
3349 // send cli data ack
3350 cc_cmd_send(cl, NULL, 0, MSG_CLI_DATA);
3351
3352 cs_debug_mask(D_TRACE, "ccc send srv_data %s", usr);
3353 if (cc_send_srv_data(cl) < 0)
3354 return -1;
3355
3356 cc->cccam220 = check_cccam_compat(cc);
3357 cc->just_logged_in = 1;
3358 cc->answer_on_keepalive = time(NULL);
3359
3360 //Wait for Partner detection (NOK1 with data) before reporting cards
3361 //When Partner is detected, cccam220=1 is set. then we can report extended card data
3362 i = process_input(buf, CC_MAXMSGSIZE, 1);
3363 if (i<=0 && i != -9)
3364 return 0; //disconnected
3365
3366 if (cc->cccam220)
3367 cs_debug_mask(D_CLIENT, "%s extended sid mode activated", getprefix());
3368 else
3369 cs_debug_mask(D_CLIENT, "%s 2.1.x compatibility mode", getprefix());
3370
3371 cs_debug_mask(D_TRACE, "ccc send cards %s", usr);
3372 if (!cc_srv_report_cards(cl))
3373 return -1;
3374 cs_ftime(&cc->ecm_time);
3375
3376 //some clients, e.g. mgcamd, does not support keepalive. So if not answered, keep connection
3377 // check for client timeout, if timeout occurs try to send keepalive
3378 cs_debug_mask(D_TRACE, "ccc connected and waiting for data %s", usr);
3379 return 0;
3380}
3381
3382void cc_srv_init2(struct s_client *cl) {
3383 if (!cl->init_done && !cl->kill) {
3384 if (IP_ISSET(cl->ip))
3385 cs_debug_mask(D_CLIENT, "cccam: new connection from %s", cs_inet_ntoa(cl->ip));
3386
3387 cl->pfd = cl->udp_fd;
3388 int32_t ret;
3389 if ((ret=cc_srv_connect(cl)) < 0) {
3390 if (errno != 0)
3391 cs_debug_mask(D_CLIENT, "cccam: failed errno: %d (%s)", errno, strerror(errno));
3392 else
3393 cs_debug_mask(D_CLIENT, "cccam: failed ret: %d", ret);
3394 cs_disconnect_client(cl);
3395 }
3396 else
3397 cl->init_done = 1;
3398 }
3399 return;
3400}
3401
3402void * cc_srv_init(struct s_client *cl, uchar *UNUSED(mbuf), int32_t UNUSED(len)) {
3403 cc_srv_init2(cl);
3404 return NULL;
3405}
3406#endif
3407
3408int32_t cc_cli_connect(struct s_client *cl) {
3409 struct s_reader *rdr = cl->reader;
3410 struct cc_data *cc = cl->cc;
3411 rdr->card_status = CARD_FAILURE;
3412 cl->stopped = 0;
3413
3414 if (!cc) {
3415 // init internals data struct
3416 if (!cs_malloc(&cc, sizeof(struct cc_data)))
3417 return -1;
3418 cc_init_locks(cc);
3419 cc->cards = ll_create("cards");
3420 cl->cc = cc;
3421 cc->pending_emms = ll_create("pending_emms");
3422 cc->extended_ecm_idx = ll_create("extended_ecm_idx");
3423 } else {
3424 cc_free_cardlist(cc->cards, 0);
3425 free_extended_ecm_idx(cc);
3426 }
3427 if (!cc->prefix) {
3428 if (!cs_malloc(&cc->prefix, strlen(cl->reader->label) + 20))
3429 return -1;
3430 }
3431 snprintf(cc->prefix, strlen(cl->reader->label)+20, "cccam(r) %s:", cl->reader->label);
3432
3433 int32_t handle, n;
3434 uint8_t data[20];
3435 uint8_t hash[SHA_DIGEST_LENGTH];
3436 uint8_t *buf = cc->send_buffer;
3437 char pwd[64];
3438
3439 // check cred config
3440 if (rdr->device[0] == 0 || rdr->r_pwd[0] == 0 || rdr->r_usr[0] == 0
3441 || rdr->r_port == 0) {
3442 cs_log("%s configuration error!", rdr->label);
3443 return -5;
3444 }
3445
3446 // connect
3447 handle = network_tcp_connection_open(rdr);
3448 if (handle <= 0) {
3449 cs_debug_mask(D_READER, "%s network connect error!", rdr->label);
3450 return -1;
3451 }
3452 if (errno == EISCONN) {
3453 cc_cli_close(cl, 0);
3454 block_connect(rdr);
3455 return -1;
3456 }
3457
3458 // get init seed
3459 if ((n = cc_recv_to(cl, data, 16)) != 16) {
3460 if (n <= 0)
3461 cs_log("init error from reader %s", rdr->label);
3462 else
3463 cs_log("%s server returned %d instead of 16 bytes as init seed (errno=%d %s)",
3464 rdr->label, n, errno, strerror(errno));
3465 cc_cli_close(cl, 0);
3466 block_connect(rdr);
3467 return -2;
3468 }
3469
3470 cc->ecm_counter = 0;
3471 cc->max_ecms = 0;
3472 cc->cmd05_mode = MODE_UNKNOWN;
3473 cc->cmd05_offset = 0;
3474 cc->cmd05_active = 0;
3475 cc->cmd05_data_len = 0;
3476 cc->answer_on_keepalive = time(NULL);
3477 cc->extended_mode = 0;
3478 cc->last_emm_card = NULL;
3479 cc->num_hop1 = 0;
3480 cc->num_hop2 = 0;
3481 cc->num_hopx = 0;
3482 cc->num_reshare0 = 0;
3483 cc->num_reshare1 = 0;
3484 cc->num_reshare2 = 0;
3485 cc->num_resharex = 0;
3486 memset(&cc->cmd05_data, 0, sizeof(cc->cmd05_data));
3487 memset(&cc->receive_buffer, 0, sizeof(cc->receive_buffer));
3488 NULLFREE(cc->nok_message);
3489 cc->cmd0c_mode = MODE_CMD_0x0C_NONE;
3490
3491 cs_ddump_mask(D_CLIENT, data, 16, "cccam: server init seed:");
3492
3493 uint16_t sum = 0x1234;
3494 uint16_t recv_sum = (data[14] << 8) | data[15];
3495 int32_t i;
3496 for (i = 0; i < 14; i++) {
3497 sum += data[i];
3498 }
3499 //Create special data to detect oscam-cccam:
3500 cc->is_oscam_cccam = sum == recv_sum;
3501
3502 cc_xor(data); // XOR init bytes with 'CCcam'
3503
3504 SHA_CTX ctx;
3505 SHA1_Init(&ctx);
3506 SHA1_Update(&ctx, data, 16);
3507 SHA1_Final(hash, &ctx);
3508
3509 cs_ddump_mask(D_CLIENT, hash, sizeof(hash), "cccam: sha1 hash:");
3510
3511 //initialisate crypto states
3512 cc_init_crypt(&cc->block[DECRYPT], hash, 20);
3513 cc_crypt(&cc->block[DECRYPT], data, 16, DECRYPT);
3514 cc_init_crypt(&cc->block[ENCRYPT], data, 16);
3515 cc_crypt(&cc->block[ENCRYPT], hash, 20, DECRYPT);
3516
3517 cc_cmd_send(cl, hash, 20, MSG_NO_HEADER); // send crypted hash to server
3518
3519 memset(buf, 0, CC_MAXMSGSIZE);
3520 memcpy(buf, rdr->r_usr, strlen(rdr->r_usr));
3521 cs_ddump_mask(D_CLIENT, buf, 20, "cccam: username '%s':", buf);
3522 cc_cmd_send(cl, buf, 20, MSG_NO_HEADER); // send usr '0' padded -> 20 bytes
3523
3524 memset(buf, 0, CC_MAXMSGSIZE);
3525 memset(pwd, 0, sizeof(pwd));
3526
3527 //cs_debug_mask(D_CLIENT, "cccam: 'CCcam' xor");
3528 memcpy(buf, "CCcam", 5);
3529 strncpy(pwd, rdr->r_pwd, sizeof(pwd) - 1);
3530 cc_crypt(&cc->block[ENCRYPT], (uint8_t *) pwd, strlen(pwd), ENCRYPT);
3531 cc_cmd_send(cl, buf, 6, MSG_NO_HEADER); // send 'CCcam' xor w/ pwd
3532
3533 if ((n = cc_recv_to(cl, data, 20)) != 20) {
3534 cs_log("%s login failed, usr/pwd invalid", getprefix());
3535 cc_cli_close(cl, 0);
3536 block_connect(rdr);
3537 return -2;
3538 }
3539 cc_crypt(&cc->block[DECRYPT], data, 20, DECRYPT);
3540 cs_ddump_mask(D_CLIENT, data, 20, "cccam: login failed, usr/pwd invalid");
3541
3542 if (memcmp(data, buf, 5)) { // check server response
3543 cs_log("%s login failed, usr/pwd invalid", getprefix());
3544 cc_cli_close(cl, 0);
3545 block_connect(rdr);
3546 return -2;
3547 } else {
3548 cs_debug_mask(D_READER, "%s login succeeded", getprefix());
3549 }
3550
3551 cs_debug_mask(D_READER, "cccam: last_s=%ld, last_g=%ld", rdr->last_s, rdr->last_g);
3552
3553 cl->pfd = cl->udp_fd;
3554 cs_debug_mask(D_READER, "cccam: pfd=%d", cl->pfd);
3555
3556 if (cc_send_cli_data(cl) <= 0) {
3557 cs_log("%s login failed, could not send client data", getprefix());
3558 cc_cli_close(cl, 0);
3559 block_connect(rdr);
3560 return -3;
3561 }
3562
3563 rdr->caid = rdr->ftab.filts[0].caid;
3564 rdr->nprov = rdr->ftab.filts[0].nprids;
3565 for (n = 0; n < rdr->nprov; n++) {
3566 rdr->availkeys[n][0] = 1;
3567 rdr->prid[n][0] = rdr->ftab.filts[0].prids[n] >> 24;
3568 rdr->prid[n][1] = rdr->ftab.filts[0].prids[n] >> 16;
3569 rdr->prid[n][2] = rdr->ftab.filts[0].prids[n] >> 8;
3570 rdr->prid[n][3] = rdr->ftab.filts[0].prids[n] & 0xff;
3571 }
3572
3573 rdr->card_status = CARD_NEED_INIT;
3574 rdr->last_g = rdr->last_s = time((time_t *) 0);
3575 rdr->tcp_connected = 1;
3576
3577 cc->just_logged_in = 1;
3578 cl->crypted = 1;
3579 cc->ecm_busy = 0;
3580
3581 return 0;
3582}
3583
3584int32_t cc_cli_init_int(struct s_client *cl) {
3585 struct s_reader *rdr = cl->reader;
3586 if (rdr->tcp_connected)
3587 return 1;
3588
3589 if (rdr->tcp_ito < 1)
3590 rdr->tcp_ito = 30;
3591 if (rdr->cc_maxhops < 0)
3592 rdr->cc_maxhops = DEFAULT_CC_MAXHOPS;
3593
3594 if (rdr->tcp_rto < 1)
3595 rdr->tcp_rto = 30; // timeout to 30s
3596 cs_debug_mask(D_READER, "cccam: inactivity timeout: %d seconds, receive timeout: %d seconds", rdr->tcp_ito, rdr->tcp_rto);
3597 cc_check_version(rdr->cc_version, rdr->cc_build);
3598 cs_debug_mask(D_READER, "proxy reader: %s (%s:%d) cccam v%s build %s, maxhops: %d",
3599 rdr->label, rdr->device, rdr->r_port, rdr->cc_version,
3600 rdr->cc_build, rdr->cc_maxhops);
3601
3602 return 0;
3603}
3604
3605int32_t cc_cli_init(struct s_client *cl) {
3606 struct s_reader *reader = cl->reader;
3607
3608 int32_t res = cc_cli_init_int(cl); //Create socket
3609
3610 if (res == 0 && reader && (reader->cc_keepalive || !cl->cc) && !reader->tcp_connected) {
3611
3612 cc_cli_connect(cl); //connect to remote server
3613
3614// while (!reader->tcp_connected && reader->cc_keepalive && cfg.reader_restart_seconds > 0) {
3615//
3616// if ((cc && cc->mode == CCCAM_MODE_SHUTDOWN))
3617// return -1;
3618//
3619// if (!reader->tcp_connected) {
3620// cc_cli_close(cl, 0);
3621// res = cc_cli_init_int(cl);
3622// if (res)
3623// return res;
3624// }
3625// cs_debug_mask(D_READER, "%s restarting reader in %d seconds", reader->label, cfg.reader_restart_seconds);
3626// cs_sleepms(cfg.reader_restart_seconds*1000);
3627// cs_debug_mask(D_READER, "%s restarting reader...", reader->label);
3628// cc_cli_connect(cl);
3629// }
3630 }
3631 return res;
3632}
3633
3634/**
3635 * return 1 if we are able to send requests:
3636 *
3637 */
3638int32_t cc_available(struct s_reader *rdr, int32_t checktype, ECM_REQUEST *er) {
3639 if (!rdr || !rdr->client) return 0;
3640
3641 struct s_client *cl = rdr->client;
3642 if(!cl) return 0;
3643 struct cc_data *cc = cl->cc;
3644
3645 if (er && cc && rdr->tcp_connected) {
3646 struct cc_card *card = get_matching_card(cl, er, 1);
3647 if (!card)
3648 return 0;
3649 }
3650 //cs_debug_mask(D_TRACE, "checking reader %s availibility", rdr->label);
3651 if (!cc || rdr->tcp_connected != 2) {
3652 //Two cases:
3653 // 1. Keepalive ON but not connected: Do NOT send requests,
3654 // because we can't connect - problem of full running pipes
3655 // 2. Keepalive OFF but not connected: Send requests to connect
3656 // pipe won't run full, because we are reading from pipe to
3657 // get the ecm request
3658 if (rdr->cc_keepalive)
3659 return 0;
3660 }
3661
3662 if (er && er->ecmlen > 255 && cc && !cc->extended_mode && (cc->remote_build_nr < 3367))
3663 return 0; // remote does not support large ecms!
3664
3665
3666 if (checktype == AVAIL_CHECK_LOADBALANCE && cc && cc->ecm_busy) {
3667 if (cc_request_timeout(cl))
3668 cc_cycle_connection(cl);
3669 if (!rdr->tcp_connected || cc->ecm_busy) {
3670 cs_debug_mask(D_TRACE, "checking reader %s availibility=0 (unavail)",
3671 rdr->label);
3672 return 0; //We are processing EMMs/ECMs
3673 }
3674 }
3675
3676 return 1;
3677}
3678
3679/**
3680 *
3681 *
3682 **/
3683void cc_card_info(void) {
3684 struct s_client *cl = cur_client();
3685 struct s_reader *rdr = cl->reader;
3686
3687 if (rdr && !rdr->tcp_connected)
3688 cc_cli_connect(cl);
3689}
3690
3691void cc_cleanup(struct s_client *cl) {
3692 if (cl->typ != 'c') {
3693 cc_cli_close(cl, 1); // we need to close open fd's
3694 }
3695 cc_free(cl);
3696}
3697
3698void cc_update_nodeid(void)
3699{
3700 if (check_filled(cfg.cc_fixed_nodeid, sizeof(cfg.cc_fixed_nodeid))) {
3701 memcpy(cc_node_id, cfg.cc_fixed_nodeid, 8);
3702 return;
3703 }
3704 //Partner Detection:
3705 uint16_t sum = 0x1234; //This is our checksum
3706 int32_t i;
3707 get_random_bytes(cc_node_id, 4);
3708 for (i = 0; i < 4; i++) {
3709 sum += cc_node_id[i];
3710 }
3711
3712 // Partner ID:
3713 cc_node_id[4] = 0x10; // (Oscam 0x10, vPlugServer 0x11, Hadu 0x12,...)
3714 sum += cc_node_id[4];
3715
3716 // generate checksum for Partner ID:
3717 cc_node_id[5] = 0xAA;
3718 for (i = 0; i < 5; i++) {
3719 cc_node_id[5] ^= cc_node_id[i];
3720 }
3721 sum += cc_node_id[5];
3722
3723 cc_node_id[6] = sum >> 8;
3724 cc_node_id[7] = sum & 0xff;
3725
3726 memcpy(cfg.cc_fixed_nodeid, cc_node_id, 8);
3727}
3728
3729bool cccam_forward_origin_card(ECM_REQUEST *er) {
3730 if (cfg.cc_forward_origin_card && er->origin_card) {
3731 struct cc_card *card = er->origin_card;
3732 struct s_ecm_answer *eab = NULL;
3733 struct s_ecm_answer *ea;
3734 for(ea = er->matching_rdr; ea; ea = ea->next) {
3735 ea->status &= ~(READER_ACTIVE|READER_FALLBACK);
3736 if (card->origin_reader == ea->reader)
3737 eab = ea;
3738 }
3739 if (eab) {
3740 cs_debug_mask(D_LB, "loadbalancer: forward card: forced by card %d to reader %s", card->id, eab->reader->label);
3741 eab->status |= READER_ACTIVE;
3742 return true;
3743 }
3744 }
3745 return false;
3746}
3747
3748bool cccam_snprintf_cards_stat(struct s_client *cl, char *emmtext, size_t emmtext_sz) {
3749 struct cc_data *rcc = cl->cc;
3750 if(rcc){
3751 LLIST *cards = rcc->cards;
3752 if (cards) {
3753 int32_t ncards = ll_count(cards);
3754 int32_t locals = rcc->num_hop1;
3755 snprintf(emmtext, emmtext_sz, " %3d/%3d card%s", locals, ncards, ncards > 1 ? "s ": " ");
3756 return true;
3757 }
3758 }
3759 return false;
3760}
3761
3762bool cccam_client_extended_mode(struct s_client *cl) {
3763 return cl && cl->cc && ((struct cc_data *)cl->cc)->extended_mode;
3764}
3765
3766#ifdef MODULE_CCCSHARE
3767static void cc_s_idle(struct s_client *cl) {
3768 cs_debug_mask(D_TRACE, "ccc idle %s", username(cl));
3769 if (cfg.cc_keep_connected) {
3770 cc_cmd_send(cl, NULL, 0, MSG_KEEPALIVE);
3771 } else {
3772 cs_debug_mask(D_CLIENT, "%s keepalive after maxidle is reached", getprefix());
3773 cs_disconnect_client(cl);
3774 }
3775}
3776#endif
3777
3778void module_cccam(struct s_module *ph) {
3779 ph->desc = "cccam";
3780 ph->type = MOD_CONN_TCP;
3781 ph->large_ecm_support = 1;
3782 ph->listenertype = LIS_CCCAM;
3783 ph->num = R_CCCAM;
3784 ph->recv = cc_recv;
3785 ph->cleanup = cc_cleanup;
3786 ph->bufsize = 2048;
3787 ph->c_init = cc_cli_init;
3788 ph->c_idle = cc_idle;
3789 ph->c_recv_chk = cc_recv_chk;
3790 ph->c_send_ecm = cc_send_ecm;
3791 ph->c_send_emm = cc_send_emm;
3792#ifdef MODULE_CCCSHARE
3793 IP_ASSIGN(ph->s_ip, cfg.cc_srvip);
3794 ph->s_handler = cc_srv_init;
3795 ph->s_init = cc_srv_init2;
3796 ph->s_idle = cc_s_idle;
3797 ph->send_dcw = cc_send_dcw;
3798#endif
3799 ph->c_available = cc_available;
3800 ph->c_card_info = cc_card_info;
3801#ifdef CS_CACHEEX
3802 ph->c_cache_push=cc_cache_push_out;
3803 ph->c_cache_push_chk=cc_cache_push_chk;
3804#endif
3805
3806 cc_update_nodeid();
3807
3808#ifdef MODULE_CCCSHARE
3809 int32_t i;
3810 for (i=0;i<CS_MAXPORTS;i++) {
3811 if (!cfg.cc_port[i]) break;
3812 ph->ptab.ports[i].s_port = cfg.cc_port[i];
3813 ph->ptab.nports++;
3814 }
3815
3816 if (cfg.cc_port[0])
3817 cccam_init_share();
3818#endif
3819}
3820#endif
Note: See TracBrowser for help on using the repository browser.