source: trunk/module-cccam.c@ 1669

Last change on this file since 1669 was 1669, checked in by merek, 11 years ago

Fix bug in module-cccam - This code solve the issue that prevent cccam client to login to oscam with only first user in oscam.users, Thanks to dpeddi

  • Property svn:mime-type set to text/plain
File size: 31.9 KB
Line 
1#include "globals.h"
2
3
4int g_flag = 0;
5/******************************** */
6/* LINKED LIST CODE - IF IT'S USEFUL ELSEWHERE, IT SHOULD BE SPLIT OFF INTO linkedlist.h/.c */
7/******************************** */
8
9// Simple, doubly linked
10// This is thread-safe, so requires pthread. Also expect locking if iterators are not destroyed.
11
12#include <pthread.h>
13
14struct llist_node {
15 void *obj;
16 struct llist_node *prv;
17 struct llist_node *nxt;
18};
19
20typedef struct llist {
21 struct llist_node *first;
22 struct llist_node *last;
23 int items;
24 pthread_mutex_t lock;
25} LLIST;
26
27typedef struct llist_itr {
28 LLIST *l;
29 struct llist_node *cur;
30} LLIST_ITR;
31
32LLIST *llist_create(void); // init linked list
33void llist_destroy(LLIST *l); // de-init linked list - frees all objects on the list
34
35void *llist_append(LLIST *l, void *o); // append object onto bottom of list, returns ptr to obj
36
37void *llist_itr_init(LLIST *l, LLIST_ITR *itr); // linked list iterator, returns ptr to first obj
38//void llist_itr_release(LLIST_ITR *itr); // release iterator
39void *llist_itr_next(LLIST_ITR *itr); // iterates, returns ptr to next obj
40
41void *llist_itr_insert(LLIST_ITR *itr, void *o); // insert object at itr point, iterates to and returns ptr to new obj
42void *llist_itr_remove(LLIST_ITR *itr); // remove obj at itr, iterates to and returns ptr to next obj
43
44int llist_count(LLIST *l); // returns number of obj in list
45
46/******************************** */
47
48#include <string.h>
49#include <stdlib.h>
50int cc_cli_init();
51
52LLIST *llist_create(void)
53{
54 LLIST *l = malloc(sizeof(LLIST));
55 bzero(l, sizeof(LLIST));
56
57 pthread_mutex_init(&l->lock, NULL);
58
59 l->items = 0;
60
61 return l;
62}
63
64void llist_destroy(LLIST *l)
65{
66 LLIST_ITR itr;
67 void *o = llist_itr_init(l, &itr);
68 while (o) {
69 free(o);
70 o = llist_itr_remove(&itr);
71 }
72// llist_itr_release(&itr);
73}
74
75void *llist_append(LLIST *l, void *o)
76{
77 pthread_mutex_lock(&l->lock);
78 if (o) {
79 struct llist_node *ln = malloc(sizeof(struct llist_node));
80
81 bzero(ln, sizeof(struct llist_node));
82 ln->obj = o;
83
84 if (l->last) {
85 ln->prv = l->last;
86 ln->prv->nxt = ln;
87 } else {
88 l->first = ln;
89 }
90 l->last = ln;
91
92 l->items++;
93 }
94 pthread_mutex_unlock(&l->lock);
95
96 return o;
97}
98
99void *llist_itr_init(LLIST *l, LLIST_ITR *itr)
100{
101 // pthread_mutex_lock(&l->lock);
102 if (l->first) {
103
104 bzero(itr, sizeof(LLIST_ITR));
105 itr->cur = l->first;
106 itr->l = l;
107
108 return itr->cur->obj;
109 }
110
111 return NULL;
112}
113/*
114void llist_itr_release(LLIST_ITR *itr)
115{
116 // pthread_mutex_unlock(&itr->l->lock);
117}
118*/
119void *llist_itr_next(LLIST_ITR *itr)
120{
121 if (itr->cur->nxt) {
122 itr->cur = itr->cur->nxt;
123 return itr->cur->obj;
124 }
125
126 return NULL;
127}
128
129void *llist_itr_remove(LLIST_ITR *itr) // this needs cleaning - I was lazy
130{
131 itr->l->items--;
132 if ((itr->cur == itr->l->first) && (itr->cur == itr->l->last)) {
133 free(itr->cur);
134 itr->l->first = NULL;
135 itr->l->last = NULL;
136 return NULL;
137 } else if (itr->cur == itr->l->first) {
138 struct llist_node *nxt = itr->cur->nxt;
139 free(itr->cur);
140 nxt->prv = NULL;
141 itr->l->first = nxt;
142 itr->cur = nxt;
143 } else if (itr->cur == itr->l->last) {
144 itr->l->last = itr->cur->prv;
145 itr->l->last->nxt = NULL;
146 free(itr->cur);
147 return NULL;
148 } else {
149 struct llist_node *nxt = itr->cur->nxt;
150 itr->cur->prv->nxt = itr->cur->nxt;
151 itr->cur->nxt->prv = itr->cur->prv;
152 free(itr->cur);
153 itr->cur = nxt;
154 }
155
156 return itr->cur->obj;
157}
158
159int llist_count(LLIST *l)
160{
161 return l->items;
162}
163
164/******************************** */
165
166#define CC_MAXMSGSIZE 512
167#define CC_MAX_PROV 16
168#define CC_MAX_ECMS 50 // before reconnect
169
170#define SWAPC(X, Y) do { char p; p = *X; *X = *Y; *Y = p; } while(0)
171#define NULLFREE(X) do { if (X) { free(X); X = NULL; } } while(0)
172
173#if (defined(WIN32) || defined(OS_CYGWIN32)) && !defined(MSG_WAITALL)
174# define MSG_WAITALL 0
175#endif
176
177typedef enum {
178 DECRYPT,
179 ENCRYPT
180} cc_crypt_mode_t;
181
182typedef enum
183{
184 MSG_CLI_DATA,
185 MSG_CW_ECM,
186 MSG_CARD_REMOVED = 4,
187 MSG_BAD_ECM,
188 MSG_KEEPALIVE,
189 MSG_NEW_CARD,
190 MSG_SRV_DATA,
191 MSG_CMD_0B = 0x0b,
192 MSG_CW_NOK1 = 0xfe,
193 MSG_CW_NOK2 = 0xff,
194 MSG_NO_HEADER = 0xffff
195} cc_msg_type_t;
196
197struct cc_crypt_block
198{
199 uint8 keytable[256];
200 uint8 state;
201 uint8 counter;
202 uint8 sum;
203};
204
205struct cc_card {
206 uint32 id; // cccam card (share) id
207 uint16 caid;
208 uint8 hop;
209 uint8 key[8]; // card serial (for au)
210 LLIST *provs; // providers
211 LLIST *badsids; // sids that have failed to decode
212};
213
214struct cc_data {
215 struct cc_crypt_block block[2]; // crypto state blocks
216
217 uint8 node_id[8], // client node id
218 peer_node_id[8], // server node id
219 dcw[16]; // control words
220
221 struct cc_card *cur_card; // ptr to selected card
222 LLIST *cards; // cards list
223
224 uint32 count;
225 uint32 ecm_count;
226 uint16 cur_sid;
227
228 int last_nok;
229 ECM_REQUEST *found;
230
231 unsigned long crc;
232
233 pthread_mutex_t lock;
234 pthread_mutex_t ecm_busy;
235};
236
237static unsigned int seed;
238static uchar fast_rnd()
239{
240 unsigned int offset = 12923;
241 unsigned int multiplier = 4079;
242
243 seed = seed * multiplier + offset;
244 return (uchar)(seed % 0xFF);
245}
246
247static void cc_init_crypt(struct cc_crypt_block *block, uint8 *key, int len)
248{
249 int i = 0 ;
250 uint8 j = 0;
251
252 for (i=0; i<256; i++) {
253 block->keytable[i] = i;
254 }
255
256 for (i=0; i<256; i++) {
257 j += key[i % len] + block->keytable[i];
258 SWAPC(&block->keytable[i], &block->keytable[j]);
259 }
260
261 block->state = *key;
262 block->counter=0;
263 block->sum=0;
264}
265
266static void cc_crypt(struct cc_crypt_block *block, uint8 *data, int len, cc_crypt_mode_t mode)
267{
268 int i;
269 uint8 z;
270
271 for (i = 0; i < len; i++) {
272 block->counter++;
273 block->sum += block->keytable[block->counter];
274 SWAPC(&block->keytable[block->counter], &block->keytable[block->sum]);
275 z = data[i];
276 data[i] = z ^ block->keytable[(block->keytable[block->counter] + block->keytable[block->sum]) & 0xff] ^ block->state;
277 if (!mode) z = data[i];
278 block->state = block->state ^ z;
279 }
280}
281
282static void cc_xor(uint8 *buf)
283{
284 const char cccam[] = "CCcam";
285 uint8 i;
286
287 for ( i = 0; i < 8; i++ ) {
288 buf[8 + i] = i * buf[i];
289 if ( i <= 5 ) {
290 buf[i] ^= cccam[i];
291 }
292 }
293}
294
295static void cc_cw_crypt(uint8 *cws)
296{
297 struct cc_data *cc;
298 uint64 node_id;
299 uint8 tmp;
300 int i;
301
302 if (reader[ridx].cc) {
303 cc = reader[ridx].cc;
304 node_id = b2ll(8, cc->node_id);
305 }
306 else {
307 cc = client[cs_idx].cc;
308 node_id = b2ll(8, cc->peer_node_id);
309 }
310
311 for (i = 0; i < 16; i++) {
312 tmp = cws[i] ^ (node_id >> (4 * i));
313 if (i & 1) tmp = ~tmp;
314 cws[i] = (cc->cur_card->id >> (2 * i)) ^ tmp;
315 }
316}
317
318static void cc_cycle_connection()
319{
320 reader[ridx].tcp_connected = 0;
321 cs_sleepms(200);
322 close(pfd);
323 client[cs_idx].udp_fd = 0;
324 cs_sleepms(100);
325 cc_cli_init();
326}
327
328static int cc_msg_recv(uint8 *buf)
329{
330 int len;
331 uint8 netbuf[CC_MAXMSGSIZE];
332 struct cc_data *cc;
333
334 if (reader[ridx].cc)
335 cc = reader[ridx].cc;
336 else
337 cc = client[cs_idx].cc;
338
339 int handle = client[cs_idx].udp_fd;
340
341 if (handle < 0) return -1;
342
343 len = recv(handle, netbuf, 4, MSG_WAITALL);
344
345 if (!len) return 0;
346
347 if (len != 4) { // invalid header length read
348 cs_log("cccam: invalid header length");
349 return -1;
350 }
351
352 cc_crypt(&cc->block[DECRYPT], netbuf, 4, DECRYPT);
353 cs_ddump(netbuf, 4, "cccam: decrypted header:");
354
355 g_flag = netbuf[0];
356
357 if (((netbuf[2] << 8) | netbuf[3]) != 0) { // check if any data is expected in msg
358 if (((netbuf[2] << 8) | netbuf[3]) > CC_MAXMSGSIZE - 2) {
359 cs_log("cccam: message too big");
360 return -1;
361 }
362
363 len = recv(handle, netbuf+4, (netbuf[2] << 8) | netbuf[3], MSG_WAITALL); // read rest of msg
364
365 if (len != ((netbuf[2] << 8) | netbuf[3])) {
366 cs_log("cccam: invalid message length read");
367 return -1;
368 }
369
370 cc_crypt(&cc->block[DECRYPT], netbuf+4, len, DECRYPT);
371 len += 4;
372 }
373
374 cs_ddump(netbuf, len, "cccam: full decrypted msg, len=%d:", len);
375
376 memcpy(buf, netbuf, len);
377 return len;
378}
379
380static int cc_cmd_send(uint8 *buf, int len, cc_msg_type_t cmd)
381{
382 int n;
383 uint8 *netbuf = malloc(len+4);
384 struct cc_data *cc;
385
386 if (reader[ridx].cc)
387 cc = reader[ridx].cc;
388 else
389 cc = client[cs_idx].cc;
390
391 bzero(netbuf, len+4);
392
393 if (cmd == MSG_NO_HEADER) {
394 memcpy(netbuf, buf, len);
395 } else {
396 // build command message
397 netbuf[0] = g_flag; // flags??
398 netbuf[1] = cmd & 0xff;
399 netbuf[2] = len >> 8;
400 netbuf[3] = len & 0xff;
401 if (buf) memcpy(netbuf+4, buf, len);
402 len += 4;
403 }
404
405 cs_ddump(netbuf, len, "cccam: send:");
406 cc_crypt(&cc->block[ENCRYPT], netbuf, len, ENCRYPT);
407
408 n = send(client[cs_idx].udp_fd, netbuf, len, 0);
409
410 NULLFREE(netbuf);
411
412 return n;
413}
414
415static int cc_send_cli_data()
416{
417 int i;
418 struct cc_data *cc = reader[ridx].cc;
419
420 cs_debug("cccam: send client data");
421
422 seed = (unsigned int) time((time_t*)0);
423 for( i=0; i<8; i++ ) cc->node_id[i]=fast_rnd();
424
425 uint8 buf[CC_MAXMSGSIZE];
426 bzero(buf, CC_MAXMSGSIZE);
427
428 memcpy(buf, reader[ridx].r_usr, sizeof(reader[ridx].r_usr));
429 memcpy(buf + 20, cc->node_id, 8 );
430 memcpy(buf + 29, reader[ridx].cc_version, sizeof(reader[ridx].cc_version)); // cccam version (ascii)
431 memcpy(buf + 61, reader[ridx].cc_build, sizeof(reader[ridx].cc_build)); // build number (ascii)
432
433 cs_log ("cccam: user: %s, version: %s, build: %s", reader[ridx].r_usr, reader[ridx].cc_version, reader[ridx].cc_build);
434
435 i = cc_cmd_send(buf, 20 + 8 + 6 + 26 + 4 + 28 + 1, MSG_CLI_DATA);
436
437 return i;
438}
439
440static int cc_send_srv_data()
441{
442 int i;
443 struct cc_data *cc = client[cs_idx].cc;
444
445 cs_debug("cccam: send server data");
446
447 seed = (unsigned int) time((time_t*)0);
448 for( i=0; i<8; i++ ) cc->node_id[i]=fast_rnd();
449
450 uint8 buf[CC_MAXMSGSIZE];
451 bzero(buf, CC_MAXMSGSIZE);
452
453 memcpy(buf, cc->node_id, 8 );
454 memcpy(buf + 8, cfg->cc_version, sizeof(reader[ridx].cc_version)); // cccam version (ascii)
455 memcpy(buf + 40, cfg->cc_build, sizeof(reader[ridx].cc_build)); // build number (ascii)
456
457 cs_log ("cccam: version: %s, build: %s", cfg->cc_version, cfg->cc_build);
458
459 return cc_cmd_send(buf, 0x48, MSG_SRV_DATA);
460}
461
462static int cc_get_nxt_ecm()
463{
464 int n, i;
465 time_t t;
466 // struct cc_data *cc = reader[ridx].cc;
467
468 t=time((time_t *)0);
469 for (i = 1, n = 1; i < CS_MAXPENDING; i++)
470 {
471 if ((t-(ulong)ecmtask[i].tps.time > ((cfg->ctimeout + 500) / 1000) + 1) &&
472 (ecmtask[i].rc >= 10)) // drop timeouts
473 {
474 ecmtask[i].rc=0;
475 }
476
477 if (ecmtask[i].rc >= 10) { // stil active and waiting
478 // search for the ecm with the lowest time, this should be the next to go
479 if ((!n || ecmtask[n].tps.time-ecmtask[i].tps.time < 0) && &ecmtask[n]) n = i;
480 }
481 }
482 return n;
483}
484
485static int cc_send_ecm(ECM_REQUEST *er, uchar *buf)
486{
487 int n, h = -1;
488 struct cc_data *cc = reader[ridx].cc;
489 struct cc_card *card;
490 LLIST_ITR itr;
491 ECM_REQUEST *cur_er;
492
493 if (cc->ecm_count) cc->ecm_count++;
494
495 if (!cc || (pfd < 1)) {
496 if (er) {
497 er->rc = 0;
498 er->rcEx = 0x27;
499 cs_log("cccam: server not init!");
500 write_ecm_answer(fd_c2m, er);
501 }
502 return 0;
503 }
504
505// pthread_mutex_lock(&cc->ecm_busy);
506 if (pthread_mutex_trylock(&cc->ecm_busy) == EBUSY) {
507 cs_debug("cccam: ecm trylock: failed to get lock");
508 return 0;
509 } else {
510 cs_debug("cccam: ecm trylock: got lock");
511 }
512// pthread_mutex_lock(&cc->lock);
513
514 if ((n = cc_get_nxt_ecm()) < 0) {
515 pthread_mutex_unlock(&cc->ecm_busy);
516 pthread_mutex_unlock(&cc->lock);
517 return 0; // no queued ecms
518 }
519 cur_er = &ecmtask[n];
520
521 if (crc32(0, cur_er->ecm, cur_er->l) == cc->crc) cur_er->rc = 99;
522 cc->crc = crc32(0, cur_er->ecm, cur_er->l);
523
524 cs_debug("cccam: ecm crc = 0x%lx", cc->crc);
525
526 if (cur_er->rc == 99) {
527 pthread_mutex_unlock(&cc->ecm_busy);
528 pthread_mutex_unlock(&cc->lock);
529 return 0; // ecm already sent
530 }
531
532 //cc->found = cur_er;
533
534 if (buf) memcpy(buf, cur_er->ecm, cur_er->l);
535
536 cc->cur_card = NULL;
537 cc->cur_sid = cur_er->srvid;
538
539 card = llist_itr_init(cc->cards, &itr);
540
541 while (card) {
542 if (card->caid == cur_er->caid) { // caid matches
543 int s = 0;
544
545 LLIST_ITR sitr;
546 uint16 *sid = llist_itr_init(card->badsids, &sitr);
547 while (sid) {
548 if (*sid == cc->cur_sid) {
549 s = 1;
550 break;
551 }
552 sid = llist_itr_next(&sitr);
553 }
554// llist_itr_release(&sitr);
555
556 LLIST_ITR pitr;
557 uint8 *prov = llist_itr_init(card->provs, &pitr);
558 while (prov && !s) {
559 if (b2i(3, prov) == cur_er->prid) { // provid matches
560 if (((h < 0) || (card->hop < h)) && (card->hop <= reader[ridx].cc_maxhop - 1)) { // card is closer and doesn't exceed max hop
561 cc->cur_card = card;
562 h = card->hop; // card has been matched
563 }
564 }
565 prov = llist_itr_next(&pitr);
566 }
567// llist_itr_release(&pitr);
568 }
569 card = llist_itr_next(&itr);
570 }
571// llist_itr_release(&itr);
572
573 if (cc->cur_card) {
574 uint8 *ecmbuf = malloc(cur_er->l+13);
575 bzero(ecmbuf, cur_er->l+13);
576
577 // build ecm message
578 ecmbuf[0] = cc->cur_card->caid >> 8;
579 ecmbuf[1] = cc->cur_card->caid & 0xff;
580 ecmbuf[2] = cur_er->prid >> 24;
581 ecmbuf[3] = cur_er->prid >> 16;
582 ecmbuf[4] = cur_er->prid >> 8;
583 ecmbuf[5] = cur_er->prid & 0xff;
584 ecmbuf[6] = cc->cur_card->id >> 24;
585 ecmbuf[7] = cc->cur_card->id >> 16;
586 ecmbuf[8] = cc->cur_card->id >> 8;
587 ecmbuf[9] = cc->cur_card->id & 0xff;
588 ecmbuf[10] = cur_er->srvid >> 8;
589 ecmbuf[11] = cur_er->srvid & 0xff;
590 ecmbuf[12] = cur_er->l & 0xff;
591 memcpy(ecmbuf+13, cur_er->ecm, cur_er->l);
592
593 cc->count = cur_er->idx;
594
595 cs_log("cccam: sending ecm for sid %04x to card %08x, hop %d", cur_er->srvid, cc->cur_card->id, cc->cur_card->hop + 1);
596 n = cc_cmd_send(ecmbuf, cur_er->l+13, MSG_CW_ECM); // send ecm
597
598 NULLFREE(ecmbuf);
599 } else {
600 n = -1;
601 cs_log("cccam: no suitable card on server");
602 cur_er->rc = 0;
603 cur_er->rcEx = 0x27;
604 //cur_er->rc = 1;
605 //cur_er->rcEx = 0;
606 cs_sleepms(100);
607 write_ecm_answer(fd_c2m, cur_er);
608 //reader[ridx].last_s = reader[ridx].last_g;
609
610 card = llist_itr_init(cc->cards, &itr);
611 while (card) {
612 if (card->caid == cur_er->caid) { // caid matches
613 LLIST_ITR sitr;
614 uint16 *sid = llist_itr_init(card->badsids, &sitr);
615 while (sid) {
616 if (*sid == cur_er->srvid)
617 sid = llist_itr_remove(&sitr);
618 else sid = llist_itr_next(&sitr);
619 }
620// llist_itr_release(&sitr);
621 }
622 card = llist_itr_next(&itr);
623 }
624// llist_itr_release(&itr);
625
626 pthread_mutex_unlock(&cc->ecm_busy);
627 }
628
629 return 0;
630}
631/*
632static int cc_abort_user_ecms(){
633 int n, i;
634 time_t t;//, tls;
635 struct cc_data *cc = reader[ridx].cc;
636
637 t=time((time_t *)0);
638 for (i=1,n=1; i<CS_MAXPENDING; i++)
639 {
640 if ((t-ecmtask[i].tps.time > ((cfg->ctimeout + 500) / 1000) + 1) &&
641 (ecmtask[i].rc>=10)) // drop timeouts
642 {
643 ecmtask[i].rc=0;
644 }
645 int td=abs(1000*(ecmtask[i].tps.time-cc->found->tps.time)+ecmtask[i].tps.millitm-cc->found->tps.millitm);
646 if (ecmtask[i].rc>=10 && ecmtask[i].cidx==cc->found->cidx && &ecmtask[i]!=cc->found){
647 cs_log("aborting idx:%d caid:%04x client:%d timedelta:%d",ecmtask[i].idx,ecmtask[i].caid,ecmtask[i].cidx,td);
648 ecmtask[i].rc=0;
649 ecmtask[i].rcEx=7;
650 write_ecm_answer(fd_c2m, &ecmtask[i]);
651 }
652 }
653 return n;
654
655}
656*/
657
658static cc_msg_type_t cc_parse_msg(uint8 *buf, int l)
659{
660 int ret = buf[1];
661 struct cc_data *cc;
662
663 if (reader[ridx].cc)
664 cc = reader[ridx].cc;
665 else
666 cc = client[cs_idx].cc;
667
668 switch (buf[1]) {
669 case MSG_CLI_DATA:
670 cs_debug("cccam: client data ack");
671 break;
672 case MSG_SRV_DATA:
673 memcpy(cc->peer_node_id, buf+4, 8);
674 cs_log("cccam: srv %s running v%s (%s)", cs_hexdump(0, cc->peer_node_id, 8), buf+12, buf+44);
675 break;
676 case MSG_NEW_CARD:
677 {
678 int i = 0;
679 struct cc_card *card = malloc(sizeof(struct cc_card));
680
681 bzero(card, sizeof(struct cc_card));
682
683 card->provs = llist_create();
684 card->badsids = llist_create();
685 card->id = b2i(4, buf+4);
686 card->caid = b2i(2, buf+12);
687 card->hop = buf[14];
688 memcpy(card->key, buf+16, 8);
689
690 cs_log("cccam: card %08x added, caid %04x, hop %d, key %s",
691 card->id, card->caid, card->hop, cs_hexdump(0, card->key, 8));
692
693
694 for (i = 0; i < buf[24]; i++) { // providers
695 uint8 *prov = malloc(3);
696
697 memcpy(prov, buf+25+(7*i), 3);
698 cs_log(" prov %d, %06x", i+1, b2i(3, prov));
699
700 llist_append(card->provs, prov);
701 }
702
703
704 llist_append(cc->cards, card);
705 if (!cc->cur_card) cc->cur_card = card;
706 }
707 break;
708 case MSG_CARD_REMOVED:
709 {
710 struct cc_card *card;
711 LLIST_ITR itr;
712
713 card = llist_itr_init(cc->cards, &itr);
714 while (card) {
715 if (card->id == b2i(4, buf+4)) {
716 cs_debug("cccam: card %08x removed, caid %04x", card->id, card->caid);
717
718 llist_destroy(card->provs);
719 llist_destroy(card->badsids);
720 free(card);
721
722 card = llist_itr_remove(&itr);
723 break;
724 } else {
725 card = llist_itr_next(&itr);
726 }
727 }
728// llist_itr_release(&itr);
729 }
730 break;
731 case MSG_CW_NOK1:
732 case MSG_CW_NOK2:
733 cs_log("cccam: cw nok, sid = %x", cc->cur_sid);
734
735 int f = 0;
736 LLIST_ITR itr;
737 uint16 *sid = llist_itr_init(cc->cur_card->badsids, &itr);
738 while (sid && !f) {
739 if (*sid == cc->cur_sid) {
740// llist_itr_release(&itr);
741 f = 1;
742 }
743 sid = llist_itr_next(&itr);
744 }
745// llist_itr_release(&itr);
746
747 if (!f) {
748 sid = malloc(sizeof(uint16));
749 *sid = cc->cur_sid;
750
751 sid = llist_append(cc->cur_card->badsids, sid);
752 cs_debug(" added sid block for card %08x", cc->cur_card->id);
753 }
754 bzero(cc->dcw, 16);
755 pthread_mutex_unlock(&cc->ecm_busy);
756 cc_send_ecm(NULL, NULL);
757 ret = 0;
758 break;
759 case MSG_CW_ECM:
760 if (is_server) {
761 ECM_REQUEST *er;
762
763 cc->cur_card = malloc(sizeof(struct cc_card));
764 bzero(cc->cur_card, sizeof(struct cc_card));
765
766 cc->cur_card->id = buf[10] << 24 | buf[11] << 16 | buf[12] << 8 | buf[13];
767
768 if ((er=get_ecmtask())) {
769 er->caid = b2i(2, buf+4);
770 er->srvid = b2i(2, buf+14);
771 er->l = buf[16];
772 memcpy(er->ecm, buf+17, er->l);
773 er->prid = b2i(4, buf+6);
774 get_cw(er);
775 }
776 } else {
777 cc_cw_crypt(buf+4);
778 memcpy(cc->dcw, buf+4, 16);
779 cs_debug("cccam: cws: %s", cs_hexdump(0, cc->dcw, 16));
780 cc_crypt(&cc->block[DECRYPT], buf+4, l-4, ENCRYPT); // additional crypto step
781 pthread_mutex_unlock(&cc->ecm_busy);
782 //cc_abort_user_ecms();
783 cc_send_ecm(NULL, NULL);
784 ret = 0;
785 }
786 break;
787 case MSG_KEEPALIVE:
788 cc_cmd_send(NULL, 0, MSG_KEEPALIVE);
789 cs_debug("cccam: keepalive");
790 break;
791 case MSG_BAD_ECM:
792 //cc->ecm_count = 1;
793 //cs_log("cccam: cmd 0x05 recvd, commencing ecm count");
794 cc_cmd_send(NULL, 0, MSG_BAD_ECM);
795 break;
796 case MSG_CMD_0B:
797 // need to work out algo (reverse) for this...
798 cc_cycle_connection();
799 default:
800 break;
801 }
802
803 if (cc->ecm_count > CC_MAX_ECMS) cc_cycle_connection();
804
805 return ret;
806}
807
808static int cc_recv_chk(uchar *dcw, int *rc, uchar *buf)
809{
810 struct cc_data *cc = reader[ridx].cc;
811
812 if (buf[1] == MSG_CW_ECM) {
813 memcpy(dcw, cc->dcw, 16);
814 cs_debug("cccam: recv chk - MSG_CW %d - %s", cc->count, cs_hexdump(0, dcw, 16));
815 *rc = 1;
816 return(cc->count);
817 } else if ((buf[1] == (MSG_CW_NOK1)) || (buf[1] == (MSG_CW_NOK2))) {
818 memset(dcw, 0, 16);
819 return *rc = 0;
820 return(cc->count);
821 }
822
823 return (-1);
824}
825
826static void cc_send_dcw(ECM_REQUEST *er)
827{
828 uchar buf[16];
829 struct cc_data *cc;
830
831 bzero(buf, sizeof(buf));
832
833 if(er->rc<=3) {
834 cc = client[cs_idx].cc;
835 memcpy(buf, er->cw, sizeof(buf));
836 cc_cw_crypt(buf);
837 NULLFREE(cc->cur_card);
838 cs_debug("cccam: send cw: er->cpti=%d", er->cpti);
839 cc_cmd_send(buf, 16, MSG_CW_ECM);
840 cc_crypt(&cc->block[ENCRYPT], buf, 16, ENCRYPT); // additional crypto step
841 } else {
842 cs_debug("cccam: send cw NOK: er->cpti=%d!", er->cpti);
843 cc_cmd_send(NULL, 0, MSG_CW_NOK1);
844 }
845}
846
847int cc_recv(uchar *buf, int l)
848{
849 int n;
850 uchar *cbuf;
851 struct cc_data *cc;
852
853 if (reader[ridx].cc)
854 cc = reader[ridx].cc;
855 else
856 cc = client[cs_idx].cc;
857
858 if (buf==NULL) return -1;
859 cbuf = malloc(l);
860 if (cbuf==NULL) return -1;
861
862 memcpy(cbuf, buf, l); // make a copy of buf
863
864 pthread_mutex_lock(&cc->lock);
865
866 n = cc_msg_recv(cbuf); // recv and decrypt msg
867
868 cs_ddump(cbuf, n, "cccam: received %d bytes from %s", n, remote_txt());
869 client[cs_idx].last = time((time_t *) 0);
870
871 if (n == 0) {
872 cs_log("cccam: connection closed to %s", remote_txt());
873 n = -1;
874 } else if (n < 4) {
875 cs_log("cccam: packet to small (%d bytes)", n);
876 n = -1;
877 } else {
878 // parse it and write it back, if we have received something of value
879 cc_parse_msg(cbuf, n);
880 memcpy(buf, cbuf, l);
881 }
882
883 NULLFREE(cbuf);
884
885 pthread_mutex_unlock(&cc->lock);
886
887 if (!is_server && (n==-1)) {
888 cs_log("cccam: cycle connection");
889 cc_cycle_connection();
890 //cs_exit(1);
891 }
892
893 return(n);
894}
895
896static int cc_cli_connect(void)
897{
898 int handle, n;
899 uint8 data[20];
900 uint8 hash[SHA_DIGEST_LENGTH];
901 uint8 buf[CC_MAXMSGSIZE];
902 char pwd[64];
903 struct cc_data *cc;
904
905 if (reader[ridx].cc) NULLFREE(reader[ridx].cc);
906
907 // init internals data struct
908 cc = malloc(sizeof(struct cc_data));
909 if (cc==NULL) {
910 cs_log("cccam: cannot allocate memory");
911 return -1;
912 }
913 reader[ridx].cc = cc;
914 bzero(reader[ridx].cc, sizeof(struct cc_data));
915 cc->cards = llist_create();
916
917 cc->ecm_count = 0;
918
919 // check cred config
920 if(reader[ridx].device[0] == 0 || reader[ridx].r_pwd[0] == 0 ||
921 reader[ridx].r_usr[0] == 0 || reader[ridx].r_port == 0)
922 return -5;
923
924 // connect
925 handle = network_tcp_connection_open();
926 if(handle < 0) return -1;
927
928 // get init seed
929 if((n = recv(handle, data, 16, MSG_WAITALL)) != 16) {
930 cs_log("cccam: server does not return 16 bytes");
931 network_tcp_connection_close(handle);
932 return -2;
933 }
934 cs_ddump(data, 16, "cccam: server init seed:");
935
936 cc_xor(data); // XOR init bytes with 'CCcam'
937
938 SHA_CTX ctx;
939 SHA1_Init(&ctx);
940 SHA1_Update(&ctx, data, 16);
941 SHA1_Final(hash, &ctx);
942
943 cs_ddump(hash, sizeof(hash), "cccam: sha1 hash:");
944
945 //initialisate crypto states
946 cc_init_crypt(&cc->block[DECRYPT], hash, 20);
947 cc_crypt(&cc->block[DECRYPT], data, 16, DECRYPT);
948 cc_init_crypt(&cc->block[ENCRYPT], data, 16);
949 cc_crypt(&cc->block[ENCRYPT], hash, 20, DECRYPT);
950
951 cc_cmd_send(hash, 20, MSG_NO_HEADER); // send crypted hash to server
952
953 bzero(buf, sizeof(buf));
954 memcpy(buf, reader[ridx].r_usr, strlen(reader[ridx].r_usr));
955 cs_ddump(buf, 20, "cccam: username '%s':", buf);
956 cc_cmd_send(buf, 20, MSG_NO_HEADER); // send usr '0' padded -> 20 bytes
957
958 bzero(buf, sizeof(buf));
959 bzero(pwd, sizeof(pwd));
960
961 cs_debug("cccam: 'CCcam' xor");
962 memcpy(buf, "CCcam", 5);
963 strncpy(pwd, reader[ridx].r_pwd, 63);
964 cc_crypt(&cc->block[ENCRYPT], (uint8 *)pwd, strlen(pwd), ENCRYPT);
965 cc_cmd_send(buf, 6, MSG_NO_HEADER); // send 'CCcam' xor w/ pwd
966
967 if ((n = recv(handle, data, 20, MSG_WAITALL)) != 20) {
968 cs_log("cccam: login failed, pwd ack not received (n = %d)", n);
969 return -2;
970 }
971 cc_crypt(&cc->block[DECRYPT], data, 20, DECRYPT);
972 cs_ddump(data, 20, "cccam: pwd ack received:");
973
974 if (memcmp(data, buf, 5)) { // check server response
975 cs_log("cccam: login failed, usr/pwd invalid");
976 return -2;
977 } else {
978 cs_debug("cccam: login succeeded");
979 }
980
981 reader[ridx].tcp_connected = 1;
982 reader[ridx].last_g = reader[ridx].last_s = time((time_t *)0);
983
984 cs_debug("cccam: last_s=%d, last_g=%d", reader[ridx].last_s, reader[ridx].last_g);
985
986 pfd=client[cs_idx].udp_fd;
987
988 if (cc_send_cli_data()<=0) {
989 cs_log("cccam: login failed, could not send client data");
990 return -3;
991 }
992
993 pthread_mutex_init(&cc->lock, NULL);
994 pthread_mutex_init(&cc->ecm_busy, NULL);
995
996 reader[ridx].caid[0] = reader[ridx].ftab.filts[0].caid;
997 reader[ridx].nprov = reader[ridx].ftab.filts[0].nprids;
998 for (n=0; n<reader[ridx].nprov; n++) {
999 reader[ridx].prid[n][0] = reader[ridx].ftab.filts[0].prids[n] << 24;
1000 reader[ridx].prid[n][1] = reader[ridx].ftab.filts[0].prids[n] << 16;
1001 reader[ridx].prid[n][2] = reader[ridx].ftab.filts[0].prids[n] << 8;
1002 reader[ridx].prid[n][3] = reader[ridx].ftab.filts[0].prids[n] & 0xff;
1003 }
1004
1005 return 0;
1006}
1007
1008static void cc_srv_report_cards()
1009{
1010 int j;
1011 uint id = 1, r, k;
1012 uint8 hop = 0, reshare;
1013 uint8 buf[CC_MAXMSGSIZE];
1014 struct cc_data *cc = client[cs_idx].cc;
1015
1016 reshare = cfg->cc_reshare;
1017
1018 for (r=0; r<CS_MAXREADER; r++) {
1019 if (reader[r].caid[0]) {
1020 bzero(buf, sizeof(buf));
1021
1022 buf[0] = id >> 24;
1023 buf[1] = id >> 16;
1024 buf[2] = id >> 8;
1025 buf[3] = id & 0xff;
1026 buf[8] = reader[r].caid[0] >> 8;
1027 buf[9] = reader[r].caid[0] & 0xff;
1028 buf[10] = hop;
1029 buf[11] = reshare;
1030 buf[20] = reader[r].nprov;
1031
1032 for (j=0; j<reader[r].nprov; j++) {
1033 memcpy(buf + 21 + (j*7), reader[r].prid[j]+1, 3);
1034 }
1035
1036 buf[21 + (j*7)] = 1;
1037 memcpy(buf + 22 + (j*7), cc->node_id, 8);
1038
1039 cc_cmd_send(buf, 30 + (j*7), MSG_NEW_CARD);
1040
1041 id++;
1042 }
1043
1044 if (reader[r].ftab.filts) {
1045 for (j=0; j<CS_MAXFILTERS; j++) {
1046 if (reader[r].ftab.filts[j].caid) {
1047 bzero(buf, sizeof(buf));
1048
1049 buf[0] = id >> 24;
1050 buf[1] = id >> 16;
1051 buf[2] = id >> 8;
1052 buf[3] = id & 0xff;
1053 buf[8] = reader[r].ftab.filts[j].caid >> 8;
1054 buf[9] = reader[r].ftab.filts[j].caid & 0xff;
1055 buf[10] = hop;
1056 buf[11] = reshare;
1057 buf[20] = reader[r].ftab.filts[j].nprids;
1058
1059 for (k=0; k<reader[r].ftab.filts[j].nprids; k++) {
1060 buf[21 + (k*7)] = reader[r].ftab.filts[j].prids[k] << 24;
1061 buf[22 + (k*7)] = reader[r].ftab.filts[j].prids[k] << 16;
1062 buf[23 + (k*7)] = reader[r].ftab.filts[j].prids[k] << 8;
1063 buf[24 + (k*7)] = reader[r].ftab.filts[j].prids[k] & 0xff;
1064 }
1065
1066 buf[21 + (k*7)] = 1;
1067 memcpy(buf + 22 + (k*7), cc->node_id, 8);
1068
1069 cc_cmd_send(buf, 30 + (k*7), MSG_NEW_CARD);
1070
1071 id++;
1072 }
1073 }
1074 }
1075 }
1076}
1077
1078static int cc_srv_connect()
1079{
1080 int i;
1081 uint seed;
1082 uint8 buf[CC_MAXMSGSIZE];
1083 uint8 data[16];
1084 char usr[20], pwd[20];
1085 struct s_auth *account;
1086 struct cc_data *cc;
1087
1088 bzero(usr, sizeof(usr));
1089 bzero(pwd, sizeof(pwd));
1090
1091 if (client[cs_idx].cc) NULLFREE(client[cs_idx].cc);
1092
1093 // init internals data struct
1094 cc = malloc(sizeof(struct cc_data));
1095 if (cc==NULL) {
1096 cs_log("cccam: cannot allocate memory");
1097 return -1;
1098 }
1099
1100 client[cs_idx].cc = cc;
1101 bzero(client[cs_idx].cc, sizeof(struct cc_data));
1102
1103 // calc + send random seed
1104 seed = (unsigned int) time((time_t*)0);
1105 for(i=0; i<16; i++ ) data[i]=fast_rnd();
1106 send(client[cs_idx].udp_fd, data, 16, 0);
1107
1108 cc_xor(data); // XOR init bytes with 'CCcam'
1109
1110 SHA_CTX ctx;
1111 SHA1_Init(&ctx);
1112 SHA1_Update(&ctx, data, 16);
1113 SHA1_Final(buf, &ctx);
1114
1115 //initialisate crypto states
1116 /*
1117 init_crypt(&cc->block[ENCRYPT], buf, 20);
1118 crypto_state__decrypt(&cc->block[ENCRYPT], data, data2, 16);
1119 init_crypt(&cc->block[DECRYPT], data2, 16);
1120 crypto_state__encrypt(&cc->block[DECRYPT], buf, buf2, 20);*/
1121
1122 cc_init_crypt(&cc->block[ENCRYPT], buf, 20);
1123 cc_crypt(&cc->block[ENCRYPT], data, 16, DECRYPT);
1124 cc_init_crypt(&cc->block[DECRYPT], data, 16);
1125 cc_crypt(&cc->block[DECRYPT], buf, 20, DECRYPT);
1126
1127 if ((i=recv(pfd, buf, 20, MSG_WAITALL)) == 20) {
1128 cs_ddump(buf, 20, "cccam: recv:");
1129 cc_crypt(&cc->block[DECRYPT], buf, 20, DECRYPT);
1130 cs_ddump(buf, 20, "cccam: hash:");
1131 } else return -1;
1132
1133 // receive username
1134 if ((i=recv(pfd, buf, 20, MSG_WAITALL)) == 20) {
1135 cc_crypt(&cc->block[DECRYPT], buf, 20, DECRYPT);
1136 cs_ddump(buf, 20, "cccam: username '%s':", buf);
1137 strncpy(usr, (char *)buf, sizeof(usr));
1138 } else return -1;
1139
1140 for (account=cfg->account; account; account=account->next)
1141 if (strcmp(usr, account->usr) == 0) {
1142 strncpy(pwd, account->pwd, sizeof(pwd));
1143 break;
1144 }
1145
1146 strncpy(pwd, cfg->account->pwd, sizeof(pwd));
1147
1148 // receive passwd / 'CCcam'
1149 cc_crypt(&cc->block[DECRYPT], (uint8 *)pwd, strlen(pwd), DECRYPT);
1150 if ((i=recv(pfd, buf, 6, MSG_WAITALL)) == 6) {
1151 cc_crypt(&cc->block[DECRYPT], buf, 6, DECRYPT);
1152 cs_ddump(buf, 6, "cccam: pwd check '%s':", buf);
1153 } else return -1;
1154
1155 cs_auth_client(account, NULL);
1156 //cs_auth_client((struct s_auth *)(-1), NULL);
1157
1158 // send passwd ack
1159 bzero(buf, 20);
1160 memcpy(buf, "CCcam\0", 6);
1161 cs_ddump(buf, 20, "cccam: send ack:");
1162 cc_crypt(&cc->block[ENCRYPT], buf, 20, ENCRYPT);
1163 send(pfd, buf, 20, 0);
1164
1165 // recv cli data
1166 bzero(buf,sizeof(buf));
1167 i = cc_msg_recv(buf);
1168 cs_ddump(buf, i, "cccam: cli data:");
1169 memcpy(cc->peer_node_id, buf+24, 8);
1170 cs_log("cccam: client '%s' (%s) running v%s (%s)", buf+4, cs_hexdump(0, cc->peer_node_id, 8), buf+33, buf+65);
1171
1172 // send cli data ack
1173 cc_cmd_send(NULL, 0, MSG_CLI_DATA);
1174
1175 if (cc_send_srv_data()<0) return -1;
1176
1177 is_server = 1;
1178
1179 // report cards
1180 cc_srv_report_cards();
1181
1182 // check for clienttimeout, if timeout occurs try to send keepalive
1183 for(;;)
1184 {
1185 i=process_input(mbuf, sizeof(mbuf), cfg->cmaxidle);
1186
1187 if (i == -9)
1188 {
1189 if (cc_cmd_send(NULL, 0, MSG_KEEPALIVE) > 0)
1190 {
1191 cs_debug("cccam: keepalive");
1192 i = 1;
1193 }
1194 }
1195
1196 if (i <= 0)
1197 {
1198 break;
1199 }
1200 }
1201
1202 cs_disconnect_client();
1203
1204 return 0;
1205}
1206
1207void cc_srv_init()
1208{
1209 pfd=client[cs_idx].udp_fd;
1210 //cc_auth_client(client[cs_idx].ip);
1211 cc_srv_connect();
1212}
1213
1214int cc_cli_init()
1215{
1216 if (!reader[ridx].tcp_connected) {
1217 static struct sockaddr_in loc_sa;
1218 struct protoent *ptrp;
1219 int p_proto;
1220
1221 pfd=0;
1222 if (reader[ridx].r_port<=0)
1223 {
1224 cs_log("cccam: invalid port %d for server %s", reader[ridx].r_port, reader[ridx].device);
1225 return(1);
1226 }
1227 if( (ptrp=getprotobyname("tcp")) )
1228 p_proto=ptrp->p_proto;
1229 else
1230 p_proto=6;
1231
1232 client[cs_idx].ip=0;
1233 memset((char *)&loc_sa,0,sizeof(loc_sa));
1234 loc_sa.sin_family = AF_INET;
1235 #ifdef LALL
1236 if (cfg->serverip[0])
1237 loc_sa.sin_addr.s_addr = inet_addr(cfg->serverip);
1238 else
1239 #endif
1240 loc_sa.sin_addr.s_addr = INADDR_ANY;
1241 loc_sa.sin_port = htons(reader[ridx].l_port);
1242
1243 if ((client[cs_idx].udp_fd=socket(PF_INET, SOCK_STREAM, p_proto))<0)
1244 {
1245 cs_log("cccam: Socket creation failed (errno=%d)", errno);
1246 cs_exit(1);
1247 }
1248
1249 #ifdef SO_PRIORITY
1250 if (cfg->netprio)
1251 setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_PRIORITY,
1252 (void *)&cfg->netprio, sizeof(ulong));
1253 #endif
1254 if (!reader[ridx].tcp_ito) {
1255 ulong keep_alive = reader[ridx].tcp_ito?1:0;
1256 setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_KEEPALIVE,
1257 (void *)&keep_alive, sizeof(ulong));
1258 }
1259
1260 memset((char *)&client[cs_idx].udp_sa,0,sizeof(client[cs_idx].udp_sa));
1261 client[cs_idx].udp_sa.sin_family = AF_INET;
1262 client[cs_idx].udp_sa.sin_port = htons((u_short)reader[ridx].r_port);
1263
1264 struct hostent *server;
1265 server = gethostbyname(reader[ridx].device);
1266 memmove((char *)&client[cs_idx].udp_sa.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
1267
1268 if (reader[ridx].tcp_rto <= 0) reader[ridx].tcp_rto = 60 * 60 * 10; // timeout to 10 hours
1269 cs_debug("cccam: reconnect timeout set to: %d", reader[ridx].tcp_rto);
1270 if (!reader[ridx].cc_maxhop) reader[ridx].cc_maxhop = 10; // default maxhop to 10 if not configured
1271
1272 cs_log("cccam: proxy %s:%d cccam v%s (%s), maxhop = %d (fd=%d, ridx=%d)",
1273 reader[ridx].device, reader[ridx].r_port, reader[ridx].cc_version,
1274 reader[ridx].cc_build, reader[ridx].cc_maxhop, client[cs_idx].udp_fd, ridx);
1275
1276 cc_cli_connect();
1277
1278 return(0);
1279 }
1280 return(-1);
1281}
1282
1283void cc_cleanup(void)
1284{
1285
1286}
1287
1288void module_cccam(struct s_module *ph)
1289{
1290 strcpy(ph->desc, "cccam");
1291 ph->type=MOD_CONN_TCP;
1292 ph->logtxt = ", crypted";
1293 ph->watchdog=1;
1294 ph->recv=cc_recv;
1295 ph->cleanup=cc_cleanup;
1296 ph->c_multi=1;
1297 ph->c_init=cc_cli_init;
1298 ph->c_recv_chk=cc_recv_chk;
1299 ph->c_send_ecm=cc_send_ecm;
1300 ph->s_ip=cfg->cc_srvip;
1301 ph->s_handler=cc_srv_init;
1302 ph->send_dcw=cc_send_dcw;
1303
1304 static PTAB ptab;
1305 ptab.ports[0].s_port = cfg->cc_port;
1306 ph->ptab = &ptab;
1307 ph->ptab->nports = 1;
1308}
Note: See TracBrowser for help on using the repository browser.