source: trunk/oscam.c@ 4149

Last change on this file since 4149 was 4142, checked in by dingo35, 13 years ago

oscam.c : update help text

File size: 86.7 KB
Line 
1//FIXME Not checked on threadsafety yet; after checking please remove this line
2#define CS_CORE
3#include "globals.h"
4#ifdef AZBOX
5# include "openxcas/openxcas_api.h"
6#endif
7#ifdef CS_WITH_GBOX
8# include "csgbox/gbox.h"
9# define CS_VERSION_X CS_VERSION "-gbx-" GBXVERSION
10#else
11# define CS_VERSION_X CS_VERSION
12#endif
13#ifdef COOL
14void coolapi_close_all();
15#endif
16
17extern void cs_statistics(struct s_client * client);
18
19/*****************************************************************************
20 Globals
21*****************************************************************************/
22struct s_module ph[CS_MAX_MOD]; // Protocols
23struct s_cardsystem cardsystem[CS_MAX_MOD]; // Protocols
24struct s_client * first_client = NULL; //Pointer to clients list, first client is master
25struct s_reader * first_reader = NULL;
26
27ushort len4caid[256]; // table for guessing caid (by len)
28char cs_confdir[128]=CS_CONFDIR;
29int cs_dblevel=0; // Debug Level (TODO !!)
30char cs_tmpdir[200]={0x00};
31pthread_mutex_t gethostbyname_lock;
32pthread_mutex_t cwcache_lock;
33pthread_key_t getclient;
34
35//Cache for **found** cws:
36struct s_ecm *cwcache;
37struct s_ecm *cwidx;
38
39//Cache for **requesting** ecms:
40struct s_ecm *ecmcache;
41struct s_ecm *ecmidx;
42pthread_mutex_t ecmcache_lock;
43
44#ifdef CS_WITH_GBOX
45struct card_struct Cards[CS_MAXCARDS];
46//struct idstore_struct idstore[CS_MAXPID];
47unsigned long IgnoreList[CS_MAXIGNORE];
48#endif
49
50struct s_config *cfg;
51#ifdef CS_LOGHISTORY
52int loghistidx; // ptr to current entry
53char loghist[CS_MAXLOGHIST*CS_LOGHISTSIZE]; // ptr of log-history
54#endif
55
56int get_ridx(struct s_reader *reader) {
57 int i;
58 struct s_reader *rdr;
59 for (i=0,rdr=first_reader; rdr ; rdr=rdr->next, i++)
60 if (reader == rdr)
61 return i;
62 return -1;
63}
64
65int get_nr_of_readers() {
66 int i;
67 struct s_reader *rdr;
68 for (i=0,rdr=first_reader; rdr ; rdr=rdr->next, i++);
69 return i;
70}
71
72int get_threadnum(struct s_client *client) {
73 struct s_client *cl;
74 int count=0;
75
76 for (cl=first_client->next; cl ; cl=cl->next) {
77 if (cl->typ==client->typ)
78 count++;
79 if(cl==client)
80 return count;
81 }
82 return 0;
83}
84
85struct s_client * cur_client(void)
86{
87 return (struct s_client *) pthread_getspecific(getclient);
88}
89
90int cs_check_violation(uint ip) {
91 if (cfg->failbantime) {
92
93 time_t now = time((time_t)0);
94 LLIST_D__ITR itr;
95 V_BAN *v_ban_entry = llist_itr_init(cfg->v_list, &itr);
96
97 while (v_ban_entry) {
98 if (ip == v_ban_entry->v_ip) {
99 if ((now - v_ban_entry->v_time) >= (cfg->failbantime * 60)) {
100 // housekeeping
101 free(v_ban_entry);
102 llist_itr_remove(&itr);
103 return 0;
104 }
105 cs_debug_mask(D_TRACE, "failban: banned ip %s - %ld seconds left",
106 cs_inet_ntoa(v_ban_entry->v_ip),(cfg->failbantime * 60) - (now - v_ban_entry->v_time));
107 return 1;
108 }
109 v_ban_entry = llist_itr_next(&itr);
110 }
111 return 0;
112 }
113 return 0;
114}
115
116void cs_add_violation(uint ip) {
117 if (cfg->failbantime) {
118
119 if (!cfg->v_list)
120 cfg->v_list = llist_create();
121
122 LLIST_D__ITR itr;
123 V_BAN *v_ban_entry = llist_itr_init(cfg->v_list, &itr);
124 while (v_ban_entry) {
125 if (ip == v_ban_entry->v_ip) {
126 cs_debug_mask(D_TRACE, "failban: banned ip %s - already exist in list", cs_inet_ntoa(v_ban_entry->v_ip));
127 return ;
128 }
129 v_ban_entry = llist_itr_next(&itr);
130 }
131
132 v_ban_entry = malloc(sizeof(V_BAN));
133 memset(v_ban_entry, 0, sizeof(V_BAN));
134
135 v_ban_entry->v_time = time((time_t *)0);
136 v_ban_entry->v_ip = ip;
137
138 llist_append(cfg->v_list, v_ban_entry);
139
140 cs_debug_mask(D_TRACE, "failban: ban ip %s with timestamp %d", cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_time);
141
142 }
143}
144//Alno Test End
145/*****************************************************************************
146 Statics
147*****************************************************************************/
148static const char *logo = " ___ ____ ___ \n / _ \\/ ___| / __|__ _ _ __ ___ \n| | | \\___ \\| | / _` | '_ ` _ \\ \n| |_| |___) | |_| (_| | | | | | |\n \\___/|____/ \\___\\__,_|_| |_| |_|\n";
149
150static void usage()
151{
152 fprintf(stderr, "%s\n\n", logo);
153 fprintf(stderr, "OSCam cardserver v%s, build #%s (%s) - (w) 2009-2010 streamboard SVN\n", CS_VERSION_X, CS_SVN_VERSION, CS_OSTYPE);
154 fprintf(stderr, "\tsee http://streamboard.gmc.to:8001/wiki/ for more details\n");
155 fprintf(stderr, "\tbased on streamboard mp-cardserver v0.9d - (w) 2004-2007 by dukat\n");
156 fprintf(stderr, "\tinbuilt modules: ");
157#ifdef WEBIF
158 #ifdef WITH_SSL
159 fprintf(stderr, "webinterface-with-ssl ");
160 #else
161 fprintf(stderr, "webinterface ");
162 #endif
163#endif
164#ifdef HAVE_DVBAPI
165#ifdef WITH_STAPI
166 fprintf(stderr, "dvbapi-with-stapi ");
167#else
168 fprintf(stderr, "dvbapi ");
169#endif
170#endif
171#ifdef IRDETO_GUESSING
172 fprintf(stderr, "irdeto-guessing ");
173#endif
174#ifdef CS_ANTICASC
175 fprintf(stderr, "anticascading ");
176#endif
177#ifdef WITH_DEBUG
178 fprintf(stderr, "debug ");
179#endif
180#ifdef CS_LED
181 fprintf(stderr, "led-trigger ");
182#endif
183#ifdef CS_WITH_DOUBLECHECK
184 fprintf(stderr, "doublecheck ");
185#endif
186#ifdef QBOXHD_LED
187 fprintf(stderr, "qboxhd-led-trigger ");
188#endif
189#ifdef CS_LOGHISTORY
190 fprintf(stderr, "loghistory ");
191#endif
192#ifdef LIBUSB
193 fprintf(stderr, "smartreader ");
194#endif
195#ifdef HAVE_PCSC
196 fprintf(stderr, "pcsc ");
197#endif
198#ifdef CS_WITH_GBOX
199 fprintf(stderr, "gbox ");
200#endif
201 fprintf(stderr, "\n\tinbuilt protocols: ");
202#ifdef MODULE_MONITOR
203 fprintf(stderr, "monitor ");
204#endif
205#ifdef MODULE_CAMD33
206 fprintf(stderr, "camd33 ");
207#endif
208#ifdef MODULE_CAMD35
209 fprintf(stderr, "camd35-udp ");
210#endif
211#ifdef MODULE_CAMD35_TCP
212 fprintf(stderr, "camd35-tcp ");
213#endif
214#ifdef MODULE_NEWCAMD
215 fprintf(stderr, "newcamd ");
216#endif
217#ifdef MODULE_CCCAM
218 fprintf(stderr, "cccam ");
219#endif
220#ifdef MODULE_RADEGAST
221 fprintf(stderr, "radegast ");
222#endif
223#ifdef MODULE_SERIAL
224 fprintf(stderr, "serial ");
225#endif
226#ifdef MODULE_CONSTCW
227 fprintf(stderr, "constcw ");
228#endif
229 fprintf(stderr, "\n\tinbuilt cardreader: ");
230#ifdef READER_NAGRA
231 fprintf(stderr, "nagra ");
232#endif
233#ifdef READER_IRDETO
234 fprintf(stderr, "irdeto ");
235#endif
236#ifdef READER_CONAX
237 fprintf(stderr, "conax ");
238#endif
239#ifdef READER_CRYPTOWORKS
240 fprintf(stderr, "cryptoworks ");
241#endif
242#ifdef READER_SECA
243 fprintf(stderr, "seca ");
244#endif
245#ifdef READER_VIACCESS
246 fprintf(stderr, "viaccess ");
247#endif
248#ifdef READER_VIDEOGUARD
249 fprintf(stderr, "videoguard ");
250#endif
251#ifdef READER_DRE
252 fprintf(stderr, "dre ");
253#endif
254#ifdef READER_TONGFANG
255 fprintf(stderr, "tongfang ");
256#endif
257 fprintf(stderr, "\n\n");
258 fprintf(stderr, "oscam [-b] [-c config-dir] [-d]");
259 fprintf(stderr, " [-h]");
260 fprintf(stderr, "\n\n\t-b : start in background\n");
261 fprintf(stderr, "\t-c <dir> : read configuration from <dir>\n");
262 fprintf(stderr, "\t default = %s\n", CS_CONFDIR);
263 fprintf(stderr, "\t-t <dir> : tmp dir <dir>\n");
264#ifdef CS_CYGWIN32
265 fprintf(stderr, "\t default = (OS-TMP)\n");
266#else
267 fprintf(stderr, "\t default = /tmp/.oscam\n");
268#endif
269 fprintf(stderr, "\t-d <level> : debug level mask\n");
270 fprintf(stderr, "\t 0 = no debugging (default)\n");
271 fprintf(stderr, "\t 1 = detailed error messages\n");
272 fprintf(stderr, "\t 2 = ATR parsing info, ECM, EMM and CW dumps\n");
273 fprintf(stderr, "\t 4 = traffic from/to the reader\n");
274 fprintf(stderr, "\t 8 = traffic from/to the clients\n");
275 fprintf(stderr, "\t 16 = traffic to the reader-device on IFD layer\n");
276 fprintf(stderr, "\t 32 = traffic to the reader-device on I/O layer\n");
277 fprintf(stderr, "\t 64 = EMM logging\n");
278 fprintf(stderr, "\t 128 = dvbapi logging\n");
279 fprintf(stderr, "\t 255 = debug all\n");
280 fprintf(stderr, "\t-h : show this help\n");
281 fprintf(stderr, "\n");
282 exit(1);
283}
284
285#ifdef NEED_DAEMON
286#ifdef OS_MACOSX
287// this is done because daemon is being deprecated starting with 10.5 and -Werror will always trigger an error
288static int daemon_compat(int nochdir, int noclose)
289#else
290static int daemon(int nochdir, int noclose)
291#endif
292{
293 int fd;
294
295 switch (fork())
296 {
297 case -1: return (-1);
298 case 0: break;
299 default: _exit(0);
300 }
301
302 if (setsid()==(-1))
303 return(-1);
304
305 if (!nochdir)
306 (void)chdir("/");
307
308 if (!noclose && (fd=open("/dev/null", O_RDWR, 0)) != -1)
309 {
310 (void)dup2(fd, STDIN_FILENO);
311 (void)dup2(fd, STDOUT_FILENO);
312 (void)dup2(fd, STDERR_FILENO);
313 if (fd>2)
314 (void)close(fd);
315 }
316 return(0);
317}
318#endif
319
320int recv_from_udpipe(uchar *buf)
321{
322 unsigned short n;
323 if (buf[0]!='U')
324 {
325 cs_log("INTERNAL PIPE-ERROR");
326 cs_exit(1);
327 }
328 memcpy(&n, buf+1, 2);
329
330 memmove(buf, buf+3, n);
331
332 return n;
333}
334
335char *username(struct s_client * client)
336{
337 if (client->usr[0])
338 return(client->usr);
339 else
340 return("anonymous");
341}
342
343static struct s_client * idx_from_ip(in_addr_t ip, in_port_t port)
344{
345 struct s_client *cl;
346 for (cl=first_client; cl ; cl=cl->next)
347 if ((cl->ip==ip) && (cl->port==port) && ((cl->typ=='c') || (cl->typ=='m')))
348 return cl;
349 return NULL;
350}
351
352struct s_client * get_client_by_tid(unsigned long tid) //FIXME untested!! no longer pid in output...
353{
354 struct s_client *cl;
355 for (cl=first_client; cl ; cl=cl->next)
356 if ((unsigned long)(cl->thread)==tid)
357 return cl;
358 return NULL;
359}
360
361static long chk_caid(ushort caid, CAIDTAB *ctab)
362{
363 int n;
364 long rc;
365 for (rc=(-1), n=0; (n<CS_MAXCAIDTAB) && (rc<0); n++)
366 if ((caid & ctab->mask[n]) == ctab->caid[n])
367 rc=ctab->cmap[n] ? ctab->cmap[n] : caid;
368 return(rc);
369}
370
371int chk_bcaid(ECM_REQUEST *er, CAIDTAB *ctab)
372{
373 long caid;
374 if ((caid=chk_caid(er->caid, ctab))<0)
375 return(0);
376 er->caid=caid;
377 return(1);
378}
379
380/*
381 * void set_signal_handler(int sig, int flags, void (*sighandler)(int))
382 * flags: 1 = restart, 2 = don't modify if SIG_IGN, may be combined
383 */
384void set_signal_handler(int sig, int flags, void (*sighandler))
385{
386#ifdef CS_SIGBSD
387 if ((signal(sig, sighandler)==SIG_IGN) && (flags & 2))
388 {
389 signal(sig, SIG_IGN);
390 siginterrupt(sig, 0);
391 }
392 else
393 siginterrupt(sig, (flags & 1) ? 0 : 1);
394#else
395 struct sigaction sa;
396 sigaction(sig, (struct sigaction *) 0, &sa);
397 if (!((flags & 2) && (sa.sa_handler==SIG_IGN)))
398 {
399 sigemptyset(&sa.sa_mask);
400 sa.sa_flags=(flags & 1) ? SA_RESTART : 0;
401 sa.sa_handler=sighandler;
402 sigaction(sig, &sa, (struct sigaction *) 0);
403 }
404#endif
405}
406
407static void cs_master_alarm()
408{
409 cs_log("PANIC: master deadlock!");
410 fprintf(stderr, "PANIC: master deadlock!");
411 fflush(stderr);
412}
413
414static void cs_sigpipe()
415{
416 if (cs_dblevel & D_ALL_DUMP)
417 cs_log("Got sigpipe signal -> captured");
418}
419
420void cs_accounts_chk()
421{
422 init_userdb(&cfg->account);
423 cs_reinit_clients();
424#ifdef CS_ANTICASC
425// struct s_client *cl;
426// for (cl=first_client->next; cl ; cl=cl->next)
427// if (cl->typ=='a')
428// break;
429 ac_clear();
430#endif
431}
432
433static void nullclose(int *fd)
434{
435 //if closing an already closed pipe, we get a sigpipe signal, and this causes a cs_exit
436 //and this causes a close and this causes a sigpipe...and so on
437 int f = *fd;
438 *fd = 0; //so first null client-fd
439 close(f); //then close fd
440}
441
442static void cleanup_thread(struct s_client *cl)
443{
444 struct s_client *prev, *cl2;
445 for (prev=first_client, cl2=first_client->next; prev->next != NULL; prev=prev->next, cl2=cl2->next)
446 if (cl == cl2)
447 break;
448 if (cl != cl2)
449 cs_log("FATAL ERROR: could not find client to remove from list.");
450 else
451 prev->next = cl2->next; //remove client from list
452
453 if(cl->typ == 'c' && ph[cl->ctyp].cleanup)
454 ph[cl->ctyp].cleanup(cl);
455
456 if(cl->pfd) nullclose(&cl->pfd); //Closing Network socket
457 if(cl->fd_m2c_c) nullclose(&cl->fd_m2c_c); //Closing client read fd
458 if(cl->fd_m2c) nullclose(&cl->fd_m2c); //Closing client read fd
459
460 cs_sleepms(1000); //wait some time before cleanup to prevent segfaults
461 NULLFREE(cl->ecmtask);
462 NULLFREE(cl->emmcache);
463 NULLFREE(cl->req);
464 NULLFREE(cl->cc);
465
466 NULLFREE (cl);
467
468 //decrease cwcache
469 pthread_mutex_lock(&cwcache_lock);
470 struct s_ecm *ecmc;
471 if (cwidx->next) {
472 if (cwidx->next->next) {
473 ecmc=cwidx->next->next;
474 NULLFREE(cwidx->next);
475 cwidx->next=ecmc;
476 } else
477 NULLFREE(cwidx->next);
478 } else {
479 ecmc=cwcache->next;
480 NULLFREE(cwcache);
481 cwcache=ecmc;
482 }
483 pthread_mutex_unlock(&cwcache_lock);
484
485 //decrease ecmache
486 pthread_mutex_lock(&ecmcache_lock);
487 if (ecmcache->next != NULL) { //keep it at least on one entry big
488 for (ecmc=ecmcache; ecmc->next->next ; ecmc=ecmc->next) ; //find last element
489 if (ecmidx==ecmc->next)
490 ecmidx = ecmcache;
491 NULLFREE(ecmc->next); //free last element
492 }
493 pthread_mutex_unlock(&ecmcache_lock);
494}
495
496void cs_exit(int sig)
497{
498 char targetfile[256];
499
500 set_signal_handler(SIGCHLD, 1, SIG_IGN);
501 set_signal_handler(SIGHUP , 1, SIG_IGN);
502 set_signal_handler(SIGPIPE, 1, SIG_IGN);
503
504 if (sig==SIGALRM) {
505 cs_debug_mask(D_TRACE, "thread %8X: SIGALRM, skipping", pthread_self());
506 return;
507 }
508
509 if (sig && (sig!=SIGQUIT))
510 cs_log("exit with signal %d", sig);
511
512 struct s_client *cl = cur_client();
513
514 switch(cl->typ)
515 {
516 case 'c':
517 cs_statistics(cl);
518 cl->last_caid = 0xFFFF;
519 cl->last_srvid = 0xFFFF;
520 cs_statistics(cl);
521 break;
522
523 case 'm': break;
524 case 'r':
525 // free AES entries allocated memory
526 if(cl->reader->aes_list) {
527 aes_clear_entries(cl->reader);
528 }
529 // close the device
530 reader_device_close(cl->reader);
531 break;
532
533 case 'h':
534 case 's':
535#ifdef CS_LED
536 cs_switch_led(LED1B, LED_OFF);
537 cs_switch_led(LED2, LED_OFF);
538 cs_switch_led(LED3, LED_OFF);
539 cs_switch_led(LED1A, LED_ON);
540#endif
541#ifdef QBOXHD_LED
542 qboxhd_led_blink(QBOXHD_LED_COLOR_YELLOW,QBOXHD_LED_BLINK_FAST);
543 qboxhd_led_blink(QBOXHD_LED_COLOR_RED,QBOXHD_LED_BLINK_FAST);
544 qboxhd_led_blink(QBOXHD_LED_COLOR_GREEN,QBOXHD_LED_BLINK_FAST);
545 qboxhd_led_blink(QBOXHD_LED_COLOR_BLUE,QBOXHD_LED_BLINK_FAST);
546 qboxhd_led_blink(QBOXHD_LED_COLOR_MAGENTA,QBOXHD_LED_BLINK_FAST);
547#endif
548
549#ifndef OS_CYGWIN32
550 snprintf(targetfile, 255, "%s%s", get_tmp_dir(), "/oscam.version");
551 if (unlink(targetfile) < 0)
552 cs_log("cannot remove oscam version file %s errno=(%d)", targetfile, errno);
553#endif
554#ifdef COOL
555 coolapi_close_all();
556#endif
557 break;
558 }
559
560 // this is very important - do not remove
561 if (cl->typ != 's') {
562 cs_log("thread %8X ended!", pthread_self());
563 cleanup_thread(cl);
564 //Restore signals before exiting thread
565 set_signal_handler(SIGPIPE , 0, cs_sigpipe);
566 set_signal_handler(SIGHUP , 1, cs_accounts_chk);
567
568 pthread_exit(NULL);
569 return;
570 }
571
572 cs_log("cardserver down");
573 cs_close_log();
574
575 NULLFREE(cl);
576
577 exit(sig); //clears all threads
578}
579
580void cs_reinit_clients()
581{
582 struct s_auth *account;
583
584 struct s_client *cl;
585 for (cl=first_client->next; cl ; cl=cl->next)
586 if( cl->typ == 'c' && cl->usr[0] ) {
587 for (account = cfg->account; (account) ; account = account->next)
588 if (!strcmp(cl->usr, account->usr))
589 break;
590
591 if (account && cl->pcrc == crc32(0L, MD5((uchar *)account->pwd, strlen(account->pwd), cur_client()->dump), 16)) {
592 cl->grp = account->grp;
593 cl->aureader = account->aureader;
594 cl->autoau = account->autoau;
595 cl->expirationdate = account->expirationdate;
596 cl->allowedtimeframe[0] = account->allowedtimeframe[0];
597 cl->allowedtimeframe[1] = account->allowedtimeframe[1];
598 cl->ncd_keepalive = account->ncd_keepalive;
599 cl->c35_suppresscmd08 = account->c35_suppresscmd08;
600 cl->tosleep = (60*account->tosleep);
601 cl->c35_sleepsend = account->c35_sleepsend;
602 cl->monlvl = account->monlvl;
603 cl->disabled = account->disabled;
604 cl->fchid = account->fchid; // CHID filters
605 cl->cltab = account->cltab; // Class
606
607 // newcamd module dosent like ident reloading
608 if(!cl->ncd_server)
609 cl->ftab = account->ftab; // Ident
610
611 cl->sidtabok = account->sidtabok; // services
612 cl->sidtabno = account->sidtabno; // services
613 cl->failban = account->failban;
614
615 memcpy(&cl->ctab, &account->ctab, sizeof(cl->ctab));
616 memcpy(&cl->ttab, &account->ttab, sizeof(cl->ttab));
617
618#ifdef CS_ANTICASC
619 cl->ac_idx = account->ac_idx;
620 cl->ac_penalty= account->ac_penalty;
621 cl->ac_limit = (account->ac_users * 100 + 80) * cfg->ac_stime;
622#endif
623 } else {
624 if (ph[cl->ctyp].type & MOD_CONN_NET) {
625 cs_debug_mask(D_TRACE, "client '%s', thread=%8X not found in db (or password changed)", cl->usr, cl->thread);
626 kill_thread(cl);
627 }
628 }
629 }
630}
631
632void cs_debug_level()
633{
634 //switch debuglevel forward one step if not set from outside
635 if(cfg->debuglvl == cs_dblevel) {
636 switch (cs_dblevel) {
637 case 0:
638 cs_dblevel = 1;
639 break;
640 case 128:
641 cs_dblevel = 255;
642 break;
643 case 255:
644 cs_dblevel = 0;
645 break;
646 default:
647 cs_dblevel <<= 1;
648 }
649 } else {
650 cs_dblevel = cfg->debuglvl;
651 }
652
653 cfg->debuglvl = cs_dblevel;
654 cs_log("%sdebug_level=%d", "all", cs_dblevel);
655}
656
657void cs_card_info()
658{
659 uchar dummy[1]={0x00};
660 struct s_client *cl;
661 for (cl=first_client->next; cl ; cl=cl->next)
662 if( cl->typ=='r' && cl->fd_m2c )
663 write_to_pipe(cl->fd_m2c, PIP_ID_CIN, dummy, 1);
664 //kill(client[i].pid, SIGUSR2);
665}
666
667struct s_client * cs_fork(in_addr_t ip) {
668 struct s_client *cl;
669
670 cl = malloc(sizeof(struct s_client));
671 if (cl) {
672 memset(cl, 0, sizeof(struct s_client));
673 int fdp[2];
674 if (pipe(fdp)) {
675 cs_log("Cannot create pipe (errno=%d: %s)", errno, strerror(errno));
676 free(cl);
677 return NULL;
678 }
679 //client part
680
681 //make_non_blocking(fdp[0]);
682 //make_non_blocking(fdp[1]);
683 cl->fd_m2c_c = fdp[0]; //store client read fd
684 cl->fd_m2c = fdp[1]; //store client read fd
685 cl->ip=ip;
686
687 //master part
688 cl->stat=1;
689
690 cl->login=cl->last=time((time_t *)0);
691 //increase cwcache
692 pthread_mutex_lock(&cwcache_lock);
693 struct s_ecm *ecmc;
694 for (ecmc=cwcache; ecmc->next ; ecmc=ecmc->next); //ends on last cwcache entry
695 ecmc->next = malloc(sizeof(struct s_ecm));
696 if (ecmc->next)
697 memset(ecmc->next, 0, sizeof(struct s_ecm));
698 pthread_mutex_unlock(&cwcache_lock);
699
700 //increase ecmcache
701 pthread_mutex_lock(&ecmcache_lock);
702 for (ecmc=ecmcache; ecmc->next ; ecmc=ecmc->next); //ends on last ecmcache entry
703 ecmc->next = malloc(sizeof(struct s_ecm));
704 if (ecmc->next)
705 memset(ecmc->next, 0, sizeof(struct s_ecm));
706 pthread_mutex_unlock(&ecmcache_lock);
707
708 //Now add new client to the list:
709 struct s_client *last;
710 for (last=first_client; last->next != NULL; last=last->next); //ends with cl on last client
711 last->next = cl;
712 } else {
713 cs_log("max connections reached (out of memory) -> reject client %s", cs_inet_ntoa(ip));
714 return NULL;
715 }
716 return(cl);
717}
718
719static void init_signal()
720{
721// for (i=1; i<NSIG; i++)
722// set_signal_handler(i, 3, cs_exit); //not catching all signals simplifies debugging
723 set_signal_handler(SIGINT, 3, cs_exit);
724 set_signal_handler(SIGKILL, 3, cs_exit);
725#ifdef OS_MACOSX
726 set_signal_handler(SIGEMT, 3, cs_exit);
727#else
728 //set_signal_handler(SIGPOLL, 3, cs_exit);
729#endif
730 //set_signal_handler(SIGPROF, 3, cs_exit);
731 set_signal_handler(SIGTERM, 3, cs_exit);
732 //set_signal_handler(SIGVTALRM, 3, cs_exit);
733
734 set_signal_handler(SIGWINCH, 1, SIG_IGN);
735 // set_signal_handler(SIGPIPE , 0, SIG_IGN);
736 set_signal_handler(SIGPIPE , 0, cs_sigpipe);
737 // set_signal_handler(SIGALRM , 0, cs_alarm);
738 set_signal_handler(SIGALRM , 0, cs_master_alarm);
739 // set_signal_handler(SIGCHLD , 1, cs_child_chk);
740 set_signal_handler(SIGHUP , 1, cs_accounts_chk);
741 //set_signal_handler(SIGHUP , 1, cs_sighup);
742 set_signal_handler(SIGUSR1, 1, cs_debug_level);
743 set_signal_handler(SIGUSR2, 1, cs_card_info);
744 set_signal_handler(SIGCONT, 1, SIG_IGN);
745 cs_log("signal handling initialized (type=%s)",
746#ifdef CS_SIGBSD
747 "bsd"
748#else
749 "sysv"
750#endif
751 );
752 return;
753}
754
755static struct s_ecm *generate_cache()
756{
757 int i;
758 struct s_ecm *idx, *cache;
759 cache=idx=malloc(sizeof(struct s_ecm));
760 memset(idx, 0, sizeof(struct s_ecm));
761 for(i=0;i<10;i++) {
762 idx->next=malloc(sizeof(struct s_ecm));
763 idx=idx->next;
764 memset(idx, 0, sizeof(struct s_ecm));
765 }
766 return cache;
767}
768
769static void init_shm()
770{
771 //Generate 5 CW cache entries:
772 cwidx=cwcache=generate_cache();
773
774 //Generate 5 ECM cache entries:
775 ecmidx=ecmcache=generate_cache();
776
777 first_client = malloc(sizeof(struct s_client));
778 if (!first_client) {
779 fprintf(stderr, "Could not allocate memory for master client, exiting...");
780 exit(1);
781 }
782 first_client->next = NULL; //terminate clients list with NULL
783 first_client->login=time((time_t *)0);
784 first_client->ip=cs_inet_addr("127.0.0.1");
785 first_client->typ='s';
786 first_client->aureader=NULL;
787 first_client->thread=pthread_self();
788 if (pthread_setspecific(getclient, first_client)) {
789 fprintf(stderr, "Could not setspecific getclient in master process, exiting...");
790 exit(1);
791 }
792
793
794 // get username master running under
795 struct passwd *pwd;
796 if ((pwd = getpwuid(getuid())) != NULL)
797 strcpy(first_client->usr, pwd->pw_name);
798 else
799 strcpy(first_client->usr, "root");
800
801 pthread_mutex_init(&gethostbyname_lock, NULL);
802 pthread_mutex_init(&cwcache_lock, NULL);
803 pthread_mutex_init(&ecmcache_lock, NULL);
804
805#ifdef CS_LOGHISTORY
806 loghistidx=0;
807 memset(loghist, 0, CS_MAXLOGHIST*CS_LOGHISTSIZE);
808#endif
809}
810
811static int start_listener(struct s_module *ph, int port_idx)
812{
813 int ov=1, timeout, is_udp, i;
814 char ptxt[2][32];
815 //struct hostent *ptrh; /* pointer to a host table entry */
816 struct protoent *ptrp; /* pointer to a protocol table entry */
817 struct sockaddr_in sad; /* structure to hold server's address */
818
819 ptxt[0][0]=ptxt[1][0]='\0';
820 if (!ph->ptab->ports[port_idx].s_port)
821 {
822 cs_log("%s: disabled", ph->desc);
823 return(0);
824 }
825 is_udp=(ph->type==MOD_CONN_UDP);
826
827 memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
828 sad.sin_family = AF_INET; /* set family to Internet */
829 if (!ph->s_ip)
830 ph->s_ip=cfg->srvip;
831 if (ph->s_ip)
832 {
833 sad.sin_addr.s_addr=ph->s_ip;
834 sprintf(ptxt[0], ", ip=%s", inet_ntoa(sad.sin_addr));
835 }
836 else
837 sad.sin_addr.s_addr=INADDR_ANY;
838 timeout=cfg->bindwait;
839 //ph->fd=0;
840 ph->ptab->ports[port_idx].fd = 0;
841
842 if (ph->ptab->ports[port_idx].s_port > 0) /* test for illegal value */
843 sad.sin_port = htons((u_short)ph->ptab->ports[port_idx].s_port);
844 else
845 {
846 cs_log("%s: Bad port %d", ph->desc, ph->ptab->ports[port_idx].s_port);
847 return(0);
848 }
849
850 /* Map transport protocol name to protocol number */
851
852 if( (ptrp=getprotobyname(is_udp ? "udp" : "tcp")) )
853 ov=ptrp->p_proto;
854 else
855 ov=(is_udp) ? 17 : 6; // use defaults on error
856
857 if ((ph->ptab->ports[port_idx].fd=socket(PF_INET,is_udp ? SOCK_DGRAM : SOCK_STREAM, ov))<0)
858 {
859 cs_log("%s: Cannot create socket (errno=%d: %s)", ph->desc, errno, strerror(errno));
860 return(0);
861 }
862
863 ov=1;
864 if (setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ov, sizeof(ov))<0)
865 {
866 cs_log("%s: setsockopt failed (errno=%d: %s)", ph->desc, errno, strerror(errno));
867 close(ph->ptab->ports[port_idx].fd);
868 return(ph->ptab->ports[port_idx].fd=0);
869 }
870
871#ifdef SO_REUSEPORT
872 setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_REUSEPORT, (void *)&ov, sizeof(ov));
873#endif
874
875#ifdef SO_PRIORITY
876 if (cfg->netprio)
877 if (!setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_PRIORITY, (void *)&cfg->netprio, sizeof(ulong)))
878 sprintf(ptxt[1], ", prio=%ld", cfg->netprio);
879#endif
880
881 if( !is_udp )
882 {
883 ulong keep_alive = 1;
884 setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_KEEPALIVE,
885 (void *)&keep_alive, sizeof(ulong));
886 }
887
888 while (timeout--)
889 {
890 if (bind(ph->ptab->ports[port_idx].fd, (struct sockaddr *)&sad, sizeof (sad))<0)
891 {
892 if (timeout)
893 {
894 cs_log("%s: Bind request failed, waiting another %d seconds",
895 ph->desc, timeout);
896 cs_sleepms(1000);
897 }
898 else
899 {
900 cs_log("%s: Bind request failed, giving up", ph->desc);
901 close(ph->ptab->ports[port_idx].fd);
902 return(ph->ptab->ports[port_idx].fd=0);
903 }
904 }
905 else timeout=0;
906 }
907
908 if (!is_udp)
909 if (listen(ph->ptab->ports[port_idx].fd, CS_QLEN)<0)
910 {
911 cs_log("%s: Cannot start listen mode (errno=%d: %s)", ph->desc, errno, strerror(errno));
912 close(ph->ptab->ports[port_idx].fd);
913 return(ph->ptab->ports[port_idx].fd=0);
914 }
915
916 cs_log("%s: initialized (fd=%d, port=%d%s%s%s)",
917 ph->desc, ph->ptab->ports[port_idx].fd,
918 ph->ptab->ports[port_idx].s_port,
919 ptxt[0], ptxt[1], ph->logtxt ? ph->logtxt : "");
920
921 for( i=0; i<ph->ptab->ports[port_idx].ftab.nfilts; i++ ) {
922 int j;
923 cs_log("CAID: %04X", ph->ptab->ports[port_idx].ftab.filts[i].caid );
924 for( j=0; j<ph->ptab->ports[port_idx].ftab.filts[i].nprids; j++ )
925 cs_log("provid #%d: %06X", j, ph->ptab->ports[port_idx].ftab.filts[i].prids[j]);
926 }
927 return(ph->ptab->ports[port_idx].fd);
928}
929
930int cs_user_resolve(struct s_auth *account)
931{
932 struct hostent *rht;
933 struct sockaddr_in udp_sa;
934 int result=0;
935 if (account->dyndns[0])
936 {
937 pthread_mutex_lock(&gethostbyname_lock);
938 in_addr_t lastip = account->dynip;
939 //Resolve with gethostbyname:
940 if (cfg->resolve_gethostbyname) {
941 rht = gethostbyname((char*)account->dyndns);
942 if (!rht)
943 cs_log("can't resolve %s", account->dyndns);
944 else {
945 memcpy(&udp_sa.sin_addr, rht->h_addr, sizeof(udp_sa.sin_addr));
946 account->dynip=cs_inet_order(udp_sa.sin_addr.s_addr);
947 result=1;
948 }
949 }
950 else { //Resolve with getaddrinfo:
951 struct addrinfo hints, *res = NULL;
952 memset(&hints, 0, sizeof(hints));
953 hints.ai_socktype = SOCK_STREAM;
954 hints.ai_family = AF_INET;
955 hints.ai_protocol = IPPROTO_TCP;
956
957 int err = getaddrinfo((const char*)account->dyndns, NULL, &hints, &res);
958 if (err != 0 || !res || !res->ai_addr) {
959 cs_log("can't resolve %s, error: %s", account->dyndns, err ? gai_strerror(err) : "unknown");
960 }
961 else {
962 account->dynip=cs_inet_order(((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr);
963 result=1;
964 }
965 if (res) freeaddrinfo(res);
966 }
967 if (lastip != account->dynip) {
968 uchar *ip = (uchar*) &account->dynip;
969 cs_log("%s: resolved ip=%d.%d.%d.%d", (char*)account->dyndns, ip[3], ip[2], ip[1], ip[0]);
970 }
971 pthread_mutex_unlock(&gethostbyname_lock);
972 }
973 if (!result)
974 account->dynip=0;
975 return result;
976}
977#if defined(CS_ANTICASC) || defined(WEBIF)
978static void start_thread(void * startroutine, char * nameroutine) {
979 pthread_t temp;
980 pthread_attr_t attr;
981 pthread_attr_init(&attr);
982#ifndef TUXBOX
983 pthread_attr_setstacksize(&attr, PTHREAD_STACK_SIZE);
984#endif
985 if (pthread_create(&temp, &attr, startroutine, NULL))
986 cs_log("ERROR: can't create %s thread", nameroutine);
987 else {
988 cs_log("%s thread started", nameroutine);
989 pthread_detach(temp);
990 }
991 pthread_attr_destroy(&attr);
992}
993#endif
994void kill_thread(struct s_client *cl) { //cs_exit is used to let thread kill itself, this routine is for a thread to kill other thread
995
996 if (!cl) return;
997 if (pthread_equal(cl->thread, pthread_self())) return; //cant kill yourself
998
999 pthread_cancel(cl->thread);
1000 cs_log("thread %8X killed!", cl->thread);
1001 cleanup_thread(cl); //FIXME what about when cancellation was not granted immediately?
1002 return;
1003}
1004
1005#ifdef CS_ANTICASC
1006void start_anticascader()
1007{
1008 struct s_client * cl = cs_fork(first_client->ip);
1009 if (cl == NULL) return;
1010 cl->thread = pthread_self();
1011 pthread_setspecific(getclient, cl);
1012 strcpy(cl->usr, first_client->usr);
1013 cl->typ = 'a';
1014
1015 set_signal_handler(SIGHUP, 1, ac_init_stat);
1016 ac_init_stat();
1017 while(1)
1018 {
1019 cs_sleepms(1000); //FIXME this is a cpu-killer!
1020 ac_do_stat();
1021 }
1022}
1023#endif
1024
1025void restart_cardreader(struct s_reader *rdr, int restart) {
1026 int i;
1027 if (restart) //kill old thread, even when .deleted flag is set
1028 kill_thread(rdr->client);
1029
1030 rdr->tcp_connected = 0;
1031 rdr->card_status = NO_CARD;
1032 rdr->tcp_block_delay = 100;
1033 cs_ftime(&rdr->tcp_block_connect_till);
1034
1035 if (rdr->device[0] && (rdr->typ & R_IS_CASCADING)) {
1036 for (i=0; i<CS_MAX_MOD; i++)
1037 if (ph[i].num && rdr->typ==ph[i].num)
1038 rdr->ph=ph[i];
1039
1040 if (!rdr->ph.num) {
1041 cs_log("Protocol Support missing. (typ=%d)", rdr->typ);
1042 return;
1043 }
1044 cs_debug_mask(D_TRACE, "reader %s protocol: %s", rdr->label, rdr->ph.desc);
1045 }
1046
1047 if (rdr->enable == 0)
1048 return;
1049
1050 if ((rdr->device[0]) && (!rdr->deleted)) {
1051 if (restart) {
1052 cs_log("restarting reader %s", rdr->label);
1053 }
1054
1055 struct s_client * cl = cs_fork(first_client->ip);
1056 if (cl == NULL) return;
1057
1058
1059 rdr->fd=cl->fd_m2c;
1060 cl->reader=rdr;
1061 cs_log("creating thread for device %s", rdr->device);
1062
1063 cl->sidtabok=rdr->sidtabok;
1064 cl->sidtabno=rdr->sidtabno;
1065
1066 rdr->client=cl;
1067
1068 cl->typ='r';
1069 //client[i].ctyp=99;
1070 pthread_attr_t attr;
1071 pthread_attr_init(&attr);
1072#if !defined(TUXBOX) && !defined(HAVE_PCSC)
1073 /* pcsc doesn't like this either; segfaults on x86, x86_64 */
1074 pthread_attr_setstacksize(&attr, PTHREAD_STACK_SIZE);
1075#endif
1076 pthread_create(&cl->thread, &attr, start_cardreader, (void *)rdr);
1077 pthread_detach(cl->thread);
1078 pthread_attr_destroy(&attr);
1079 }
1080}
1081
1082static void init_cardreader() {
1083 struct s_reader *rdr;
1084 for (rdr=first_reader; rdr ; rdr=rdr->next)
1085 if (rdr->device[0])
1086 restart_cardreader(rdr, 0);
1087}
1088
1089static void cs_fake_client(struct s_client *client, char *usr, int uniq, in_addr_t ip)
1090{
1091 /* Uniq = 1: only one connection per user
1092 *
1093 * Uniq = 2: set (new connected) user only to fake if source
1094 * ip is different (e.g. for newcamd clients with
1095 * different CAID's -> Ports)
1096 *
1097 * Uniq = 3: only one connection per user, but only the last
1098 * login will survive (old mpcs behavior)
1099 *
1100 * Uniq = 4: set user only to fake if source ip is
1101 * different, but only the last login will survive
1102 */
1103
1104 struct s_client *cl;
1105 for (cl=first_client->next; cl ; cl=cl->next)
1106 {
1107 if (cl != client && (cl->typ == 'c') && !cl->dup && !strcmp(cl->usr, usr)
1108 && (uniq < 5) && ((uniq % 2) || (cl->ip != ip)))
1109 {
1110 if (uniq == 3 || uniq == 4)
1111 {
1112 cl->dup = 1;
1113 cl->aureader = NULL;
1114 cs_log("client(%8X) duplicate user '%s' from %s set to fake (uniq=%d)", cl->thread, usr, cs_inet_ntoa(ip), uniq);
1115 if (cl->failban & BAN_DUPLICATE) {
1116 cs_add_violation(ip);
1117 }
1118 }
1119 else
1120 {
1121 client->dup = 1;
1122 client->aureader = NULL;
1123 cs_log("client(%8X) duplicate user '%s' from %s set to fake (uniq=%d)", pthread_self(), usr, cs_inet_ntoa(ip), uniq);
1124 if (cl->failban & BAN_DUPLICATE) {
1125 cs_add_violation(ip);
1126 }
1127 break;
1128 }
1129
1130 }
1131 }
1132
1133}
1134
1135int cs_auth_client(struct s_client * client, struct s_auth *account, const char *e_txt)
1136{
1137 int rc=0;
1138 char buf[32];
1139 char *t_crypt="encrypted";
1140 char *t_plain="plain";
1141 char *t_grant=" granted";
1142 char *t_reject=" rejected";
1143 char *t_msg[]= { buf, "invalid access", "invalid ip", "unknown reason" };
1144 memset(&client->grp, 0xff, sizeof(uint64));
1145 //client->grp=0xffffffffffffff;
1146 client->aureader=NULL;
1147 switch((long)account)
1148 {
1149#ifdef CS_WITH_GBOX
1150 case -2: // gbx-dummy
1151 client->dup=0;
1152 break;
1153#endif
1154 case 0: // reject access
1155 rc=1;
1156 cs_add_violation((uint)client->ip);
1157 cs_log("%s %s-client %s%s (%s)",
1158 client->crypted ? t_crypt : t_plain,
1159 ph[client->ctyp].desc,
1160 client->ip ? cs_inet_ntoa(client->ip) : "",
1161 client->ip ? t_reject : t_reject+1,
1162 e_txt ? e_txt : t_msg[rc]);
1163 break;
1164 default: // grant/check access
1165 if (client->ip && account->dyndns[0]) {
1166 if (cfg->clientdyndns) {
1167 if (client->ip != account->dynip)
1168 cs_user_resolve(account);
1169 if (client->ip != account->dynip) {
1170 cs_add_violation((uint)client->ip);
1171 rc=2;
1172 }
1173 }
1174 else
1175 cs_log("Warning: clientdyndns disabled in config. Enable clientdyndns to use hostname restrictions");
1176 }
1177
1178 if (!rc)
1179 {
1180 client->dup=0;
1181 if (client->typ=='c')
1182 {
1183 client->last_caid = 0xFFFE;
1184 client->last_srvid = 0xFFFE;
1185 client->expirationdate = account->expirationdate;
1186 client->disabled = account->disabled;
1187 client->allowedtimeframe[0] = account->allowedtimeframe[0];
1188 client->allowedtimeframe[1] = account->allowedtimeframe[1];
1189 client->failban = account->failban;
1190 client->c35_suppresscmd08 = account->c35_suppresscmd08;
1191 client->ncd_keepalive = account->ncd_keepalive;
1192 client->grp = account->grp;
1193 client->aureader = account->aureader;
1194 client->autoau = account->autoau;
1195 client->tosleep = (60*account->tosleep);
1196 client->c35_sleepsend = account->c35_sleepsend;
1197 memcpy(&client->ctab, &account->ctab, sizeof(client->ctab));
1198 if (account->uniq)
1199 cs_fake_client(client, account->usr, account->uniq, client->ip);
1200 client->ftab = account->ftab; // IDENT filter
1201 client->cltab = account->cltab; // CLASS filter
1202 client->fchid = account->fchid; // CHID filter
1203 client->sidtabok= account->sidtabok; // services
1204 client->sidtabno= account->sidtabno; // services
1205 client->pcrc = crc32(0L, MD5((uchar *)account->pwd, strlen(account->pwd), client->dump), 16);
1206 memcpy(&client->ttab, &account->ttab, sizeof(client->ttab));
1207#ifdef CS_ANTICASC
1208 ac_init_client(account);
1209#endif
1210 }
1211 }
1212 client->monlvl=account->monlvl;
1213 strcpy(client->usr, account->usr);
1214 case -1: // anonymous grant access
1215 if (rc)
1216 t_grant=t_reject;
1217 else
1218 if (client->typ=='m')
1219 sprintf(t_msg[0], "lvl=%d", client->monlvl);
1220 else
1221 if(client->autoau)
1222 if(client->ncd_server)
1223 {
1224 struct s_reader *rdr;
1225 for (rdr=first_reader; rdr ; rdr=rdr->next)
1226 if(rdr->caid[0]==cfg->ncd_ptab.ports[client->port_idx].ftab.filts[0].caid) {
1227 client->aureader=rdr;
1228 break;
1229 }
1230 if(!client->aureader)
1231 sprintf(t_msg[0], "au(auto)=0"); //FIXME dont think this is correct, but this was old behaviour
1232 else
1233 sprintf(t_msg[0], "au(auto)=%s", client->aureader->label);
1234 }
1235 else
1236 sprintf(t_msg[0], "au=auto");
1237 else
1238 if(!client->aureader)
1239 sprintf(t_msg[0], "au(auto)=0"); //FIXME dont think this is correct, but this was old behaviour
1240 else
1241 sprintf(t_msg[0], "au=%s", client->aureader->label);
1242
1243 if(client->ncd_server)
1244 {
1245 cs_log("%s %s:%d-client %s%s (%s, %s)",
1246 client->crypted ? t_crypt : t_plain,
1247 e_txt ? e_txt : ph[client->ctyp].desc,
1248 cfg->ncd_ptab.ports[client->port_idx].s_port,
1249 client->ip ? cs_inet_ntoa(client->ip) : "",
1250 client->ip ? t_grant : t_grant+1,
1251 username(client), t_msg[rc]);
1252 }
1253 else
1254 {
1255 cs_log("%s %s-client %s%s (%s, %s)",
1256 client->crypted ? t_crypt : t_plain,
1257 e_txt ? e_txt : ph[client->ctyp].desc,
1258 client->ip ? cs_inet_ntoa(client->ip) : "",
1259 client->ip ? t_grant : t_grant+1,
1260 username(client), t_msg[rc]);
1261 }
1262
1263 break;
1264 }
1265 return(rc);
1266}
1267
1268void cs_disconnect_client(struct s_client * client)
1269{
1270 char buf[32]={0};
1271 if (client->ip)
1272 sprintf(buf, " from %s", cs_inet_ntoa(client->ip));
1273 cs_log("%s disconnected %s", username(client), buf);
1274 cs_exit(0);
1275}
1276
1277/**
1278 * ecm cache
1279 **/
1280static int check_and_store_ecmcache(ECM_REQUEST *er, uint64 grp)
1281{
1282 struct s_ecm *ecmc;
1283 pthread_mutex_lock(&ecmcache_lock);
1284 for (ecmc=ecmcache; ecmc ; ecmc=ecmc->next) {
1285 if ((grp & ecmc->grp) &&
1286 ecmc->caid==er->caid &&
1287 (!memcmp(ecmc->ecmd5, er->ecmd5, CS_ECMSTORESIZE)))
1288 {
1289 er->rc = 99;
1290 pthread_mutex_unlock(&ecmcache_lock);
1291 return(1);
1292 }
1293 }
1294 //store_ecm(er, grp); //Only ECM, no CW!
1295 if (ecmidx->next)
1296 ecmidx=ecmidx->next;
1297 else
1298 ecmidx=ecmcache;
1299 memcpy(ecmidx->ecmd5, er->ecmd5, CS_ECMSTORESIZE);
1300 ecmidx->caid = er->caid;
1301 ecmidx->grp = grp;
1302 ecmidx->reader = er->selected_reader;
1303
1304 pthread_mutex_unlock(&ecmcache_lock);
1305 return(0);
1306}
1307
1308/**
1309 * cache 1: client-invoked
1310 * returns found ecm task index
1311 **/
1312static int check_cwcache1(ECM_REQUEST *er, uint64 grp)
1313{
1314 //cs_ddump(ecmd5, CS_ECMSTORESIZE, "ECM search");
1315 //cs_log("cache1 CHECK: grp=%lX", grp);
1316 struct s_ecm *ecmc;
1317 int count=0;
1318
1319 ushort lc=0, *lp;
1320 if (cs_dblevel) {
1321 for (lp=(ushort *)er->ecm+(er->l>>2), lc=0; lp>=(ushort *)er->ecm; lp--)
1322 lc^=*lp;
1323 }
1324
1325 pthread_mutex_lock(&cwcache_lock);
1326 for (ecmc=cwcache; ecmc ; ecmc=ecmc->next, count++) {
1327 if (memcmp(ecmc->ecmd5, er->ecmd5, CS_ECMSTORESIZE))
1328 continue;
1329
1330 cs_debug_mask(D_TRACE, "cache: ecm %04X found: ccaid=%04X caid=%04X grp=%lld cgrp=%lld count=%d", lc, er->caid, ecmc->caid, grp, ecmc->grp, count);
1331
1332 if (!(grp & ecmc->grp))
1333 continue;
1334
1335 if (ecmc->caid != er->caid)
1336 continue;
1337
1338 memcpy(er->cw, ecmc->cw, 16);
1339 er->selected_reader = ecmc->reader;
1340 pthread_mutex_unlock(&cwcache_lock);
1341 return 1;
1342 }
1343 pthread_mutex_unlock(&cwcache_lock);
1344 cs_debug_mask(D_TRACE, "cache: %04X not found count=%d", lc, count);
1345 return 0;
1346}
1347
1348/**
1349 * cache 2: reader-invoked
1350 * returns 1 if found in cache. cw is copied to er
1351 **/
1352int check_cwcache2(ECM_REQUEST *er, uint64 grp)
1353{
1354 struct s_reader *save = er->selected_reader;
1355 int rc = check_cwcache1(er, grp);
1356 er->selected_reader = save;
1357 return rc;
1358}
1359
1360
1361static void store_cw(ECM_REQUEST *er, uint64 grp)
1362{
1363#ifdef CS_WITH_DOUBLECHECK
1364 if (cfg->double_check && er->checked < 2)
1365 return;
1366#endif
1367 pthread_mutex_lock(&cwcache_lock);
1368 if (cwidx->next)
1369 cwidx=cwidx->next;
1370 else
1371 cwidx=cwcache;
1372 //cs_log("store ecm from reader %d", er->selected_reader);
1373 memcpy(cwidx->ecmd5, er->ecmd5, CS_ECMSTORESIZE);
1374 memcpy(cwidx->cw, er->cw, 16);
1375 cwidx->caid = er->caid;
1376 cwidx->grp = grp;
1377 cwidx->reader = er->selected_reader;
1378
1379 if (cs_dblevel) {
1380 ushort lc, *lp;
1381 for (lp=(ushort *)er->ecm+(er->l>>2), lc=0; lp>=(ushort *)er->ecm; lp--)
1382 lc^=*lp;
1383 cs_debug_mask(D_TRACE, "store_cw: ecm=%04X grp=%lld", lc, grp);
1384 }
1385 //cs_ddump(cwcache[*cwidx].ecmd5, CS_ECMSTORESIZE, "ECM stored (idx=%d)", *cwidx);
1386 pthread_mutex_unlock(&cwcache_lock);
1387}
1388
1389// only for debug
1390static struct s_client * get_thread_by_pipefd(int fd)
1391{
1392 struct s_client *cl;
1393 for (cl=first_client->next; cl ; cl=cl->next)
1394 if (fd==cl->fd_m2c || fd==cl->fd_m2c_c)
1395 return cl;
1396 return first_client; //master process
1397}
1398
1399/*
1400 * write_to_pipe():
1401 * write all kind of data to pipe specified by fd
1402 */
1403int write_to_pipe(int fd, int id, uchar *data, int n)
1404{
1405 if (!fd) {
1406 cs_log("write_to_pipe: fd==0 id: %d", id);
1407 return -1;
1408 }
1409
1410 cs_debug_mask(D_TRACE, "write to pipe %d (%s) thread: %8X to %8X", fd, PIP_ID_TXT[id], pthread_self(), get_thread_by_pipefd(fd)->thread);
1411
1412 uchar buf[3+sizeof(void*)];
1413
1414 // fixme
1415 // copy data to allocated memory
1416 // needed for compatibility
1417 // need to be freed after read_from_pipe
1418 void *d = malloc(n);
1419 memcpy(d, data, n);
1420
1421 if ((id<0) || (id>PIP_ID_MAX))
1422 return(PIP_ID_ERR);
1423
1424 memcpy(buf, PIP_ID_TXT[id], 3);
1425 memcpy(buf+3, &d, sizeof(void*));
1426
1427 n=3+sizeof(void*);
1428
1429 return(write(fd, buf, n));
1430}
1431
1432
1433/*
1434 * read_from_pipe():
1435 * read all kind of data from pipe specified by fd
1436 * special-flag redir: if set AND data is ECM: this will redirected to appr. client
1437 */
1438int read_from_pipe(int fd, uchar **data, int redir)
1439{
1440 int rc;
1441 long hdr=0;
1442 uchar buf[3+sizeof(void*)];
1443 memset(buf, 0, sizeof(buf));
1444
1445 redir=redir;
1446 *data=(uchar *)0;
1447 rc=PIP_ID_NUL;
1448
1449 if (bytes_available(fd)) {
1450 if (read(fd, buf, sizeof(buf))==sizeof(buf)) {
1451 memcpy(&hdr, buf+3, sizeof(void*));
1452 } else {
1453 cs_log("WARNING: pipe header to small !");
1454 return PIP_ID_ERR;
1455 }
1456 } else {
1457 cs_log("!bytes_available(fd)");
1458 return PIP_ID_NUL;
1459 }
1460
1461 uchar id[4];
1462 memcpy(id, buf, 3);
1463 id[3]='\0';
1464
1465 cs_debug_mask(D_TRACE, "read from pipe %d (%s) thread: %8X", fd, id, (unsigned int)pthread_self());
1466
1467 int l;
1468 for (l=0; (rc<0) && (PIP_ID_TXT[l]); l++)
1469 if (!memcmp(buf, PIP_ID_TXT[l], 3))
1470 rc=l;
1471
1472 if (rc<0) {
1473 cs_log("WARNING: pipe garbage from pipe %i", fd);
1474 return PIP_ID_ERR;
1475 }
1476
1477 *data = (void*)hdr;
1478
1479 return(rc);
1480}
1481
1482/*
1483 * write_ecm_request():
1484 */
1485int write_ecm_request(int fd, ECM_REQUEST *er)
1486{
1487 return(write_to_pipe(fd, PIP_ID_ECM, (uchar *) er, sizeof(ECM_REQUEST)));
1488}
1489
1490/*
1491 * This function writes the current CW from ECM struct to a cwl file.
1492 * The filename is re-calculated and file re-opened every time.
1493 * This will consume a bit cpu time, but nothing has to be stored between
1494 * each call. If not file exists, a header is prepended
1495 */
1496void logCWtoFile(ECM_REQUEST *er)
1497{
1498 FILE *pfCWL;
1499 char srvname[128];
1500 /* %s / %s _I %04X _ %s .cwl */
1501 char buf[256 + sizeof(srvname)];
1502 char date[7];
1503 unsigned char i, parity, writeheader = 0;
1504 time_t t;
1505 struct tm *timeinfo;
1506 struct s_srvid *this;
1507
1508 /*
1509 * search service name for that id and change characters
1510 * causing problems in file name
1511 */
1512 srvname[0] = 0;
1513 for (this=cfg->srvid; this; this = this->next) {
1514 if (this->srvid == er->srvid) {
1515 cs_strncpy(srvname, this->name, sizeof(srvname));
1516 srvname[sizeof(srvname)-1] = 0;
1517 for (i = 0; srvname[i]; i++)
1518 if (srvname[i] == ' ') srvname[i] = '_';
1519 break;
1520 }
1521 }
1522
1523 /* calc log file name */
1524 time(&t);
1525 timeinfo = localtime(&t);
1526 strftime(date, sizeof(date), "%Y%m%d", timeinfo);
1527 sprintf(buf, "%s/%s_I%04X_%s.cwl", cfg->cwlogdir, date, er->srvid, srvname);
1528
1529 /* open failed, assuming file does not exist, yet */
1530 if((pfCWL = fopen(buf, "r")) == NULL) {
1531 writeheader = 1;
1532 } else {
1533 /* we need to close the file if it was opened correctly */
1534 fclose(pfCWL);
1535 }
1536
1537 if ((pfCWL = fopen(buf, "a+")) == NULL) {
1538 /* maybe this fails because the subdir does not exist. Is there a common function to create it?
1539 for the moment do not print to log on every ecm
1540 cs_log(""error opening cw logfile for writing: %s (errno %d)", buf, errno); */
1541 return;
1542 }
1543 if (writeheader) {
1544 /* no global macro for cardserver name :( */
1545 fprintf(pfCWL, "# OSCam cardserver v%s - http://streamboard.gmc.to:8001/oscam/wiki\n", CS_VERSION_X);
1546 fprintf(pfCWL, "# control word log file for use with tsdec offline decrypter\n");
1547 strftime(buf, sizeof(buf),"DATE %Y-%m-%d, TIME %H:%M:%S, TZ %Z\n", timeinfo);
1548 fprintf(pfCWL, "# %s", buf);
1549 fprintf(pfCWL, "# CAID 0x%04X, SID 0x%04X, SERVICE \"%s\"\n", er->caid, er->srvid, srvname);
1550 }
1551
1552 parity = er->ecm[0]&1;
1553 fprintf(pfCWL, "%d ", parity);
1554 for (i = parity * 8; i < 8 + parity * 8; i++)
1555 fprintf(pfCWL, "%02X ", er->cw[i]);
1556 /* better use incoming time er->tps rather than current time? */
1557 strftime(buf,sizeof(buf),"%H:%M:%S\n", timeinfo);
1558 fprintf(pfCWL, "# %s", buf);
1559 fflush(pfCWL);
1560 fclose(pfCWL);
1561}
1562
1563/**
1564 * distributes found ecm-request to all clients with rc=99
1565 **/
1566void distribute_ecm(ECM_REQUEST *er)
1567{
1568 struct s_client *cl;
1569 ECM_REQUEST *ecm;
1570 int n, i;
1571 if (er->rc==1) //found converted to cache...
1572 er->rc = 2; //cache
1573
1574 for (cl=first_client->next; cl ; cl=cl->next) {
1575 if (cl->fd_m2c && cl->typ=='c' && cl->ecmtask && (er->selected_reader->grp & cl->grp)) {
1576
1577 n=(ph[cl->ctyp].multi)?CS_MAXPENDING:1;
1578 for (i=0; i<n; i++) {
1579 ecm = &cl->ecmtask[i];
1580 if (ecm->rc == 99 && ecm->caid==er->caid && memcmp(ecm->ecmd5, er->ecmd5, CS_ECMSTORESIZE)==0) {
1581 er->cpti = ecm->cpti;
1582 //cs_log("distribute %04X:%06X:%04X cpti %d to client %s", ecm->caid, ecm->prid, ecm->srvid, ecm->cpti, username(cl));
1583 write_ecm_request(cl->fd_m2c, er);
1584 }
1585 //else if (ecm->rc == 99)
1586 // cs_log("NO-distribute %04X:%06X:%04X cpti %d to client %s", ecm->caid, ecm->prid, ecm->srvid, ecm->cpti, username(cl));
1587 }
1588 }
1589 }
1590}
1591
1592
1593int write_ecm_answer(struct s_reader * reader, ECM_REQUEST *er)
1594{
1595 int i;
1596 uchar c;
1597 for (i=0; i<16; i+=4)
1598 {
1599 c=((er->cw[i]+er->cw[i+1]+er->cw[i+2]) & 0xff);
1600 if (er->cw[i+3]!=c)
1601 {
1602 cs_debug_mask(D_TRACE, "notice: changed dcw checksum byte cw[%i] from %02x to %02x", i+3, er->cw[i+3],c);
1603 er->cw[i+3]=c;
1604 }
1605 }
1606
1607 er->selected_reader=reader;
1608//cs_log("answer from reader %d (rc=%d)", er->selected_reader, er->rc);
1609 er->caid=er->ocaid;
1610
1611#ifdef CS_WITH_GBOX
1612 if (er->rc==1||(er->gbxRidx&&er->rc==0)) {
1613#else
1614 if (er->rc==1) {
1615#endif
1616 store_cw(er, reader->grp);
1617
1618 /* CWL logging only if cwlogdir is set in config */
1619 if (cfg->cwlogdir != NULL)
1620 logCWtoFile(er);
1621 }
1622
1623 int res=0;
1624 if( er->client && er->client->fd_m2c ) {
1625 //Wie got an ECM (or nok). Now we should check for another clients waiting for it:
1626 res = write_ecm_request(er->client->fd_m2c, er);
1627 //return(write_ecm_request(first_client->fd_m2c, er)); //does this ever happen? Schlocke: should never happen!
1628 }
1629 distribute_ecm(er);
1630
1631 return res;
1632}
1633
1634 /*
1635static int cs_read_timer(int fd, uchar *buf, int l, int msec)
1636{
1637 struct timeval tv;
1638 fd_set fds;
1639 int rc;
1640
1641 if (!fd) return(-1);
1642 tv.tv_sec = msec / 1000;
1643 tv.tv_usec = (msec % 1000) * 1000;
1644 FD_ZERO(&fds);
1645 FD_SET(cur_client()->pfd, &fds);
1646
1647 select(fd+1, &fds, 0, 0, &tv);
1648
1649 rc=0;
1650 if (FD_ISSET(cur_client()->pfd, &fds))
1651 if (!(rc=read(fd, buf, l)))
1652 rc=-1;
1653
1654 return(rc);
1655}*/
1656
1657ECM_REQUEST *get_ecmtask()
1658{
1659 int i, n;
1660 ECM_REQUEST *er=0;
1661 struct s_client *cl = cur_client();
1662 if(!cl) return NULL;
1663 if (!cl->ecmtask)
1664 {
1665 n=(ph[cl->ctyp].multi)?CS_MAXPENDING:1;
1666 if( (cl->ecmtask=(ECM_REQUEST *)malloc(n*sizeof(ECM_REQUEST))) )
1667 memset(cl->ecmtask, 0, n*sizeof(ECM_REQUEST));
1668 }
1669
1670 n=(-1);
1671 if (!cl->ecmtask)
1672 {
1673 cs_log("Cannot allocate memory (errno=%d)", errno);
1674 n=(-2);
1675 }
1676 else
1677 if (ph[cl->ctyp].multi)
1678 {
1679 for (i=0; (n<0) && (i<CS_MAXPENDING); i++)
1680 if (cl->ecmtask[i].rc<99)
1681 er=&cl->ecmtask[n=i];
1682 }
1683 else
1684 er=&cl->ecmtask[n=0];
1685
1686 if (n<0)
1687 cs_log("WARNING: ecm pending table overflow !");
1688 else
1689 {
1690 memset(er, 0, sizeof(ECM_REQUEST));
1691 er->rc=100;
1692 er->cpti=n;
1693 er->client=cl;
1694 cs_ftime(&er->tps);
1695 }
1696 return(er);
1697}
1698
1699static void send_reader_stat(struct s_reader *rdr, ECM_REQUEST *er, int rc)
1700{
1701 if (!cfg->lb_mode || rc == 100)
1702 return;
1703 struct timeb tpe;
1704 cs_ftime(&tpe);
1705 int time = 1000*(tpe.time-er->tps.time)+tpe.millitm-er->tps.millitm;
1706
1707 add_stat(rdr, er->caid, er->prid, er->srvid, time, rc);
1708}
1709
1710// rc codes:
1711// 0 = found
1712// 1 = cache1
1713// 2 = cache2
1714// 3 = emu
1715// 4 = not found
1716// 5 = timeout
1717// 6 = sleeping
1718// 7 = fake
1719// 8 = invalid
1720// 9 = corrupt
1721// 10= no card
1722// 11= expdate
1723// 12= disabled
1724// 13= stopped
1725// 100=unhandled
1726
1727int send_dcw(struct s_client * client, ECM_REQUEST *er)
1728{
1729 static const char *stxt[]={"found", "cache1", "cache2", "emu",
1730 "not found", "timeout", "sleeping",
1731 "fake", "invalid", "corrupt", "no card", "expdate", "disabled", "stopped"};
1732 static const char *stxtEx[]={"", "group", "caid", "ident", "class", "chid", "queue", "peer"};
1733 static const char *stxtWh[]={"", "user ", "reader ", "server ", "lserver "};
1734 char sby[32]="", sreason[32]="", schaninfo[32]="";
1735 char erEx[32]="";
1736 char uname[38]="";
1737 struct timeb tpe;
1738 ushort lc, *lp;
1739 for (lp=(ushort *)er->ecm+(er->l>>2), lc=0; lp>=(ushort *)er->ecm; lp--)
1740 lc^=*lp;
1741
1742#ifdef CS_WITH_GBOX
1743 if(er->gbxFrom)
1744 snprintf(uname,sizeof(uname)-1, "%s(%04X)", username(client), er->gbxFrom);
1745 else
1746#endif
1747 snprintf(uname,sizeof(uname)-1, "%s", username(client));
1748 if (er->rc==0)
1749 {
1750#ifdef CS_WITH_GBOX
1751 if(er->selected_reader->typ==R_GBOX)
1752 snprintf(sby, sizeof(sby)-1, " by %s(%04X)", er->reader0->label,er->gbxCWFrom);
1753 else
1754#endif
1755 // add marker to reader if ECM_REQUEST was betatunneled
1756 if(er->btun)
1757 snprintf(sby, sizeof(sby)-1, " by %s(btun)", er->selected_reader->label);
1758 else
1759 snprintf(sby, sizeof(sby)-1, " by %s", er->selected_reader->label);
1760 }
1761 if (er->rc<4) er->rcEx=0;
1762 if (er->rcEx)
1763 snprintf(erEx, sizeof(erEx)-1, "rejected %s%s", stxtWh[er->rcEx>>4],
1764 stxtEx[er->rcEx&0xf]);
1765
1766 if(cfg->mon_appendchaninfo)
1767 snprintf(schaninfo, sizeof(schaninfo)-1, " - %s", get_servicename(er->srvid, er->caid));
1768
1769 if(er->msglog[0])
1770 snprintf(sreason, sizeof(sreason)-1, " (%s)", er->msglog);
1771
1772 cs_ftime(&tpe);
1773 client->cwlastresptime = 1000*(tpe.time-er->tps.time)+tpe.millitm-er->tps.millitm;
1774
1775#ifdef CS_LED
1776 if(!er->rc) cs_switch_led(LED2, LED_BLINK_OFF);
1777#endif
1778
1779 send_reader_stat(er->selected_reader, er, er->rc);
1780
1781#ifdef WEBIF
1782 if(er->rc == 0)
1783 snprintf(client->lastreader, sizeof(client->lastreader)-1, "%s", sby);
1784 else if ((er->rc == 1) || (er->rc == 2))
1785 snprintf(client->lastreader, sizeof(client->lastreader)-1, "by %s (cache)", er->selected_reader->label);
1786 else
1787 snprintf(client->lastreader, sizeof(client->lastreader)-1, "%s", stxt[er->rc]);
1788#endif
1789
1790 if(!client->ncd_server && client->autoau && er->rcEx==0 && er->selected_reader)
1791 {
1792 if(client->aureader && er->caid!=client->aureader->caid[0])
1793 {
1794 client->aureader=NULL;
1795 }
1796
1797 struct s_reader *cur = er->selected_reader;
1798
1799 if (cur->typ == R_CCCAM && !cur->caid[0] && !cur->audisabled &&
1800 cur->card_system == get_cardsystem(er->caid) && hexserialset(er->selected_reader))
1801 client->aureader= er->selected_reader;
1802 else if((er->caid == cur->caid[0]) && (!cur->audisabled)) {
1803 client->aureader = er->selected_reader; // First chance - check whether actual reader can AU
1804 } else {
1805 for (cur=first_reader; cur ; cur=cur->next) { //second chance loop through all readers to find an AU reader
1806 if (matching_reader(er, cur)) {
1807 if (cur->typ == R_CCCAM && !cur->caid[0] && !cur->audisabled &&
1808 cur->card_system == get_cardsystem(er->caid) && hexserialset(cur))
1809 {
1810 client->aureader = cur;
1811 break;
1812 }
1813 else if((er->caid == cur->caid[0]) && (er->prid == cur->auprovid) && (!cur->audisabled))
1814 {
1815 client->aureader = cur;
1816 break;
1817 }
1818 }
1819 }
1820 if(!cur) {
1821 client->aureader=NULL;
1822 }
1823 }
1824 //}
1825 }
1826
1827 er->caid = er->ocaid;
1828 switch(er->rc) {
1829 case 0:
1830 case 3:
1831 // 0 - found
1832 // 3 - emu FIXME: obsolete ?
1833 client->cwfound++;
1834 first_client->cwfound++;
1835 break;
1836
1837 case 1:
1838 case 2:
1839 // 1 - cache1
1840 // 2 - cache2
1841 client->cwcache++;
1842 first_client->cwcache++;
1843 break;
1844
1845 case 4:
1846 case 9:
1847 case 10:
1848 // 4 - not found
1849 // 9 - corrupt
1850 // 10 - no card
1851 if (er->rcEx) {
1852 client->cwignored++;
1853 first_client->cwignored++;
1854 } else {
1855 client->cwnot++;
1856 first_client->cwnot++;
1857 }
1858 break;
1859
1860 case 5:
1861 // 5 - timeout
1862 client->cwtout++;
1863 first_client->cwtout++;
1864 break;
1865
1866 default:
1867 client->cwignored++;
1868 first_client->cwignored++;
1869 }
1870
1871#ifdef CS_ANTICASC
1872 ac_chk(er, 1);
1873#endif
1874
1875 int is_fake = 0;
1876 if (er->rc==7) {
1877 is_fake = 1;
1878 er->rc=0;
1879 }
1880
1881#ifdef CS_WITH_DOUBLECHECK
1882 if (cfg->double_check && er->rc < 4) {
1883 if (er->checked == 0) {//First CW, save it and wait for next one
1884 er->checked = 1;
1885 er->origin_reader = er->selected_reader;
1886 memcpy(er->cw_checked, er->cw, sizeof(er->cw));
1887 cs_log("DOUBLE CHECK FIRST CW by %s idx %d cpti %d", er->origin_reader->label, er->idx, er->cpti);
1888 }
1889 else if (er->origin_reader != er->selected_reader) { //Second (or third and so on) cw. We have to compare
1890 if (memcmp(er->cw_checked, er->cw, sizeof(er->cw)) == 0) {
1891 er->checked++;
1892 cs_log("DOUBLE CHECKED! %d. CW by %s idx %d cpti %d", er->checked, er->selected_reader->label, er->idx, er->cpti);
1893 }
1894 else {
1895 cs_log("DOUBLE CHECKED NONMATCHING! %d. CW by %s idx %d cpti %d", er->checked, er->selected_reader->label, er->idx, er->cpti);
1896 }
1897 }
1898
1899 if (er->checked < 2) { //less as two same cw? mark as pending!
1900 er->rc = 100;
1901 return 0;
1902 }
1903
1904 store_cw(er, er->selected_reader->grp); //Store in cache!
1905
1906 }
1907#endif
1908
1909 ph[client->ctyp].send_dcw(client, er);
1910
1911 if (is_fake)
1912 er->rc=7;
1913
1914 cs_log("%s (%04X&%06X/%04X/%02X:%04X): %s (%d ms)%s (of %d avail %d)%s%s",
1915 uname, er->caid, er->prid, er->srvid, er->l, lc,
1916 er->rcEx?erEx:stxt[er->rc], client->cwlastresptime, sby, er->reader_count, er->reader_avail, schaninfo, sreason);
1917
1918 cs_ddump_mask (D_ATR, er->cw, 16, "cw:");
1919
1920#ifdef QBOXHD_LED
1921 if (er->rc < 4) {
1922 qboxhd_led_blink(QBOXHD_LED_COLOR_GREEN, QBOXHD_LED_BLINK_MEDIUM);
1923 } else if (er->rc < 14) {
1924 qboxhd_led_blink(QBOXHD_LED_COLOR_RED, QBOXHD_LED_BLINK_MEDIUM);
1925 }
1926#endif
1927
1928 return 0;
1929}
1930
1931void chk_dcw(struct s_client *cl, ECM_REQUEST *er)
1932{
1933 if (!cl || !cl->ecmtask)
1934 return;
1935
1936 ECM_REQUEST *ert;
1937
1938 //cs_log("dcw check from reader %d for idx %d (rc=%d)", er->selected_reader, er->cpti, er->rc);
1939 ert=&cl->ecmtask[er->cpti];
1940 if (ert->rc<99) {
1941 //cs_debug_mask(D_TRACE, "chk_dcw: already done rc=%d %s", er->rc, er->selected_reader->label);
1942 send_reader_stat(er->selected_reader, er, (er->rc <= 0)?4:0);
1943 return; // already done
1944 }
1945 if( (er->caid!=ert->caid) || memcmp(er->ecmd5, ert->ecmd5, sizeof(er->ecmd5)) )
1946 return; // obsolete
1947
1948 ert->rcEx=er->rcEx;
1949 strcpy(ert->msglog, er->msglog);
1950 ert->selected_reader=er->selected_reader;
1951
1952 // different er->rc codes:
1953 // 0 error
1954 // 1 found
1955 // 2 cache 2
1956 // 3 (emu?)
1957 if (er->rc>0) // found
1958 {
1959 switch(er->rc)
1960 {
1961 case 2:
1962 ert->rc=2;
1963 break;
1964 case 3:
1965 ert->rc=3;
1966 break;
1967 default:
1968 ert->rc=0;
1969 }
1970 ert->rcEx=0;
1971 memcpy(ert->cw , er->cw , sizeof(er->cw));
1972#ifdef CS_WITH_GBOX
1973 ert->gbxCWFrom=er->gbxCWFrom;
1974#endif
1975 } else { // not found (from ONE of the readers !)
1976 int i;
1977 if (er->selected_reader)
1978 ert->matching_rdr[get_ridx(er->selected_reader)]=0; //FIXME one of these two might be superfluous
1979
1980 struct s_reader *rdr;
1981 for (i=0,rdr=first_reader; (ert) && rdr ; rdr=rdr->next, i++) {
1982 if (ert->matching_rdr[i]) { // we have still another chance
1983 ert->selected_reader=0;
1984 ert=(ECM_REQUEST *)0;
1985 }
1986 }
1987
1988 if (ert) ert->rc=4;
1989 else send_reader_stat(er->selected_reader, er, 4);
1990 }
1991 if (ert) send_dcw(cl, ert);
1992 return;
1993}
1994
1995ulong chk_provid(uchar *ecm, ushort caid) {
1996 int i, len, descriptor_length = 0;
1997 ulong provid = 0;
1998
1999 switch(caid >> 8) {
2000 case 0x01:
2001 // seca
2002 provid = b2i(2, ecm+3);
2003 break;
2004
2005 case 0x05:
2006 // viaccess
2007 i = (ecm[4] == 0xD2) ? ecm[5]+2 : 0; // skip d2 nano
2008 if((ecm[5+i] == 3) && ((ecm[4+i] == 0x90) || (ecm[4+i] == 0x40)))
2009 provid = (b2i(3, ecm+6+i) & 0xFFFFF0);
2010
2011 i = (ecm[6] == 0xD2) ? ecm[7]+2 : 0; // skip d2 nano long ecm
2012 if((ecm[7+i] == 7) && ((ecm[6+i] == 0x90) || (ecm[6+i] == 0x40)))
2013 provid = (b2i(3, ecm+8+i) & 0xFFFFF0);
2014
2015 break;
2016
2017 case 0x0D:
2018 // cryptoworks
2019 len = (((ecm[1] & 0xf) << 8) | ecm[2])+3;
2020 for(i=8; i<len; i+=descriptor_length+2) {
2021 descriptor_length = ecm[i+1];
2022 if (ecm[i] == 0x83) {
2023 provid = (ulong)ecm[i+2] & 0xFE;
2024 break;
2025 }
2026 }
2027 break;
2028 }
2029 return(provid);
2030}
2031
2032#ifdef IRDETO_GUESSING
2033void guess_irdeto(ECM_REQUEST *er)
2034{
2035 uchar b3;
2036 int b47;
2037 //ushort chid;
2038 struct s_irdeto_quess *ptr;
2039
2040 b3 = er->ecm[3];
2041 ptr = cfg->itab[b3];
2042 if( !ptr ) {
2043 cs_debug_mask(D_TRACE, "unknown irdeto byte 3: %02X", b3);
2044 return;
2045 }
2046 b47 = b2i(4, er->ecm+4);
2047 //chid = b2i(2, er->ecm+6);
2048 //cs_debug_mask(D_TRACE, "ecm: b47=%08X, ptr->b47=%08X, ptr->caid=%04X", b47, ptr->b47, ptr->caid);
2049 while( ptr )
2050 {
2051 if( b47==ptr->b47 )
2052 {
2053 if( er->srvid && (er->srvid!=ptr->sid) )
2054 {
2055 cs_debug_mask(D_TRACE, "sid mismatched (ecm: %04X, guess: %04X), wrong oscam.ird file?",
2056 er->srvid, ptr->sid);
2057 return;
2058 }
2059 er->caid=ptr->caid;
2060 er->srvid=ptr->sid;
2061 er->chid=(ushort)ptr->b47;
2062// cs_debug_mask(D_TRACE, "quess_irdeto() found caid=%04X, sid=%04X, chid=%04X",
2063// er->caid, er->srvid, er->chid);
2064 return;
2065 }
2066 ptr=ptr->next;
2067 }
2068}
2069#endif
2070
2071void cs_betatunnel(ECM_REQUEST *er)
2072{
2073 int n;
2074 struct s_client *cl = cur_client();
2075 ulong mask_all = 0xFFFF;
2076 uchar headerN3[10] = {0xc7, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x87, 0x12};
2077 uchar headerN2[10] = {0xc9, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x48, 0x12};
2078 TUNTAB *ttab;
2079 ttab = &cl->ttab;
2080
2081 for (n = 0; (n < CS_MAXTUNTAB); n++) {
2082 if ((er->caid==ttab->bt_caidfrom[n]) && ((er->srvid==ttab->bt_srvid[n]) || (ttab->bt_srvid[n])==mask_all)) {
2083
2084 er->caid = ttab->bt_caidto[n];
2085 er->prid = 0;
2086 er->l = er->ecm[2] + 3;
2087
2088 memmove(er->ecm + 13, er->ecm + 3, er->l - 3);
2089
2090 if (er->l > 0x88) {
2091 memcpy(er->ecm + 3, headerN3, 10);
2092
2093 if (er->ecm[0] == 0x81)
2094 er->ecm[12] += 1;
2095
2096 er->ecm[1]=0x70;
2097 }
2098 else
2099 memcpy(er->ecm + 3, headerN2, 10);
2100
2101 er->l += 10;
2102 er->ecm[2] = er->l - 3;
2103 er->btun = 1;
2104
2105 cl->cwtun++;
2106 first_client->cwtun++;
2107
2108 cs_debug_mask(D_TRACE, "ECM converted from: 0x%X to BetaCrypt: 0x%X for service id:0x%X",
2109 ttab->bt_caidfrom[n], ttab->bt_caidto[n], ttab->bt_srvid[n]);
2110 }
2111 }
2112}
2113
2114void guess_cardsystem(ECM_REQUEST *er)
2115{
2116 ushort last_hope=0;
2117
2118 // viaccess - check by provid-search
2119 if( (er->prid=chk_provid(er->ecm, 0x500)) )
2120 er->caid=0x500;
2121
2122 // nagra
2123 // is ecm[1] always 0x30 ?
2124 // is ecm[3] always 0x07 ?
2125 if ((er->ecm[6]==1) && (er->ecm[4]==er->ecm[2]-2))
2126 er->caid=0x1801;
2127
2128 // seca2 - very poor
2129 if ((er->ecm[8]==0x10) && ((er->ecm[9]&0xF1)==1))
2130 last_hope=0x100;
2131
2132 // is cryptoworks, but which caid ?
2133 if ((er->ecm[3]==0x81) && (er->ecm[4]==0xFF) &&
2134 (!er->ecm[5]) && (!er->ecm[6]) && (er->ecm[7]==er->ecm[2]-5))
2135 last_hope=0xd00;
2136
2137#ifdef IRDETO_GUESSING
2138 if (!er->caid && er->ecm[2]==0x31 && er->ecm[0x0b]==0x28)
2139 guess_irdeto(er);
2140#endif
2141
2142 if (!er->caid) // guess by len ..
2143 er->caid=len4caid[er->ecm[2]+3];
2144
2145 if (!er->caid)
2146 er->caid=last_hope;
2147}
2148
2149void request_cw(ECM_REQUEST *er, int flag, int reader_types)
2150{
2151 int i;
2152 if ((reader_types == 0) || (reader_types == 2))
2153 er->level=flag;
2154 flag=(flag)?3:1; // flag specifies with/without fallback-readers
2155 struct s_reader *rdr;
2156
2157 ushort lc=0, *lp;
2158 if (cs_dblevel) {
2159 for (lp=(ushort *)er->ecm+(er->l>>2), lc=0; lp>=(ushort *)er->ecm; lp--)
2160 lc^=*lp;
2161 }
2162
2163 for (i=0,rdr=first_reader; rdr ; rdr=rdr->next, i++) {
2164 int status = 0;
2165 switch (reader_types)
2166 {
2167 // network and local cards
2168 default:
2169 case 0:
2170 if (er->matching_rdr[i]&flag){
2171 cs_debug_mask(D_TRACE, "request_cw1 to reader %s ridx=%d fd=%d ecm=%04X", rdr->label, i, rdr->fd, lc);
2172 status = write_ecm_request(rdr->fd, er);
2173 }
2174 break;
2175 // only local cards
2176 case 1:
2177 if (!(rdr->typ & R_IS_NETWORK))
2178 if (er->matching_rdr[i]&flag) {
2179 cs_debug_mask(D_TRACE, "request_cw2 to reader %s ridx=%d fd=%d ecm=%04X", rdr->label, i, rdr->fd, lc);
2180 status = write_ecm_request(rdr->fd, er);
2181 }
2182 break;
2183 // only network
2184 case 2:
2185 //cs_log("request_cw3 ridx=%d fd=%d", i, rdr->fd);
2186 if ((rdr->typ & R_IS_NETWORK))
2187 if (er->matching_rdr[i]&flag) {
2188 cs_debug_mask(D_TRACE, "request_cw3 to reader %s ridx=%d fd=%d ecm=%04X", rdr->label, i, rdr->fd, lc);
2189 status = write_ecm_request(rdr->fd, er);
2190 }
2191 break;
2192 }
2193 if (status == -1) {
2194 cs_log("request_cw() failed on reader %s (%d) errno=%d, %s", rdr->label, i, errno, strerror(errno));
2195 if (rdr->fd) {
2196 rdr->fd_error++;
2197 if (rdr->fd_error > 5) {
2198 rdr->fd_error = 0;
2199 restart_cardreader(rdr, 1); //Schlocke: This restarts the reader!
2200 }
2201 }
2202 }
2203 else
2204 rdr->fd_error = 0;
2205 }
2206}
2207
2208static int update_reader_count(ECM_REQUEST *er) {
2209 int i, m;
2210 struct s_reader *rdr;
2211 for (i=m=0,rdr=first_reader; rdr ; rdr=rdr->next, i++) {
2212 m|=er->matching_rdr[i];
2213 if (er->matching_rdr[i] == 1)
2214 er->reader_count++;
2215 }
2216 return m;
2217}
2218
2219void get_cw(struct s_client * client, ECM_REQUEST *er)
2220{
2221 int i, j, m;
2222 time_t now = time((time_t)0);
2223
2224 client->lastecm = now;
2225
2226 if (!er->caid)
2227 guess_cardsystem(er);
2228
2229 /* Quickfix Area */
2230
2231 if( (er->caid & 0xFF00) == 0x600 && !er->chid )
2232 er->chid = (er->ecm[6]<<8)|er->ecm[7];
2233
2234 // quickfix for 0100:000065
2235 if (er->caid == 0x100 && er->prid == 0x65 && er->srvid == 0)
2236 er->srvid = 0x0642;
2237
2238 // Quickfixes for Opticum/Globo HD9500
2239 // Quickfix for 0500:030300
2240 if (er->caid == 0x500 && er->prid == 0x030300)
2241 er->prid = 0x030600;
2242
2243 // Quickfix for 0500:D20200
2244 if (er->caid == 0x500 && er->prid == 0xD20200)
2245 er->prid = 0x030600;
2246
2247 //betacrypt ecm with nagra header
2248 if (er->caid == 0x1702 && er->l == 0x89 && er->ecm[3] == 0x07 && er->ecm[4] == 0x84)
2249 er->caid = 0x1833;
2250
2251 /* END quickfixes */
2252
2253 if (!er->prid)
2254 er->prid = chk_provid(er->ecm, er->caid);
2255
2256 // Set providerid for newcamd clients if none is given
2257 if( (!er->prid) && client->ncd_server ) {
2258 int pi = client->port_idx;
2259 if( pi >= 0 && cfg->ncd_ptab.nports && cfg->ncd_ptab.nports >= pi )
2260 er->prid = cfg->ncd_ptab.ports[pi].ftab.filts[0].prids[0];
2261 }
2262
2263 // CAID not supported or found
2264 if (!er->caid) {
2265 er->rc = 8;
2266 er->rcEx = E2_CAID;
2267 snprintf( er->msglog, MSGLOGSIZE, "CAID not supported or found" );
2268 }
2269
2270 // user expired
2271 if(client->expirationdate && client->expirationdate < client->lastecm)
2272 er->rc = 11;
2273
2274 // out of timeframe
2275 if(client->allowedtimeframe[0] && client->allowedtimeframe[1]) {
2276 struct tm *acttm;
2277 acttm = localtime(&now);
2278 int curtime = (acttm->tm_hour * 60) + acttm->tm_min;
2279 int mintime = client->allowedtimeframe[0];
2280 int maxtime = client->allowedtimeframe[1];
2281 if(!((mintime <= maxtime && curtime > mintime && curtime < maxtime) || (mintime > maxtime && (curtime > mintime || curtime < maxtime)))) {
2282 er->rc = 11;
2283 }
2284 cs_debug_mask(D_TRACE, "Check Timeframe - result: %d, start: %d, current: %d, end: %d\n",er->rc, mintime, curtime, maxtime);
2285 }
2286
2287 // user disabled
2288 if(client->disabled != 0) {
2289 if (client->failban & BAN_DISABLED){
2290 cs_add_violation(client->ip);
2291 cs_exit(SIGQUIT); // don't know whether this is best way to kill the thread
2292 }
2293 er->rc = 12;
2294 }
2295
2296
2297 // rc<100 -> ecm error
2298 if (er->rc > 99) {
2299
2300 m = er->caid;
2301 er->ocaid = er->caid;
2302 i = er->srvid;
2303
2304 if ((i != client->last_srvid) || (!client->lastswitch)) {
2305 if(cfg->usrfileflag)
2306 cs_statistics(client);
2307 client->lastswitch = now;
2308 }
2309
2310 // user sleeping
2311 if ((client->tosleep) && (now - client->lastswitch > client->tosleep)) {
2312
2313 if (client->failban & BAN_SLEEPING) {
2314 cs_add_violation(client->ip);
2315 cs_exit(SIGQUIT); // todo don't know whether this is best way to kill the thread
2316 }
2317
2318 if (client->c35_sleepsend != 0) {
2319 er->rc = 13; // send stop command CMD08 {00 xx}
2320 } else {
2321 er->rc = 6;
2322 }
2323 }
2324
2325 client->last_srvid = i;
2326 client->last_caid = m;
2327
2328 for (j = 0; (j < 6) && (er->rc > 99); j++)
2329 {
2330 switch(j) {
2331
2332 case 0:
2333 // fake (uniq)
2334 if (client->dup)
2335 er->rc = 7;
2336 break;
2337
2338 case 1:
2339 // invalid (caid)
2340 if (!chk_bcaid(er, &client->ctab)) {
2341 er->rc = 8;
2342 er->rcEx = E2_CAID;
2343 snprintf( er->msglog, MSGLOGSIZE, "invalid caid %x",er->caid );
2344 }
2345 break;
2346
2347 case 2:
2348 // invalid (srvid)
2349 if (!chk_srvid(client, er))
2350 {
2351 er->rc = 8;
2352 snprintf( er->msglog, MSGLOGSIZE, "invalid SID" );
2353 }
2354
2355 break;
2356
2357 case 3:
2358 // invalid (ufilters)
2359 if (!chk_ufilters(er))
2360 er->rc = 8;
2361 break;
2362
2363 case 4:
2364 // invalid (sfilter)
2365 if (!chk_sfilter(er, ph[client->ctyp].ptab))
2366 er->rc = 8;
2367 break;
2368
2369 case 5:
2370 // corrupt
2371 if( (i = er->l - (er->ecm[2] + 3)) ) {
2372 if (i > 0) {
2373 cs_debug_mask(D_TRACE, "warning: ecm size adjusted from 0x%X to 0x%X",
2374 er->l, er->ecm[2] + 3);
2375 er->l = (er->ecm[2] + 3);
2376 }
2377 else
2378 er->rc = 9;
2379 }
2380 break;
2381 }
2382 }
2383 }
2384
2385 //Schlocke: above checks could change er->rc so
2386 if (er->rc > 99) {
2387 /*BetaCrypt tunneling
2388 *moved behind the check routines,
2389 *because newcamd ECM will fail
2390 *if ECM is converted before
2391 */
2392 if (&client->ttab)
2393 cs_betatunnel(er);
2394
2395 // ignore ecm ...
2396 int offset = 3;
2397 // ... and betacrypt header for cache md5 calculation
2398 if ((er->caid >> 8) == 0x17)
2399 offset = 13;
2400
2401 // store ECM in cache
2402 memcpy(er->ecmd5, MD5(er->ecm+offset, er->l-offset, client->dump), CS_ECMSTORESIZE);
2403
2404 // cache1
2405 if (check_cwcache1(er, client->grp))
2406 er->rc = 1;
2407 else if (check_and_store_ecmcache(er, client->grp))
2408 return;
2409
2410#ifdef CS_ANTICASC
2411 ac_chk(er, 0);
2412#endif
2413 }
2414
2415 if(er->rc > 99) {
2416 er->reader_avail=0;
2417 struct s_reader *rdr;
2418 for (i=0,rdr=first_reader; rdr ; rdr=rdr->next, i++)
2419 if (matching_reader(er, rdr)) {
2420 er->matching_rdr[i] = (rdr->fallback)? 2: 1;
2421 if (cfg->lb_mode || !rdr->fallback)
2422 er->reader_avail++;
2423 }
2424
2425 if (cfg->lb_mode) {
2426 cs_debug_mask(D_TRACE, "requesting client %s best reader for %04X/%06X/%04X",
2427 username(client), er->caid, er->prid, er->srvid);
2428 get_best_reader(er);
2429 }
2430
2431 m = update_reader_count(er);
2432
2433 switch(m) {
2434 // no reader -> not found
2435 case 0:
2436 er->rc = 4;
2437 if (!er->rcEx)
2438 er->rcEx = E2_GROUP;
2439 snprintf(er->msglog, MSGLOGSIZE, "no matching reader");
2440 break;
2441
2442 // fallbacks only, switch them
2443 case 2:
2444 for (i=0,rdr=first_reader; rdr ; rdr=rdr->next, i++)
2445 er->matching_rdr[i]>>=1;
2446 }
2447 }
2448
2449 if (er->rc < 100) {
2450 if (cfg->delay)
2451 cs_sleepms(cfg->delay);
2452
2453 send_dcw(client, er);
2454 return;
2455 }
2456
2457 er->rcEx = 0;
2458 request_cw(er, 0, cfg->preferlocalcards ? 1 : 0);
2459}
2460
2461void log_emm_request(struct s_reader *rdr)
2462{
2463 cs_log("%s emm-request sent (reader=%s, caid=%04X, auprovid=%06lX)",
2464 username(cur_client()), rdr->label, rdr->caid[0],
2465 rdr->auprovid ? rdr->auprovid : b2i(4, rdr->prid[0]));
2466}
2467
2468void do_emm(struct s_client * client, EMM_PACKET *ep)
2469{
2470 char *typtext[]={"unknown", "unique", "shared", "global"};
2471
2472 struct s_reader *aureader = client->aureader;
2473 cs_ddump_mask(D_EMM, ep->emm, ep->l, "emm:");
2474
2475 //Unique Id matching for pay-per-view channels:
2476 if (client->autoau) {
2477 struct s_reader *rdr;
2478 for (rdr=first_reader; rdr ; rdr=rdr->next)
2479 if (rdr->card_system>0 && !rdr->audisabled)
2480 if (reader_get_emm_type(ep, rdr)) //decodes ep->type and ep->hexserial from the EMM
2481 if (memcmp(ep->hexserial, rdr->hexserial, sizeof(ep->hexserial))==0) {
2482 aureader = rdr;
2483 break; //
2484 }
2485 }
2486
2487 if (!aureader) {
2488 cs_debug_mask(D_EMM, "emm disabled, client has no au-reader!");
2489 return;
2490 }
2491
2492 //2nd check for audisabled.
2493 if (aureader->audisabled) {
2494 cs_debug_mask(D_EMM, "AU is disabled for reader %s", aureader->label);
2495 return;
2496 }
2497
2498 if (aureader->card_system>0) {
2499 if (!reader_get_emm_type(ep, aureader)) { //decodes ep->type and ep->hexserial from the EMM
2500 cs_debug_mask(D_EMM, "emm skipped");
2501 return;
2502 }
2503 }
2504 else {
2505 cs_debug_mask(D_EMM, "emm skipped, reader %s has no cardsystem defined!", aureader->label);
2506 return;
2507 }
2508
2509 //test: EMM becomes skipped if auprivid doesn't match with provid from EMM
2510 if(aureader->auprovid && b2i(4, ep->provid)) {
2511 if(aureader->auprovid != b2i(4, ep->provid)) {
2512 cs_debug_mask(D_EMM, "emm skipped, reader %s auprovid doesn't match %06lX != %06lX!", aureader->label, aureader->auprovid, b2i(4, ep->provid));
2513 return;
2514 }
2515 }
2516
2517 cs_debug_mask(D_EMM, "emmtype %s. Reader %s has serial %s.", typtext[ep->type], aureader->label, cs_hexdump(0, aureader->hexserial, 8));
2518 cs_ddump_mask(D_EMM, ep->hexserial, 8, "emm UA/SA:");
2519
2520 client->last=time((time_t)0);
2521 if (aureader->b_nano[ep->emm[0]] & 0x02) //should this nano be saved?
2522 {
2523 char token[256];
2524 FILE *fp;
2525 time_t rawtime;
2526 time (&rawtime);
2527 struct tm *timeinfo;
2528 timeinfo = localtime (&rawtime); /* to access LOCAL date/time info */
2529 char buf[80];
2530 strftime (buf, 80, "%Y/%m/%d %H:%M:%S", timeinfo);
2531 sprintf (token, "%s%s_emm.log", cs_confdir, aureader->label);
2532 int emm_length = ((ep->emm[1] & 0x0f) << 8) | ep->emm[2];
2533
2534 if (!(fp = fopen (token, "a")))
2535 {
2536 cs_log ("ERROR: Cannot open file '%s' (errno=%d: %s)\n", token, errno, strerror(errno));
2537 }
2538 else
2539 {
2540 fprintf (fp, "%s %s ", buf, cs_hexdump(0, ep->hexserial, 8));
2541 fprintf (fp, "%s\n", cs_hexdump(0, ep->emm, emm_length + 3));
2542 fclose (fp);
2543 cs_log ("Succesfully added EMM to %s.", token);
2544 }
2545
2546 sprintf (token, "%s%s_emm.bin", cs_confdir, aureader->label);
2547 if (!(fp = fopen (token, "ab")))
2548 {
2549 cs_log ("ERROR: Cannot open file '%s' (errno=%d: %s)\n", token, errno, strerror(errno));
2550 }
2551 else
2552 {
2553 if ((int)fwrite(ep->emm, 1, emm_length+3, fp) == emm_length+3)
2554 {
2555 cs_log ("Succesfully added binary EMM to %s.", token);
2556 }
2557 else
2558 {
2559 cs_log ("ERROR: Cannot write binary EMM to %s (errno=%d: %s)\n", token, errno, strerror(errno));
2560 }
2561 fclose (fp);
2562 }
2563 }
2564
2565 int is_blocked = 0;
2566 switch (ep->type) {
2567 case UNKNOWN: is_blocked = aureader->blockemm_unknown;
2568 break;
2569 case UNIQUE: is_blocked = aureader->blockemm_u;
2570 break;
2571 case SHARED: is_blocked = aureader->blockemm_s;
2572 break;
2573 case GLOBAL: is_blocked = aureader->blockemm_g;
2574 break;
2575 }
2576
2577 if (is_blocked != 0) {
2578#ifdef WEBIF
2579 aureader->emmblocked[ep->type]++;
2580 is_blocked = aureader->emmblocked[ep->type];
2581#endif
2582 /* we have to write the log for blocked EMM here because
2583 this EMM never reach the reader module where the rest
2584 of EMM log is done. */
2585 if (aureader->logemm & 0x08) {
2586 cs_log("%s emmtype=%s, len=%d, idx=0, cnt=%d: blocked (0 ms) by %s",
2587 client->usr,
2588 typtext[ep->type],
2589 ep->emm[2],
2590 is_blocked,
2591 aureader->label);
2592 }
2593 return;
2594 }
2595
2596
2597 client->lastemm = time((time_t)0);
2598
2599 if (aureader->card_system > 0) {
2600 if (!check_emm_cardsystem(aureader, ep)) { // wrong caid
2601 client->emmnok++;
2602 return;
2603 }
2604 client->emmok++;
2605 }
2606 ep->client = cur_client();
2607 cs_debug_mask(D_EMM, "emm is being sent to reader %s.", aureader->label);
2608 write_to_pipe(aureader->fd, PIP_ID_EMM, (uchar *) ep, sizeof(EMM_PACKET));
2609}
2610
2611int comp_timeb(struct timeb *tpa, struct timeb *tpb)
2612{
2613 if (tpa->time>tpb->time) return(1);
2614 if (tpa->time<tpb->time) return(-1);
2615 if (tpa->millitm>tpb->millitm) return(1);
2616 if (tpa->millitm<tpb->millitm) return(-1);
2617 return(0);
2618}
2619
2620struct timeval *chk_pending(struct timeb tp_ctimeout)
2621{
2622 int i;
2623 ulong td;
2624 struct timeb tpn, tpe, tpc; // <n>ow, <e>nd, <c>heck
2625
2626 ECM_REQUEST *er;
2627 cs_ftime(&tpn);
2628 tpe=tp_ctimeout; // latest delay -> disconnect
2629
2630 struct s_client *cl = cur_client();
2631
2632 if (cl->ecmtask)
2633 i=(ph[cl->ctyp].multi)?CS_MAXPENDING:1;
2634 else
2635 i=0;
2636
2637 //cs_log("num pend=%d", i);
2638
2639 for (--i; i>=0; i--) {
2640 if (cl->ecmtask[i].rc>=99) { // check all pending ecm-requests
2641 int act, j;
2642 er=&cl->ecmtask[i];
2643 tpc=er->tps;
2644 unsigned int tt;
2645 tt = (er->stage) ? cfg->ctimeout : cfg->ftimeout;
2646 tpc.time +=tt / 1000;
2647 tpc.millitm += tt % 1000;
2648 if (!er->stage && er->rc>=100) {
2649 struct s_reader *rdr;
2650 for (j=0, act=1, rdr=first_reader; (act) && rdr ; rdr=rdr->next, j++) {
2651 if (cfg->preferlocalcards && !er->locals_done) {
2652 if ((er->matching_rdr[j]&1) && !(rdr->typ & R_IS_NETWORK))
2653 act=0;
2654 } else if (cfg->preferlocalcards && er->locals_done) {
2655 if ((er->matching_rdr[j]&1) && (rdr->typ & R_IS_NETWORK))
2656 act=0;
2657 } else {
2658 if (er->matching_rdr[j]&1)
2659 act=0;
2660 }
2661 }
2662
2663 //cs_log("stage 0, act=%d r0=%d, r1=%d, r2=%d, r3=%d, r4=%d r5=%d", act,
2664 // er->matching_rdr[0], er->matching_rdr[1], er->matching_rdr[2],
2665 // er->matching_rdr[3], er->matching_rdr[4], er->matching_rdr[5]);
2666
2667 if (act) {
2668 int inc_stage = 1;
2669 if (cfg->preferlocalcards && !er->locals_done) {
2670 er->locals_done = 1;
2671 struct s_reader *rdr;
2672 for (rdr=first_reader; rdr ; rdr=rdr->next)
2673 if (rdr->typ & R_IS_NETWORK)
2674 inc_stage = 0;
2675 }
2676 unsigned int tt;
2677 if (!inc_stage) {
2678 request_cw(er, er->stage, 2);
2679 tt = 1000 * (tpn.time - er->tps.time) + tpn.millitm - er->tps.millitm;
2680 tpc.time += tt / 1000;
2681 tpc.millitm += tt % 1000;
2682 } else {
2683 er->locals_done = 0;
2684 er->stage++;
2685 request_cw(er, er->stage, cfg->preferlocalcards ? 1 : 0);
2686
2687 tt = (cfg->ctimeout-cfg->ftimeout);
2688 tpc.time += tt / 1000;
2689 tpc.millitm += tt % 1000;
2690 }
2691 }
2692 }
2693 if (comp_timeb(&tpn, &tpc)>0) { // action needed
2694 //cs_log("Action now %d.%03d", tpn.time, tpn.millitm);
2695 //cs_log(" %d.%03d", tpc.time, tpc.millitm);
2696 if (er->stage) {
2697 er->rc=5; // timeout
2698 if (cfg->lb_mode) {
2699 int r;
2700 struct s_reader *rdr;
2701 for (r=0,rdr=first_reader; rdr ; rdr=rdr->next, r++)
2702 if (er->matching_rdr[r])
2703 send_reader_stat(rdr, er, 5);
2704 }
2705 send_dcw(cl, er);
2706 continue;
2707 } else {
2708 er->stage++;
2709 if (er->rc>=100) //do not request rc=99
2710 request_cw(er, er->stage, 0);
2711 unsigned int tt;
2712 tt = (cfg->ctimeout-cfg->ftimeout);
2713 tpc.time += tt / 1000;
2714 tpc.millitm += tt % 1000;
2715 }
2716 }
2717 //build_delay(&tpe, &tpc);
2718 if (comp_timeb(&tpe, &tpc)>0) {
2719 tpe.time=tpc.time;
2720 tpe.millitm=tpc.millitm;
2721 }
2722 }
2723 }
2724
2725 td=(tpe.time-tpn.time)*1000+(tpe.millitm-tpn.millitm)+5;
2726 cl->tv.tv_sec = td/1000;
2727 cl->tv.tv_usec = (td%1000)*1000;
2728 //cs_log("delay %d.%06d", tv.tv_sec, tv.tv_usec);
2729 return(&cl->tv);
2730}
2731
2732int process_input(uchar *buf, int l, int timeout)
2733{
2734 int rc;
2735 fd_set fds;
2736 struct timeb tp;
2737
2738 struct s_client *cl = cur_client();
2739
2740 cs_ftime(&tp);
2741 tp.time+=timeout;
2742
2743 while (1) {
2744 FD_ZERO(&fds);
2745
2746 if (cl->pfd)
2747 FD_SET(cl->pfd, &fds);
2748
2749 FD_SET(cl->fd_m2c_c, &fds);
2750
2751 rc=select(((cl->pfd > cl->fd_m2c_c) ? cl->pfd : cl->fd_m2c_c)+1, &fds, 0, 0, chk_pending(tp));
2752 if (rc<0) {
2753 if (errno==EINTR) continue;
2754 else return(0);
2755 }
2756
2757 if (FD_ISSET(cl->fd_m2c_c, &fds)) { // read from pipe
2758 if (process_client_pipe(cl, buf, l)==PIP_ID_UDP) {
2759 rc=ph[cl->ctyp].recv(cl, buf, l);
2760 break;
2761 }
2762 }
2763
2764 if (cl->pfd && FD_ISSET(cl->pfd, &fds)) { // read from client
2765 rc=ph[cl->ctyp].recv(cl, buf, l);
2766 break;
2767 }
2768
2769 if (tp.time<=time((time_t *)0)) { // client maxidle reached
2770 rc=(-9);
2771 break;
2772 }
2773 }
2774 return(rc);
2775}
2776
2777static void restart_clients()
2778{
2779 cs_log("restarting clients");
2780 struct s_client *cl;
2781 for (cl=first_client->next; cl ; cl=cl->next)
2782 if (cl->typ=='c' && ph[cl->ctyp].type & MOD_CONN_NET) {
2783 kill_thread(cl);
2784 cs_log("killing client c %8X", (unsigned long)(cl->thread));
2785 }
2786}
2787
2788
2789static void process_master_pipe(int mfdr)
2790{
2791 int n;
2792 uchar *ptr;
2793
2794 switch(n=read_from_pipe(mfdr, &ptr, 1))
2795 {
2796 case PIP_ID_KCL: //Kill all clients
2797 restart_clients();
2798 break;
2799 case PIP_ID_ERR:
2800 cs_exit(1); //better than reading from dead pipe!
2801 break;
2802 default:
2803 cs_log("unhandled pipe message %d (master pipe)", n);
2804 break;
2805 }
2806 if (ptr) free(ptr);
2807}
2808
2809
2810int process_client_pipe(struct s_client *cl, uchar *buf, int l) {
2811 uchar *ptr;
2812 unsigned short n;
2813 int pipeCmd = read_from_pipe(cl->fd_m2c_c, &ptr, 0);
2814
2815 switch(pipeCmd) {
2816 case PIP_ID_ECM:
2817 chk_dcw(cl, (ECM_REQUEST *)ptr);
2818 break;
2819 case PIP_ID_UDP:
2820 if (ptr[0]!='U') {
2821 cs_log("INTERNAL PIPE-ERROR");
2822 }
2823 memcpy(&n, ptr+1, 2);
2824 if (n+3<=l) {
2825 memcpy(buf, ptr, n+3);
2826 }
2827 break;
2828 case PIP_ID_ERR:
2829 cs_exit(1);
2830 break;
2831 default:
2832 cs_log("unhandled pipe message %d (client %s)", pipeCmd, cl->usr);
2833 break;
2834 }
2835 if (ptr) free(ptr);
2836 return pipeCmd;
2837}
2838
2839void cs_log_config()
2840{
2841 uchar buf[20];
2842
2843 if (cfg->nice!=99)
2844 sprintf((char *)buf, ", nice=%d", cfg->nice);
2845 else
2846 buf[0]='\0';
2847 cs_log("version=%s, build #%s, system=%s-%s-%s%s", CS_VERSION_X, CS_SVN_VERSION, CS_OS_CPU, CS_OS_HW, CS_OS_SYS, buf);
2848 cs_log("client max. idle=%d sec, debug level=%d", cfg->cmaxidle, cs_dblevel);
2849
2850 if( cfg->max_log_size )
2851 sprintf((char *)buf, "%d Kb", cfg->max_log_size);
2852 else
2853 strcpy((char *)buf, "unlimited");
2854 cs_log("max. logsize=%s", buf);
2855 cs_log("client timeout=%lu ms, fallback timeout=%lu ms, cache delay=%d ms",
2856 cfg->ctimeout, cfg->ftimeout, cfg->delay);
2857}
2858
2859void cs_waitforcardinit()
2860{
2861 if (cfg->waitforcards)
2862 {
2863 cs_log("waiting for local card init");
2864 int card_init_done;
2865 cs_sleepms(3000); // short sleep for card detect to work proberly
2866 do {
2867 card_init_done = 1;
2868 struct s_reader *rdr;
2869 for (rdr=first_reader; rdr ; rdr=rdr->next)
2870 if (!(rdr->typ & R_IS_CASCADING) && rdr->card_status == CARD_NEED_INIT) {
2871 card_init_done = 0;
2872 break;
2873 }
2874 cs_sleepms(300); // wait a little bit
2875 //alarm(cfg->cmaxidle + cfg->ctimeout / 1000 + 1);
2876 } while (!card_init_done);
2877 cs_log("init for all local cards done");
2878 }
2879}
2880
2881int accept_connection(int i, int j) {
2882 struct sockaddr_in cad;
2883 int scad,n;
2884 scad = sizeof(cad);
2885 uchar buf[2048];
2886
2887 if (ph[i].type==MOD_CONN_UDP) {
2888
2889 if ((n=recvfrom(ph[i].ptab->ports[j].fd, buf+3, sizeof(buf)-3, 0, (struct sockaddr *)&cad, (socklen_t *)&scad))>0) {
2890 struct s_client *cl;
2891 cl=idx_from_ip(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port));
2892
2893 unsigned short rl;
2894 rl=n;
2895 buf[0]='U';
2896 memcpy(buf+1, &rl, 2);
2897
2898 if (!cl) {
2899 if (cs_check_violation((uint)cs_inet_order(cad.sin_addr.s_addr)))
2900 return 0;
2901 //printf("IP: %s - %d\n", inet_ntoa(*(struct in_addr *)&cad.sin_addr.s_addr), cad.sin_addr.s_addr);
2902
2903 cl = cs_fork(cs_inet_order(cad.sin_addr.s_addr));
2904 if (!cl) return 0;
2905
2906 cl->ctyp=i;
2907 cl->port_idx=j;
2908 cl->udp_fd=ph[i].ptab->ports[j].fd;
2909 cl->udp_sa=cad;
2910
2911 cl->port=ntohs(cad.sin_port);
2912 cl->typ='c';
2913
2914 write_to_pipe(cl->fd_m2c, PIP_ID_UDP, (uchar*)&buf, n+3);
2915
2916 pthread_attr_t attr;
2917 pthread_attr_init(&attr);
2918#ifndef TUXBOX
2919 pthread_attr_setstacksize(&attr, PTHREAD_STACK_SIZE);
2920#endif
2921 pthread_create(&cl->thread, &attr, ph[i].s_handler, (void *) cl);
2922 pthread_detach(cl->thread);
2923 pthread_attr_destroy(&attr);
2924 } else {
2925 write_to_pipe(cl->fd_m2c, PIP_ID_UDP, (uchar*)&buf, n+3);
2926 }
2927 }
2928 } else { //TCP
2929
2930 int pfd3;
2931 if ((pfd3=accept(ph[i].ptab->ports[j].fd, (struct sockaddr *)&cad, (socklen_t *)&scad))>0) {
2932
2933 if (cs_check_violation((uint)cs_inet_order(cad.sin_addr.s_addr))) {
2934 close(pfd3);
2935 return 0;
2936 }
2937
2938 struct s_client * cl = cs_fork(cs_inet_order(cad.sin_addr.s_addr));
2939 if (cl == NULL) {
2940 close(pfd3);
2941 return 0;
2942 }
2943
2944 int flag = 1;
2945 setsockopt(pfd3, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
2946
2947 cl->ctyp=i;
2948 cl->udp_fd=pfd3;
2949 cl->port_idx=j;
2950
2951 cl->pfd=pfd3;
2952 cl->port=ntohs(cad.sin_port);
2953 cl->typ='c';
2954
2955 pthread_attr_t attr;
2956 pthread_attr_init(&attr);
2957#ifndef TUXBOX
2958 pthread_attr_setstacksize(&attr, PTHREAD_STACK_SIZE);
2959#endif
2960 pthread_create(&cl->thread, &attr, ph[i].s_handler, (void*) cl);
2961 pthread_detach(cl->thread);
2962 pthread_attr_destroy(&attr);
2963 }
2964 }
2965 return 0;
2966}
2967
2968/**
2969 * get tmp dir
2970 **/
2971char * get_tmp_dir()
2972{
2973 if (cs_tmpdir[0])
2974 return cs_tmpdir;
2975
2976#ifdef OS_CYGWIN32
2977 char *d = getenv("TMPDIR");
2978 if (!d || !d[0])
2979 d = getenv("TMP");
2980 if (!d || !d[0])
2981 d = getenv("TEMP");
2982 if (!d || !d[0])
2983 getcwd(cs_tmpdir, sizeof(cs_tmpdir)-1);
2984
2985 strcpy(cs_tmpdir, d);
2986 char *p = cs_tmpdir;
2987 while(*p) p++;
2988 p--;
2989 if (*p != '/' && *p != '\\')
2990 strcat(cs_tmpdir, "/");
2991 strcat(cs_tmpdir, "_oscam");
2992#else
2993 strcpy(cs_tmpdir, "/tmp/.oscam");
2994#endif
2995 mkdir(cs_tmpdir, S_IRWXU);
2996 return cs_tmpdir;
2997}
2998
2999
3000int main (int argc, char *argv[])
3001{
3002
3003
3004if (pthread_key_create(&getclient, NULL)) {
3005 fprintf(stderr, "Could not create getclient, exiting...");
3006 exit(1);
3007}
3008#ifdef CS_LED
3009 cs_switch_led(LED1A, LED_DEFAULT);
3010 cs_switch_led(LED1A, LED_ON);
3011#endif
3012
3013 //struct sockaddr_in cad; /* structure to hold client's address */
3014 //int scad; /* length of address */
3015 //int fd; /* socket descriptors */
3016 int i, j;
3017 int bg=0;
3018 int gfd; //nph,
3019 int fdp[2];
3020 int mfdr=0; // Master FD (read)
3021 int fd_c2m=0;
3022
3023 cfg = malloc(sizeof(struct s_config));
3024 memset(cfg, 0, sizeof(struct s_config));
3025
3026 void (*mod_def[])(struct s_module *)=
3027 {
3028#ifdef MODULE_MONITOR
3029 module_monitor,
3030#endif
3031#ifdef MODULE_CAMD33
3032 module_camd33,
3033#endif
3034#ifdef MODULE_CAMD35
3035 module_camd35,
3036#endif
3037#ifdef MODULE_CAMD35_TCP
3038 module_camd35_tcp,
3039#endif
3040#ifdef MODULE_NEWCAMD
3041 module_newcamd,
3042#endif
3043#ifdef MODULE_CCCAM
3044 module_cccam,
3045#endif
3046#ifdef MODULE_CONSTCW
3047 module_constcw,
3048#endif
3049#ifdef CS_WITH_GBOX
3050 module_gbox,
3051#endif
3052#ifdef MODULE_RADEGAST
3053 module_radegast,
3054#endif
3055#ifdef MODULE_SERIAL
3056 module_oscam_ser,
3057#endif
3058#ifdef HAVE_DVBAPI
3059 module_dvbapi,
3060#endif
3061 0
3062 };
3063
3064 void (*cardsystem_def[])(struct s_cardsystem *)=
3065 {
3066#ifdef READER_NAGRA
3067 reader_nagra,
3068#endif
3069#ifdef READER_IRDETO
3070 reader_irdeto,
3071#endif
3072#ifdef READER_CONAX
3073 reader_conax,
3074#endif
3075#ifdef READER_CRYPTOWORKS
3076 reader_cryptoworks,
3077#endif
3078#ifdef READER_SECA
3079 reader_seca,
3080#endif
3081#ifdef READER_VIACCESS
3082 reader_viaccess,
3083#endif
3084#ifdef READER_VIDEOGUARD
3085 reader_videoguard1,
3086 reader_videoguard2,
3087 reader_videoguard12,
3088#endif
3089#ifdef READER_DRE
3090 reader_dre,
3091#endif
3092#ifdef READER_TONGFANG
3093 reader_tongfang,
3094#endif
3095 0
3096 };
3097
3098 while ((i=getopt(argc, argv, "bc:t:d:hm:x"))!=EOF)
3099 {
3100 switch(i) {
3101 case 'b':
3102 bg=1;
3103 break;
3104 case 'c':
3105 cs_strncpy(cs_confdir, optarg, sizeof(cs_confdir));
3106 break;
3107 case 'd':
3108 cs_dblevel=atoi(optarg);
3109 break;
3110 case 't':
3111 mkdir(optarg, S_IRWXU);
3112 j = open(optarg, O_RDONLY);
3113 if (j >= 0) {
3114 close(j);
3115 cs_strncpy(cs_tmpdir, optarg, sizeof(cs_tmpdir));
3116 } else {
3117 printf("WARNING: tmpdir does not exist. using default value.\n");
3118 }
3119 break;
3120 case 'm':
3121 printf("WARNING: -m parameter is deprecated, ignoring it.\n");
3122 break;
3123 case 'h':
3124 default :
3125 usage();
3126 }
3127 }
3128 if (cs_confdir[strlen(cs_confdir)]!='/') strcat(cs_confdir, "/");
3129 init_shm();
3130 init_config();
3131 init_stat();
3132 cfg->debuglvl = cs_dblevel; // give static debuglevel to outer world
3133 for (i=0; mod_def[i]; i++) // must be later BEFORE init_config()
3134 {
3135 memset(&ph[i], 0, sizeof(struct s_module));
3136 mod_def[i](&ph[i]);
3137 }
3138 for (i=0; cardsystem_def[i]; i++) // must be later BEFORE init_config()
3139 {
3140 memset(&cardsystem[i], 0, sizeof(struct s_cardsystem));
3141 cardsystem_def[i](&cardsystem[i]);
3142 }
3143
3144
3145 cs_log("auth size=%d", sizeof(struct s_auth));
3146
3147 init_rnd();
3148 init_sidtab();
3149 init_readerdb();
3150 init_userdb(&cfg->account);
3151 init_signal();
3152 init_srvid();
3153 init_tierid();
3154 //Todo #ifdef CCCAM
3155 init_provid();
3156
3157 init_len4caid();
3158#ifdef IRDETO_GUESSING
3159 init_irdeto_guess_tab();
3160#endif
3161
3162
3163 if (pipe(fdp))
3164 {
3165 cs_log("Cannot create pipe (errno=%d: %s)", errno, strerror(errno));
3166 cs_exit(1);
3167 }
3168 mfdr=fdp[0];
3169 fd_c2m=fdp[1];
3170 gfd=mfdr+1;
3171
3172 first_client->fd_m2c=fd_c2m;
3173 first_client->fd_m2c_c=mfdr;
3174
3175#ifdef OS_MACOSX
3176 if (bg && daemon_compat(1,0))
3177#else
3178 if (bg && daemon(1,0))
3179#endif
3180 {
3181 cs_log("Error starting in background (errno=%d: %s)", errno, strerror(errno));
3182 cs_exit(1);
3183 }
3184
3185 write_versionfile();
3186 server_pid = getpid();
3187
3188#ifdef AZBOX
3189 openxcas_debug_message_onoff(1); // debug
3190
3191 if (openxcas_open_with_smartcard("oscamCAS") < 0) {
3192 cs_log("openxcas: could not init");
3193 }
3194#endif
3195
3196 for (i=0; i<CS_MAX_MOD; i++)
3197 if( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
3198 for(j=0; j<ph[i].ptab->nports; j++)
3199 {
3200 start_listener(&ph[i], j);
3201 if( ph[i].ptab->ports[j].fd+1>gfd )
3202 gfd=ph[i].ptab->ports[j].fd+1;
3203 }
3204
3205 //set time for server to now to avoid 0 in monitor/webif
3206 first_client->last=time((time_t *)0);
3207
3208#ifdef WEBIF
3209 if(cfg->http_port == 0)
3210 cs_log("http disabled");
3211 else
3212 start_thread((void *) &http_srv, "http");
3213#endif
3214
3215 init_cardreader();
3216
3217 cs_waitforcardinit();
3218
3219#ifdef CS_LED
3220 cs_switch_led(LED1A, LED_OFF);
3221 cs_switch_led(LED1B, LED_ON);
3222#endif
3223
3224#ifdef QBOXHD_LED
3225 if(!cfg->disableqboxhdled)
3226 cs_log("QboxHD LED enabled");
3227 qboxhd_led_blink(QBOXHD_LED_COLOR_YELLOW,QBOXHD_LED_BLINK_FAST);
3228 qboxhd_led_blink(QBOXHD_LED_COLOR_RED,QBOXHD_LED_BLINK_FAST);
3229 qboxhd_led_blink(QBOXHD_LED_COLOR_GREEN,QBOXHD_LED_BLINK_FAST);
3230 qboxhd_led_blink(QBOXHD_LED_COLOR_BLUE,QBOXHD_LED_BLINK_FAST);
3231 qboxhd_led_blink(QBOXHD_LED_COLOR_MAGENTA,QBOXHD_LED_BLINK_FAST);
3232#endif
3233
3234#ifdef CS_ANTICASC
3235 if( !cfg->ac_enabled )
3236 cs_log("anti cascading disabled");
3237 else {
3238 init_ac();
3239 start_thread((void *) &start_anticascader, "anticascader"); // 96
3240
3241 }
3242#endif
3243
3244 for (i=0; i<CS_MAX_MOD; i++)
3245 if (ph[i].type & MOD_CONN_SERIAL) // for now: oscam_ser only
3246 if (ph[i].s_handler)
3247 ph[i].s_handler(i);
3248
3249 //cs_close_log();
3250 while (1) {
3251 fd_set fds;
3252
3253 do {
3254 FD_ZERO(&fds);
3255 FD_SET(mfdr, &fds);
3256 for (i=0; i<CS_MAX_MOD; i++)
3257 if ( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
3258 for (j=0; j<ph[i].ptab->nports; j++)
3259 if (ph[i].ptab->ports[j].fd)
3260 FD_SET(ph[i].ptab->ports[j].fd, &fds);
3261 errno=0;
3262 select(gfd, &fds, 0, 0, 0);
3263 } while (errno==EINTR);
3264
3265 first_client->last=time((time_t *)0);
3266
3267 if (FD_ISSET(mfdr, &fds)) {
3268 process_master_pipe(mfdr);
3269 }
3270 for (i=0; i<CS_MAX_MOD; i++) {
3271 if( (ph[i].type & MOD_CONN_NET) && ph[i].ptab ) {
3272 for( j=0; j<ph[i].ptab->nports; j++ ) {
3273 if( ph[i].ptab->ports[j].fd && FD_ISSET(ph[i].ptab->ports[j].fd, &fds) ) {
3274 accept_connection(i,j);
3275 }
3276 }
3277 } // if (ph[i].type & MOD_CONN_NET)
3278 }
3279 }
3280
3281#ifdef AZBOX
3282 if (openxcas_close() < 0) {
3283 cs_log("openxcas: could not close");
3284 }
3285#endif
3286
3287 cs_exit(1);
3288}
3289
3290#ifdef CS_LED
3291void cs_switch_led(int led, int action) {
3292
3293 if(action < 2) { // only LED_ON and LED_OFF
3294 char ledfile[256];
3295 FILE *f;
3296
3297 #ifdef DOCKSTAR
3298 switch(led){
3299 case LED1A:snprintf(ledfile, 255, "/sys/class/leds/dockstar:orange:misc/brightness");
3300 break;
3301 case LED1B:snprintf(ledfile, 255, "/sys/class/leds/dockstar:green:health/brightness");
3302 break;
3303 case LED2:snprintf(ledfile, 255, "/sys/class/leds/dockstar:green:health/brightness");
3304 break;
3305 case LED3:snprintf(ledfile, 255, "/sys/class/leds/dockstar:orange:misc/brightness");
3306 break;
3307 }
3308 #else
3309 switch(led){
3310 case LED1A:snprintf(ledfile, 255, "/sys/class/leds/nslu2:red:status/brightness");
3311 break;
3312 case LED1B:snprintf(ledfile, 255, "/sys/class/leds/nslu2:green:ready/brightness");
3313 break;
3314 case LED2:snprintf(ledfile, 255, "/sys/class/leds/nslu2:green:disk-1/brightness");
3315 break;
3316 case LED3:snprintf(ledfile, 255, "/sys/class/leds/nslu2:green:disk-2/brightness");
3317 break;
3318 }
3319 #endif
3320
3321 if (!(f=fopen(ledfile, "w"))){
3322 // FIXME: sometimes cs_log was not available when calling cs_switch_led -> signal 11
3323 //cs_log("Cannot open file \"%s\" (errno=%d)", ledfile, errno);
3324 return;
3325 }
3326 fprintf(f,"%d", action);
3327 fclose(f);
3328 } else { // LED Macros
3329 switch(action){
3330 case LED_DEFAULT:
3331 cs_switch_led(LED1A, LED_OFF);
3332 cs_switch_led(LED1B, LED_OFF);
3333 cs_switch_led(LED2, LED_ON);
3334 cs_switch_led(LED3, LED_OFF);
3335 break;
3336 case LED_BLINK_OFF:
3337 cs_switch_led(led, LED_OFF);
3338 cs_sleepms(100);
3339 cs_switch_led(led, LED_ON);
3340 break;
3341 case LED_BLINK_ON:
3342 cs_switch_led(led, LED_ON);
3343 cs_sleepms(300);
3344 cs_switch_led(led, LED_OFF);
3345 break;
3346 }
3347 }
3348}
3349#endif
3350
3351#ifdef QBOXHD_LED
3352void qboxhd_led_blink(int color, int duration) {
3353 int f;
3354
3355 if (cfg->disableqboxhdled) {
3356 return;
3357 }
3358
3359 // try QboxHD-MINI first
3360 if ( (f = open ( QBOXHDMINI_LED_DEVICE, O_RDWR |O_NONBLOCK )) > -1 ) {
3361 qboxhdmini_led_color_struct qbminiled;
3362 ulong qboxhdmini_color = 0x000000;
3363
3364 if (color != QBOXHD_LED_COLOR_OFF) {
3365 switch(color) {
3366 case QBOXHD_LED_COLOR_RED:
3367 qboxhdmini_color = QBOXHDMINI_LED_COLOR_RED;
3368 break;
3369 case QBOXHD_LED_COLOR_GREEN:
3370 qboxhdmini_color = QBOXHDMINI_LED_COLOR_GREEN;
3371 break;
3372 case QBOXHD_LED_COLOR_BLUE:
3373 qboxhdmini_color = QBOXHDMINI_LED_COLOR_BLUE;
3374 break;
3375 case QBOXHD_LED_COLOR_YELLOW:
3376 qboxhdmini_color = QBOXHDMINI_LED_COLOR_YELLOW;
3377 break;
3378 case QBOXHD_LED_COLOR_MAGENTA:
3379 qboxhdmini_color = QBOXHDMINI_LED_COLOR_MAGENTA;
3380 break;
3381 }
3382
3383 // set LED on with color
3384 qbminiled.red = (uchar)((qboxhdmini_color&0xFF0000)>>16); // R
3385 qbminiled.green = (uchar)((qboxhdmini_color&0x00FF00)>>8); // G
3386 qbminiled.blue = (uchar)(qboxhdmini_color&0x0000FF); // B
3387
3388 ioctl(f,QBOXHDMINI_IOSET_RGB,&qbminiled);
3389 cs_sleepms(duration);
3390 }
3391
3392 // set LED off
3393 qbminiled.red = 0;
3394 qbminiled.green = 0;
3395 qbminiled.blue = 0;
3396
3397 ioctl(f,QBOXHDMINI_IOSET_RGB,&qbminiled);
3398 close(f);
3399
3400 } else if ( (f = open ( QBOXHD_LED_DEVICE, O_RDWR |O_NONBLOCK )) > -1 ) {
3401
3402 qboxhd_led_color_struct qbled;
3403
3404 if (color != QBOXHD_LED_COLOR_OFF) {
3405 // set LED on with color
3406 qbled.H = color;
3407 qbled.S = 99;
3408 qbled.V = 99;
3409 ioctl(f,QBOXHD_SET_LED_ALL_PANEL_COLOR, &qbled);
3410 cs_sleepms(duration);
3411 }
3412
3413 // set LED off
3414 qbled.H = 0;
3415 qbled.S = 0;
3416 qbled.V = 0;
3417 ioctl(f,QBOXHD_SET_LED_ALL_PANEL_COLOR, &qbled);
3418 close(f);
3419 }
3420
3421 return;
3422}
3423#endif
Note: See TracBrowser for help on using the repository browser.