source: trunk/module-cccam.c@ 1671

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

Replace bzero with memset, as bzero is deprecated on the most oses and not portable

  • Property svn:mime-type set to text/plain
File size: 32.0 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 memset(l, 0, 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 memset(ln, 0, 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 memset(itr, 0, 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 memset(netbuf, 0, 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 memset(buf, 0, 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 memset(buf, 0, 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 memset(ecmbuf, 0, 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 memset(card, 0, 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 memset(cc->dcw, 0, 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 memset(cc->cur_card, 0, 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 memset(buf, 0, 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 memset(reader[ridx].cc, 0, 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 memset(buf, 0, 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 memset(buf, 0, sizeof(buf));
959 memset(pwd, 0, 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 memset(buf, 0, 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 memset(buf, 0, 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 memset(usr, 0, sizeof(usr));
1089 memset(pwd, 0, 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 memset(client[cs_idx].cc, 0, 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 // receive passwd / 'CCcam'
1147 cc_crypt(&cc->block[DECRYPT], (uint8 *)pwd, strlen(pwd), DECRYPT);
1148 if ((i=recv(pfd, buf, 6, MSG_WAITALL)) == 6) {
1149 cc_crypt(&cc->block[DECRYPT], buf, 6, DECRYPT);
1150 cs_ddump(buf, 6, "cccam: pwd check '%s':", buf);
1151 } else return -1;
1152
1153 cs_auth_client(account, NULL);
1154 //cs_auth_client((struct s_auth *)(-1), NULL);
1155
1156 // send passwd ack
1157 memset(buf, 0, 20);
1158 memcpy(buf, "CCcam\0", 6);
1159 cs_ddump(buf, 20, "cccam: send ack:");
1160 cc_crypt(&cc->block[ENCRYPT], buf, 20, ENCRYPT);
1161 send(pfd, buf, 20, 0);
1162
1163 // recv cli data
1164 memset(buf, 0, sizeof(buf));
1165 i = cc_msg_recv(buf);
1166 cs_ddump(buf, i, "cccam: cli data:");
1167 memcpy(cc->peer_node_id, buf+24, 8);
1168 cs_log("cccam: client '%s' (%s) running v%s (%s)", buf+4, cs_hexdump(0, cc->peer_node_id, 8), buf+33, buf+65);
1169
1170 // send cli data ack
1171 cc_cmd_send(NULL, 0, MSG_CLI_DATA);
1172
1173 if (cc_send_srv_data()<0) return -1;
1174
1175 is_server = 1;
1176
1177 // report cards
1178 cc_srv_report_cards();
1179
1180 // check for clienttimeout, if timeout occurs try to send keepalive
1181 for(;;)
1182 {
1183 i=process_input(mbuf, sizeof(mbuf), cfg->cmaxidle);
1184
1185 if (i == -9)
1186 {
1187 if (cc_cmd_send(NULL, 0, MSG_KEEPALIVE) > 0)
1188 {
1189 cs_debug("cccam: keepalive");
1190 i = 1;
1191 }
1192 }
1193
1194 if (i <= 0)
1195 {
1196 break;
1197 }
1198 }
1199
1200 cs_disconnect_client();
1201
1202 return 0;
1203}
1204
1205void cc_srv_init()
1206{
1207 pfd=client[cs_idx].udp_fd;
1208 //cc_auth_client(client[cs_idx].ip);
1209 cc_srv_connect();
1210}
1211
1212int cc_cli_init()
1213{
1214 if (!reader[ridx].tcp_connected) {
1215 static struct sockaddr_in loc_sa;
1216 struct protoent *ptrp;
1217 int p_proto;
1218
1219 pfd=0;
1220 if (reader[ridx].r_port<=0)
1221 {
1222 cs_log("cccam: invalid port %d for server %s", reader[ridx].r_port, reader[ridx].device);
1223 return(1);
1224 }
1225 if( (ptrp=getprotobyname("tcp")) )
1226 p_proto=ptrp->p_proto;
1227 else
1228 p_proto=6;
1229
1230 client[cs_idx].ip=0;
1231 memset((char *)&loc_sa,0,sizeof(loc_sa));
1232 loc_sa.sin_family = AF_INET;
1233 #ifdef LALL
1234 if (cfg->serverip[0])
1235 loc_sa.sin_addr.s_addr = inet_addr(cfg->serverip);
1236 else
1237 #endif
1238 loc_sa.sin_addr.s_addr = INADDR_ANY;
1239 loc_sa.sin_port = htons(reader[ridx].l_port);
1240
1241 if ((client[cs_idx].udp_fd=socket(PF_INET, SOCK_STREAM, p_proto))<0)
1242 {
1243 cs_log("cccam: Socket creation failed (errno=%d)", errno);
1244 cs_exit(1);
1245 }
1246
1247 #ifdef SO_PRIORITY
1248 if (cfg->netprio)
1249 setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_PRIORITY,
1250 (void *)&cfg->netprio, sizeof(ulong));
1251 #endif
1252 if (!reader[ridx].tcp_ito) {
1253 ulong keep_alive = reader[ridx].tcp_ito?1:0;
1254 setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_KEEPALIVE,
1255 (void *)&keep_alive, sizeof(ulong));
1256 }
1257
1258 memset((char *)&client[cs_idx].udp_sa,0,sizeof(client[cs_idx].udp_sa));
1259 client[cs_idx].udp_sa.sin_family = AF_INET;
1260 client[cs_idx].udp_sa.sin_port = htons((u_short)reader[ridx].r_port);
1261
1262 struct hostent *server;
1263 server = gethostbyname(reader[ridx].device);
1264 memmove((char *)&client[cs_idx].udp_sa.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
1265
1266 if (reader[ridx].tcp_rto <= 0) reader[ridx].tcp_rto = 60 * 60 * 10; // timeout to 10 hours
1267 cs_debug("cccam: reconnect timeout set to: %d", reader[ridx].tcp_rto);
1268 if (!reader[ridx].cc_maxhop) reader[ridx].cc_maxhop = 10; // default maxhop to 10 if not configured
1269
1270 cs_log("cccam: proxy %s:%d cccam v%s (%s), maxhop = %d (fd=%d, ridx=%d)",
1271 reader[ridx].device, reader[ridx].r_port, reader[ridx].cc_version,
1272 reader[ridx].cc_build, reader[ridx].cc_maxhop, client[cs_idx].udp_fd, ridx);
1273
1274 cc_cli_connect();
1275
1276 return(0);
1277 }
1278 return(-1);
1279}
1280
1281void cc_cleanup(void)
1282{
1283
1284}
1285
1286void module_cccam(struct s_module *ph)
1287{
1288 strcpy(ph->desc, "cccam");
1289 ph->type=MOD_CONN_TCP;
1290 ph->logtxt = ", crypted";
1291 ph->watchdog=1;
1292 ph->recv=cc_recv;
1293 ph->cleanup=cc_cleanup;
1294 ph->c_multi=1;
1295 ph->c_init=cc_cli_init;
1296 ph->c_recv_chk=cc_recv_chk;
1297 ph->c_send_ecm=cc_send_ecm;
1298 ph->s_ip=cfg->cc_srvip;
1299 ph->s_handler=cc_srv_init;
1300 ph->send_dcw=cc_send_dcw;
1301
1302 static PTAB ptab;
1303 ptab.ports[0].s_port = cfg->cc_port;
1304 ph->ptab = &ptab;
1305 ph->ptab->nports = 1;
1306}
Note: See TracBrowser for help on using the repository browser.