source: trunk/oscam.c@ 431

Last change on this file since 431 was 121, checked in by smurzch2, 11 years ago

Make code compiling under Mac OS X.

Functions like strncpy, fopen, ... wants char *, not unsigned char *.

File size: 64.9 KB
Line 
1#define CS_CORE
2#include "globals.h"
3#ifdef CS_WITH_GBOX
4# include "csgbox/gbox.h"
5# define CS_VERSION_X CS_VERSION "-gbx-" GBXVERSION
6#else
7# define CS_VERSION_X CS_VERSION
8#endif
9/*****************************************************************************
10 Globals
11*****************************************************************************/
12int pfd=0; // Primary FD, must be closed on exit
13int mfdr=0; // Master FD (read)
14int fd_m2c=0; // FD Master -> Client (for clients / read )
15int fd_c2m=0; // FD Client -> Master (for clients / write )
16int fd_c2l=0; // FD Client -> Logger (for clients / write )
17int cs_dblevel=0; // Debug Level (TODO !!)
18int cs_idx=0; // client index (0=master, ...)
19int cs_ptyp=D_MASTER; // process-type
20struct s_module ph[CS_MAX_MOD]; // Protocols
21int maxph=0; // Protocols used
22int cs_hw=0; // hardware autodetect
23int is_server=0; // used in modules to specify function
24pid_t master_pid=0; // master pid OUTSIDE shm
25ushort len4caid[256]; // table for guessing caid (by len)
26char cs_confdir[128]=CS_CONFDIR;
27uchar mbuf[1024]; // global buffer
28ECM_REQUEST *ecmtask;
29EMM_PACKET epg;
30#ifdef CS_ANTICASC
31struct s_acasc ac_stat[CS_MAXPID];
32#endif
33
34/*****************************************************************************
35 Shared Memory
36*****************************************************************************/
37int *ecmidx; // Shared Memory
38int *logidx; // Shared Memory
39int *oscam_sem; // sem (multicam.o)
40int *c_start; // idx of 1st client
41int *log_fd; // log-process is running
42struct s_ecm *ecmcache; // Shared Memory
43struct s_client *client; // Shared Memory
44struct s_reader *reader; // Shared Memory
45
46struct card_struct *Cards; // Shared Memory
47struct idstore_struct *idstore; // Shared Memory
48unsigned long *IgnoreList; // Shared Memory
49
50struct s_config *cfg; // Shared Memory
51#ifdef CS_ANTICASC
52struct s_acasc_shm *acasc; // anti-cascading table indexed by account.ac_idx
53#endif
54#ifdef CS_LOGHISTORY
55int *loghistidx; // ptr to current entry
56char *loghist; // ptr of log-history
57#endif
58int *mcl=0; // Master close log?
59
60static int shmsize = CS_ECMCACHESIZE*(sizeof(struct s_ecm)) +
61 CS_MAXPID*(sizeof(struct s_client)) +
62 CS_MAXREADER*(sizeof(struct s_reader)) +
63#ifdef CS_WITH_GBOX
64 CS_MAXCARDS*(sizeof(struct card_struct))+
65 CS_MAXIGNORE*(sizeof(long))+
66 CS_MAXPID*(sizeof(struct idstore_struct))+
67#endif
68#ifdef CS_ANTICASC
69 CS_MAXPID*(sizeof(struct s_acasc_shm)) +
70#endif
71#ifdef CS_LOGHISTORY
72 CS_MAXLOGHIST*CS_LOGHISTSIZE + sizeof(int) +
73#endif
74 sizeof(struct s_config)+(6*sizeof(int));
75
76#ifdef CS_NOSHM
77char cs_memfile[128]=CS_MMAPFILE;
78#endif
79
80/*****************************************************************************
81 Statics
82*****************************************************************************/
83static char mloc[128]={0};
84static int shmid=0; // Shared Memory ID
85static int cs_last_idx=0; // client index of last fork (master only)
86static char* credit[] = {
87 "dukat for the great MpCS piece of code",
88 "all members of streamboard.de.vu for testing",
89 "scotty and aroureos for the first softcam (no longer used)",
90 "John Moore for the hsic-client (humax 5400) and the arm-support",
91 "doz21 for the sio-routines and his support on camd3-protocol",
92 "kindzadza for his support on radegast-protocol",
93 "DS and ago for several modules in mpcs development",
94 "dingo35 for seca reader-support",
95 "dingo35 and okmikel for newcamd-support",
96 "hellmaster1024 for gb*x-support",
97 "the vdr-sc team for several good ideas :-)",
98 NULL };
99
100static void cs_set_mloc(int ato, char *txt)
101{
102 if (ato>=0)
103 alarm(ato);
104 if (txt)
105 strcpy(mloc, txt);
106}
107
108char *cs_platform(char *buf)
109{
110 static char *hw=NULL;
111 if (!hw)
112 {
113#ifdef TUXBOX
114 struct stat st;
115 cs_hw=CS_HW_DBOX2; // dbox2, default for now
116 if (!stat("/dev/sci0", &st)) cs_hw=CS_HW_DREAM; // dreambox
117 switch(cs_hw)
118 {
119#ifdef PPC
120 case CS_HW_DBOX2: hw="dbox2" ; break;
121#endif
122 case CS_HW_DREAM: hw="dreambox"; break;
123 }
124#endif
125 if (!hw) hw=CS_OS_HW;
126 }
127 sprintf(buf, "%s-%s-%s", CS_OS_CPU, hw, CS_OS_SYS);
128 return(buf);
129}
130
131static void usage()
132{
133 int i;
134 fprintf(stderr, "\nOSCam cardserver v%s (%s) - (w) 2009 by smurzch\n", CS_VERSION_X, CS_OSTYPE);
135 fprintf(stderr, "\tbased on streamboard mp-cardserver v0.9d - (w) 2004-2007 by dukat\n\n");
136 fprintf(stderr, "oscam [-b] [-c config-dir]");
137#ifdef CS_NOSHM
138 fprintf(stderr, " [-m memory-file]");
139#endif
140 fprintf(stderr, "\n\n\t-b : start in background\n");
141 fprintf(stderr, "\t-c <dir> : read configuration from <dir>\n");
142 fprintf(stderr, "\t default=%s\n", CS_CONFDIR);
143#ifdef CS_NOSHM
144 fprintf(stderr, "\t-m <file>: use <file> as mmaped memory file\n");
145 fprintf(stderr, "\t default=%s\n", CS_MMAPFILE);
146#endif
147 fprintf(stderr, "\nthanks to ...\n");
148 for (i=0; credit[i]; i++)
149 fprintf(stderr, "\t%s\n", credit[i]);
150 fprintf(stderr, "\n");
151 exit(1);
152}
153
154#ifdef NEED_DAEMON
155#ifdef OS_MACOSX
156// this is done because daemon is being deprecated starting with 10.5 and -Werror will always trigger an error
157static int daemon_compat(int nochdir, int noclose)
158#else
159static int daemon(int nochdir, int noclose)
160#endif
161{
162 int fd;
163
164 switch (fork())
165 {
166 case -1: return (-1);
167 case 0: break;
168 default: _exit(0);
169 }
170
171 if (setsid()==(-1))
172 return(-1);
173
174 if (!nochdir)
175 (void)chdir("/");
176
177 if (!noclose && (fd=open("/dev/null", O_RDWR, 0)) != -1)
178 {
179 (void)dup2(fd, STDIN_FILENO);
180 (void)dup2(fd, STDOUT_FILENO);
181 (void)dup2(fd, STDERR_FILENO);
182 if (fd>2)
183 (void)close(fd);
184 }
185 return(0);
186}
187#endif
188
189int recv_from_udpipe(uchar *buf, int l)
190{
191 unsigned short n;
192 if (!pfd) return(-9);
193 if (!read(pfd, buf, 3)) cs_exit(1);
194 if (buf[0]!='U')
195 {
196 cs_log("INTERNAL PIPE-ERROR");
197 cs_exit(1);
198 }
199 memcpy(&n, buf+1, 2);
200 return(read(pfd, buf, n));
201}
202
203char *username(int idx)
204{
205 if (client[idx].usr[0])
206 return(client[idx].usr);
207 else
208 return("anonymous");
209}
210
211static int idx_from_ip(in_addr_t ip, in_port_t port)
212{
213 int i, idx;
214 for (i=idx=0; (i<CS_MAXPID) && (!idx); i++)
215 if ((client[i].ip==ip) && (client[i].port==port) &&
216 ((client[i].typ=='c') || (client[i].typ=='m')))
217 idx=i;
218 return(idx);
219}
220
221int idx_from_pid(pid_t pid)
222{
223 int i, idx;
224 for (i=0, idx=(-1); (i<CS_MAXPID) && (idx<0); i++)
225 if (client[i].pid==pid)
226 idx=i;
227 return(idx);
228}
229
230static long chk_caid(ushort caid, CAIDTAB *ctab)
231{
232 int n;
233 long rc;
234 for (rc=(-1), n=0; (n<CS_MAXCAIDTAB) && (rc<0); n++)
235 if ((caid & ctab->mask[n]) == ctab->caid[n])
236 rc=ctab->cmap[n] ? ctab->cmap[n] : caid;
237 return(rc);
238}
239
240int chk_bcaid(ECM_REQUEST *er, CAIDTAB *ctab)
241{
242 long caid;
243 if ((caid=chk_caid(er->caid, ctab))<0)
244 return(0);
245 er->caid=caid;
246 return(1);
247}
248
249/*
250 * void set_signal_handler(int sig, int flags, void (*sighandler)(int))
251 * flags: 1 = restart, 2 = don't modify if SIG_IGN, may be combined
252 */
253void set_signal_handler(int sig, int flags, void (*sighandler)(int))
254{
255#ifdef CS_SIGBSD
256 if ((signal(sig, sighandler)==SIG_IGN) && (flags & 2))
257 {
258 signal(sig, SIG_IGN);
259 siginterrupt(sig, 0);
260 }
261 else
262 siginterrupt(sig, (flags & 1) ? 0 : 1);
263#else
264 struct sigaction sa;
265 sigaction(sig, (struct sigaction *) 0, &sa);
266 if (!((flags & 2) && (sa.sa_handler==SIG_IGN)))
267 {
268 sigemptyset(&sa.sa_mask);
269 sa.sa_flags=(flags & 1) ? SA_RESTART : 0;
270 sa.sa_handler=sighandler;
271 sigaction(sig, &sa, (struct sigaction *) 0);
272 }
273#endif
274}
275
276static void cs_alarm(int sig)
277{
278 cs_debug("Got alarm signal");
279 cs_log("disconnect from %s (deadlock!)", cs_inet_ntoa(client[cs_idx].ip));
280 cs_exit(0);
281}
282
283static void cs_master_alarm(int sig)
284{
285 cs_log("PANIC: master deadlock! last location: %s", mloc);
286 fprintf(stderr, "PANIC: master deadlock! last location: %s", mloc);
287 fflush(stderr);
288 cs_exit(0);
289}
290
291static void cs_sigpipe(int sig)
292{
293 if ((cs_idx) && (master_pid!=getppid()))
294 cs_exit(0);
295 cs_log("Got sigpipe signal -> captured");
296}
297
298void cs_exit(int sig)
299{
300 int i;
301
302 set_signal_handler(SIGCHLD, 1, SIG_IGN);
303 set_signal_handler(SIGHUP , 1, SIG_IGN);
304 if (sig && (sig!=SIGQUIT))
305 cs_log("exit with signal %d", sig);
306 switch(client[cs_idx].typ)
307 {
308 case 'c': cs_statistics(cs_idx);
309 case 'm': break;
310 case 'n': *log_fd=0;
311 break;
312 case 's': *log_fd=0;
313 for (i=1; i<CS_MAXPID; i++)
314 if (client[i].pid)
315 kill(client[i].pid, SIGQUIT);
316 cs_log("cardserver down");
317#ifndef CS_NOSHM
318 if (ecmcache) shmdt((void *)ecmcache);
319#endif
320 break;
321 }
322 if (pfd) close(pfd);
323#ifdef CS_NOSHM
324 munmap((void *)ecmcache, (size_t)shmsize);
325 if (shmid) close(shmid);
326 unlink(CS_MMAPFILE); // ignore errors, last process must succeed
327#endif
328 exit(sig);
329}
330
331static void cs_reinit_clients()
332{
333 int i;
334 struct s_auth *account;
335
336 for( i=1; i<CS_MAXPID; i++ )
337 if( client[i].pid && client[i].typ=='c' && client[i].usr[0] )
338 {
339 for (account=cfg->account; (account) ; account=account->next)
340 if (!strcmp(client[i].usr, account->usr))
341 break;
342
343 if (account &&
344 client[i].pcrc==crc32(0L, MD5((uchar *)account->pwd, strlen(account->pwd), NULL), 16))
345 {
346 client[i].grp = account->grp;
347 client[i].au = account->au;
348 client[i].tosleep = (60*account->tosleep);
349 client[i].monlvl = account->monlvl;
350 client[i].fchid = account->fchid; // CHID filters
351 client[i].cltab = account->cltab; // Class
352 client[i].ftab = account->ftab; // Ident
353 client[i].sidtabok= account->sidtabok; // services
354 client[i].sidtabno= account->sidtabno; // services
355 memcpy(&client[i].ctab, &account->ctab, sizeof(client[i].ctab));
356 memcpy(&client[i].ttab, &account->ttab, sizeof(client[i].ttab));
357#ifdef CS_ANTICASC
358 client[i].ac_idx = account->ac_idx;
359 client[i].ac_penalty = account->ac_penalty;
360 client[i].ac_limit = (account->ac_users*100+80)*cfg->ac_stime;
361#endif
362 }
363 else
364 {
365 if (ph[client[i].ctyp].type & MOD_CONN_NET)
366 {
367 cs_debug("client '%s', pid=%d not found in db (or password changed)",
368 client[i].usr, client[i].pid);
369 kill(client[i].pid, SIGQUIT);
370 }
371 }
372 }
373}
374
375static void cs_sighup()
376{
377 uchar dummy[1]={0x00};
378 write_to_pipe(fd_c2m, PIP_ID_HUP, dummy, 1);
379}
380
381static void cs_accounts_chk()
382{
383 int i;
384
385 init_userdb();
386 cs_reinit_clients();
387#ifdef CS_ANTICASC
388 for (i=0; i<CS_MAXPID; i++)
389 if (client[i].typ=='a')
390 {
391 kill(client[i].pid, SIGHUP);
392 break;
393 }
394#endif
395}
396
397static void cs_debug_level()
398{
399 int i;
400
401 cs_dblevel ^= D_ALL_DUMP;
402 if (master_pid==getpid())
403 for (i=0; i<CS_MAXPID && client[i].pid; i++)
404 client[i].dbglvl=cs_dblevel;
405 else
406 client[cs_idx].dbglvl=cs_dblevel;
407 cs_log("%sdebug_level=%d", (master_pid==getpid())?"all ":"",cs_dblevel);
408}
409
410static void cs_card_info(int i)
411{
412 uchar dummy[1]={0x00};
413 for( i=1; i<CS_MAXPID; i++ )
414 if( client[i].pid && client[i].typ=='r' && client[i].fd_m2c ){
415 write_to_pipe(client[i].fd_m2c, PIP_ID_CIN, dummy, 1);
416 }
417
418 //kill(client[i].pid, SIGUSR2);
419}
420
421static void cs_child_chk(int i)
422{
423 while (waitpid(0, NULL, WNOHANG)>0);
424 for (i=1; i<CS_MAXPID; i++)
425 if (client[i].pid)
426 if (kill(client[i].pid, 0)) {
427 if ((client[i].typ!='c') && (client[i].typ!='m'))
428 {
429 char *txt="";
430 *log_fd=0;
431 switch(client[i].typ)
432 {
433#ifdef CS_ANTICASC
434 case 'a': txt="anticascader"; break;
435#endif
436 case 'l': txt="logger"; break;
437 case 'p': txt="proxy"; break;
438 case 'r': txt="reader"; break;
439 case 'n': txt="resolver"; break;
440 }
441 cs_log("PANIC: %s lost !! (pid=%d)", txt, client[i].pid);
442 cs_exit(1);
443 }
444 else
445 {
446#ifdef CS_ANTICASC
447 char usr[32];
448 ushort ac_idx;
449 ushort ac_limit;
450 uchar ac_penalty;
451 if( cfg->ac_enabled )
452 {
453 strncpy(usr, client[i].usr, sizeof(usr)-1);
454 ac_idx = client[i].ac_idx;
455 ac_limit = client[i].ac_limit;
456 ac_penalty = client[i].ac_penalty;
457 }
458#endif
459 if (client[i].fd_m2c) close(client[i].fd_m2c);
460 if (client[i].ufd) close(client[i].ufd);
461 memset(&client[i], 0, sizeof(struct s_client));
462#ifdef CS_ANTICASC
463 if( cfg->ac_enabled )
464 {
465 client[i].ac_idx = ac_idx;
466 client[i].ac_limit = ac_limit;
467 client[i].ac_penalty = ac_penalty;
468 strcpy(client[i].usr, usr);
469 }
470#endif
471 client[i].au=(-1);
472 }
473 }
474 return;
475}
476
477int cs_fork(in_addr_t ip, in_port_t port)
478{
479 int i;
480 pid_t pid;
481 for (i=1; (i<CS_MAXPID) && (client[i].pid); i++);
482 if (i<CS_MAXPID)
483 {
484 int fdp[2];
485 memset(&client[i], 0, sizeof(struct s_client));
486 client[i].au=(-1);
487 if (pipe(fdp))
488 {
489 cs_log("Cannot create pipe (errno=%d)", errno);
490 cs_exit(1);
491 }
492 switch(pid=fork())
493 {
494 case -1:
495 cs_log("PANIC: Cannot fork() (errno=%d)", errno);
496 cs_exit(1);
497 case 0: // HERE is client
498 alarm(0);
499 set_signal_handler(SIGALRM, 0, cs_alarm);
500 set_signal_handler(SIGCHLD, 1, SIG_IGN);
501 set_signal_handler(SIGHUP , 1, SIG_IGN);
502 set_signal_handler(SIGINT , 1, SIG_IGN);
503 set_signal_handler(SIGUSR1, 1, cs_debug_level);
504 is_server=((ip) || (port<90)) ? 1 : 0;
505 fd_m2c=fdp[0];
506 close(fdp[1]);
507 close(mfdr);
508 if( port!=97 ) cs_close_log();
509 mfdr=0;
510 cs_ptyp=D_CLIENT;
511 cs_idx=i;
512#ifndef CS_NOSHM
513 shmid=0;
514#endif
515 break;
516 default: // HERE is master
517 client[i].fd_m2c=fdp[1];
518 client[i].dbglvl=cs_dblevel;
519 close(fdp[0]);
520 if (ip)
521 {
522 client[i].typ='c'; // dynamic client
523 client[i].ip=ip;
524 client[i].port=port;
525 cs_log("client(%d) connect from %s (pid=%d, pipfd=%d)",
526 i-cdiff, cs_inet_ntoa(ip), pid, client[i].fd_m2c);
527 }
528 else
529 {
530 client[i].stat=1;
531 switch(port)
532 {
533 case 99: client[i].typ='r'; // reader
534 client[i].sidtabok=reader[ridx].sidtabok;
535 client[i].sidtabno=reader[ridx].sidtabno;
536 reader[ridx].fd=client[i].fd_m2c;
537 reader[ridx].cs_idx=i;
538 if (reader[ridx].r_port)
539 cs_log("proxy started (pid=%d, server=%s)",
540 pid, reader[ridx].device);
541 else
542 {
543 if (reader[ridx].typ==R_MOUSE || reader[ridx].typ==R_SMART)
544 cs_log("reader started (pid=%d, device=%s, detect=%s%s, mhz=%d)",
545 pid, reader[ridx].device,
546 reader[ridx].detect&0x80 ? "!" : "",
547 RDR_CD_TXT[reader[ridx].detect&0x7f],
548 reader[ridx].mhz);
549 else
550 cs_log("reader started (pid=%d, device=%s)",
551 pid, reader[ridx].device);
552 client[i].ip=client[0].ip;
553 strcpy(client[i].usr, client[0].usr);
554 }
555 cdiff=i;
556 break;
557 case 98: client[i].typ='n'; // resolver
558 client[i].ip=client[0].ip;
559 strcpy(client[i].usr, client[0].usr);
560 cs_log("resolver started (pid=%d, delay=%d sec)",
561 pid, cfg->resolvedelay);
562 cdiff=i;
563 break;
564 case 97: client[i].typ='l'; // logger
565 client[i].ip=client[0].ip;
566 strcpy(client[i].usr, client[0].usr);
567 cs_log("logger started (pid=%d)", pid);
568 cdiff=i;
569 break;
570#ifdef CS_ANTICASC
571 case 96: client[i].typ='a';
572 client[i].ip=client[0].ip;
573 strcpy(client[i].usr, client[0].usr);
574 cs_log("anticascader started (pid=%d, delay=%d min)",
575 pid, cfg->ac_stime);
576 cdiff=i;
577 break;
578#endif
579 default: client[i].typ='c'; // static client
580 client[i].ip=client[0].ip;
581 client[i].ctyp=port;
582 cs_log("%s: initialized (pid=%d%s)", ph[port].desc,
583 pid, ph[port].logtxt ? ph[port].logtxt : "");
584 break;
585 }
586 }
587 client[i].login=client[i].last=time((time_t *)0);
588 client[i].pid=pid; // MUST be last -> wait4master()
589 cs_last_idx=i;
590 i=0;
591 }
592 }
593 else
594 {
595 cs_log("max connections reached -> reject client %s", cs_inet_ntoa(ip));
596 i=(-1);
597 }
598 return(i);
599}
600
601static void init_signal()
602{
603 int i;
604 for (i=1; i<NSIG; i++)
605 set_signal_handler(i, 3, cs_exit);
606 set_signal_handler(SIGWINCH, 1, SIG_IGN);
607// set_signal_handler(SIGPIPE , 0, SIG_IGN);
608 set_signal_handler(SIGPIPE , 0, cs_sigpipe);
609// set_signal_handler(SIGALRM , 0, cs_alarm);
610 set_signal_handler(SIGALRM , 0, cs_master_alarm);
611 set_signal_handler(SIGCHLD , 1, cs_child_chk);
612// set_signal_handler(SIGHUP , 1, cs_accounts_chk);
613 set_signal_handler(SIGHUP , 1, cs_sighup);
614 set_signal_handler(SIGUSR1, 1, cs_debug_level);
615 set_signal_handler(SIGUSR2, 1, cs_card_info);
616 set_signal_handler(SIGCONT, 1, SIG_IGN);
617 cs_log("signal handling initialized (type=%s)",
618#ifdef CS_SIGBSD
619 "bsd"
620#else
621 "sysv"
622#endif
623 );
624 return;
625}
626
627static void init_shm()
628{
629#ifdef CS_NOSHM
630 //int i, fd;
631 char *buf;
632 if ((shmid=open(cs_memfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR))<0)
633 {
634 fprintf(stderr, "Cannot create mmaped file (errno=%d)", errno);
635 cs_exit(1);
636 }
637
638 buf=(char *)malloc(shmsize);
639 memset(buf, 0, shmsize);
640 write(shmid, buf, shmsize);
641 free(buf);
642
643 ecmcache=(struct s_ecm *)mmap((void *)0, (size_t) shmsize,
644 PROT_READ|PROT_WRITE, MAP_SHARED, shmid, 0);
645#else
646 struct shmid_ds sd;
647 char *shmerr_txt="Cannot %s shared memory (errno=%d)\n";
648 if ((shmid=shmget(IPC_PRIVATE, shmsize, IPC_CREAT | 0600))<0)
649 {
650 fprintf(stderr, shmerr_txt, "create", errno);
651 shmid=0;
652 cs_exit(1);
653 }
654 if ((ecmcache=(struct s_ecm *)shmat(shmid, 0, 0))==(void *)(-1))
655 {
656 fprintf(stderr, shmerr_txt, "attach", errno);
657 cs_exit(1);
658 }
659 memset(ecmcache, 0, shmsize);
660 shmctl(shmid, IPC_RMID, &sd);
661#endif
662#ifdef CS_ANTICASC
663 acasc=(struct s_acasc_shm *)&ecmcache[CS_ECMCACHESIZE];
664 ecmidx=(int *)&acasc[CS_MAXPID];
665#else
666 ecmidx=(int *)&ecmcache[CS_ECMCACHESIZE];
667#endif
668 mcl=(int *)((void *)ecmidx+sizeof(int));
669 logidx=(int *)((void *)mcl+sizeof(int));
670 c_start=(int *)((void *)logidx+sizeof(int));
671 log_fd=(int *)((void *)c_start+sizeof(int));
672 oscam_sem=(int *)((void *)log_fd+sizeof(int));
673 client=(struct s_client *)((void *)oscam_sem+sizeof(int));
674 reader=(struct s_reader *)&client[CS_MAXPID];
675#ifdef CS_WITH_GBOX
676 Cards=(struct card_struct*)&reader[CS_MAXREADER];
677 IgnoreList=(unsigned long*)&Cards[CS_MAXCARDS];
678 idstore=(struct idstore_struct*)&IgnoreList[CS_MAXIGNORE];
679 cfg=(struct s_config *)&idstore[CS_MAXPID];
680#else
681 cfg=(struct s_config *)&reader[CS_MAXREADER];
682#endif
683#ifdef CS_LOGHISTORY
684 loghistidx=(int *)((void *)cfg+sizeof(struct s_config));
685 loghist=(char *)((void *)loghistidx+sizeof(int));
686#endif
687
688#ifdef DEBUG_SHM_POINTER
689 printf("SHM ALLOC: %x\n", shmsize);
690 printf("SHM START: %p\n", (void *) ecmcache);
691 printf("SHM ST1: %p %x (%x)\n", (void *) ecmidx, ((void *) ecmidx) - ((void *) ecmcache), CS_ECMCACHESIZE*(sizeof(struct s_ecm)));
692 printf("SHM ST2: %p %x (%x)\n", (void *) oscam_sem, ((void *) oscam_sem) - ((void *) ecmidx), sizeof(int));
693 printf("SHM ST3: %p %x (%x)\n", (void *) client, ((void *) client) - ((void *) oscam_sem), sizeof(int));
694 printf("SHM ST4: %p %x (%x)\n", (void *) reader, ((void *) reader) - ((void *) client), CS_MAXPID*(sizeof(struct s_client)));
695 printf("SHM ST5: %p %x (%x)\n", (void *) cfg, ((void *) cfg) - ((void *) reader), CS_MAXREADER*(sizeof(struct s_reader)));
696 printf("SHM ST6: %p %x (%x)\n", ((void *) cfg)+sizeof(struct s_config), sizeof(struct s_config), sizeof(struct s_config));
697 printf("SHM ENDE: %p\n", ((void *) cfg)+sizeof(struct s_config));
698 printf("SHM SIZE: %x\n", ((void *) cfg)-((void *) ecmcache) + sizeof(struct s_config));
699 fflush(stdout);
700#endif
701
702 *ecmidx=0;
703 *logidx=0;
704 *oscam_sem=0;
705 client[0].pid=getpid();
706 client[0].login=time((time_t *)0);
707 client[0].ip=cs_inet_addr("127.0.0.1");
708 client[0].typ='s';
709 client[0].au=(-1);
710 client[0].dbglvl=cs_dblevel;
711 strcpy(client[0].usr, "root");
712#ifdef CS_LOGHISTORY
713 *loghistidx=0;
714 memset(loghist, 0, CS_MAXLOGHIST*CS_LOGHISTSIZE);
715#endif
716}
717
718static int start_listener(struct s_module *ph, int port_idx)
719{
720 int ov=1, timeout, is_udp, i;
721 char ptxt[2][32];
722 //struct hostent *ptrh; /* pointer to a host table entry */
723 struct protoent *ptrp; /* pointer to a protocol table entry */
724 struct sockaddr_in sad; /* structure to hold server's address */
725
726 ptxt[0][0]=ptxt[1][0]='\0';
727 if (!ph->ptab->ports[port_idx].s_port)
728 {
729 cs_log("%s: disabled", ph->desc);
730 return(0);
731 }
732 is_udp=(ph->type==MOD_CONN_UDP);
733
734 memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
735 sad.sin_family = AF_INET; /* set family to Internet */
736 if (!ph->s_ip)
737 ph->s_ip=cfg->srvip;
738 if (ph->s_ip)
739 {
740 sad.sin_addr.s_addr=ph->s_ip;
741 sprintf(ptxt[0], ", ip=%s", inet_ntoa(sad.sin_addr));
742 }
743 else
744 sad.sin_addr.s_addr=INADDR_ANY;
745 timeout=cfg->bindwait;
746 //ph->fd=0;
747 ph->ptab->ports[port_idx].fd = 0;
748
749 if (ph->ptab->ports[port_idx].s_port > 0) /* test for illegal value */
750 sad.sin_port = htons((u_short)ph->ptab->ports[port_idx].s_port);
751 else
752 {
753 cs_log("%s: Bad port %d", ph->desc, ph->ptab->ports[port_idx].s_port);
754 return(0);
755 }
756
757 /* Map transport protocol name to protocol number */
758
759 if( (ptrp=getprotobyname(is_udp ? "udp" : "tcp")) )
760 ov=ptrp->p_proto;
761 else
762 ov=(is_udp) ? 17 : 6; // use defaults on error
763
764 if ((ph->ptab->ports[port_idx].fd=socket(PF_INET,is_udp ? SOCK_DGRAM : SOCK_STREAM, ov))<0)
765 {
766 cs_log("%s: Cannot create socket (errno=%d)", ph->desc, errno);
767 return(0);
768 }
769
770 ov=1;
771 if (setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ov, sizeof(ov))<0)
772 {
773 cs_log("%s: setsockopt failed (errno=%d)", ph->desc, errno);
774 close(ph->ptab->ports[port_idx].fd);
775 return(ph->ptab->ports[port_idx].fd=0);
776 }
777
778#ifdef SO_REUSEPORT
779 setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_REUSEPORT, (void *)&ov, sizeof(ov));
780#endif
781
782#ifdef SO_PRIORITY
783 if (cfg->netprio)
784 if (!setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_PRIORITY, (void *)&cfg->netprio, sizeof(ulong)))
785 sprintf(ptxt[1], ", prio=%ld", cfg->netprio);
786#endif
787
788 if( !is_udp )
789 {
790 ulong keep_alive = 1;
791 setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_KEEPALIVE,
792 (void *)&keep_alive, sizeof(ulong));
793 }
794
795 while (timeout--)
796 {
797 if (bind(ph->ptab->ports[port_idx].fd, (struct sockaddr *)&sad, sizeof (sad))<0)
798 {
799 if (timeout)
800 {
801 cs_log("%s: Bind request failed, waiting another %d seconds",
802 ph->desc, timeout);
803 sleep(1);
804 }
805 else
806 {
807 cs_log("%s: Bind request failed, giving up", ph->desc);
808 close(ph->ptab->ports[port_idx].fd);
809 return(ph->ptab->ports[port_idx].fd=0);
810 }
811 }
812 else timeout=0;
813 }
814
815 if (!is_udp)
816 if (listen(ph->ptab->ports[port_idx].fd, CS_QLEN)<0)
817 {
818 cs_log("%s: Cannot start listen mode (errno=%d)", ph->desc, errno);
819 close(ph->ptab->ports[port_idx].fd);
820 return(ph->ptab->ports[port_idx].fd=0);
821 }
822
823 cs_log("%s: initialized (fd=%d, port=%d%s%s%s)",
824 ph->desc, ph->ptab->ports[port_idx].fd,
825 ph->ptab->ports[port_idx].s_port,
826 ptxt[0], ptxt[1], ph->logtxt ? ph->logtxt : "");
827
828 for( i=0; i<ph->ptab->ports[port_idx].ftab.nfilts; i++ ) {
829 int j;
830 cs_log("CAID: %04X", ph->ptab->ports[port_idx].ftab.filts[i].caid );
831 for( j=0; j<ph->ptab->ports[port_idx].ftab.filts[i].nprids; j++ )
832 cs_log("provid #%d: %06X", j, ph->ptab->ports[port_idx].ftab.filts[i].prids[j]);
833 }
834 return(ph->ptab->ports[port_idx].fd);
835}
836
837static void *cs_client_resolve(void *dummy)
838{
839 while (1)
840 {
841 struct hostent *rht;
842 struct s_auth *account;
843 struct sockaddr_in udp_sa;
844
845 for (account=cfg->account; account; account=account->next)
846 if (account->dyndns[0])
847 {
848 if (rht=gethostbyname((const char *)account->dyndns))
849 {
850 memcpy(&udp_sa.sin_addr, rht->h_addr, sizeof(udp_sa.sin_addr));
851 account->dynip=cs_inet_order(udp_sa.sin_addr.s_addr);
852 }
853 else
854 cs_log("can't resolve hostname %s (user: %s)", account->dyndns, account->usr);
855 client[cs_idx].last=time((time_t)0);
856 }
857 sleep(cfg->resolvedelay);
858 }
859}
860
861static void start_client_resolver()
862{
863 int i;
864 pthread_t tid;
865
866 if (i=pthread_create(&tid, (pthread_attr_t *)0, cs_client_resolve, (void *) 0))
867 cs_log("ERROR: can't create resolver-thread (err=%d)", i);
868 else
869 {
870 cs_log("resolver thread started");
871 pthread_detach(tid);
872 }
873}
874
875void cs_resolve()
876{
877 int i, idx;
878 struct hostent *rht;
879 struct s_auth *account;
880 for (i=0; i<CS_MAXREADER; i++)
881 if ((idx=reader[i].cs_idx) && (reader[i].typ & R_IS_NETWORK))
882 {
883 client[cs_idx].last=time((time_t)0);
884 if (rht=gethostbyname(reader[i].device))
885 {
886 memcpy(&client[idx].udp_sa.sin_addr, rht->h_addr,
887 sizeof(client[idx].udp_sa.sin_addr));
888 client[idx].ip=cs_inet_order(client[idx].udp_sa.sin_addr.s_addr);
889 }
890 else
891 cs_log("can't resolve %s", reader[i].device);
892 client[cs_idx].last=time((time_t)0);
893 }
894}
895
896#ifdef USE_PTHREAD
897static void *cs_logger(void *dummy)
898#else
899static void cs_logger(void)
900#endif
901{
902 *log_fd=client[cs_idx].fd_m2c;
903 while(1)
904 {
905 uchar *ptr;
906 //struct timeval tv;
907 fd_set fds;
908
909 FD_ZERO(&fds);
910 FD_SET(fd_m2c, &fds);
911 select(fd_m2c+1, &fds, 0, 0, 0);
912#ifndef USE_PTHREAD
913 if (master_pid!=getppid())
914 cs_exit(0);
915#endif
916 if (FD_ISSET(fd_m2c, &fds))
917 {
918 int n;
919// switch(n=read_from_pipe(fd_m2c, &ptr, 1))
920 n=read_from_pipe(fd_m2c, &ptr, 1);
921//if (n!=PIP_ID_NUL) printf("received %d bytes\n", n); fflush(stdout);
922 switch(n)
923 {
924 case PIP_ID_LOG:
925 cs_write_log(ptr);
926 break;
927 }
928 }
929 }
930}
931
932static void start_resolver()
933{
934 int i;
935#ifdef USE_PTHREAD
936 pthread_t tid;
937 if (i=pthread_create(&tid, (pthread_attr_t *)0, cs_logger, (void *) 0))
938 cs_log("ERROR: can't create logging-thread (err=%d)", i);
939 else
940 {
941 cs_log("logging thread started");
942 pthread_detach(tid);
943 }
944#endif
945 sleep(1); // wait for reader
946 while(1)
947 {
948 if (master_pid!=getppid())
949 cs_exit(0);
950 cs_resolve();
951 for (i=0; i<cfg->resolvedelay; i++)
952 if (master_pid!=getppid())
953 cs_exit(0);
954 else
955 sleep(1);
956// sleep(cfg->resolvedelay);
957 }
958}
959
960#ifdef CS_ANTICASC
961static void start_anticascader()
962{
963 int i;
964
965 use_ac_log=1;
966 set_signal_handler(SIGHUP, 1, ac_init_stat);
967
968 ac_init_stat(0);
969 while(1)
970 {
971 for( i=0; i<cfg->ac_stime*60; i++ )
972 if( master_pid!=getppid() )
973 cs_exit(0);
974 else
975 sleep(1);
976
977 if (master_pid!=getppid())
978 cs_exit(0);
979
980 ac_do_stat();
981 }
982}
983#endif
984
985static void init_cardreader()
986{
987 for (ridx=0; ridx<CS_MAXREADER; ridx++)
988 if (reader[ridx].device[0])
989 switch(cs_fork(0, 99))
990 {
991 case -1:
992 cs_exit(1);
993 case 0:
994 break;
995 default:
996 wait4master();
997 start_cardreader();
998 }
999}
1000
1001static void init_service(int srv)
1002{
1003#ifdef USE_PTHREAD
1004 uchar dummy[1]={0x00};
1005#endif
1006
1007 switch(cs_fork(0, srv))
1008 {
1009 case -1:
1010 cs_exit(1);
1011 case 0:
1012 break;
1013 default:
1014 wait4master();
1015 switch(srv)
1016 {
1017#ifdef CS_ANTICASC
1018 case 96: start_anticascader();
1019#endif
1020#ifdef USE_PTHREAD
1021 case 97: cs_logger(dummy);
1022#else
1023 case 97: cs_logger();
1024#endif
1025 case 98: start_resolver();
1026 }
1027 }
1028}
1029
1030void wait4master()
1031{
1032 int i;
1033 for (i=0; (i<1000) && (client[cs_idx].pid!=getpid()); i++)
1034 usleep(1000L);
1035 if (client[cs_idx].pid!=getpid())
1036 {
1037 cs_log("PANIC: client not found in shared memory");
1038 cs_exit(1);
1039 }
1040 cs_debug("starting client %d with ip %s",
1041 cs_idx-cdiff, cs_inet_ntoa(client[cs_idx].ip));
1042}
1043
1044static void cs_fake_client(char *usr, int uniq, in_addr_t ip)
1045{
1046 /* - Uniq = 1: only one connection per user
1047 * - Uniq = 2: set user only to fake if source ip is different (e.g. for
1048 * newcamd clients with different CAID's -> Ports)
1049 */
1050
1051 int i;
1052
1053 for (i=cdiff+1; i<CS_MAXPID; i++) {
1054 if (client[i].pid
1055 && (client[i].typ == 'c')
1056 && !client[i].dup
1057 && !strcmp(client[i].usr, usr)
1058 && ((uniq == 1) || (client[i].ip != ip)))
1059 {
1060 client[cs_idx].dup = 1;
1061 client[cs_idx].au = -1;
1062 cs_log("client(%d) duplicate user '%s' from %s set to fake (uniq=%d)", cs_idx-cdiff, usr, cs_inet_ntoa(ip), uniq);
1063 break;
1064 }
1065 }
1066}
1067
1068int cs_auth_client(struct s_auth *account, char *e_txt)
1069{
1070 int rc=0;
1071 char buf[16];
1072 char *t_crypt="encrypted";
1073 char *t_plain="plain";
1074 char *t_grant=" granted";
1075 char *t_reject=" rejected";
1076 char *t_msg[]= { buf, "invalid access", "invalid ip", "unknown reason" };
1077 client[cs_idx].grp=0xffffffff;
1078 client[cs_idx].au=(-1);
1079 switch((long)account)
1080 {
1081 case -2: // gbx-dummy
1082 client[cs_idx].dup=0;
1083 break;
1084 case 0: // reject access
1085 rc=1;
1086 cs_log("%s %s-client %s%s (%s)",
1087 client[cs_idx].crypted ? t_crypt : t_plain,
1088 ph[client[cs_idx].ctyp].desc,
1089 client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1090 client[cs_idx].ip ? t_reject : t_reject+1,
1091 e_txt ? e_txt : t_msg[rc]);
1092 break;
1093 default: // grant/check access
1094 if (client[cs_idx].ip && account->dyndns[0])
1095 if (client[cs_idx].ip != account->dynip)
1096 rc=2;
1097 if (!rc)
1098 {
1099 client[cs_idx].dup=0;
1100 if (client[cs_idx].typ=='c')
1101 {
1102 client[cs_idx].grp=account->grp;
1103 client[cs_idx].au=account->au;
1104 client[cs_idx].tosleep=(60*account->tosleep);
1105 memcpy(&client[cs_idx].ctab, &account->ctab, sizeof(client[cs_idx].ctab));
1106 if (account->uniq)
1107 cs_fake_client(account->usr, account->uniq, client[cs_idx].ip);
1108 client[cs_idx].ftab = account->ftab; // IDENT filter
1109 client[cs_idx].cltab = account->cltab; // CLASS filter
1110 client[cs_idx].fchid = account->fchid; // CHID filter
1111 client[cs_idx].sidtabok= account->sidtabok; // services
1112 client[cs_idx].sidtabno= account->sidtabno; // services
1113 client[cs_idx].pcrc = crc32(0L, MD5((uchar *)account->pwd, strlen(account->pwd), NULL), 16);
1114 memcpy(&client[cs_idx].ttab, &account->ttab, sizeof(client[cs_idx].ttab));
1115#ifdef CS_ANTICASC
1116 ac_init_client(account);
1117#endif
1118 }
1119 }
1120 client[cs_idx].monlvl=account->monlvl;
1121 strcpy(client[cs_idx].usr, account->usr);
1122 case -1: // anonymous grant access
1123 if (rc)
1124 t_grant=t_reject;
1125 else
1126 {
1127 if (client[cs_idx].typ=='m')
1128 sprintf(t_msg[0], "lvl=%d", client[cs_idx].monlvl);
1129 else
1130 sprintf(t_msg[0], "au=%d", client[cs_idx].au+1);
1131 }
1132
1133 if(client[cs_idx].ncd_server)
1134 {
1135 cs_log("%s %s:%d-client %s%s (%s, %s)",
1136 client[cs_idx].crypted ? t_crypt : t_plain,
1137 e_txt ? e_txt : ph[client[cs_idx].ctyp].desc,
1138 cfg->ncd_ptab.ports[client[cs_idx].port_idx].s_port,
1139 client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1140 client[cs_idx].ip ? t_grant : t_grant+1,
1141 username(cs_idx), t_msg[rc]);
1142 }
1143 else
1144 {
1145 cs_log("%s %s-client %s%s (%s, %s)",
1146 client[cs_idx].crypted ? t_crypt : t_plain,
1147 e_txt ? e_txt : ph[client[cs_idx].ctyp].desc,
1148 client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1149 client[cs_idx].ip ? t_grant : t_grant+1,
1150 username(cs_idx), t_msg[rc]);
1151 }
1152
1153 break;
1154 }
1155 return(rc);
1156}
1157
1158void cs_disconnect_client(void)
1159{
1160 char buf[32]={0};
1161 if (client[cs_idx].ip)
1162 sprintf(buf, " from %s", cs_inet_ntoa(client[cs_idx].ip));
1163 cs_log("%s disconnected%s", username(cs_idx), buf);
1164 cs_exit(0);
1165}
1166
1167int check_ecmcache(ECM_REQUEST *er, ulong grp)
1168{
1169 int i;
1170// cs_ddump(ecmd5, CS_ECMSTORESIZE, "ECM search");
1171//cs_log("cache CHECK: grp=%lX", grp);
1172 for(i=0; i<CS_ECMCACHESIZE; i++)
1173 if ((grp & ecmcache[i].grp) &&
1174 (!memcmp(ecmcache[i].ecmd5, er->ecmd5, CS_ECMSTORESIZE)))
1175 {
1176//cs_log("cache found: grp=%lX cgrp=%lX", grp, ecmcache[i].grp);
1177 memcpy(er->cw, ecmcache[i].cw, 16);
1178 return(1);
1179 }
1180 return(0);
1181}
1182
1183static void store_ecm(ECM_REQUEST *er)
1184{
1185//cs_log("store ecm from reader %d", er->reader[0]);
1186 memcpy(ecmcache[*ecmidx].ecmd5, er->ecmd5, CS_ECMSTORESIZE);
1187 memcpy(ecmcache[*ecmidx].cw, er->cw, 16);
1188 ecmcache[*ecmidx].caid=er->caid;
1189 ecmcache[*ecmidx].prid=er->prid;
1190 ecmcache[*ecmidx].grp =reader[er->reader[0]].grp;
1191// cs_ddump(ecmcache[*ecmidx].ecmd5, CS_ECMSTORESIZE, "ECM stored (idx=%d)", *ecmidx);
1192 *ecmidx=(*ecmidx+1) % CS_ECMCACHESIZE;
1193}
1194
1195void store_logentry(char *txt)
1196{
1197#ifdef CS_LOGHISTORY
1198 char *ptr;
1199 ptr=(char *)(loghist+(*loghistidx*CS_LOGHISTSIZE));
1200 ptr[0]='\1'; // make username unusable
1201 ptr[1]='\0';
1202 if ((client[cs_idx].typ=='c') || (client[cs_idx].typ=='m'))
1203 strncpy(ptr, client[cs_idx].usr, 31);
1204 strncpy(ptr+32, txt, CS_LOGHISTSIZE-33);
1205 *loghistidx=(*loghistidx+1) % CS_MAXLOGHIST;
1206#endif
1207}
1208
1209/*
1210 * write_to_pipe():
1211 * write all kind of data to pipe specified by fd
1212 */
1213int write_to_pipe(int fd, int id, uchar *data, int n)
1214{
1215 uchar buf[1024+3+sizeof(int)];
1216
1217//printf("WRITE_START pid=%d", getpid()); fflush(stdout);
1218 if ((id<0) || (id>PIP_ID_MAX))
1219 return(PIP_ID_ERR);
1220 memcpy(buf, PIP_ID_TXT[id], 3);
1221 memcpy(buf+3, &n, sizeof(int));
1222 memcpy(buf+3+sizeof(int), data, n);
1223 n+=3+sizeof(int);
1224//n=write(fd, buf, n);
1225//printf("WRITE_END pid=%d", getpid()); fflush(stdout);
1226//return(n);
1227 if( !fd )
1228 cs_log("write_to_pipe: fd==0");
1229 return(write(fd, buf, n));
1230}
1231
1232/*
1233 * read_from_pipe():
1234 * read all kind of data from pipe specified by fd
1235 * special-flag redir: if set AND data is ECM: this will redirected to appr. client
1236 */
1237int read_from_pipe(int fd, uchar **data, int redir)
1238{
1239 int rc;
1240 static int hdr=0;
1241 static uchar buf[1024+1+3+sizeof(int)];
1242
1243 *data=(uchar *)0;
1244 rc=PIP_ID_NUL;
1245
1246 if (!hdr)
1247 {
1248 if (bytes_available(fd))
1249 {
1250 if (read(fd, buf, 3+sizeof(int))==3+sizeof(int))
1251 memcpy(&hdr, buf+3, sizeof(int));
1252 else
1253 cs_log("WARNING: pipe header to small !");
1254 }
1255 }
1256 if (hdr)
1257 {
1258 int l;
1259 for (l=0; (rc<0) && (PIP_ID_TXT[l]); l++)
1260 if (!memcmp(buf, PIP_ID_TXT[l], 3))
1261 rc=l;
1262
1263 if (rc<0)
1264 {
1265 fprintf(stderr, "WARNING: pipe garbage");
1266 fflush(stderr);
1267 cs_log("WARNING: pipe garbage");
1268 rc=PIP_ID_ERR;
1269 }
1270 else
1271 {
1272 l=hdr;
1273 if ((l+3-1+sizeof(int))>sizeof(buf))
1274 {
1275 cs_log("WARNING: packet size (%d) to large", l);
1276 l=sizeof(buf)+3-1+sizeof(int);
1277 }
1278 if (!bytes_available(fd))
1279 return(PIP_ID_NUL);
1280 hdr=0;
1281 if (read(fd, buf+3+sizeof(int), l)==l)
1282 *data=buf+3+sizeof(int);
1283 else
1284 {
1285 cs_log("WARNING: pipe data to small !");
1286 return(PIP_ID_ERR);
1287 }
1288 buf[l+3+sizeof(int)]=0;
1289 if ((redir) && (rc==PIP_ID_ECM))
1290 {
1291 //int idx;
1292 ECM_REQUEST *er;
1293 er=(ECM_REQUEST *)(buf+3+sizeof(int));
1294 if( er->cidx && client[er->cidx].fd_m2c )
1295 if (!write(client[er->cidx].fd_m2c, buf, l+3+sizeof(int))) cs_exit(1);
1296 rc=PIP_ID_DIR;
1297 }
1298 }
1299 }
1300 return(rc);
1301}
1302
1303/*
1304 * write_ecm_request():
1305 */
1306int write_ecm_request(int fd, ECM_REQUEST *er)
1307{
1308 return(write_to_pipe(fd, PIP_ID_ECM, (uchar *) er, sizeof(ECM_REQUEST)));
1309}
1310
1311int write_ecm_DCW(int fd, ECM_REQUEST *er)
1312{
1313 return(write_to_pipe(fd, PIP_ID_DCW, (uchar *) er, sizeof(ECM_REQUEST)));
1314}
1315
1316void logCWtoFile(ECM_REQUEST *er)
1317{
1318 /* This function writes the current CW from ECM struct to a cwl file.
1319 The filename is re-calculated and file re-opened every time.
1320 This will consume a bit cpu time, but nothing has to be stored between
1321 each call. If not file exists, a header is prepended */
1322
1323 FILE *pfCWL;
1324 char srvname[23];
1325 /* %s / %s _I %04X _ %s .cwl */
1326 char buf[sizeof(cfg->cwlogdir)+1+6+2+4+1+sizeof(srvname)+5];
1327 char date[7];
1328 unsigned char i, parity, writeheader = 0;
1329 time_t t;
1330 struct tm *timeinfo;
1331 struct s_srvid *this;
1332
1333 if (cfg->cwlogdir[0]) /* CWL logging only if cwlogdir is set in config */
1334 {
1335 /* search service name for that id and change characters
1336 causing problems in file name */
1337 srvname[0] = 0;
1338 for (this=cfg->srvid; this; this=this->next) {
1339 if (this->srvid==er->srvid) {
1340 strncpy(srvname, this->name, sizeof(srvname));
1341 srvname[sizeof(srvname)-1] = 0;
1342 for (i=0;srvname[i];i++)
1343 if (srvname[i]==' ') srvname[i]='_';
1344 break;
1345 }
1346 }
1347
1348 /* calc log file name */
1349 time(&t);
1350 timeinfo = localtime(&t);
1351 strftime(date,sizeof(date),"%y%m%d",timeinfo);
1352 sprintf(buf, "%s/%s_I%04X_%s.cwl", cfg->cwlogdir, date, er->srvid, srvname);
1353
1354 if((pfCWL=fopen(buf,"r")) == NULL)
1355 {
1356 /* open failed, assuming file does not exist, yet */
1357 writeheader = 1;
1358 } else
1359 {
1360 /* we need to close the file if it was opened correctly */
1361 fclose(pfCWL);
1362 }
1363
1364 if ((pfCWL=fopen(buf, "a+")) == NULL)
1365 {
1366 /* maybe this fails because the subdir does not exist. Is there a common function to create it? */
1367 /* for the moment do not print to log on every ecm
1368 cs_log(""error opening cw logfile for writing: %s (errno %d)", buf, errno); */
1369 return;
1370 }
1371 if (writeheader)
1372 {
1373 /* no global macro for cardserver name :( */
1374 fprintf(pfCWL, "# OSCam cardserver v%s - http://streamboard.gmc.to:8001/oscam/wiki\n", CS_VERSION_X);
1375 fprintf(pfCWL, "# control word log file for use with tsdec offline decrypter\n");
1376 strftime(buf,sizeof(buf),"DATE %Y-%m-%d, TIME %H:%M:%S, TZ %Z\n",timeinfo);
1377 fprintf(pfCWL, "# %s",buf);
1378 fprintf(pfCWL, "# CAID 0x%04X, SID 0x%04X, SERVICE \"%s\"\n", er->caid, er->srvid, srvname);
1379 }
1380
1381 parity = er->ecm[0]&1;
1382 fprintf(pfCWL, "%d ",parity);
1383 for (i=parity*8; i<8+parity*8; i++)
1384 fprintf(pfCWL, "%02X ",er->cw[i]);
1385 /* better use incoming time er->tps rather than current time? */
1386 strftime(buf,sizeof(buf),"%H:%M:%S\n",timeinfo);
1387 fprintf(pfCWL, "# %s",buf);
1388 fflush(pfCWL);
1389 fclose(pfCWL);
1390 } /* if (cfg->pidfile[0]) */
1391}
1392
1393int write_ecm_answer(int fd, ECM_REQUEST *er)
1394{
1395 int i, f;
1396 uchar c;
1397 for (i=f=0; i<16; i+=4)
1398 {
1399 c=((er->cw[i]+er->cw[i+1]+er->cw[i+2]) & 0xff);
1400 if (er->cw[i+3]!=c)
1401 {
1402 f=1;
1403 er->cw[i+3]=c;
1404 }
1405 }
1406 if (f)
1407 cs_debug("notice: changed dcw checksum bytes");
1408
1409 er->reader[0]=ridx;
1410//cs_log("answer from reader %d (rc=%d)", er->reader[0], er->rc);
1411 er->caid=er->ocaid;
1412 if (er->rc==1||(er->gbxRidx&&er->rc==0)){
1413 store_ecm(er);
1414 logCWtoFile(er);
1415 }
1416
1417 return(write_ecm_request(fd, er));
1418}
1419
1420static int cs_read_timer(int fd, uchar *buf, int l, int msec)
1421{
1422 struct timeval tv;
1423 fd_set fds;
1424 int rc;
1425
1426 if (!fd) return(-1);
1427 tv.tv_sec = msec / 1000;
1428 tv.tv_usec = (msec % 1000) * 1000;
1429 FD_ZERO(&fds);
1430 FD_SET(pfd, &fds);
1431
1432 select(fd+1, &fds, 0, 0, &tv);
1433
1434 rc=0;
1435 if (FD_ISSET(pfd, &fds))
1436 if (!(rc=read(fd, buf, l)))
1437 rc=-1;
1438
1439 return(rc);
1440}
1441
1442ECM_REQUEST *get_ecmtask()
1443{
1444 int i, n;
1445 ECM_REQUEST *er=0;
1446
1447 if (!ecmtask)
1448 {
1449 n=(ph[client[cs_idx].ctyp].multi)?CS_MAXPENDING:1;
1450 if( (ecmtask=(ECM_REQUEST *)malloc(n*sizeof(ECM_REQUEST))) )
1451 memset(ecmtask, 0, n*sizeof(ECM_REQUEST));
1452 }
1453
1454 n=(-1);
1455 if (!ecmtask)
1456 {
1457 cs_log("Cannot allocate memory (errno=%d)", errno);
1458 n=(-2);
1459 }
1460 else
1461 if (ph[client[cs_idx].ctyp].multi)
1462 {
1463 for (i=0; (n<0) && (i<CS_MAXPENDING); i++)
1464 if (ecmtask[i].rc<100)
1465 er=&ecmtask[n=i];
1466 }
1467 else
1468 er=&ecmtask[n=0];
1469
1470 if (n<0)
1471 cs_log("WARNING: ecm pending table overflow !");
1472 else
1473 {
1474 memset(er, 0, sizeof(ECM_REQUEST));
1475 er->rc=100;
1476 er->cpti=n;
1477 er->cidx=cs_idx;
1478 cs_ftime(&er->tps);
1479 }
1480 return(er);
1481}
1482
1483int send_dcw(ECM_REQUEST *er)
1484{
1485 static char *stxt[]={"found", "cache1", "cache2", "emu",
1486 "not found", "timeout", "sleeping",
1487 "fake", "invalid", "corrupt"};
1488 static char *stxtEx[]={"", "group", "caid", "ident", "class", "chid", "queue"};
1489 static char *stxtWh[]={"", "user ", "reader ", "server ", "lserver "};
1490 char sby[32]="";
1491 char erEx[32]="";
1492 char uname[38]="";
1493 struct timeb tpe;
1494 ushort lc, *lp;
1495 for (lp=(ushort *)er->ecm+(er->l>>2), lc=0; lp>=(ushort *)er->ecm; lp--)
1496 lc^=*lp;
1497 cs_ftime(&tpe);
1498 if(er->gbxFrom)
1499 snprintf(uname,sizeof(uname)-1, "%s(%04X)", username(cs_idx), er->gbxFrom);
1500 else
1501 snprintf(uname,sizeof(uname)-1, "%s", username(cs_idx));
1502 if (er->rc==0)
1503 {
1504 if(reader[er->reader[0]].typ==R_GBOX)
1505 snprintf(sby, sizeof(sby)-1, " by %s(%04X)", reader[er->reader[0]].label,er->gbxCWFrom);
1506 else
1507 snprintf(sby, sizeof(sby)-1, " by %s", reader[er->reader[0]].label);
1508 }
1509 if (er->rc<4) er->rcEx=0;
1510 if (er->rcEx)
1511 snprintf(erEx, sizeof(erEx)-1, "rejected %s%s", stxtWh[er->rcEx>>4],
1512 stxtEx[er->rcEx&0xf]);
1513 cs_log("%s (%04X&%06X/%04X/%02X:%04X): %s (%d ms)%s",
1514 uname, er->caid, er->prid, er->srvid, er->l, lc,
1515 er->rcEx?erEx:stxt[er->rc],
1516 1000*(tpe.time-er->tps.time)+tpe.millitm-er->tps.millitm, sby);
1517 er->caid=er->ocaid;
1518 switch(er->rc)
1519 {
1520 case 2:
1521 case 1: client[cs_idx].cwcache++;
1522 case 3:
1523 case 0: client[cs_idx].cwfound++; break;
1524 default: client[cs_idx].cwnot++;
1525 if (er->rc>5)
1526 client[cs_idx].cwcache++;
1527 }
1528#ifdef CS_ANTICASC
1529 ac_chk(er, 1);
1530#endif
1531
1532 if( cfg->show_ecm_dw && !client[cs_idx].dbglvl )
1533 cs_dump(er->cw, 16, 0);
1534 if (er->rc==7) er->rc=0;
1535 ph[client[cs_idx].ctyp].send_dcw(er);
1536 return 0;
1537}
1538
1539static void chk_dcw(int fd)
1540{
1541 ECM_REQUEST *er, *ert;
1542 if (read_from_pipe(fd, (uchar **)&er, 0)!=PIP_ID_ECM)
1543 return;
1544 //cs_log("dcw check from reader %d for idx %d (rc=%d)", er->reader[0], er->cpti, er->rc);
1545 ert=&ecmtask[er->cpti];
1546 if (ert->rc<100)
1547 return; // already done
1548 if( (er->caid!=ert->caid) || memcmp(er->ecm , ert->ecm , sizeof(er->ecm)) )
1549 return; // obsolete
1550 ert->rcEx=er->rcEx;
1551 if (er->rc>0) // found
1552 {
1553 ert->rc=(er->rc==2)?2:0;
1554 ert->rcEx=0;
1555 ert->reader[0]=er->reader[0];
1556 memcpy(ert->cw , er->cw , sizeof(er->cw));
1557 ert->gbxCWFrom=er->gbxCWFrom;
1558 }
1559 else // not found (from ONE of the readers !)
1560 {
1561 int i;
1562 ert->reader[er->reader[0]]=0;
1563 for (i=0; (ert) && (i<CS_MAXREADER); i++)
1564 if (ert->reader[i]) // we have still another chance
1565 ert=(ECM_REQUEST *)0;
1566 if (ert) ert->rc=4;
1567 }
1568 if (ert) send_dcw(ert);
1569 return;
1570}
1571
1572ulong chk_provid(uchar *ecm, ushort caid)
1573{
1574 int i;
1575 ulong provid=0;
1576 switch(caid)
1577 {
1578 case 0x100: // seca
1579 provid=b2i(2, ecm+3);
1580 break;
1581 case 0x500: // viaccess
1582 i=(ecm[4]==0xD2) ? ecm[5] + 2 : 0; // skip d2 nano
1583 if ((ecm[5+i]==3) && ((ecm[4+i]==0x90) || (ecm[4+i]==0x40)))
1584 provid=(b2i(3, ecm+6+i) & 0xFFFFF0);
1585 default:
1586 // cryptoworks ?
1587 if( caid&0x0d00 && ecm[8]==0x83 && ecm[9]==1 )
1588 provid=(ulong)ecm[10];
1589 }
1590 return(provid);
1591}
1592
1593/*
1594void guess_irdeto(ECM_REQUEST *er)
1595{
1596 uchar b3;
1597 int b47;
1598 //ushort chid;
1599 struct s_irdeto_quess *ptr;
1600
1601 b3 = er->ecm[3];
1602 ptr = cfg->itab[b3];
1603 if( !ptr ) {
1604 cs_debug("unknown irdeto byte 3: %02X", b3);
1605 return;
1606 }
1607 b47 = b2i(4, er->ecm+4);
1608 //chid = b2i(2, er->ecm+6);
1609 //cs_debug("ecm: b47=%08X, ptr->b47=%08X, ptr->caid=%04X", b47, ptr->b47, ptr->caid);
1610 while( ptr )
1611 {
1612 if( b47==ptr->b47 )
1613 {
1614 if( er->srvid && (er->srvid!=ptr->sid) )
1615 {
1616 cs_debug("sid mismatched (ecm: %04X, guess: %04X), wrong oscam.ird file?",
1617 er->srvid, ptr->sid);
1618 return;
1619 }
1620 er->caid=ptr->caid;
1621 er->srvid=ptr->sid;
1622 er->chid=(ushort)ptr->b47;
1623// cs_debug("quess_irdeto() found caid=%04X, sid=%04X, chid=%04X",
1624// er->caid, er->srvid, er->chid);
1625 return;
1626 }
1627 ptr=ptr->next;
1628 }
1629}
1630*/
1631
1632void guess_cardsystem(ECM_REQUEST *er)
1633{
1634 ushort last_hope=0;
1635
1636 // viaccess - check by provid-search
1637 if( (er->prid=chk_provid(er->ecm, 0x500)) )
1638 er->caid=0x500;
1639
1640 // nagra
1641 // is ecm[1] always 0x30 ?
1642 // is ecm[3] always 0x07 ?
1643 if ((er->ecm[6]==1) && (er->ecm[4]==er->ecm[2]-2))
1644 er->caid=0x1801;
1645
1646 // seca2 - very poor
1647 if ((er->ecm[8]==0x10) && ((er->ecm[9]&0xF1)==1))
1648 last_hope=0x100;
1649
1650 // is cryptoworks, but which caid ?
1651 if ((er->ecm[3]==0x81) && (er->ecm[4]==0xFF) &&
1652 (!er->ecm[5]) && (!er->ecm[6]) && (er->ecm[7]==er->ecm[2]-5))
1653 last_hope=0xd00;
1654
1655/*
1656 if (!er->caid && er->ecm[2]==0x31 && er->ecm[0x0b]==0x28)
1657 guess_irdeto(er);
1658*/
1659
1660 if (!er->caid) // guess by len ..
1661 er->caid=len4caid[er->ecm[2]+3];
1662
1663 if (!er->caid)
1664 er->caid=last_hope;
1665}
1666
1667void request_cw(ECM_REQUEST *er, int flag, int reader_types)
1668{
1669 int i;
1670 if ((reader_types == 0) || (reader_types == 2))
1671 er->level=flag;
1672 flag=(flag)?3:1; // flag specifies with/without fallback-readers
1673 for (i=0; i<CS_MAXREADER; i++)
1674 {
1675 switch (reader_types)
1676 {
1677 // network and local cards
1678 default:
1679 case 0:
1680 if (er->reader[i]&flag)
1681 write_ecm_request(reader[i].fd, er);
1682 break;
1683 // only local cards
1684 case 1:
1685 if (!(reader[i].typ & R_IS_NETWORK))
1686 if (er->reader[i]&flag)
1687 write_ecm_request(reader[i].fd, er);
1688 break;
1689 // only network
1690 case 2:
1691 if ((reader[i].typ & R_IS_NETWORK))
1692 if (er->reader[i]&flag)
1693 write_ecm_request(reader[i].fd, er);
1694 break;
1695 }
1696 }
1697}
1698
1699void get_cw(ECM_REQUEST *er)
1700{
1701 int i, j, m, rejected;
1702 //uchar orig_caid[sizeof(er->caid)];
1703 time_t now;
1704//test the guessing ...
1705//cs_log("caid should be %04X, provid %06X", er->caid, er->prid);
1706//er->caid=0;
1707
1708 client[cs_idx].lastecm=time((time_t)0);
1709
1710 if (!er->caid)
1711 guess_cardsystem(er);
1712
1713 if( (er->caid & 0xFF00)==0x600 && !er->chid )
1714 er->chid = (er->ecm[6]<<8)|er->ecm[7];
1715
1716 if (!er->prid)
1717 er->prid=chk_provid(er->ecm, er->caid);
1718
1719// quickfix for 0100:000065
1720 if (er->caid == 0x100 && er->prid == 0x65 && er->srvid == 0)
1721 er->srvid = 0x0642;
1722
1723 if( (!er->prid) && client[cs_idx].ncd_server )
1724 {
1725 int pi = client[cs_idx].port_idx;
1726 if( pi>=0 && cfg->ncd_ptab.nports && cfg->ncd_ptab.nports >= pi )
1727 er->prid = cfg->ncd_ptab.ports[pi].ftab.filts[0].prids[0];
1728 }
1729
1730//cs_log("caid IS NOW .. %04X, provid %06X", er->caid, er->prid);
1731
1732 rejected=0;
1733 if (er->rc>99) // rc<100 -> ecm error
1734 {
1735 now=time((time_t *) 0);
1736 m=er->caid;
1737 er->ocaid=er->caid;
1738
1739 i=er->srvid;
1740 if ((i!=client[cs_idx].last_srvid) || (!client[cs_idx].lastswitch))
1741 client[cs_idx].lastswitch=now;
1742 if ((client[cs_idx].tosleep) &&
1743 (now-client[cs_idx].lastswitch>client[cs_idx].tosleep))
1744 er->rc=6; // sleeping
1745 client[cs_idx].last_srvid=i;
1746 client[cs_idx].last_caid=m;
1747
1748 for (j=0; (j<6) && (er->rc>99); j++)
1749 switch(j)
1750 {
1751 case 0: if (client[cs_idx].dup)
1752 er->rc=7; // fake
1753 break;
1754 case 1: if (!chk_bcaid(er, &client[cs_idx].ctab))
1755 {
1756// cs_log("chk_bcaid failed");
1757 er->rc=8; // invalid
1758 er->rcEx=E2_CAID;
1759 }
1760 break;
1761 case 2: if (!chk_srvid(er, cs_idx))
1762 er->rc=8;
1763 break;
1764 case 3: if (!chk_ufilters(er))
1765 er->rc=8;
1766 break;
1767 case 4: if (!chk_sfilter(er, ph[client[cs_idx].ctyp].ptab))
1768 er->rc=8;
1769 break;
1770 case 5: if( (i=er->l-(er->ecm[2]+3)) )
1771 {
1772 if (i>0)
1773 {
1774 cs_debug("warning: ecm size adjusted from 0x%X to 0x%X",
1775 er->l, er->ecm[2]+3);
1776 er->l=(er->ecm[2]+3);
1777 }
1778 else
1779 er->rc=9; // corrupt
1780 }
1781 break;
1782 }
1783
1784 if (&client[cs_idx].ttab) // Betatunneling
1785 // moved behind the check routines, because newcamd-ECM will fail if ecm is converted before
1786 {
1787 int n;
1788 ulong mask_all=0xFFFF;
1789 TUNTAB *ttab;
1790 ttab=&client[cs_idx].ttab;
1791 for (n=0; (n<CS_MAXTUNTAB); n++)
1792 if ((er->caid==ttab->bt_caidfrom[n]) && ((er->srvid==ttab->bt_srvid[n]) || (ttab->bt_srvid[n])==mask_all))
1793 {
1794 int l;
1795 char hack_n3[13]={0x70, 0x51, 0xc7, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x87, 0x12, 0x07};
1796 char hack_n2[13]={0x70, 0x51, 0xc9, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x48, 0x12, 0x07};
1797 er->caid=ttab->bt_caidto[n];
1798 er->prid=0;
1799 er->l=(er->ecm[2]+3);
1800 memmove(er->ecm+14, er->ecm+4, er->l-1);
1801 if (er->l > 0x88)
1802 {
1803 memcpy(er->ecm+1, hack_n3, 13);
1804 if (er->ecm[0]==0x81) er->ecm[12]+= 1;
1805 }
1806 else memcpy(er->ecm+1, hack_n2, 13);
1807 er->l+=10;
1808 er->ecm[2]=er->l-3;
1809 cs_debug("ecm converted from: 0x%X to betacrypt: 0x%X for service id:0x%X",
1810 ttab->bt_caidfrom[n], ttab->bt_caidto[n], ttab->bt_srvid[n]);
1811 }
1812 }
1813
1814 memcpy(er->ecmd5, MD5(er->ecm, er->l, NULL), CS_ECMSTORESIZE);
1815
1816 if (check_ecmcache(er, client[cs_idx].grp))
1817 er->rc=1; // cache1
1818
1819#ifdef CS_ANTICASC
1820 ac_chk(er, 0);
1821#endif
1822 if( er->rc<100 && er->rc!=1 )
1823 rejected=1;
1824 }
1825
1826 if( !rejected && er->rc!=1 )
1827 {
1828 for (i=m=0; i<CS_MAXREADER; i++)
1829 if (matching_reader(er, &reader[i])&&(i!=ridx))
1830 m|=er->reader[i]=(reader[i].fallback)?2:1;
1831
1832 switch(m)
1833 {
1834 case 0: er->rc=4; // no reader -> not found
1835 if (!er->rcEx) er->rcEx=E2_GROUP;
1836 break;
1837 case 2: for (i=0; i<CS_MAXREADER; i++) // fallbacks only, switch them.
1838 er->reader[i]>>=1;
1839 }
1840 }
1841 if (er->rc<100)
1842 {
1843 if (cfg->delay) usleep(cfg->delay);
1844 send_dcw(er);
1845 return;
1846 }
1847
1848 er->rcEx=0;
1849 request_cw(er, 0, cfg->preferlocalcards ? 1 : 0);
1850}
1851
1852void log_emm_request(int auidx)
1853{
1854// cs_log("%s send emm-request (reader=%s, caid=%04X)",
1855// cs_inet_ntoa(client[cs_idx].ip), reader[auidx].label, reader[auidx].caid[0]);
1856 cs_log("%s emm-request sent (reader=%s, caid=%04X)",
1857 username(cs_idx), reader[auidx].label, reader[auidx].caid[0]);
1858}
1859
1860void do_emm(EMM_PACKET *ep)
1861{
1862 int au;//, ephs;
1863 au=client[cs_idx].au;
1864
1865 if ((au<0) || (au>=CS_MAXREADER))
1866 return;
1867 client[cs_idx].lastemm=time((time_t)0);
1868 cs_ddump(reader[au].hexserial, 8, "reader serial:");
1869 cs_ddump(ep->hexserial, 8, "emm SA:");
1870// if ((!reader[au].fd) || (reader[au].b_nano[ep->emm[3]])) // blocknano is obsolete
1871 if ((!reader[au].fd) || // reader has no fd
1872 (reader[au].caid[0]!=b2i(2,ep->caid)) || // wrong caid
1873 (memcmp(reader[au].hexserial, ep->hexserial, 8))) // wrong serial
1874 return;
1875
1876 ep->cidx=cs_idx;
1877 write_to_pipe(reader[au].fd, PIP_ID_EMM, (uchar *) ep, sizeof(EMM_PACKET));
1878}
1879
1880static int comp_timeb(struct timeb *tpa, struct timeb *tpb)
1881{
1882 if (tpa->time>tpb->time) return(1);
1883 if (tpa->time<tpb->time) return(-1);
1884 if (tpa->millitm>tpb->millitm) return(1);
1885 if (tpa->millitm<tpb->millitm) return(-1);
1886 return(0);
1887}
1888
1889static void build_delay(struct timeb *tpe, struct timeb *tpc)
1890{
1891 if (comp_timeb(tpe, tpc)>0)
1892 {
1893 tpe->time=tpc->time;
1894 tpe->millitm=tpc->millitm;
1895 }
1896}
1897
1898struct timeval *chk_pending(struct timeb tp_ctimeout)
1899{
1900 int i;
1901 ulong td;
1902 struct timeb tpn, tpe, tpc; // <n>ow, <e>nd, <c>heck
1903 static struct timeval tv;
1904
1905 ECM_REQUEST *er;
1906 cs_ftime(&tpn);
1907 tpe=tp_ctimeout; // latest delay -> disconnect
1908
1909 if (ecmtask)
1910 i=(ph[client[cs_idx].ctyp].multi)?CS_MAXPENDING:1;
1911 else
1912 i=0;
1913//cs_log("num pend=%d", i);
1914 for (--i; i>=0; i--)
1915 if (ecmtask[i].rc>=100) // check all pending ecm-requests
1916 {
1917 int act, j;
1918 er=&ecmtask[i];
1919 tpc=er->tps;
1920 tpc.millitm += (er->stage) ? cfg->ctimeout : cfg->ftimeout;
1921 tpc.time += tpc.millitm / 1000;
1922 tpc.millitm = tpc.millitm % 1000;
1923 if (!er->stage)
1924 {
1925 for (j=0, act=1; (act) && (j<CS_MAXREADER); j++)
1926 {
1927 if (cfg->preferlocalcards && !er->locals_done)
1928 {
1929 if ((er->reader[j]&1) && !(reader[j].typ & R_IS_NETWORK))
1930 act=0;
1931 }
1932 else if (cfg->preferlocalcards && er->locals_done)
1933 {
1934 if ((er->reader[j]&1) && (reader[j].typ & R_IS_NETWORK))
1935 act=0;
1936 }
1937 else
1938 {
1939 if (er->reader[j]&1)
1940 act=0;
1941 }
1942 }
1943//cs_log("stage 0, act=%d r0=%d, r1=%d, r2=%d, r3=%d, r4=%d r5=%d", act,
1944// er->reader[0], er->reader[1], er->reader[2],
1945// er->reader[3], er->reader[4], er->reader[5]);
1946 if (act)
1947 {
1948 int inc_stage = 1;
1949
1950 if (cfg->preferlocalcards && !er->locals_done)
1951 {
1952 int i;
1953
1954 er->locals_done = 1;
1955 for (i = 0; i < CS_MAXREADER; i++)
1956 {
1957 if (reader[i].typ & R_IS_NETWORK)
1958 {
1959 inc_stage = 0;
1960 }
1961 }
1962 }
1963 if (!inc_stage)
1964 {
1965 request_cw(er, er->stage, 2);
1966 tpc.millitm += 1000 * (tpn.time - er->tps.time) + tpn.millitm - er->tps.millitm;
1967 tpc.time += tpc.millitm / 1000;
1968 tpc.millitm = tpc.millitm % 1000;
1969 }
1970 else
1971 {
1972 er->locals_done = 0;
1973 er->stage++;
1974 request_cw(er, er->stage, cfg->preferlocalcards ? 1 : 0);
1975
1976 tpc.millitm += (cfg->ctimeout-cfg->ftimeout);
1977 tpc.time += tpc.millitm / 1000;
1978 tpc.millitm = tpc.millitm % 1000;
1979 }
1980 }
1981 }
1982 if (comp_timeb(&tpn, &tpc)>0) // action needed
1983 {
1984//cs_log("Action now %d.%03d", tpn.time, tpn.millitm);
1985//cs_log(" %d.%03d", tpc.time, tpc.millitm);
1986 if (er->stage)
1987 {
1988 er->rc=5; // timeout
1989 send_dcw(er);
1990 continue;
1991 }
1992 else
1993 {
1994 er->stage++;
1995 request_cw(er, er->stage, 0);
1996 tpc.millitm += (cfg->ctimeout-cfg->ftimeout);
1997 tpc.time += tpc.millitm / 1000;
1998 tpc.millitm = tpc.millitm % 1000;
1999 }
2000 }
2001 build_delay(&tpe, &tpc);
2002 }
2003 td=(tpe.time-tpn.time)*1000+(tpe.millitm-tpn.millitm)+5;
2004 tv.tv_sec = td/1000;
2005 tv.tv_usec = (td%1000)*1000;
2006//cs_log("delay %d.%06d", tv.tv_sec, tv.tv_usec);
2007 return(&tv);
2008}
2009
2010int process_input(uchar *buf, int l, int timeout)
2011{
2012 int rc;
2013 fd_set fds;
2014 struct timeb tp;
2015
2016 if (master_pid!=getppid()) cs_exit(0);
2017 if (!pfd) return(-1);
2018 cs_ftime(&tp);
2019 tp.time+=timeout;
2020 if (ph[client[cs_idx].ctyp].watchdog)
2021 alarm(cfg->cmaxidle + (cfg->ctimeout + 500) / 1000 + 1);
2022 while (1)
2023 {
2024 FD_ZERO(&fds);
2025 FD_SET(pfd, &fds);
2026 FD_SET(fd_m2c, &fds);
2027
2028 rc=select(((pfd>fd_m2c)?pfd:fd_m2c)+1, &fds, 0, 0, chk_pending(tp));
2029 if (master_pid!=getppid()) cs_exit(0);
2030 if (rc<0)
2031 {
2032 if (errno==EINTR) continue;
2033 else return(0);
2034 }
2035
2036 if (FD_ISSET(fd_m2c, &fds)) // read from pipe
2037 chk_dcw(fd_m2c);
2038
2039 if (FD_ISSET(pfd, &fds)) // read from client
2040 {
2041 rc=ph[client[cs_idx].ctyp].recv(buf, l);
2042 break;
2043 }
2044 if (tp.time<=time((time_t *)0)) // client maxidle reached
2045 {
2046 rc=(-9);
2047 break;
2048 }
2049 }
2050 if (ph[client[cs_idx].ctyp].watchdog)
2051 alarm(cfg->cmaxidle + (cfg->ctimeout + 500) / 1000 + 1);
2052 return(rc);
2053}
2054
2055static void process_master_pipe()
2056{
2057 int n;
2058 uchar *ptr;
2059
2060 switch(n=read_from_pipe(mfdr, &ptr, 1))
2061 {
2062 case PIP_ID_LOG:
2063 cs_write_log(ptr);
2064 break;
2065 case PIP_ID_HUP:
2066 cs_accounts_chk();
2067 break;
2068 }
2069}
2070
2071void cs_log_config()
2072{
2073 uchar buf[2048];
2074
2075 if (cfg->nice!=99)
2076 sprintf((char *)buf, ", nice=%d", cfg->nice);
2077 else
2078 buf[0]='\0';
2079 cs_log("version=%s, system=%s%s", CS_VERSION_X, cs_platform((char *)buf+64), buf);
2080 cs_log("max. clients=%d, client max. idle=%d sec",
2081#ifdef CS_ANTICASC
2082 CS_MAXPID-3, cfg->cmaxidle);
2083#else
2084 CS_MAXPID-2, cfg->cmaxidle);
2085#endif
2086 if( cfg->max_log_size )
2087 sprintf((char *)buf, "%d Kb", cfg->max_log_size);
2088 else
2089 strcpy((char *)buf, "unlimited");
2090 cs_log("max. logsize=%s", buf);
2091 cs_log("client timeout=%lu ms, fallback timeout=%lu ms, cache delay=%d ms",
2092 cfg->ctimeout, cfg->ftimeout, cfg->delay);
2093#ifdef CS_NOSHM
2094 cs_log("shared memory initialized (size=%d, fd=%d)", shmsize, shmid);
2095#else
2096 cs_log("shared memory initialized (size=%d, id=%d)", shmsize, shmid);
2097#endif
2098}
2099
2100int main (int argc, char *argv[])
2101{
2102 struct sockaddr_in cad; /* structure to hold client's address */
2103 int scad; /* length of address */
2104 //int fd; /* socket descriptors */
2105 int i, j, n;
2106 int bg=0;
2107 int gfd; //nph,
2108 int fdp[2];
2109 uchar buf[2048];
2110 void (*mod_def[])(struct s_module *)=
2111 {
2112 module_monitor,
2113 module_camd33,
2114 module_camd35,
2115 module_camd35_tcp,
2116 module_newcamd,
2117#ifdef CS_WITH_GBOX
2118 module_gbox,
2119#endif
2120 module_radegast,
2121 module_oscam_ser,
2122 0
2123 };
2124
2125 while ((i=getopt(argc, argv, "bc:d:hm:"))!=EOF)
2126 {
2127 switch(i)
2128 {
2129 case 'b': bg=1;
2130 break;
2131 case 'c': strncpy(cs_confdir, optarg, sizeof(cs_confdir)-1);
2132 break;
2133 case 'd': cs_dblevel=atoi(optarg);
2134 break;
2135 case 'm':
2136#ifdef CS_NOSHM
2137 strncpy(cs_memfile, optarg, sizeof(cs_memfile)-1);
2138 break;
2139#endif
2140 case 'h':
2141 default : usage();
2142 }
2143 }
2144 if (cs_confdir[strlen(cs_confdir)]!='/') strcat(cs_confdir, "/");
2145 init_shm();
2146 init_config();
2147 for (i=0; mod_def[i]; i++) // must be later BEFORE init_config()
2148 {
2149 memset(&ph[i], 0, sizeof(struct s_module));
2150 mod_def[i](&ph[i]);
2151 }
2152
2153 cs_log("auth size=%d", sizeof(struct s_auth));
2154 //cs_log_config();
2155 cfg->delay*=1000;
2156 init_sidtab();
2157 init_readerdb();
2158 init_userdb();
2159 init_signal();
2160 cs_set_mloc(30, "init");
2161 init_srvid();
2162 init_len4caid();
2163 //init_irdeto_guess_tab();
2164 cs_init_statistics(cfg->usrfile);
2165
2166 if (pipe(fdp))
2167 {
2168 cs_log("Cannot create pipe (errno=%d)", errno);
2169 cs_exit(1);
2170 }
2171 mfdr=fdp[0];
2172 fd_c2m=fdp[1];
2173 gfd=mfdr+1;
2174
2175#ifdef OS_MACOSX
2176 if (bg && daemon_compat(1,0))
2177#else
2178 if (bg && daemon(1,0))
2179#endif
2180 {
2181 cs_log("Error starting in background (errno=%d)", errno);
2182 cs_exit(1);
2183 }
2184 master_pid=client[0].pid=getpid();
2185 if (cfg->pidfile[0])
2186 {
2187 FILE *fp;
2188 if (!(fp=fopen(cfg->pidfile, "w")))
2189 {
2190 cs_log("Cannot open pid-file (errno=%d)", errno);
2191 cs_exit(1);
2192 }
2193 fprintf(fp, "%d\n", getpid());
2194 fclose(fp);
2195 }
2196
2197 for (i=0; i<CS_MAX_MOD; i++)
2198 if( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
2199 for(j=0; j<ph[i].ptab->nports; j++)
2200 {
2201 start_listener(&ph[i], j);
2202 if( ph[i].ptab->ports[j].fd+1>gfd )
2203 gfd=ph[i].ptab->ports[j].fd+1;
2204 }
2205
2206 start_client_resolver();
2207 init_service(97); // logger
2208 init_service(98); // resolver
2209 init_cardreader();
2210
2211 if (cfg->waitforcards)
2212 {
2213 int card_init_done;
2214
2215 cs_log("Waiting for local card init ....");
2216
2217 sleep(3); // short sleep for card detect to work proberly
2218
2219 for(;;)
2220 {
2221 card_init_done = 1;
2222
2223 for (i = 0; i < CS_MAXREADER; i++)
2224 {
2225 if (!reader[i].online && reader[i].card_status)
2226 {
2227 if (!(reader[i].card_status & CARD_FAILURE))
2228 {
2229 card_init_done = 0;
2230 break;
2231 }
2232 }
2233 }
2234
2235 if (card_init_done)
2236 break;
2237
2238 cs_sleepms(300); // wait a little bit
2239
2240 alarm(cfg->cmaxidle + cfg->ctimeout / 1000 + 1);
2241 }
2242
2243 cs_log("Init for all local cards done !");
2244 }
2245
2246
2247#ifdef CS_ANTICASC
2248 if( !cfg->ac_enabled )
2249 cs_log("anti cascading disabled");
2250 else
2251 {
2252 init_ac();
2253 init_service(96);
2254 }
2255#endif
2256
2257 for (i=0; i<CS_MAX_MOD; i++)
2258 if (ph[i].type & MOD_CONN_SERIAL) // for now: oscam_ser only
2259 if (ph[i].s_handler)
2260 ph[i].s_handler(i);
2261
2262 cs_close_log();
2263 *mcl=1;
2264 while (1)
2265 {
2266 fd_set fds;
2267
2268 do
2269 {
2270 FD_ZERO(&fds);
2271 FD_SET(mfdr, &fds);
2272 for (i=0; i<CS_MAX_MOD; i++)
2273 if ( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
2274 for (j=0; j<ph[i].ptab->nports; j++)
2275 if (ph[i].ptab->ports[j].fd)
2276 FD_SET(ph[i].ptab->ports[j].fd, &fds);
2277 errno=0;
2278 cs_set_mloc(0, "before select");
2279 select(gfd, &fds, 0, 0, 0);
2280 cs_set_mloc(60, "after select");
2281 } while (errno==EINTR);
2282 cs_set_mloc(-1, "event (global)");
2283
2284 client[0].last=time((time_t *)0);
2285 scad = sizeof(cad);
2286 if (FD_ISSET(mfdr, &fds))
2287 {
2288 cs_set_mloc(-1, "event: master-pipe");
2289 process_master_pipe();
2290 }
2291 for (i=0; i<CS_MAX_MOD; i++)
2292 {
2293 if( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
2294 {
2295 for( j=0; j<ph[i].ptab->nports; j++ )
2296 {
2297 if( ph[i].ptab->ports[j].fd && FD_ISSET(ph[i].ptab->ports[j].fd, &fds) )
2298 {
2299 if (ph[i].type==MOD_CONN_UDP)
2300 {
2301 cs_set_mloc(-1, "event: udp-socket");
2302 if ((n=recvfrom(ph[i].ptab->ports[j].fd, buf+3, sizeof(buf)-3, 0, (struct sockaddr *)&cad, (socklen_t *)&scad))>0)
2303 {
2304 int idx;
2305 idx=idx_from_ip(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port));
2306 if (!idx)
2307 {
2308 if (pipe(fdp))
2309 {
2310 cs_log("Cannot create pipe (errno=%d)", errno);
2311 cs_exit(1);
2312 }
2313 switch(cs_fork(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port)))
2314 {
2315 case -1:
2316 close(fdp[0]);
2317 close(fdp[1]);
2318 break;
2319 case 0:
2320 client[idx=cs_last_idx].ufd=fdp[1];
2321 close(fdp[0]);
2322 break;
2323 default:
2324// close(fdp[1]); // now used to simulate event
2325 pfd=fdp[0];
2326 wait4master();
2327 client[cs_idx].ctyp=i;
2328 client[cs_idx].port_idx=j;
2329 client[cs_idx].udp_fd=ph[i].ptab->ports[j].fd;
2330 client[cs_idx].udp_sa=cad;
2331 if (ph[client[cs_idx].ctyp].watchdog)
2332 alarm(cfg->cmaxidle + cfg->ctimeout / 1000 + 1);
2333 ph[i].s_handler(cad); // never return
2334 }
2335 }
2336 if (idx)
2337 {
2338 unsigned short rl;
2339 rl=n;
2340 buf[0]='U';
2341 memcpy(buf+1, &rl, 2);
2342 if (!write(client[idx].ufd, buf, n+3)) cs_exit(1);
2343 }
2344 }
2345 }
2346 else
2347 {
2348 cs_set_mloc(-1, "event: tcp-socket");
2349 if ((pfd=accept(ph[i].ptab->ports[j].fd, (struct sockaddr *)&cad, (socklen_t *)&scad))>0)
2350 {
2351 switch(cs_fork(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port)))
2352 {
2353 case -1:
2354 case 0:
2355 close(pfd);
2356 break;
2357 default:
2358 wait4master();
2359 client[cs_idx].ctyp=i;
2360 client[cs_idx].udp_fd=pfd;
2361 client[cs_idx].port_idx=j;
2362 if (ph[client[cs_idx].ctyp].watchdog)
2363 alarm(cfg->cmaxidle + cfg->ctimeout / 1000 + 1);
2364 ph[i].s_handler();
2365 }
2366 }
2367 }
2368 }
2369 }
2370 } // if (ph[i].type & MOD_CONN_NET)
2371 }
2372 }
2373 cs_exit(1);
2374}
Note: See TracBrowser for help on using the repository browser.