source: trunk/module-cccam.c @ 1750

Last change on this file since 1750 was 1750, checked in by merek, 10 years ago

fix for cccam server advertising bad idents, thanks to red321z and equeorto

  • 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  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]+0, 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] >> 16;
1061            buf[22 + (k*7)] = reader[r].ftab.filts[j].prids[k] >> 8;
1062            buf[23 + (k*7)] = reader[r].ftab.filts[j].prids[k] & 0xff;
1063          }
1064
1065          buf[21 + (k*7)] = 1;
1066          memcpy(buf + 22 + (k*7), cc->node_id, 7);
1067
1068          cc_cmd_send(buf, 30 + (k*7), MSG_NEW_CARD);
1069
1070          id++;
1071        }
1072      }
1073    }
1074  }
1075}
1076
1077static int cc_srv_connect()
1078{
1079  int i;
1080  uint seed;
1081  uint8 buf[CC_MAXMSGSIZE];
1082  uint8 data[16];
1083  char usr[20], pwd[20];
1084  struct s_auth *account;
1085  struct cc_data *cc;
1086
1087  memset(usr, 0, sizeof(usr));
1088  memset(pwd, 0, sizeof(pwd));
1089
1090  if (client[cs_idx].cc) NULLFREE(client[cs_idx].cc);
1091
1092  // init internals data struct
1093  cc = malloc(sizeof(struct cc_data));
1094  if (cc==NULL) {
1095    cs_log("cccam: cannot allocate memory");
1096    return -1;
1097  }
1098
1099  client[cs_idx].cc = cc;
1100  memset(client[cs_idx].cc, 0, sizeof(struct cc_data));
1101
1102  // calc + send random seed
1103  seed = (unsigned int) time((time_t*)0);
1104  for(i=0; i<16; i++ ) data[i]=fast_rnd();
1105  send(client[cs_idx].udp_fd, data, 16, 0);
1106
1107  cc_xor(data);  // XOR init bytes with 'CCcam'
1108
1109  SHA_CTX ctx;
1110  SHA1_Init(&ctx);
1111  SHA1_Update(&ctx, data, 16);
1112  SHA1_Final(buf, &ctx);
1113
1114  //initialisate crypto states
1115  /*
1116  init_crypt(&cc->block[ENCRYPT], buf, 20);
1117  crypto_state__decrypt(&cc->block[ENCRYPT], data, data2, 16);
1118  init_crypt(&cc->block[DECRYPT], data2, 16);
1119  crypto_state__encrypt(&cc->block[DECRYPT], buf, buf2, 20);*/
1120
1121  cc_init_crypt(&cc->block[ENCRYPT], buf, 20);
1122  cc_crypt(&cc->block[ENCRYPT], data, 16, DECRYPT);
1123  cc_init_crypt(&cc->block[DECRYPT], data, 16);
1124  cc_crypt(&cc->block[DECRYPT], buf, 20, DECRYPT);
1125
1126  if ((i=recv(pfd, buf, 20, MSG_WAITALL)) == 20) {
1127    cs_ddump(buf, 20, "cccam: recv:");
1128    cc_crypt(&cc->block[DECRYPT], buf, 20, DECRYPT);
1129    cs_ddump(buf, 20, "cccam: hash:");
1130  } else return -1;
1131
1132  // receive username
1133  if ((i=recv(pfd, buf, 20, MSG_WAITALL)) == 20) {
1134    cc_crypt(&cc->block[DECRYPT], buf, 20, DECRYPT);
1135    cs_ddump(buf, 20, "cccam: username '%s':", buf);
1136    strncpy(usr, (char *)buf, sizeof(usr));
1137  } else return -1;
1138
1139  for (account=cfg->account; account; account=account->next)
1140    if (strcmp(usr, account->usr) == 0) {
1141      strncpy(pwd, account->pwd, sizeof(pwd));
1142      break;
1143    }
1144
1145  // receive passwd / 'CCcam'
1146  cc_crypt(&cc->block[DECRYPT], (uint8 *)pwd, strlen(pwd), DECRYPT);
1147  if ((i=recv(pfd, buf, 6, MSG_WAITALL)) == 6) {
1148    cc_crypt(&cc->block[DECRYPT], buf, 6, DECRYPT);
1149    cs_ddump(buf, 6, "cccam: pwd check '%s':", buf);
1150  } else return -1;
1151
1152  cs_auth_client(account, NULL);
1153  //cs_auth_client((struct s_auth *)(-1), NULL);
1154
1155  // send passwd ack
1156  memset(buf, 0, 20);
1157  memcpy(buf, "CCcam\0", 6);
1158  cs_ddump(buf, 20, "cccam: send ack:");
1159  cc_crypt(&cc->block[ENCRYPT], buf, 20, ENCRYPT);
1160  send(pfd, buf, 20, 0);
1161
1162  // recv cli data
1163  memset(buf, 0, sizeof(buf));
1164  i = cc_msg_recv(buf);
1165  cs_ddump(buf, i, "cccam: cli data:");
1166  memcpy(cc->peer_node_id, buf+24, 8);
1167  cs_log("cccam: client '%s' (%s) running v%s (%s)", buf+4, cs_hexdump(0, cc->peer_node_id, 8), buf+33, buf+65);
1168
1169  // send cli data ack
1170  cc_cmd_send(NULL, 0, MSG_CLI_DATA);
1171
1172  if (cc_send_srv_data()<0) return -1;
1173
1174  is_server = 1;
1175
1176  // report cards
1177  cc_srv_report_cards();
1178
1179  // check for clienttimeout, if timeout occurs try to send keepalive
1180  for(;;)
1181  {
1182    i=process_input(mbuf, sizeof(mbuf), cfg->cmaxidle);
1183     
1184    if (i == -9)
1185    {
1186      if (cc_cmd_send(NULL, 0, MSG_KEEPALIVE) > 0)
1187      {
1188        cs_debug("cccam: keepalive");
1189        i = 1;
1190      }
1191    }
1192     
1193    if (i <= 0)
1194    {
1195      break;
1196    }
1197  }
1198
1199  cs_disconnect_client();
1200
1201  return 0;
1202}
1203
1204void cc_srv_init()
1205{
1206  pfd=client[cs_idx].udp_fd;
1207  //cc_auth_client(client[cs_idx].ip);
1208  cc_srv_connect();
1209}
1210
1211int cc_cli_init()
1212{
1213  if (!reader[ridx].tcp_connected) {
1214    static struct sockaddr_in loc_sa;
1215    struct protoent *ptrp;
1216    int p_proto;
1217
1218    pfd=0;
1219    if (reader[ridx].r_port<=0)
1220    {
1221      cs_log("cccam: invalid port %d for server %s", reader[ridx].r_port, reader[ridx].device);
1222      return(1);
1223    }
1224    if( (ptrp=getprotobyname("tcp")) )
1225      p_proto=ptrp->p_proto;
1226    else
1227      p_proto=6;
1228
1229    client[cs_idx].ip=0;
1230    memset((char *)&loc_sa,0,sizeof(loc_sa));
1231    loc_sa.sin_family = AF_INET;
1232  #ifdef LALL
1233    if (cfg->serverip[0])
1234      loc_sa.sin_addr.s_addr = inet_addr(cfg->serverip);
1235    else
1236  #endif
1237      loc_sa.sin_addr.s_addr = INADDR_ANY;
1238    loc_sa.sin_port = htons(reader[ridx].l_port);
1239
1240    if ((client[cs_idx].udp_fd=socket(PF_INET, SOCK_STREAM, p_proto))<0)
1241    {
1242      cs_log("cccam: Socket creation failed (errno=%d)", errno);
1243      cs_exit(1);
1244    }
1245
1246  #ifdef SO_PRIORITY
1247    if (cfg->netprio)
1248      setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_PRIORITY,
1249                 (void *)&cfg->netprio, sizeof(ulong));
1250  #endif
1251    if (!reader[ridx].tcp_ito) {
1252      ulong keep_alive = reader[ridx].tcp_ito?1:0;
1253      setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_KEEPALIVE,
1254      (void *)&keep_alive, sizeof(ulong));
1255    }
1256
1257    memset((char *)&client[cs_idx].udp_sa,0,sizeof(client[cs_idx].udp_sa));
1258    client[cs_idx].udp_sa.sin_family = AF_INET;
1259    client[cs_idx].udp_sa.sin_port = htons((u_short)reader[ridx].r_port);
1260
1261    struct hostent *server;
1262    server = gethostbyname(reader[ridx].device);
1263    memmove((char *)&client[cs_idx].udp_sa.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
1264
1265    if (reader[ridx].tcp_rto <= 0) reader[ridx].tcp_rto = 60 * 60 * 10;  // timeout to 10 hours
1266    cs_debug("cccam: reconnect timeout set to: %d", reader[ridx].tcp_rto);
1267    if (!reader[ridx].cc_maxhop) reader[ridx].cc_maxhop = 10; // default maxhop to 10 if not configured
1268
1269    cs_log("cccam: proxy %s:%d cccam v%s (%s), maxhop = %d (fd=%d, ridx=%d)",
1270            reader[ridx].device, reader[ridx].r_port, reader[ridx].cc_version,
1271            reader[ridx].cc_build, reader[ridx].cc_maxhop, client[cs_idx].udp_fd, ridx);
1272
1273    cc_cli_connect();
1274
1275    return(0);
1276  }
1277  return(-1);
1278}
1279
1280void cc_cleanup(void)
1281{
1282
1283}
1284
1285void module_cccam(struct s_module *ph)
1286{
1287  strcpy(ph->desc, "cccam");
1288  ph->type=MOD_CONN_TCP;
1289  ph->logtxt = ", crypted";
1290  ph->watchdog=1;
1291  ph->recv=cc_recv;
1292  ph->cleanup=cc_cleanup;
1293  ph->c_multi=1;
1294  ph->c_init=cc_cli_init;
1295  ph->c_recv_chk=cc_recv_chk;
1296  ph->c_send_ecm=cc_send_ecm;
1297  ph->s_ip=cfg->cc_srvip;
1298  ph->s_handler=cc_srv_init;
1299  ph->send_dcw=cc_send_dcw;
1300
1301  static PTAB ptab;
1302  ptab.ports[0].s_port = cfg->cc_port;
1303  ph->ptab = &ptab;
1304  ph->ptab->nports = 1;
1305}
Note: See TracBrowser for help on using the repository browser.