source: trunk/oscam.c @ 1284

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

Add Triple Dragon support, thanks to Single

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