source: trunk/module-cccam.c@ 4097

Last change on this file since 4097 was 4097, checked in by schlocke, 13 years ago

cccam: fixed ppc swap

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