source: trunk/oscam.c@ 56

Last change on this file since 56 was 56, checked in by smurzch2, 12 years ago

Appliy patch from C.H.A.D.o/streamboard.

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