Code:
r714 r727
93 93 /* I got the idea of expanding during the round function from SSLeay */
94 94 /* FIXME: can we do this in an endian-proof way? */
95 #ifdef WORDS_BIGENDIAN
95 #if __BYTE_ORDER == __BIG_ENDIAN
96 96 #define blk0(i) block->l[i]
97 97 #else
#
TabularUnified branches/smartreader/globals.h ¶
r714 r727
780 780 extern int nagra2_do_ecm(ECM_REQUEST *er);
781 781 extern int nagra2_card_info(void);
782 extern int nagra2_do_emm(EMM_PACKET *);
782 783
783 784 // protocol modules
#
TabularUnified branches/smartreader/module-cccam.c ¶
r716 r727
128 128 itr->l->items--;
129 129 if ((itr->cur == itr->l->first) && (itr->cur == itr->l->last)) {
130 [color=red] // cs_log("DEBUG %d: first&last", llist_count(itr->l));
131 130 free(itr->cur);
132 131 itr->l->first = NULL;
… …
134 133 return NULL;
135 134 } else if (itr->cur == itr->l->first) {
136 // cs_log("DEBUG %d: first", llist_count(itr->l));
137 135 struct llist_node *nxt = itr->cur->nxt;
138 136 free(itr->cur);
… …
141 139 itr->cur = nxt;
142 140 } else if (itr->cur == itr->l->last) {
143 // cs_log("DEBUG %d: last", llist_count(itr->l));
144 141 itr->l->last = itr->cur->prv;
145 142 itr->l->last->nxt = NULL;
… …
147 144 return NULL;
148 145 } else {
149 // cs_log("DEBUG %d: free middle", llist_count(itr->l));
150 146 struct llist_node *nxt = itr->cur->nxt;
151 147 itr->cur->prv->nxt = itr->cur->nxt;
… …
225 221 uint32 count;
226 222 uint16 cur_sid;
223
224 int last_nok;
227 225 };
228 226
… …
497 495 memcpy(buf + 29, reader[ridx].cc_version, sizeof(reader[ridx].cc_version)); // cccam version (ascii)
498 496 memcpy(buf + 61, reader[ridx].cc_build, sizeof(reader[ridx].cc_build)); // build number (ascii)
499 cs_log ("User: %s, version: %s, build: %s", reader[ridx].r_usr, reader[ridx].cc_version, reader[ridx].cc_build);
497
498 cs_log ("cccam: user: %s, version: %s, build: %s", reader[ridx].r_usr, reader[ridx].cc_version, reader[ridx].cc_build);
499
500
500 501 return cc_cmd_send(buf, 20 + 8 + 6 + 26 + 4 + 28 + 1, MSG_CLI_DATA);
502 }
503
504 static int cc_get_nxt_ecm(){
505 int n, i;
506 time_t t;
507
508 t=time((time_t *)0);
509 for (i = 1, n = 1; i < CS_MAXPENDING; i++)
510 {
511 if ((t-ecmtask[i].tps.time > ((cfg->ctimeout + 500) / 1000) + 1) &&
512 (ecmtask[i].rc >= 10)) // drop timeouts
513 {
514 ecmtask[i].rc=0;
515 }
516
517 if (ecmtask[i].rc >= 10) { // stil active and waiting
518 // search for the ecm with the lowest time, this should be the next to go
519 if ((!n || ecmtask[n].tps.time-ecmtask[i].tps.time < 0)) n = i;
520 }
521 }
522 return n;
501 523 }
502 524
… …
507 529 struct cc_card *card;
508 530 LLIST_ITR itr;
509
510 memcpy(buf, er->ecm, er->l);
531 ECM_REQUEST *cur_er;
532
533 if ((n = cc_get_nxt_ecm()) < 0) return 0; // no queued ecms
534 cur_er = &ecmtask[n];
535 if (cur_er->rc == 99) return 0; // ecm already sent
536
537 memcpy(buf, cur_er->ecm, cur_er->l);
511 538
512 539 cc->cur_card = NULL;
513 cc->cur_sid = er->srvid;
540 cc->cur_sid = cur_er->srvid;
514 541
515 542 card = llist_itr_init(cc->cards, &itr);
516 543
517 544 while (card) {
518 if (card->caid == er->caid) { // caid matches
545 if (card->caid == cur_er->caid) { // caid matches
519 546 int s = 0;
520 547
… …
533 560 uint8 *prov = llist_itr_init(card->provs, &pitr);
534 561 while (prov && !s) {
535 if (b2i(3, prov) == er->prid) { // provid matches
562 if (b2i(3, prov) == cur_er->prid) { // provid matches
536 563 if ((h < 0) || (card->hop < h)) { // card is closer
537 564 cc->cur_card = card;
… …
548 575
549 576 if (cc->cur_card) {
550 uint8 *ecmbuf = malloc(er->l+13);
551 bzero(ecmbuf, er->l+13);
577 uint8 *ecmbuf = malloc(cur_er->l+13);
578 bzero(ecmbuf, cur_er->l+13);
552 579
553 580 // build ecm message
554 581 ecmbuf[0] = cc->cur_card->caid >> 8;
555 582 ecmbuf[1] = cc->cur_card->caid & 0xff;
556 ecmbuf[2] = er->prid >> 24;
557 ecmbuf[3] = er->prid >> 16;
558 ecmbuf[4] = er->prid >> 8;
559 ecmbuf[5] = er->prid & 0xff;
583 ecmbuf[2] = cur_er->prid >> 24;
584 ecmbuf[3] = cur_er->prid >> 16;
585 ecmbuf[4] = cur_er->prid >> 8;
586 ecmbuf[5] = cur_er->prid & 0xff;
560 587 ecmbuf[6] = cc->cur_card->id >> 24;
561 588 ecmbuf[7] = cc->cur_card->id >> 16;
562 589 ecmbuf[8] = cc->cur_card->id >> 8;
563 590 ecmbuf[9] = cc->cur_card->id & 0xff;
564 ecmbuf[10] = er->srvid >> 8;
565 ecmbuf[11] = er->srvid & 0xff;
566 ecmbuf[12] = er->l & 0xff;
567 memcpy(ecmbuf+13, buf, er->l);
568
569 cc->count = er->idx;
570
571 cs_log("cccam: sending ecm for sid %04x to card %08x, hop %d", er->srvid, cc->cur_card->id, cc->cur_card->hop + 1);
572 n = cc_cmd_send(ecmbuf, er->l+13, MSG_ECM); // send ecm
591 ecmbuf[10] = cur_er->srvid >> 8;
592 ecmbuf[11] = cur_er->srvid & 0xff;
593 ecmbuf[12] = cur_er->l & 0xff;
594 memcpy(ecmbuf+13, buf, cur_er->l);
595
596 cc->count = cur_er->idx;
597
598 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);
599 n = cc_cmd_send(ecmbuf, cur_er->l+13, MSG_ECM); // send ecm
573 600
574 601 X_FREE(ecmbuf);
… …
576 603 n = -1;
577 604 cs_log("cccam: no suitable card on server");
605 cur_er->rc = 0;
606 cur_er->rcEx = 0x27;
607 //cur_er->rc = 1;
608 //cur_er->rcEx = 0;
609 usleep(100000);
610 write_ecm_answer(fd_c2m, cur_er);
611 //reader[ridx].last_s = reader[ridx].last_g;
612
613 card = llist_itr_init(cc->cards, &itr);
614 while (card) {
615 if (card->caid == cur_er->caid) { // caid matches
616 LLIST_ITR sitr;
617 uint16 *sid = llist_itr_init(card->badsids, &sitr);
618 while (sid) {
619 sid = llist_itr_remove(&sitr);
620 }
621 llist_itr_release(&sitr);
622 }
623 card = llist_itr_next(&itr);
624 }
625 llist_itr_release(&itr);
578 626 }
579 627
580 628 return 0;
581 629 }
630
631 // this is a hack and it's baaaaaad. It's also not used yet!
632 /*
633 static void cc_rebuild_caid_tab()
634 {
635 int zz;
636 for(zz = 0; zz < CS_MAXCAIDTAB; zz++) {
637 cs_log("caid %x", reader[ridx].ctab.caid[zz]);
638 }
639 }
640 */
582 641
583 642 static cc_msg_type_t cc_parse_msg(uint8 *buf, int l)
… …
594 653 break;
595 654 case MSG_NEW_CARD:
596 if (b2i(2, buf+12) == reader[ridx].ctab.caid[0]) { // only add cards with relevant caid (for now)
597 int i;
655 // find blank caid slot in tab and add caid
656
657 {
658 int i = 0;
659 /*, p = 0;
660 while(reader[ridx].ctab.caid[i]) {
661 if (reader[ridx].ctab.caid[i] == b2i(2, buf+12)) p = 1;
662 i++;
663 }
664 if (!p) {
665 reader[ridx].ctab.caid[i] = b2i(2, buf+12);
666 }
667 */
668
669 // if (b2i(2, buf+12) == reader[ridx].ctab.caid[0]) { // only add cards with relevant caid (for now)
670 // int i;
598 671 struct cc_card *card = malloc(sizeof(struct cc_card));
599 672
… …
699 772 return(cc->count);
700 773 } else if ((buf[1] == (MSG_CW_NOK1)) || (buf[1] == (MSG_CW_NOK2))) {
701 /*memcpy(dcw, cc->dcw, 16);
702 return *rc = 1;
703 return(cc->count);*/
774 memset(dcw, 0, 16);
775 return *rc = 0;
776 return(cc->count);
704 777 }
705 778
… …
832 905 int cc_cli_init(void)
833 906 {
834 static struct sockaddr_in loc_sa;
835 struct protoent *ptrp;
836 int p_proto;
837
838 pfd=0;
839 if (reader[ridx].r_port<=0)
840 {
841 cs_log("cccam: invalid port %d for server %s", reader[ridx].r_port, reader[ridx].device);
842 return(1);
843 }
844 if( (ptrp=getprotobyname("tcp")) )
845 p_proto=ptrp->p_proto;
846 else
847 p_proto=6;
848
849 client[cs_idx].ip=0;
850 memset((char *)&loc_sa,0,sizeof(loc_sa));
851 loc_sa.sin_family = AF_INET;
852 #ifdef LALL
853 if (cfg->serverip[0])
854 loc_sa.sin_addr.s_addr = inet_addr(cfg->serverip);
855 else
856 #endif
857 loc_sa.sin_addr.s_addr = INADDR_ANY;
858 loc_sa.sin_port = htons(reader[ridx].l_port);
859
860 if ((client[cs_idx].udp_fd=socket(PF_INET, SOCK_STREAM, p_proto))<0)
861 {
862 cs_log("cccam: Socket creation failed (errno=%d)", errno);
863 cs_exit(1);
864 }
865
866 #ifdef SO_PRIORITY
867 if (cfg->netprio)
868 setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_PRIORITY,
869 (void *)&cfg->netprio, sizeof(ulong));
870 #endif
871 if (!reader[ridx].tcp_ito) {
872 ulong keep_alive = reader[ridx].tcp_ito?1:0;
873 setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_KEEPALIVE,
874 (void *)&keep_alive, sizeof(ulong));
875 }
876
877 memset((char *)&client[cs_idx].udp_sa,0,sizeof(client[cs_idx].udp_sa));
878 client[cs_idx].udp_sa.sin_family = AF_INET;
879 client[cs_idx].udp_sa.sin_port = htons((u_short)reader[ridx].r_port);
880
881 struct hostent *server;
882 server = gethostbyname(reader[ridx].device);
883 bcopy((char *)server->h_addr, (char *)&client[cs_idx].udp_sa.sin_addr.s_addr, server->h_length);
884
885 cs_log("cccam: proxy %s:%d cccam v%s (%s) (fd=%d)",
886 reader[ridx].device, reader[ridx].r_port, reader[ridx].cc_version,
887 reader[ridx].cc_build, client[cs_idx].udp_fd);
888
889 cc_cli_connect();
890
891 return(0);
907 if (!reader[ridx].tcp_connected) {
908 static struct sockaddr_in loc_sa;
909 struct protoent *ptrp;
910 int p_proto;
911
912 pfd=0;
913 if (reader[ridx].r_port<=0)
914 {
915 cs_log("cccam: invalid port %d for server %s", reader[ridx].r_port, reader[ridx].device);
916 return(1);
917 }
918 if( (ptrp=getprotobyname("tcp")) )
919 p_proto=ptrp->p_proto;
920 else
921 p_proto=6;
922
923 client[cs_idx].ip=0;
924 memset((char *)&loc_sa,0,sizeof(loc_sa));
925 loc_sa.sin_family = AF_INET;
926 #ifdef LALL
927 if (cfg->serverip[0])
928 loc_sa.sin_addr.s_addr = inet_addr(cfg->serverip);
929 else
930 #endif
931 loc_sa.sin_addr.s_addr = INADDR_ANY;
932 loc_sa.sin_port = htons(reader[ridx].l_port);
933
934 if ((client[cs_idx].udp_fd=socket(PF_INET, SOCK_STREAM, p_proto))<0)
935 {
936 cs_log("cccam: Socket creation failed (errno=%d)", errno);
937 cs_exit(1);
938 }
939
940 #ifdef SO_PRIORITY
941 if (cfg->netprio)
942 setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_PRIORITY,
943 (void *)&cfg->netprio, sizeof(ulong));
944 #endif
945 if (!reader[ridx].tcp_ito) {
946 ulong keep_alive = reader[ridx].tcp_ito?1:0;
947 setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_KEEPALIVE,
948 (void *)&keep_alive, sizeof(ulong));
949 }
950
951 memset((char *)&client[cs_idx].udp_sa,0,sizeof(client[cs_idx].udp_sa));
952 client[cs_idx].udp_sa.sin_family = AF_INET;
953 client[cs_idx].udp_sa.sin_port = htons((u_short)reader[ridx].r_port);
954
955 struct hostent *server;
956 server = gethostbyname(reader[ridx].device);
957 bcopy((char *)server->h_addr, (char *)&client[cs_idx].udp_sa.sin_addr.s_addr, server->h_length);
958
959 reader[ridx].tcp_rto = 60 * 60 * 10; // timeout to 10 hours
960
961 cs_log("cccam: proxy %s:%d cccam v%s (%s) (fd=%d, ridx=%d)",
962 reader[ridx].device, reader[ridx].r_port, reader[ridx].cc_version,
963 reader[ridx].cc_build, client[cs_idx].udp_fd, ridx);
964
965 cc_cli_connect();
966
967 return(0);
968 }
969 return(-1);
892 970 }
893 971
#
TabularUnified branches/smartreader/module-newcamd.c ¶
r577 r727
64 64 break;
65 65 case COMMTYPE_SERVER:
66 if( *netMsgId == 0xFFFE ) *netMsgId = 0; // � 0xFFFF ?
66 if( *netMsgId == 0xFFFE ) *netMsgId = 0; // ��� 0xFFFF ?
67 67 break;
68 68 }
… …
531 531 ctab_caid = client[cs_idx].ctab.caid[i]&client[cs_idx].ctab.mask[i];
532 532 if( ctab_caid ) c++;
533
533 534 if( psfilt->caid==ctab_caid )
534 535 {
#
TabularUnified branches/smartreader/oscam-config.c ¶
r684 r727
1103 1103 if (!strcmp(value, "cs357x")) { rdr->typ=R_CAMD35; return; }
1104 1104 if (!strcmp(value, "gbox")) { rdr->typ=R_GBOX; return; }
1105 if (!strcmp(value, "cccam")) { rdr->typ=R_CCCAM; return; }
1105 if (!strcmp(value, "cccam")) {
1106 rdr->typ=R_CCCAM;
1107 // strcpy(value, "1");
1108 // chk_caidtab(value, &rdr->ctab); // this is a MAJOR hack for auto multiple caid support (not currently working due to ncd table issue)
1109 return;
1110 }
1106 1111 if (!strcmp(value, "radegast")) { rdr->typ=R_RADEGAST; return; }
1107 1112 if (!strcmp(value, "newcamd") ||
#
TabularUnified branches/smartreader/oscam.c ¶
r660 r727
95 95 "dingo35 and okmikel for newcamd-support",
96 96 "hellmaster1024 for gb*x-support",
97 "cogsi for cccam reader and radegast reader support",
97 98 "the vdr-sc team for several good ideas :-)",
98 99 NULL };
… …
1512 1513 static char *stxt[]={"found", "cache1", "cache2", "emu",
1513 1514 "not found", "timeout", "sleeping",
1514 "fake", "invalid", "corrupt"};
1515 static char *stxtEx[]={"", "group", "caid", "ident", "class", "chid", "queue"};
1515 "fake", "invalid", "corrupt", "no card"};
1516 static char *stxtEx[]={"", "group", "caid", "ident", "class", "chid", "queue", "peer"};
1516 1517 static char *stxtWh[]={"", "user ", "reader ", "server ", "lserver "};
1517 1518 char sby[32]="";
#
TabularUnified branches/smartreader/reader-common.c ¶
r684 r727
427 427 switch(reader[ridx].card_system)
428 428 {
429 case SC_NAGRA:
430 rc=nagra2_do_emm(ep); break;
429 431 case SC_IRDETO:
430 432 rc=irdeto_do_emm(ep); break;
#
TabularUnified branches/smartreader/reader-nagra.c ¶
r707 r727
12 12 extern ushort cta_lr;
13 13 int is_pure_nagra=0;
14 int hasMod=0;
15 14 unsigned char rom[15];
16 15 unsigned char plainDT08RSA[64];
… …
191 190 [sci0] -> b8 04 19 90 7b f4 90 00
192 191 */
192 }
193
194 void getCamID(void)
195 {
196 /*
197 Hack:
198 Get camid. For provider 0401/3411 camid is 0xff,0xff,0xff,0xff.
199 for other provider we will take them from hexserial
200 */
201 unsigned char prv0401[] = {0x00, 0x00, 0x04, 0x01};
202 unsigned char prv3411[] = {0x00, 0x00, 0x34, 0x11};
203 if ((memcmp(prv3411,&reader[ridx].prid[0],4)==0) || (memcmp(prv0401,&reader[ridx].prid[0],4)==0))
204 {
205 memset(camid,0xff,4);
206 }
207 else
208 {
209 memcpy(camid,reader[ridx].hexserial,4);
210 }
193 211 }
194 212
… …
329 347 //cs_debug("[nagra-reader] dt08 72byte idea decrypted: %s", cs_hexdump (1, &static_dt08[35], 37));
330 348
349 getCamID();
350 cs_debug("[nagra-reader] using camid %sfor dt08 calc",cs_hexdump (1,camid,4));
351
331 352 // Calculate signature
332 353 memcpy (signature, static_dt08, 8);
… …
334 355 memcpy (static_dt08 + 4, camid, 4);
335 356 Signature(sign2,IdeaCamKey,static_dt08,72);
336
337 memcpy (plainDT08RSA, static_dt08+8, 64);
338 357
339 358 BN_CTX_free (ctx);
… …
343 362 if (memcmp (signature, sign2, 8)==0)
344 363 {
364 memcpy (plainDT08RSA, static_dt08+8, 64);
345 365 cs_debug("[nagra-reader] DT08 signature check ok");
346 hasMod=1;
347 366 }
348 367 else
349 368 {
369 memcpy (plainDT08RSA, reader[ridx].rsa_mod, 64);
350 370 cs_debug("[nagra-reader] DT08 signature check nok");
351 hasMod=0;
371 cs_debug("[nagra-reader] DT08 use n3_rsakey as pairingkey");
352 372 }
353 373 }
… …
418 438 reader[ridx].prid[0][2]=cta_res[7];
419 439 reader[ridx].prid[0][3]=cta_res[8];
420 reader[ridx].caid[0] =(SYSTEM_NAGRA|cta_res[11]);
440 reader[ridx].caid[0] =(SYSTEM_NAGRA|cta_res[11]);
421 441 memcpy(irdId,cta_res+14,4);
422 442 cs_debug("[nagra-reader] CAID: %04X, IRD ID: %s",reader[ridx].caid[0], cs_hexdump (1,irdId,4));
… …
437 457 }
438 458 case 0x08:
439 case 0x88: if (cta_res[11] == 0x49) decryptDT08(); return 1;
459 case 0x88: if (cta_res[11] == 0x49) decryptDT08();
440 460 default:
441 461 return 1;
… …
588 608 return(0);
589 609 }
590
610 /*
611 very experimental EMM support !!
612 */
591 613 int nagra2_do_emm(EMM_PACKET *ep)
592 614 {
615 cs_debug("[nagra-reader] -----------------");
616 cs_debug("[nagra-reader] -----------------");
617 cs_dump(ep->emm, 64, "[nagra-reader]EMM:");
618 cs_debug("[nagra-reader] -----------------");
619 cs_debug("[nagra-reader] -----------------");
593 620 if(!do_cmd(ep->emm[8],ep->emm[9]+2,0x84,0x02,ep->emm+8+2))
594 621 {
… …
596 623 return (0);
597 624 }
598 cs_sleepms(500);
599 cs_dump(ep->emm, 64, "[nagra-reader]EMM:");
625 cs_sleepms(300);
600 626 return 1;
601 627 }