source: trunk/module-cccam.c@ 4149

Last change on this file since 4149 was 4141, checked in by dingo35, 13 years ago

all: simplify debug system, add D_DVBAPI = -d128, eliminate cs_ptyp which complicates stuff unnecc

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