source: trunk/module-cccam.c@ 3181

Last change on this file since 3181 was 3181, checked in by dingo35, 10 years ago

Adding threadsafety FIXMEs, feel free to join checking..

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