source: trunk/module-cccam.c@ 4004

Last change on this file since 4004 was 4004, checked in by schlocke, 10 years ago

cccam: added UA/SA to webif reader cards.

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