source: trunk/oscam.c@ 1715

Last change on this file since 1715 was 1715, checked in by merek, 11 years ago

Dont store provider id in cache because provider id was not checked for caching

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