source: trunk/module-cccam.c@ 4098

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

cccam: removed non-working preferred card, changed keepconnected mgcamd
compatibility

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