static void do_report_emm_support(void) { if(!config_enabled(WITH_CARDREADER)) { cs_log("Binary without Cardreader Support! No EMM processing possible!"); } else { report_emm_support(READER_NAGRA, "Nagra"); report_emm_support(READER_IRDETO, "Irdeto"); report_emm_support(READER_CONAX, "Conax"); report_emm_support(READER_CRYPTOWORKS, "Cryptoworks"); report_emm_support(READER_SECA, "Seca"); report_emm_support(READER_VIACCESS, "Viaccess"); report_emm_support(READER_VIDEOGUARD, "NDS Videoguard"); report_emm_support(READER_DRE, "DRE Crypt"); report_emm_support(READER_TONGFANG, "TONGFANG"); report_emm_support(READER_BULCRYPT, "Bulcrypt"); report_emm_support(READER_GRIFFIN, "Griffin"); report_emm_support(READER_DGCRYPT, "DGCrypt"); } }
static int32_t radegast_recv(struct s_client *client, uchar *buf, int32_t l) { int32_t n; if (!client->pfd) return(-1); if (client->typ == 'c') { // server code if ((n=recv(client->pfd, buf, l, 0))>0) client->last=time((time_t *) 0); } else { // client code if ((n=recv(client->pfd, buf, l, 0))>0) { cs_ddump_mask(D_CLIENT, buf, n, "radegast: received %d bytes from %s", n, remote_txt()); client->last = time((time_t *) 0); if (buf[0] == 2) { // dcw received if (buf[3] != 0x10) { // dcw ok cs_log("radegast: no dcw"); n = -1; } } } } return(n); }
static void radegast_process_ecm(uchar *buf, int32_t l) { int32_t i, n, sl; ECM_REQUEST *er; struct s_client *cl = cur_client(); if (!(er=get_ecmtask())) return; for (i=0; i<l; i+=(sl+2)) { sl=buf[i+1]; switch(buf[i]) { case 2: // CAID (upper byte only, oldstyle) er->caid=buf[i+2]<<8; break; case 10: // CAID er->caid=b2i(2, buf+i+2); break; case 3: // ECM DATA //er->ecmlen = sl; er->ecmlen = (((buf[i+1+2] & 0x0F) << 8) | buf[i+2+2]) + 3; memcpy(er->ecm, buf+i+2, er->ecmlen); break; case 6: // PROVID (ASCII) n=(sl>6) ? 3 : (sl>>1); er->prid=cs_atoi((char *) buf+i+2+sl-(n<<1), n, 0); break; case 7: // KEYNR (ASCII), not needed break; case 8: // ECM PROCESS PID ?? don't know, not needed break; } } if (l!=i) cs_log("WARNING: ECM-request corrupt"); else get_cw(cl, er); }
int csc_dodelchan(void *source, int cargc, char **cargv) { nick *sender=source; reguser *rup=getreguserfromnick(sender); chanindex *cip; regchan *rcp; char *reason; char buf[512]; if (!rup) return CMD_ERROR; if (cargc<2) { chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "delchan"); return CMD_ERROR; } reason = cargv[1]; if(!checkreason(sender, reason)) return CMD_ERROR; if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) { chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]); return CMD_ERROR; } if (rcp->ID == lastchannelID) { chanservsendmessage(sender, "Sorry, can't delete last channel -- wait a while and try again."); return CMD_ERROR; } cs_log(sender,"DELCHAN %s (%s)",cip->name->content,reason); chanservwallmessage("%s (%s) just used DELCHAN on %s (reason: %s)", sender->nick, rup->username, cip->name->content, reason); snprintf(buf, sizeof(buf), "Channel deleted: %s", reason); cs_removechannel(rcp, buf); chanservstdmessage(sender, QM_DONE); return CMD_OK; }
static dmx_t *find_demux(int32_t fd, int32_t dmx_dev_num) { if(dmx_dev_num < 0 || dmx_dev_num >= MAX_COOL_DMX) { cs_log("Invalid demux %d", dmx_dev_num); return NULL; } int32_t i, idx; idx = dmx_dev_num; if(fd == 0) { for(i = 0; i < MAX_FILTER; i++) { if(!cdemuxes[idx][i].opened) { cdemuxes[idx][i].fd = COOLDEMUX_FD(dmx_dev_num, i); cs_debug_mask(D_DVBAPI, "opening new fd: %08x", cdemuxes[idx][i].fd); cdemuxes[idx][i].demux_index = dmx_dev_num; return &cdemuxes[idx][i]; } } cs_debug_mask(D_DVBAPI, "ERROR: no free demux found"); return NULL; } idx = COOLDEMUX_DMX_DEV(fd); for(i = 0; i < MAX_FILTER; i++) { if(cdemuxes[idx][i].fd == fd) { return &cdemuxes[idx][i]; } } cs_debug_mask(D_DVBAPI, "ERROR: CANT FIND Demux %08x", fd); return NULL; }
void gbox_write_peer_onl(void) { FILE *fhandle = fopen(FILE_GBOX_PEER_ONL, "w"); if(!fhandle) { cs_log("Couldn't open %s: %s\n", FILE_GBOX_PEER_ONL, strerror(errno)); return; } struct s_client *cl; for(cl = first_client; cl; cl = cl->next) { if(cl->gbox && (cl->typ == 'p')) { struct gbox_peer *peer = cl->gbox; if (peer->online) { fprintf(fhandle, "1 %s %s %04X 2.%02X\n",cl->reader->device, cs_inet_ntoa(cl->ip),peer->gbox.id, peer->gbox.minor_version); } else { fprintf(fhandle, "0 %s %s %04X 0.00\n",cl->reader->device, cs_inet_ntoa(cl->ip),peer->gbox.id); } } } fclose(fhandle); return; }
int32_t constcw_analyse_file(uint16_t c_caid, uint32_t c_prid, uint16_t c_sid, uchar *dcw) { //CAID:PROVIDER:SID:PMT:PID::XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX FILE *fp; char token[512]; uint32_t caid, provid, sid, pmt, pid; int32_t cw[16]; // FIXME c_prid = c_prid; fp=fopen(cur_client()->reader->device, "r"); if (!fp) return (0); while (fgets(token, sizeof(token), fp)){ if (token[0]=='#') continue; sscanf(token, "%4x:%6x:%4x:%4x:%4x::%2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", &caid, &provid, &sid, &pmt, &pid, &cw[0], &cw[1], &cw[2], &cw[3], &cw[4], &cw[5], &cw[6], &cw[7], &cw[8], &cw[9], &cw[10], &cw[11], &cw[12], &cw[13], &cw[14], &cw[15]); //cs_log("Line found: %s", token); if (c_caid == caid && c_sid == sid){ fclose(fp); int8_t i; for(i = 0; i < 16; ++i) dcw[i] = (uchar) cw[i]; cs_log("Entry found: %04X:%06X:%04X:%04X:%04X::%s", caid, provid, sid, pmt, pid, cs_hexdump(1, dcw, 16, token, sizeof(token))); return 1; } } fclose(fp); return 0; }
void cs_disable_log(int8_t disabled) { if(cfg.disablelog != disabled) { if(disabled && logStarted) { cs_log("Stopping log..."); log_list_flush(); } cfg.disablelog = disabled; if(disabled) { if(logStarted) { cs_sleepms(20); cs_close_log(); } } else { cs_open_logfiles(); } } }
struct s_client *create_client(IN_ADDR_T ip) { struct s_client *cl; if(!cs_malloc(&cl, sizeof(struct s_client))) { cs_log("max connections reached (out of memory) -> reject client %s", IP_ISSET(ip) ? cs_inet_ntoa(ip) : "with null address"); return NULL; } //client part IP_ASSIGN(cl->ip, ip); cl->account = first_client->account; //master part SAFE_MUTEX_INIT(&cl->thread_lock, NULL); cl->login = cl->last = time(NULL); cl->tid = (uint32_t)rand(); //Now add new client to the list: struct s_client *last; cs_writelock(__func__, &clientlist_lock); for(last = first_client; last && last->next; last = last->next) { ; } //ends with cl on last client if (last) last->next = cl; int32_t bucket = (uintptr_t)cl / 16 % CS_CLIENT_HASHBUCKETS; cl->nexthashed = first_client_hashed[bucket]; first_client_hashed[bucket] = cl; cs_writeunlock(__func__, &clientlist_lock); return cl; }
/************************************************************************************************************************ * client functions *************************************************************************************************************************/ int pandora_client_init(struct s_client *cl) { static struct sockaddr_in loc_sa; int16_t p_proto; char ptxt[16]; struct s_reader *rdr = cl->reader; uchar md5tmp[MD5_DIGEST_LENGTH]; cl->pfd = 0; if (rdr->r_port <= 0) { cs_log("invalid port %d for server %s", rdr->r_port, rdr->device); return (1); } p_proto = IPPROTO_UDP; set_null_ip(&cl->ip); memset((char *) &loc_sa, 0, sizeof(loc_sa)); loc_sa.sin_family = AF_INET; if (IP_ISSET(cfg.srvip)) IP_ASSIGN(SIN_GET_ADDR(loc_sa), cfg.srvip); else loc_sa.sin_addr.s_addr = INADDR_ANY; loc_sa.sin_port = htons(rdr->l_port); if ((cl->udp_fd = socket(PF_INET, SOCK_DGRAM, p_proto)) < 0) { cs_log("Socket creation failed (errno=%d)", errno); return 1; } int32_t opt = 1; setsockopt(cl->udp_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); #ifdef SO_REUSEPORT setsockopt(cl->udp_fd, SOL_SOCKET, SO_REUSEPORT, (void *)&opt, sizeof(opt)); #endif set_socket_priority(cl->udp_fd, cfg.netprio); if (rdr->l_port > 0) { if (bind(cl->udp_fd, (struct sockaddr *) &loc_sa, sizeof(loc_sa)) < 0) { cs_log("bind failed (errno=%d)", errno); close(cl->udp_fd); return (1); } snprintf(ptxt, sizeof(ptxt), ", port=%d", rdr->l_port); } else ptxt[0] = '\0'; memcpy(cl->pand_md5_key, MD5((uchar*)rdr->r_pwd, strlen(rdr->r_pwd), md5tmp), 16); cl->crypted = 1; //cl->grp = 0xFFFFFFFF; //rdr->caid[0] = rdr->ctab.caid[0]; cl->pand_send_ecm = rdr->pand_send_ecm; memset((char *) &cl->udp_sa, 0, sizeof(cl->udp_sa)); #ifdef IPV6SUPPORT ((struct sockaddr_in *)(&cl->udp_sa))->sin_family = AF_INET; ((struct sockaddr_in *)(&cl->udp_sa))->sin_port = htons((u_short) rdr->r_port); #else cl->udp_sa.sin_family = AF_INET; cl->udp_sa.sin_port = htons((u_short) rdr->r_port); #endif cs_log("proxy %s:%d pandora %s (%s)", rdr->device, rdr->r_port, rdr->pand_send_ecm?"with ECM support":"", ptxt ); cl->pfd = cl->udp_fd; //fcntl(cl->udp_fd, F_SETFL, fcntl(cl->udp_fd, F_GETFL, 0) | O_NONBLOCK); //!!!!! return (0); }
static int32_t oscam_ser_check_ecm(ECM_REQUEST *er, uchar *buf, int32_t l) { int32_t i; struct s_serial_client *serialdata = cur_client()->serialdata; if (l<16) { cs_log(incomplete, l); return(1); } switch(serialdata->connected) { case P_HSIC: er->ecmlen = l-12; er->caid = b2i(2, buf+1 ); er->prid = b2i(3, buf+3 ); er->pid = b2i(2, buf+6 ); er->srvid= b2i(2, buf+10); memcpy(er->ecm, buf+12, er->ecmlen); break; case P_SSSP: er->pid=b2i(2, buf+3); for (i=0; (i<8) && (serialdata->sssp_tab[i].pid!=er->pid); i++); if (i>=serialdata->sssp_num) { cs_debug_mask(D_CLIENT, "illegal request, unknown pid=%04X", er->pid); return(2); } er->ecmlen = l-5; er->srvid= serialdata->sssp_srvid; er->caid = serialdata->sssp_tab[i].caid; er->prid = serialdata->sssp_tab[i].prid; memcpy(er->ecm, buf+5, er->ecmlen); break; case P_BOMBA: er->ecmlen = l; memcpy(er->ecm, buf, er->ecmlen); break; case P_DSR95: buf[l]='\0'; // prepare for trim trim((char *)buf+13); // strip spc, nl, cr ... er->ecmlen = strlen((char *)buf+13)>>1; er->prid=cs_atoi((char *)buf+3, 3, 0); // ignore errors er->caid=cs_atoi((char *)buf+9, 2, 0); // ignore errors if (cs_atob(er->ecm, (char *)buf+13, er->ecmlen)<0) { cs_log("illegal characters in ecm-request"); return(1); } if( serialdata->dsr9500type==P_DSR_WITHSID ) { er->ecmlen -= 2; er->srvid=cs_atoi((char *)buf+13+(er->ecmlen << 1), 2, 0); } break; case P_GS: er->ecmlen = ((buf[3]<<8)|buf[2]) - 6; er->srvid = (buf[5]<<8)|buf[4]; // sid er->caid = (buf[7]<<8)|buf[6]; er->prid = 0; if (er->ecmlen > 256) er->ecmlen = 256; memcpy(er->ecm, buf+10, er->ecmlen); break; case P_ALPHA: l=oscam_ser_alpha_convert(buf, l); er->ecmlen= b2i(2, buf+1 )-2; er->caid = b2i(2, buf+3 ); if ((er->ecmlen!=l-5) || (er->ecmlen>257)) { cs_log(incomplete, l); return(1); } memcpy(er->ecm, buf+5, er->ecmlen); break; case P_GBOX: er->srvid = b2i(2, buf+serialdata->gbox_lens.cat_len+3+3); er->ecmlen = serialdata->gbox_lens.ecm_len+3; memcpy(er->ecm, buf+serialdata->gbox_lens.cat_len+3+serialdata->gbox_lens.pmt_len+3, er->ecmlen); break; } return(0); }
static int32_t oscam_ser_recv(struct s_client *client, uchar *xbuf, int32_t l) { int32_t s, p, n, r; uchar job=IS_BAD; static uchar lb; static int32_t have_lb=0; uchar *buf=xbuf+1; struct s_serial_client *serialdata=client->serialdata; if (!client->pfd) return(-1); cs_ftime(&serialdata->tps); serialdata->tpe=serialdata->tps; serialdata->tpe.millitm+=serialdata->oscam_ser_timeout; serialdata->tpe.time+=(serialdata->tpe.millitm/1000); serialdata->tpe.millitm%=1000; buf[0]=lb; for (s=p=r=0, n=have_lb; (s<4) && (p>=0); s++) { switch(s) { case 0: // STAGE 0: skip known garbage from DSR9500 if (oscam_ser_selrec(buf, 2-n, l, &n)) { if ((buf[0]==0x0A) && (buf[1]==0x0D)) p=(-4); if ((buf[0]==0x0D) && (buf[1]==0x0A)) p=(-4); } else p=(-3); have_lb=0; break; case 1: // STAGE 1: identify protocol p=(-3); if (oscam_ser_selrec(buf, 1, l, &n)) // now we have 3 bytes in buf { if((buf[0] == 0x04) && (buf[1] == 0x00) && (buf[2] == 0x02)) { //skip unsupported Advanced Serial Sharing Protocol HF 8900 oscam_ser_selrec(buf, 2, l, &n); // get rest 2 bytes to buffor p=(-4); have_lb=0; break; } else { p=(-2); if (client->typ == 'c') // HERE IS SERVER { job=IS_ECM; // assume ECM switch(buf[0]) { case 0x00: if( (buf[1]==0x01)&&(buf[2]==0x00) ) { p=P_GS; job=IS_LGO; serialdata->tpe.time++; } break; case 0x01: if( (buf[1]&0xf0)==0xb0 ) p=P_GBOX; else {p=P_SSSP; job=IS_PMT;} break; // pmt-request case 0x02: p=P_HSIC; break; case 0x03: switch(serialdata->oscam_ser_proto) { case P_SSSP : case P_GS : case P_DSR95 : p=serialdata->oscam_ser_proto; break; case P_AUTO : p=(buf[1]<0x30) ? P_SSSP : P_DSR95; break; // auto for GS is useless !! } break; case 0x04: p=P_DSR95; job=IS_ECHO; serialdata->dsr9500type=P_DSR_GNUSMAS; break; case 0x7E: p=P_ALPHA; if (buf[1]!=0x80) job=IS_BAD; break; case 0x80: case 0x81: p=P_BOMBA; break; } } else // HERE IS CLIENT { job=IS_DCW; // assume DCW switch(serialdata->oscam_ser_proto) { case P_HSIC : if ((buf[0]==4) && (buf[1]==4)) p=P_HSIC; break; case P_BOMBA: p=P_BOMBA; break; case P_DSR95: if (buf[0]==4) p=P_DSR95; break; case P_ALPHA: if (buf[0]==0x88) p=P_ALPHA; break; } } if ((serialdata->oscam_ser_proto!=p) && (serialdata->oscam_ser_proto!=P_AUTO)) p=(-2); } } break; case 2: // STAGE 2: examine length if (client->typ == 'c') switch(p) { case P_SSSP : r=(buf[1]<<8)|buf[2]; break; case P_BOMBA : r=buf[2]; break; case P_HSIC : if (oscam_ser_selrec(buf, 12, l, &n)) r=buf[14]; else p=(-1); break; case P_DSR95 : if( job==IS_ECHO ) { r=17*serialdata->samsung_dcw-3+serialdata->samsung_0a; serialdata->samsung_dcw=serialdata->samsung_0a=0; } else { if (oscam_ser_selrec(buf, 16, l, &n)) { uchar b; if (cs_atob(&b, (char *)buf+17, 1)<0) p=(-2); else { r=(b<<1); r+=(serialdata->dsr9500type==P_DSR_WITHSID)?4:0; } } else p=(-1); } break; case P_GS : if (job==IS_LGO) r=5; else { if (oscam_ser_selrec(buf, 1, l, &n)) r=(buf[3]<<8)|buf[2]; else p=(-1); } break; case P_ALPHA : r=-0x7F; // char specifying EOT break; case P_GBOX : r=((buf[1]&0xf)<<8) | buf[2]; serialdata->gbox_lens.cat_len = r; break; default : serialdata->dsr9500type=P_DSR_AUTO; } else switch(p) { case P_HSIC : r=(buf[2]==0x3A) ? 20 : 0; break; // 3A=DCW / FC=ECM was wrong case P_BOMBA : r=13; break; case P_DSR95 : r=14; break; case P_ALPHA : r=(buf[1]<<8)|buf[2]; break; // should be 16 always } break; case 3: // STAGE 3: get the rest ... if (r>0) // read r additional bytes { int32_t all = n+r; if( !oscam_ser_selrec(buf, r, l, &n) ) { cs_debug_mask(D_CLIENT, "not all data received, waiting another 50 ms"); serialdata->tpe.millitm+=50; if( !oscam_ser_selrec(buf, all-n, l, &n) ) p=(-1); } // auto detect DSR9500 protocol if( client->typ == 'c' && p==P_DSR95 && serialdata->dsr9500type==P_DSR_AUTO ) { serialdata->tpe.millitm+=20; if( oscam_ser_selrec(buf, 2, l, &n) ) { if( cs_atoi((char *)buf+n-2, 1, 1)==0xFFFFFFFF ) { switch( (buf[n-2]<<8)|buf[n-1] ) { case 0x0A0D : serialdata->dsr9500type=P_DSR_OPEN; break; case 0x0D0A : serialdata->dsr9500type=P_DSR_PIONEER; break; default : serialdata->dsr9500type=P_DSR_UNKNOWN; break; } }else{ if( oscam_ser_selrec(buf, 2, l, &n) ) if( cs_atoi((char *)buf+n-2, 1, 1)==0xFFFFFFFF ) serialdata->dsr9500type=P_DSR_UNKNOWN; else serialdata->dsr9500type=P_DSR_WITHSID; else { serialdata->dsr9500type=P_DSR_UNKNOWN; p=(-1); } } } else serialdata->dsr9500type=P_DSR_GNUSMAS; if( p ) cs_log("detected dsr9500-%s type receiver", dsrproto_txt[serialdata->dsr9500type]); } // gbox if( client->typ == 'c' && p==P_GBOX ) { int32_t j; for( j=0; (j<3) && (p>0); j++) switch( j ) { case 0: // PMT head if( !oscam_ser_selrec(buf, 3, l, &n) ) p=(-1); else if( !(buf[n-3]==0x02 && (buf[n-2]&0xf0)==0xb0) ) p=(-2); break; case 1: // PMT + ECM header serialdata->gbox_lens.pmt_len=((buf[n-2]&0xf)<<8)|buf[n-1]; if( !oscam_ser_selrec(buf, serialdata->gbox_lens.pmt_len+3, l, &n) ) p=(-1); break; case 2: // ECM + ECM PID serialdata->gbox_lens.ecm_len=((buf[n-2]&0xf)<<8)|buf[n-1]; if( !oscam_ser_selrec(buf, serialdata->gbox_lens.ecm_len+4, l, &n) ) p=(-1); } } // gbox } else if (r<0) // read until specified char (-r) { while((buf[n-1]!=(-r)) && (p>0)) if (!oscam_ser_selrec(buf, 1, l, &n)) p=(-1); } break; } } if (p==(-2) || p==(-1)) { oscam_ser_selrec(buf, l-n, l, &n); // flush buffer serialdata->serial_errors++; } cs_ftime(&serialdata->tpe); cs_ddump_mask(D_CLIENT, buf, n, "received %d bytes from %s in %ld msec", n, remote_txt(), 1000*(serialdata->tpe.time-serialdata->tps.time)+serialdata->tpe.millitm-serialdata->tps.millitm); client->last=serialdata->tpe.time; switch(p) { case (-1): if (client->typ == 'c'&&(n>2)&&(buf[0]==2)&&(buf[1]==2)&&(buf[2]==2)) { oscam_ser_disconnect(); cs_log("humax powered on"); // this is nice ;) } else { if(client->typ == 'c' && buf[0] == 0x1 && buf[1] == 0x08 && buf[2] == 0x20 && buf[3] == 0x08) { oscam_ser_disconnect(); cs_log("ferguson powered on"); // this is nice to ;) } else cs_log(incomplete, n); } break; case (-2): cs_debug_mask(D_CLIENT, "unknown request or garbage"); break; } xbuf[0]=(uchar) ((job<<4) | p); return((p<0)?0:n+1); }
int csu_dodomainmode(void *source, int cargc, char **cargv) { maildomain *mdp; nick *sender=source; flag_t forceflags, currentflags; char buf1[60]; int carg=2,limdone=0,actlimdone=0; unsigned int newlim=0; unsigned int newactlim=0; if (cargc<1) { chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"domainmode"); return CMD_ERROR; } if (checkdomain(cargv[0])) { chanservstdmessage(sender,QM_INVALIDDOMAIN,cargv[0]); return CMD_ERROR; } if(!(mdp=findorcreatemaildomain(cargv[0]))) { return CMD_ERROR; } if (cargc>1) { /* Save the current modes.. */ strcpy(buf1,getdomainmode(mdp)); /* Pick out the + flags: start from 0 */ forceflags=0; setflags(&forceflags, MDFLAG_ALL, cargv[1], mdflags, REJECT_NONE); currentflags=mdp->flags; setflags(¤tflags, MDFLAG_ALL, cargv[1], mdflags, REJECT_NONE); if ((forceflags & MDFLAG_LIMIT) && (!(forceflags & MDFLAG_ACTLIMIT) || strrchr(cargv[1],'l') < strrchr(cargv[1],'u'))) { if (cargc<=carg) { chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"domainmode"); return CMD_ERROR; } newlim=strtol(cargv[carg++],NULL,10); limdone=1; } if ((forceflags & MDFLAG_LIMIT) && !limdone) { if (cargc<=carg) { chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"domainmode"); return CMD_ERROR; } newlim=strtol(cargv[carg++],NULL,10); limdone=1; } if ((forceflags & MDFLAG_ACTLIMIT) && !actlimdone) { if (cargc<=carg) { chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode"); return CMD_ERROR; } newactlim=strtol(cargv[carg++],NULL,10); actlimdone=1; } /* It parsed OK, so update the structure.. */ mdp->flags=currentflags; if(actlimdone) mdp->actlimit=newactlim; if(!(currentflags & MDFLAG_ACTLIMIT)) mdp->actlimit=0; if(limdone) mdp->limit=newlim; if(!(currentflags & MDFLAG_LIMIT)) mdp->limit=0; if(mdp->ID) { if(mdp->flags) { csdb_updatemaildomain(mdp); } else { csdb_deletemaildomain(mdp); } } else { mdp->ID=++lastdomainID; csdb_createmaildomain(mdp); } chanservstdmessage(sender, QM_DONE); cs_log(sender,"DOMAINMODE %s %s (%s -> %s)",mdp->name->content,cargv[1],buf1,getdomainmode(mdp)); } chanservstdmessage(sender,QM_CURDOMAINMODES,mdp->name->content,getdomainmode(mdp)); return CMD_OK; }
static void cs_master_alarm(void) { cs_log("PANIC: master deadlock!"); fprintf(stderr, "PANIC: master deadlock!"); fflush(stderr); }
static void process_clients(void) { int32_t i, k, j, rc, pfdcount = 0; struct s_client *cl; struct s_reader *rdr; struct pollfd *pfd; struct s_client **cl_list; uint32_t cl_size = 0; char buf[10]; if (pipe(thread_pipe) == -1) { printf("cannot create pipe, errno=%d\n", errno); exit(1); } cl_size = chk_resize_cllist(&pfd, &cl_list, 0, 100); pfd[pfdcount].fd = thread_pipe[0]; pfd[pfdcount].events = POLLIN | POLLPRI | POLLHUP; cl_list[pfdcount] = NULL; while (!exit_oscam) { pfdcount = 1; //connected tcp clients for (cl=first_client->next; cl; cl=cl->next) { if (cl->init_done && !cl->kill && cl->pfd && cl->typ=='c' && !cl->is_udp) { if (cl->pfd && !cl->thread_active) { cl_size = chk_resize_cllist(&pfd, &cl_list, cl_size, pfdcount); cl_list[pfdcount] = cl; pfd[pfdcount].fd = cl->pfd; pfd[pfdcount++].events = POLLIN | POLLPRI | POLLHUP; } } //reader: //TCP: // - TCP socket must be connected // - no active init thread //UDP: // - connection status ignored // - no active init thread rdr = cl->reader; if (rdr && cl->typ=='p' && cl->init_done) { if (cl->pfd && !cl->thread_active && ((rdr->tcp_connected && rdr->ph.type==MOD_CONN_TCP)||(rdr->ph.type==MOD_CONN_UDP))) { cl_size = chk_resize_cllist(&pfd, &cl_list, cl_size, pfdcount); cl_list[pfdcount] = cl; pfd[pfdcount].fd = cl->pfd; pfd[pfdcount++].events = POLLIN | POLLPRI | POLLHUP; } } } //server (new tcp connections or udp messages) for (k = 0; k < CS_MAX_MOD; k++) { struct s_module *module = &modules[k]; if ((module->type & MOD_CONN_NET)) { for (j = 0; j < module->ptab.nports; j++) { if (module->ptab.ports[j].fd) { cl_size = chk_resize_cllist(&pfd, &cl_list, cl_size, pfdcount); cl_list[pfdcount] = NULL; pfd[pfdcount].fd = module->ptab.ports[j].fd; pfd[pfdcount++].events = POLLIN | POLLPRI | POLLHUP; } } } } if (pfdcount >= 1024) cs_log("WARNING: too many users!"); rc = poll(pfd, pfdcount, 5000); if (rc<1) continue; for (i=0; i<pfdcount; i++) { //clients cl = cl_list[i]; if (cl && !is_valid_client(cl)) continue; if (pfd[i].fd == thread_pipe[0] && (pfd[i].revents & (POLLIN | POLLPRI))) { // a thread ended and cl->pfd should be added to pollfd list again (thread_active==0) if(read(thread_pipe[0], buf, sizeof(buf)) == -1){ cs_debug_mask(D_TRACE, "Reading from pipe failed (errno=%d %s)", errno, strerror(errno)); } continue; } //clients // message on an open tcp connection if (cl && cl->init_done && cl->pfd && (cl->typ == 'c' || cl->typ == 'm')) { if (pfd[i].fd == cl->pfd && (pfd[i].revents & (POLLHUP | POLLNVAL))) { //client disconnects kill_thread(cl); continue; } if (pfd[i].fd == cl->pfd && (pfd[i].revents & (POLLIN | POLLPRI))) { add_job(cl, ACTION_CLIENT_TCP, NULL, 0); } } //reader // either an ecm answer, a keepalive or connection closed from a proxy // physical reader ('r') should never send data without request rdr = NULL; struct s_client *cl2 = NULL; if (cl && cl->typ == 'p'){ rdr = cl->reader; if(rdr) cl2 = rdr->client; } if (rdr && cl2 && cl2->init_done) { if (cl2->pfd && pfd[i].fd == cl2->pfd && (pfd[i].revents & (POLLHUP | POLLNVAL))) { //connection to remote proxy was closed //oscam should check for rdr->tcp_connected and reconnect on next ecm request sent to the proxy network_tcp_connection_close(rdr, "closed"); rdr_debug_mask(rdr, D_READER, "connection closed"); } if (cl2->pfd && pfd[i].fd == cl2->pfd && (pfd[i].revents & (POLLIN | POLLPRI))) { add_job(cl2, ACTION_READER_REMOTE, NULL, 0); } } //server sockets // new connection on a tcp listen socket or new message on udp listen socket if (!cl && (pfd[i].revents & (POLLIN | POLLPRI))) { for (k = 0; k < CS_MAX_MOD; k++) { struct s_module *module = &modules[k]; if ((module->type & MOD_CONN_NET)) { for (j = 0; j < module->ptab.nports; j++) { if (module->ptab.ports[j].fd && module->ptab.ports[j].fd == pfd[i].fd) { accept_connection(module, k, j); } } } } } } first_client->last=time((time_t *)0); } free(pfd); free(cl_list); return; }
int32_t main (int32_t argc, char *argv[]) { int32_t i, j; prog_name = argv[0]; if (pthread_key_create(&getclient, NULL)) { fprintf(stderr, "Could not create getclient, exiting..."); exit(1); } void (*mod_def[])(struct s_module *)= { #ifdef MODULE_MONITOR module_monitor, #endif #ifdef MODULE_CAMD33 module_camd33, #endif #ifdef MODULE_CAMD35 module_camd35, #endif #ifdef MODULE_CAMD35_TCP module_camd35_tcp, #endif #ifdef MODULE_NEWCAMD module_newcamd, #endif #ifdef MODULE_CCCAM module_cccam, #endif #ifdef MODULE_PANDORA module_pandora, #endif #ifdef MODULE_GHTTP module_ghttp, #endif #ifdef CS_CACHEEX module_csp, #endif #ifdef MODULE_GBOX module_gbox, #endif #ifdef MODULE_CONSTCW module_constcw, #endif #ifdef MODULE_RADEGAST module_radegast, #endif #ifdef MODULE_SERIAL module_serial, #endif #ifdef HAVE_DVBAPI module_dvbapi, #endif 0 }; void (*cardsystem_def[])(struct s_cardsystem *)= { #ifdef READER_NAGRA reader_nagra, #endif #ifdef READER_IRDETO reader_irdeto, #endif #ifdef READER_CONAX reader_conax, #endif #ifdef READER_CRYPTOWORKS reader_cryptoworks, #endif #ifdef READER_SECA reader_seca, #endif #ifdef READER_VIACCESS reader_viaccess, #endif #ifdef READER_VIDEOGUARD reader_videoguard1, reader_videoguard2, reader_videoguard12, #endif #ifdef READER_DRE reader_dre, #endif #ifdef READER_TONGFANG reader_tongfang, #endif #ifdef READER_BULCRYPT reader_bulcrypt, #endif #ifdef READER_GRIFFIN reader_griffin, #endif #ifdef READER_DGCRYPT reader_dgcrypt, #endif 0 }; void (*cardreader_def[])(struct s_cardreader *)= { #ifdef CARDREADER_DB2COM cardreader_db2com, #endif #if defined(CARDREADER_INTERNAL_AZBOX) cardreader_internal_azbox, #elif defined(CARDREADER_INTERNAL_COOLAPI) cardreader_internal_cool, #elif defined(CARDREADER_INTERNAL_SCI) cardreader_internal_sci, #endif #ifdef CARDREADER_PHOENIX cardreader_mouse, #endif #ifdef CARDREADER_MP35 cardreader_mp35, #endif #ifdef CARDREADER_PCSC cardreader_pcsc, #endif #ifdef CARDREADER_SC8IN1 cardreader_sc8in1, #endif #ifdef CARDREADER_SMARGO cardreader_smargo, #endif #ifdef CARDREADER_SMART cardreader_smartreader, #endif #ifdef CARDREADER_STAPI cardreader_stapi, #endif 0 }; parse_cmdline_params(argc, argv); if (bg && do_daemon(1,0)) { printf("Error starting in background (errno=%d: %s)", errno, strerror(errno)); cs_exit(1); } get_random_bytes_init(); #ifdef WEBIF if (cs_restart_mode) restart_daemon(); #endif memset(&cfg, 0, sizeof(struct s_config)); cfg.max_pending = max_pending; if (cs_confdir[strlen(cs_confdir) - 1] != '/') strcat(cs_confdir, "/"); init_signal_pre(); // because log could cause SIGPIPE errors, init a signal handler first init_first_client(); cs_lock_create(&system_lock, 5, "system_lock"); cs_lock_create(&config_lock, 10, "config_lock"); cs_lock_create(&gethostbyname_lock, 10, "gethostbyname_lock"); cs_lock_create(&clientlist_lock, 5, "clientlist_lock"); cs_lock_create(&readerlist_lock, 5, "readerlist_lock"); cs_lock_create(&fakeuser_lock, 5, "fakeuser_lock"); cs_lock_create(&ecmcache_lock, 5, "ecmcache_lock"); cs_lock_create(&readdir_lock, 5, "readdir_lock"); cs_lock_create(&cwcycle_lock, 5, "cwcycle_lock"); cs_lock_create(&hitcache_lock, 5, "hitcache_lock"); coolapi_open_all(); init_config(); cs_init_log(); if (!oscam_pidfile && cfg.pidfile) oscam_pidfile = cfg.pidfile; if (!oscam_pidfile) { oscam_pidfile = get_tmp_dir_filename(default_pidfile, sizeof(default_pidfile), "oscam.pid"); } if (oscam_pidfile) pidfile_create(oscam_pidfile); cs_init_statistics(); init_check(); init_stat(); // These initializations *MUST* be called after init_config() // because modules depend on config values. for (i=0; mod_def[i]; i++) { struct s_module *module = &modules[i]; mod_def[i](module); } for (i=0; cardsystem_def[i]; i++) { memset(&cardsystems[i], 0, sizeof(struct s_cardsystem)); cardsystem_def[i](&cardsystems[i]); } for (i=0; cardreader_def[i]; i++) { memset(&cardreaders[i], 0, sizeof(struct s_cardreader)); cardreader_def[i](&cardreaders[i]); } init_sidtab(); init_readerdb(); cfg.account = init_userdb(); init_signal(); init_srvid(); init_tierid(); init_provid(); start_garbage_collector(gbdb); cacheex_init(); init_len4caid(); init_irdeto_guess_tab(); write_versionfile(false); led_init(); led_status_default(); azbox_init(); mca_init(); global_whitelist_read(); cacheex_load_config_file(); for (i = 0; i < CS_MAX_MOD; i++) { struct s_module *module = &modules[i]; if ((module->type & MOD_CONN_NET)) { for (j = 0; j < module->ptab.nports; j++) { start_listener(module, &module->ptab.ports[j]); } } } //set time for server to now to avoid 0 in monitor/webif first_client->last=time((time_t *)0); webif_init(); start_thread((void *) &reader_check, "reader check"); cw_process_thread_start(); lcd_thread_start(); do_report_emm_support(); init_cardreader(); cs_waitforcardinit(); led_status_starting(); ac_init(); for (i = 0; i < CS_MAX_MOD; i++) { struct s_module *module = &modules[i]; if ((module->type & MOD_CONN_SERIAL) && module->s_handler) module->s_handler(NULL, NULL, i); } // main loop function process_clients(); cw_process_thread_wakeup(); // Stop cw_process thread pthread_cond_signal(&reader_check_sleep_cond); // Stop reader_check thread // Cleanup webif_close(); azbox_close(); coolapi_close_all(); mca_close(); led_status_stopping(); led_stop(); lcd_thread_stop(); remove_versionfile(); stat_finish(); cccam_done_share(); kill_all_clients(); kill_all_readers(); if (oscam_pidfile) unlink(oscam_pidfile); webif_tpls_free(); init_free_userdb(cfg.account); cfg.account = NULL; init_free_sidtab(); free_readerdb(); free_irdeto_guess_tab(); config_free(); cs_log("cardserver down"); log_free(); stop_garbage_collector(); free(first_client->account); free(first_client); // This prevents the compiler from removing config_mak from the final binary syslog_ident = config_mak; return exit_oscam; }
int32_t stapi_open(void) { uint32_t ErrorCode; DIR *dirp; struct dirent entry, *dp = NULL; struct stat buf; int32_t i; char pfad[80]; stapi_on=1; int32_t stapi_priority=0; dirp = opendir(PROCDIR); if (!dirp) { cs_log("opendir failed (errno=%d %s)", errno, strerror(errno)); return 0; } memset(dev_list, 0, sizeof(struct STDEVICE)*PTINUM); if (dvbapi_priority) { struct s_dvbapi_priority *p; for (p=dvbapi_priority; p != NULL; p=p->next) { if (p->type=='s') { stapi_priority=1; break; } } } if (!stapi_priority) { cs_log("WARNING: no PTI devices defined, stapi disabled"); return 0; } oscam_stapi_CheckVersion(); i=0; while (!cs_readdir_r(dirp, &entry, &dp)) { if (!dp) break; snprintf(pfad, sizeof(pfad), "%s%s", PROCDIR, dp->d_name); if (stat(pfad,&buf) != 0) continue; if (!(buf.st_mode & S_IFDIR && strncmp(dp->d_name, ".", 1)!=0)) continue; int32_t do_open=0; struct s_dvbapi_priority *p; for (p=dvbapi_priority; p != NULL; p=p->next) { if (p->type!='s') continue; if(strcmp(dp->d_name, p->devname)==0) { do_open=1; break; } } if (!do_open) { cs_log("PTI: %s skipped", dp->d_name); continue; } ErrorCode= oscam_stapi_Open(dp->d_name, &dev_list[i].SessionHandle); if (ErrorCode != 0) { cs_log("STPTI_Open ErrorCode: %d", ErrorCode); continue; } //debug //oscam_stapi_Capability(dp->d_name); cs_strncpy(dev_list[i].name,dp->d_name, sizeof(dev_list[i].name)); cs_log("PTI: %s open %d", dp->d_name, i); ErrorCode = oscam_stapi_SignalAllocate(dev_list[i].SessionHandle, &dev_list[i].SignalHandle); if (ErrorCode != 0) cs_log("SignalAllocate: ErrorCode: %d SignalHandle: %x", ErrorCode, dev_list[i].SignalHandle); i++; if (i>=PTINUM) break; } closedir(dirp); if (i==0) return 0; pthread_mutex_init(&filter_lock, NULL); for (i=0;i<PTINUM;i++) { if (dev_list[i].SessionHandle==0) continue; struct read_thread_param *para; if (!cs_malloc(¶, sizeof(struct read_thread_param))) return 0; para->id=i; para->cli=cur_client(); int32_t ret = pthread_create(&dev_list[i].thread, NULL, stapi_read_thread, (void *)para); if(ret){ cs_log("ERROR: can't create stapi read thread (errno=%d %s)", ret, strerror(ret)); return 0; } else pthread_detach(dev_list[i].thread); } atexit(stapi_off); cs_log("liboscam_stapi v.%s initialized", oscam_stapi_LibVersion()); return 1; }
void log_emm_request(struct s_reader *rdr){ cs_log("%s emm-request sent (reader=%s, caid=%04X, auprovid=%06X)", username(cur_client()), rdr->label, rdr->caid, rdr->auprovid ? rdr->auprovid : b2i(4, rdr->prid[0])); }
static int32_t camd35_recv(uint8_t *buf, int32_t rs) { int32_t rc, s, n = 0, buflen = 0; for(rc = s = 0; !rc; s++) { switch(s) { case 0: if(rs < 36) { rc = -1; goto out; } break; case 1: switch(camd35_auth_client(buf)) { case 0: break; // ok case 1: rc = -2; break; // unknown user default: rc = -9; break; // error's from cs_auth() } memmove(buf, buf + 4, rs -= 4); break; case 2: aes_decrypt(&cl_aes_keys, buf, rs); if(rs != boundary(4, rs)) { cs_log_dbg(0, "WARNING: packet size has wrong decryption boundary"); } n = (buf[0] == 3) ? 0x34 : 0; //Fix for ECM request size > 255 (use ecm length field) if(buf[0] == 0) { buflen = (((buf[21] & 0x0f) << 8) | buf[22]) + 3; } else if(buf[0] == 0x3d || buf[0] == 0x3e || buf[0] == 0x3f) //cacheex-push { buflen = buf[1] | (buf[2] << 8); } else { buflen = buf[1]; } n = boundary(4, n + 20 + buflen); cs_log_dbg(0, "received %d bytes from client", rs); if(n < rs) { cs_log_dbg(0, "ignoring %d bytes of garbage", rs - n); } else if(n > rs) { rc = -3; } break; case 3: if(crc32(0, buf + 20, buflen) != b2i(4, buf + 4)) { rc = -4; cs_log_dump_dbg(buf, rs, "camd35 checksum failed for packet: "); cs_log_dbg(0, "checksum: %X", b2i(4, buf+4)); } if(!rc) { rc = n; } break; } } out: if((rs > 0) && ((rc == -1) || (rc == -2))) { cs_log_dbg(0, "received %d bytes from client (native)", rs); } switch(rc) { case -1: cs_log("packet is too small (received %d bytes, expected at least 36 bytes)", rs); break; case -2: cs_log("unknown user"); break; case -3: cs_log("incomplete request !"); break; case -4: cs_log("checksum error (wrong password ?)"); break; } return (rc); }
void *work_thread(void *ptr) { struct job_data *data = (struct job_data *)ptr; struct s_client *cl = data->cl; struct s_reader *reader = cl->reader; struct timeb start, end; // start time poll, end time poll struct job_data tmp_data; struct pollfd pfd[1]; pthread_setspecific(getclient, cl); cl->thread = pthread_self(); cl->thread_active = 1; set_work_thread_name(data); struct s_module *module = get_module(cl); uint16_t bufsize = module->bufsize; //CCCam needs more than 1024bytes! if(!bufsize) { bufsize = 1024; } uint8_t *mbuf; if(!cs_malloc(&mbuf, bufsize)) { return NULL; } cl->work_mbuf = mbuf; // Track locally allocated data, because some callback may call cs_exit/cs_disconect_client/pthread_exit and then mbuf would be leaked int32_t n = 0, rc = 0, i, idx, s; uint8_t dcw[16]; int8_t restart_reader = 0; while(cl->thread_active) { cs_ftime(&start); // register start time while(cl->thread_active) { if(!cl || cl->kill || !is_valid_client(cl)) { pthread_mutex_lock(&cl->thread_lock); cl->thread_active = 0; pthread_mutex_unlock(&cl->thread_lock); cs_debug_mask(D_TRACE, "ending thread (kill)"); __free_job_data(cl, data); cl->work_mbuf = NULL; // Prevent free_client from freeing mbuf (->work_mbuf) free_client(cl); if(restart_reader) { restart_cardreader(reader, 0); } NULLFREE(mbuf); pthread_exit(NULL); return NULL; } if(data && data->action != ACTION_READER_CHECK_HEALTH) { cs_debug_mask(D_TRACE, "data from add_job action=%d client %c %s", data->action, cl->typ, username(cl)); } if(!data) { if(!cl->kill && cl->typ != 'r') { client_check_status(cl); } // do not call for physical readers as this might cause an endless job loop pthread_mutex_lock(&cl->thread_lock); if(cl->joblist && ll_count(cl->joblist) > 0) { LL_ITER itr = ll_iter_create(cl->joblist); data = ll_iter_next_remove(&itr); if(data) { set_work_thread_name(data); } //cs_debug_mask(D_TRACE, "start next job from list action=%d", data->action); } pthread_mutex_unlock(&cl->thread_lock); } if(!data) { /* for serial client cl->pfd is file descriptor for serial port not socket for example: pfd=open("/dev/ttyUSB0"); */ if(!cl->pfd || module->listenertype == LIS_SERIAL) { break; } pfd[0].fd = cl->pfd; pfd[0].events = POLLIN | POLLPRI; pthread_mutex_lock(&cl->thread_lock); cl->thread_active = 2; pthread_mutex_unlock(&cl->thread_lock); rc = poll(pfd, 1, 3000); pthread_mutex_lock(&cl->thread_lock); cl->thread_active = 1; pthread_mutex_unlock(&cl->thread_lock); if(rc > 0) { cs_ftime(&end); // register end time cs_debug_mask(D_TRACE, "[OSCAM-WORK] new event %d occurred on fd %d after %"PRId64" ms inactivity", pfd[0].revents, pfd[0].fd, comp_timeb(&end, &start)); data = &tmp_data; data->ptr = NULL; cs_ftime(&start); // register start time for new poll next run if(reader) { data->action = ACTION_READER_REMOTE; } else { if(cl->is_udp) { data->action = ACTION_CLIENT_UDP; data->ptr = mbuf; data->len = bufsize; } else { data->action = ACTION_CLIENT_TCP; } if(pfd[0].revents & (POLLHUP | POLLNVAL | POLLERR)) { cl->kill = 1; } } } } if(!data) { continue; } if(!reader && data->action < ACTION_CLIENT_FIRST) { __free_job_data(cl, data); break; } if(!data->action) { break; } struct timeb actualtime; cs_ftime(&actualtime); int32_t gone = comp_timeb(&actualtime, &data->time); if(data != &tmp_data && gone > (int) cfg.ctimeout+1000) { cs_debug_mask(D_TRACE, "dropping client data for %s time %dms", username(cl), gone); __free_job_data(cl, data); continue; } if(data != &tmp_data) { cl->work_job_data = data; } // Track the current job_data switch(data->action) { case ACTION_READER_IDLE: reader_do_idle(reader); break; case ACTION_READER_REMOTE: s = check_fd_for_data(cl->pfd); if(s == 0) // no data, another thread already read from fd? { break; } if(s < 0) { if(reader->ph.type == MOD_CONN_TCP) { network_tcp_connection_close(reader, "disconnect"); } break; } rc = reader->ph.recv(cl, mbuf, bufsize); if(rc < 0) { if(reader->ph.type == MOD_CONN_TCP) { network_tcp_connection_close(reader, "disconnect on receive"); } break; } cl->last = time(NULL); // *********************************** TO BE REPLACE BY CS_FTIME() LATER **************** idx = reader->ph.c_recv_chk(cl, dcw, &rc, mbuf, rc); if(idx < 0) { break; } // no dcw received if(!idx) { idx = cl->last_idx; } reader->last_g = time(NULL); // *********************************** TO BE REPLACE BY CS_FTIME() LATER **************** // for reconnect timeout for(i = 0, n = 0; i < cfg.max_pending && n == 0; i++) { if(cl->ecmtask[i].idx == idx) { cl->pending--; casc_check_dcw(reader, i, rc, dcw); n++; } } break; case ACTION_READER_RESET: cardreader_do_reset(reader); break; case ACTION_READER_ECM_REQUEST: reader_get_ecm(reader, data->ptr); break; case ACTION_READER_EMM: reader_do_emm(reader, data->ptr); break; case ACTION_READER_CARDINFO: reader_do_card_info(reader); break; case ACTION_READER_INIT: if(!cl->init_done) { reader_init(reader); } break; case ACTION_READER_RESTART: cl->kill = 1; restart_reader = 1; break; case ACTION_READER_RESET_FAST: reader->card_status = CARD_NEED_INIT; cardreader_do_reset(reader); break; case ACTION_READER_CHECK_HEALTH: cardreader_do_checkhealth(reader); break; case ACTION_READER_CAPMT_NOTIFY: if(reader->ph.c_capmt) { reader->ph.c_capmt(cl, data->ptr); } break; case ACTION_CLIENT_UDP: n = module->recv(cl, data->ptr, data->len); if(n < 0) { break; } module->s_handler(cl, data->ptr, n); break; case ACTION_CLIENT_TCP: s = check_fd_for_data(cl->pfd); if(s == 0) // no data, another thread already read from fd? { break; } if(s < 0) // system error or fd wants to be closed { cl->kill = 1; // kill client on next run continue; } n = module->recv(cl, mbuf, bufsize); if(n < 0) { cl->kill = 1; // kill client on next run continue; } module->s_handler(cl, mbuf, n); break; case ACTION_CACHEEX_TIMEOUT: #ifdef CS_CACHEEX cacheex_timeout(data->ptr); #endif break; case ACTION_FALLBACK_TIMEOUT: fallback_timeout(data->ptr); break; case ACTION_CLIENT_TIMEOUT: ecm_timeout(data->ptr); break; case ACTION_ECM_ANSWER_READER: chk_dcw(data->ptr); break; case ACTION_ECM_ANSWER_CACHE: write_ecm_answer_fromcache(data->ptr); break; case ACTION_CLIENT_INIT: if(module->s_init) { module->s_init(cl); } cl->is_udp = module->type == MOD_CONN_UDP; cl->init_done = 1; break; case ACTION_CLIENT_IDLE: if(module->s_idle) { module->s_idle(cl); } else { cs_log("user %s reached %d sec idle limit.", username(cl), cfg.cmaxidle); cl->kill = 1; } break; case ACTION_CACHE_PUSH_OUT: { #ifdef CS_CACHEEX ECM_REQUEST *er = data->ptr; int32_t res = 0, stats = -1; // cc-nodeid-list-check if(reader) { if(reader->ph.c_cache_push_chk && !reader->ph.c_cache_push_chk(cl, er)) { break; } res = reader->ph.c_cache_push(cl, er); stats = cacheex_add_stats(cl, er->caid, er->srvid, er->prid, 0); } else { if(module->c_cache_push_chk && !module->c_cache_push_chk(cl, er)) { break; } res = module->c_cache_push(cl, er); } debug_ecm(D_CACHEEX, "pushed ECM %s to %s res %d stats %d", buf, username(cl), res, stats); cl->cwcacheexpush++; if(cl->account) { cl->account->cwcacheexpush++; } first_client->cwcacheexpush++; #endif break; } case ACTION_CLIENT_KILL: cl->kill = 1; break; case ACTION_CLIENT_SEND_MSG: { #ifdef MODULE_CCCAM struct s_clientmsg *clientmsg = (struct s_clientmsg *)data->ptr; cc_cmd_send(cl, clientmsg->msg, clientmsg->len, clientmsg->cmd); #endif break; } } // switch __free_job_data(cl, data); } if(thread_pipe[1] && (mbuf[0] != 0x00)) { cs_ddump_mask(D_TRACE, mbuf, 1, "[OSCAM-WORK] Write to pipe:"); if(write(thread_pipe[1], mbuf, 1) == -1) // wakeup client check { cs_debug_mask(D_TRACE, "[OSCAM-WORK] Writing to pipe failed (errno=%d %s)", errno, strerror(errno)); } } // Check for some race condition where while we ended, another thread added a job pthread_mutex_lock(&cl->thread_lock); if(cl->joblist && ll_count(cl->joblist) > 0) { pthread_mutex_unlock(&cl->thread_lock); continue; } else { cl->thread_active = 0; pthread_mutex_unlock(&cl->thread_lock); break; } } cl->thread_active = 0; cl->work_mbuf = NULL; // Prevent free_client from freeing mbuf (->work_mbuf) NULLFREE(mbuf); pthread_exit(NULL); return NULL; }
void *stapi_read_thread(void *sparam) { int32_t dev_index, ErrorCode, i, j, CRCValid; uint32_t QueryBufferHandle = 0, DataSize = 0; uchar buf[BUFFLEN]; struct read_thread_param *para = sparam; dev_index = para->id; pthread_setspecific(getclient, para->cli); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_cleanup_push(stapi_cleanup_thread, (void*) dev_index); int32_t error_count = 0; while (1) { QueryBufferHandle = 0; ErrorCode = oscam_stapi_SignalWaitBuffer(dev_list[dev_index].SignalHandle, &QueryBufferHandle, 1000); switch (ErrorCode) { case 0: // NO_ERROR: break; case 852042: // ERROR_SIGNAL_ABORTED cs_log("Caught abort signal"); pthread_exit(NULL); break; case 11: // ERROR_TIMEOUT: //cs_log("timeout %d", dev_index); //TODO: if pidindex == -1 try next continue; break; default: if (QueryBufferHandle != 0) { cs_log("SignalWaitBuffer error: %d", ErrorCode); oscam_stapi_BufferFlush(QueryBufferHandle); continue; } cs_log("SignalWaitBuffer: index %d ErrorCode: %d - QueryBuffer: %x", dev_index, ErrorCode, QueryBufferHandle); error_count++; if (error_count>10) { cs_log("Too many errors in reader thread %d, quitting.", dev_index); pthread_exit(NULL); } continue; break; } uint32_t NumFilterMatches = 0; int32_t demux_id = 0, filter_num = 0; DataSize = 0; uint32_t k; uint32_t MatchedFilterList[10]; ErrorCode = oscam_stapi_BufferReadSection(QueryBufferHandle, MatchedFilterList, 10, &NumFilterMatches, &CRCValid, buf, BUFFLEN, &DataSize); if (ErrorCode != 0) { cs_log("BufferRead: index: %d ErrorCode: %d", dev_index, ErrorCode); cs_sleepms(1000); continue; } if (DataSize<=0) continue; pthread_mutex_lock(&filter_lock); // don't use cs_lock() here; multiple threads using same s_client struct for(k=0;k<NumFilterMatches;k++) { for (i=0;i<MAX_DEMUX;i++) { for (j=0;j<MAX_FILTER;j++) { if (dev_list[dev_index].demux_fd[i][j].fd == MatchedFilterList[k]) { demux_id=i; filter_num=j; dvbapi_process_input(demux_id, filter_num, buf, DataSize); } } } } pthread_mutex_unlock(&filter_lock); } pthread_cleanup_pop(0); }
int32_t ecm_ratelimit_check(struct s_reader *reader, ECM_REQUEST *er, int32_t reader_mode) // If reader_mode is 1, ECM_REQUEST need to be assigned to reader and slot. // Else just report if a free slot is available. { // No rate limit set if(!reader->ratelimitecm) { return OK; } int32_t foundspace = -1, h, maxslots = MAXECMRATELIMIT; //init slots to oscam global maximums struct ecmrl rl; struct timeb now; rl = get_ratelimit(er); if(rl.ratelimitecm > 0) { cs_debug_mask(D_CLIENT, "ratelimit found for CAID: %04X PROVID: %06X SRVID: %04X CHID: %04X maxecms: %d cycle: %d ms srvidhold: %d ms", rl.caid, rl.provid, rl.srvid, rl.chid, rl.ratelimitecm, rl.ratelimittime, rl.srvidholdtime); } else // nothing found: apply general reader limits { rl.ratelimitecm = reader->ratelimitecm; rl.ratelimittime = reader->ratelimittime; rl.srvidholdtime = reader->srvidholdtime; rl.caid = er->caid; rl.provid = er->prid; rl.chid = er->chid; rl.srvid = er->srvid; cs_debug_mask(D_CLIENT, "ratelimiter apply readerdefault for CAID: %04X PROVID: %06X SRVID: %04X CHID: %04X maxecms: %d cycle: %d ms srvidhold: %d ms", rl.caid, rl.provid, rl.srvid, rl.chid, rl.ratelimitecm, rl.ratelimittime, rl.srvidholdtime); } // Below this line: rate limit functionality. // No cooldown set if(!reader->cooldown[0]) { cs_debug_mask(D_CLIENT, "ratelimiter find a slot for srvid %04X on reader %s", er->srvid, reader->label); foundspace = ecm_ratelimit_findspace(reader, er, rl, reader_mode); if(foundspace < 0) { if(reader_mode) { if(foundspace != -2) { cs_debug_mask(D_CLIENT, "ratelimiter no free slot for srvid %04X on reader %s -> dropping!", er->srvid, reader->label); write_ecm_answer(reader, er, E_NOTFOUND, E2_RATELIMIT, NULL, "Ratelimiter: no slots free!"); } } return ERROR; // not even trowing an error... obvious reason ;) } else //we are within ecmratelimits { if(reader_mode) { // Register new slot //reader->rlecmh[foundspace].srvid=er->srvid; // register srvid reader->rlecmh[foundspace] = rl; // register this srvid ratelimit params cs_ftime(&reader->rlecmh[foundspace].last); // register request time memcpy(reader->rlecmh[foundspace].ecmd5, er->ecmd5, CS_ECMSTORESIZE);// register ecmhash reader->rlecmh[foundspace].kindecm = er->ecm[0]; // register kind of ecm } return OK; } } // Below this line: rate limit functionality with cooldown option. // Cooldown state cycle: // state = 0: Cooldown setup phase. No rate limit set. // If number of ecm request exceed reader->ratelimitecm, cooldownstate goes to 2. // state = 2: Cooldown delay phase. No rate limit set. // If number of ecm request still exceed reader->ratelimitecm at end of cooldown delay phase, // cooldownstate goes to 1 (rate limit phase). // Else return back to setup phase (state 0). // state = 1: Cooldown ratelimit phase. Rate limit set. // If cooldowntime reader->cooldown[1] is elapsed, return to cooldown setup phase (state 0). cs_ftime(&now); int32_t gone = comp_timeb(&now, &reader->cooldowntime); if(reader->cooldownstate == 1) // Cooldown in ratelimit phase { if(gone <= reader->cooldown[1]*1000) // check if cooldowntime is elapsed { maxslots = reader->ratelimitecm; } // use user defined ratelimitecm else // Cooldown time is elapsed { reader->cooldownstate = 0; // set cooldown setup phase reader->cooldowntime.time = -1; // reset cooldowntime maxslots = MAXECMRATELIMIT; //use oscam defined max slots cs_log("Reader: %s ratelimiter returning to setup phase cooling down period of %d seconds is done!", reader->label, reader->cooldown[1]); } } // if cooldownstate == 1 if(reader->cooldownstate == 2 && gone > reader->cooldown[0]*1000) { // Need to check if the otherslots are not exceeding the ratelimit at the moment that // cooldown[0] time was exceeded! // time_t actualtime = reader->cooldowntime + reader->cooldown[0]; maxslots = 0; // maxslots is used as counter for(h = 0; h < MAXECMRATELIMIT; h++) { if(reader->rlecmh[h].last.time == -1) { continue; } // skip empty slots // how many active slots are registered at end of cooldown delay period gone = comp_timeb(&now, &reader->rlecmh[h].last); if(gone <= reader->ratelimittime) { maxslots++; if(maxslots >= reader->ratelimitecm) { break; } // Need to go cooling down phase } } if(maxslots < reader->ratelimitecm) { reader->cooldownstate = 0; // set cooldown setup phase reader->cooldowntime.time = -1; // reset cooldowntime maxslots = MAXECMRATELIMIT; // maxslots is maxslots again cs_log("Reader: %s ratelimiter returning to setup phase after %d seconds cooldowndelay!", reader->label, reader->cooldown[0]); } else { reader->cooldownstate = 1; // Entering ratelimit for cooldown ratelimitseconds cs_ftime(&reader->cooldowntime); // set time to enforce ecmratelimit for defined cooldowntime maxslots = reader->ratelimitecm; // maxslots is maxslots again sort_ecmrl(reader); // keep youngest ecm requests in list + housekeeping cs_log("Reader: %s ratelimiter starting cooling down period of %d seconds!", reader->label, reader->cooldown[1]); } } // if cooldownstate == 2 cs_debug_mask(D_CLIENT, "ratelimiter cooldownphase %d find a slot for srvid %04X on reader %s", reader->cooldownstate, er->srvid, reader->label); foundspace = ecm_ratelimit_findspace(reader, er, rl, reader_mode); if(foundspace < 0) { if(reader_mode) { if(foundspace != -2) { cs_debug_mask(D_CLIENT, "ratelimiter cooldownphase %d no free slot for srvid %04X on reader %s -> dropping!", reader->cooldownstate, er->srvid, reader->label); write_ecm_answer(reader, er, E_NOTFOUND, E2_RATELIMIT, NULL, "Ratelimiter: cooldown no slots free!"); } } return ERROR; // not even trowing an error... obvious reason ;) } else //we are within ecmratelimits { if(reader_mode) { // Register new slot //reader->rlecmh[foundspace].srvid=er->srvid; // register srvid reader->rlecmh[foundspace] = rl; // register this srvid ratelimit params cs_ftime(&reader->rlecmh[foundspace].last); // register request time memcpy(reader->rlecmh[foundspace].ecmd5, er->ecmd5, CS_ECMSTORESIZE);// register ecmhash reader->rlecmh[foundspace].kindecm = er->ecm[0]; // register kind of ecm } } if(reader->cooldownstate == 0 && foundspace >= reader->ratelimitecm) { if(!reader_mode) // No actual ecm request, just check { return OK; } cs_log("Reader: %s ratelimiter cooldown detected overrun ecmratelimit of %d during setup phase!", reader->label, (foundspace - reader->ratelimitecm + 1)); reader->cooldownstate = 2; // Entering cooldowndelay phase cs_ftime(&reader->cooldowntime); // Set cooldowntime to calculate delay cs_debug_mask(D_CLIENT, "ratelimiter cooldowndelaying %d seconds", reader->cooldown[0]); } // Cooldown state housekeeping is done. There is a slot available. if(reader_mode) { // Register new slot //reader->rlecmh[foundspace].srvid=er->srvid; // register srvid reader->rlecmh[foundspace] = rl; // register this srvid ratelimit params cs_ftime(&reader->rlecmh[foundspace].last); // register request time memcpy(reader->rlecmh[foundspace].ecmd5, er->ecmd5, CS_ECMSTORESIZE);// register ecmhash reader->rlecmh[foundspace].kindecm = er->ecm[0]; // register kind of ecm } return OK; }
void cs_exit_oscam(void) { exit_oscam = 1; cs_log("exit oscam requested"); }
void dvbapi_load_channel_cache(void) { if (USE_OPENXCAS) // Why? return; char fname[256]; char line[1024]; FILE *file; struct s_channel_cache *c; get_config_filename(fname, sizeof(fname), "oscam.ccache"); file = fopen(fname, "r"); if(!file) { cs_log("dvbapi channelcache can't read from file %s", fname); return; } int32_t i = 1; int32_t valid = 0; char *ptr, *saveptr1 = NULL; char *split[6]; memset(line, 0, sizeof(line)); while(fgets(line, sizeof(line), file)) { if(!line[0] || line[0] == '#' || line[0] == ';') { continue; } for(i = 0, ptr = strtok_r(line, ",", &saveptr1); ptr && i < 6 ; ptr = strtok_r(NULL, ",", &saveptr1), i++) { split[i] = ptr; } valid = (i == 5); if(valid) { if(!cs_malloc(&c, sizeof(struct s_channel_cache))) { continue; } c->caid = a2i(split[0], 4); c->prid = a2i(split[1], 6); c->srvid = a2i(split[2], 4); c->pid = a2i(split[3], 4); c->chid = a2i(split[4], 6); if(valid && c->caid != 0) { if(!channel_cache) { channel_cache = ll_create("channel cache"); } ll_append(channel_cache, c); } else { NULLFREE(c); } } } fclose(file); cs_log("dvbapi channelcache loaded from %s", fname); }
static void write_versionfile(bool use_stdout) { FILE *fp = stdout; if (!use_stdout) { char targetfile[256]; fp = fopen(get_tmp_dir_filename(targetfile, sizeof(targetfile), "oscam.version"), "w"); if (!fp) { cs_log("Cannot open %s (errno=%d %s)", targetfile, errno, strerror(errno)); return; } struct tm st; time_t now = time(NULL); localtime_r(&now, &st); fprintf(fp, "Unix starttime: %ld\n", (long)now); fprintf(fp, "Starttime: %02d.%02d.%04d %02d:%02d:%02d\n", st.tm_mday, st.tm_mon + 1, st.tm_year + 1900, st.tm_hour, st.tm_min, st.tm_sec); } fprintf(fp, "Version: oscam-%s-r%s\n", CS_VERSION, CS_SVN_VERSION); fprintf(fp, "\n"); write_conf(WEBIF, "Web interface support"); write_conf(TOUCH, "Touch interface support"); write_conf(WITH_SSL, "SSL support"); write_conf(HAVE_DVBAPI, "DVB API support"); if (config_enabled(HAVE_DVBAPI)) { write_conf(WITH_AZBOX, "DVB API with AZBOX support"); write_conf(WITH_MCA, "DVB API with MCA support"); write_conf(WITH_COOLAPI, "DVB API with COOLAPI support"); write_conf(WITH_STAPI, "DVB API with STAPI support"); } write_conf(CS_ANTICASC, "Anti-cascading support"); write_conf(IRDETO_GUESSING, "Irdeto guessing"); write_conf(WITH_DEBUG, "Debug mode"); write_conf(MODULE_MONITOR, "Monitor"); write_conf(WITH_LB, "Loadbalancing support"); write_conf(CW_CYCLE_CHECK, "CW Cycle Check support"); write_conf(LCDSUPPORT, "LCD support"); write_conf(LEDSUPPORT, "LED support"); write_conf(IPV6SUPPORT, "IPv6 support"); write_conf(CS_CACHEEX, "Cache exchange support"); fprintf(fp, "\n"); write_conf(MODULE_CAMD33, "camd 3.3x"); write_conf(MODULE_CAMD35, "camd 3.5 UDP"); write_conf(MODULE_CAMD35_TCP, "camd 3.5 TCP"); write_conf(MODULE_NEWCAMD, "newcamd"); write_conf(MODULE_CCCAM, "CCcam"); write_conf(MODULE_CCCSHARE, "CCcam share"); write_conf(MODULE_PANDORA, "Pandora"); write_conf(MODULE_GHTTP, "ghttp"); write_conf(MODULE_GBOX, "gbox"); write_conf(MODULE_RADEGAST, "radegast"); write_conf(MODULE_SERIAL, "serial"); write_conf(MODULE_CONSTCW, "constant CW"); fprintf(fp, "\n"); write_conf(WITH_CARDREADER, "Reader support"); if (config_enabled(WITH_CARDREADER)) { fprintf(fp, "\n"); write_readerconf(READER_NAGRA, "Nagra"); write_readerconf(READER_IRDETO, "Irdeto"); write_readerconf(READER_CONAX, "Conax"); write_readerconf(READER_CRYPTOWORKS, "Cryptoworks"); write_readerconf(READER_SECA, "Seca"); write_readerconf(READER_VIACCESS, "Viaccess"); write_readerconf(READER_VIDEOGUARD, "NDS Videoguard"); write_readerconf(READER_DRE, "DRE Crypt"); write_readerconf(READER_TONGFANG, "TONGFANG"); write_readerconf(READER_BULCRYPT, "Bulcrypt"); write_readerconf(READER_GRIFFIN, "Griffin"); write_readerconf(READER_DGCRYPT, "DGCrypt"); fprintf(fp, "\n"); write_cardreaderconf(CARDREADER_PHOENIX, "phoenix"); write_cardreaderconf(CARDREADER_INTERNAL_AZBOX, "internal_azbox"); write_cardreaderconf(CARDREADER_INTERNAL_COOLAPI, "internal_coolapi"); write_cardreaderconf(CARDREADER_INTERNAL_SCI, "internal_sci"); write_cardreaderconf(CARDREADER_SC8IN1, "sc8in1"); write_cardreaderconf(CARDREADER_MP35, "mp35"); write_cardreaderconf(CARDREADER_SMARGO, "smargo"); write_cardreaderconf(CARDREADER_PCSC, "pcsc"); write_cardreaderconf(CARDREADER_SMART, "smartreader"); write_cardreaderconf(CARDREADER_DB2COM, "db2com"); write_cardreaderconf(CARDREADER_STAPI, "stapi"); } else { write_readerconf(WITH_CARDREADER, "Reader Support"); } if (!use_stdout) fclose(fp); }
static void refresh_lcd_file(void) { char targetfile[256]; char tmpfile[256]; char channame[32]; if(cfg.lcd_output_path == NULL){ snprintf(targetfile, sizeof(targetfile),"%s%s", get_tmp_dir(), "/oscam.lcd"); snprintf(tmpfile, sizeof(tmpfile), "%s%s.tmp", get_tmp_dir(), "/oscam.lcd"); } else { snprintf(targetfile, sizeof(targetfile),"%s%s", cfg.lcd_output_path, "/oscam.lcd"); snprintf(tmpfile, sizeof(tmpfile), "%s%s.tmp", cfg.lcd_output_path, "/oscam.lcd"); } int8_t iscccam = 0; int32_t seconds = 0, secs = 0, fullmins = 0, mins = 0, fullhours = 0, hours = 0, days = 0; time_t now = time((time_t*)0); while(running) { now = time((time_t*)0); int16_t cnt = 0, idx = 0, count_r = 0, count_p = 0, count_u = 0; FILE *fpsave; if((fpsave = fopen(tmpfile, "w"))){ idx = 0; int16_t i; char *type; char *label; char *status; // Statuslines start secs = 0; fullmins = 0; mins = 0; fullhours = 0; hours = 0; days = 0; seconds = now - first_client->login; secs = seconds % 60; if (seconds > 60) { fullmins = seconds / 60; mins = fullmins % 60; if(fullmins > 60) { fullhours = fullmins / 60; hours = fullhours % 24; days = fullhours / 24; } } fprintf(fpsave,"Version: %s\n", CS_VERSION); fprintf(fpsave,"Revision: %s\n", CS_SVN_VERSION); if(days == 0) fprintf(fpsave, "up: %02d:%02d:%02d\n", hours, mins, secs); else fprintf(fpsave, "up: %02dd %02d:%02d:%02d\n", days, hours, mins, secs); fprintf(fpsave,"totals: %d/%d/%d/%d/%d/%d\n", first_client->cwfound, first_client->cwnot, first_client->cwignored, first_client->cwtout, first_client->cwcache, first_client->cwtun); fprintf(fpsave,"uptime: %d\n", seconds); // Statuslines end // Readertable head fprintf(fpsave,"Typ| Label | Idle | w | s | b | e | St\n"); fprintf(fpsave,"---+------------+--------------+---+---+---+---+----\n"); struct s_client *cl; // Reader/Proxy table start for ( i=0, cl=first_client; cl ; cl=cl->next, i++) { if ((cl->typ=='r' || cl->typ=='p') && ((now - cl->last) < 20 || !cfg.lcd_hide_idle)){ type = ""; label = ""; status = "OFF"; secs = 0; fullmins = 0; mins = 0; fullhours = 0; hours = 0; days = 0; seconds = now - cl->last; if (cl->typ == 'r'){ type = "R"; idx = count_r; label = cl->reader->label; if (cl->reader->card_status == CARD_INSERTED) status = "OK"; count_r++; } else if (cl->typ == 'p'){ type = "P"; iscccam = 0; idx = count_p; label = cl->reader->label; if ((strncmp(monitor_get_proto(cl), "cccam", 5) == 0)) iscccam = 1; if (cl->reader->card_status == CARD_INSERTED) status = "CON"; count_p++; } secs = seconds % 60; if (seconds > 60) { fullmins = seconds / 60; mins = fullmins % 60; if(fullmins > 60) { fullhours = fullmins / 60; hours = fullhours % 24; days = fullhours / 24; } } int16_t written = 0, skipped = 0, blocked = 0, error = 0; char *emmtext; if(cs_malloc(&emmtext, 16 * sizeof(char), -1)){ if(cl->typ == 'r' || !iscccam ){ for (i=0; i<4; i++) { error += cl->reader->emmerror[i]; blocked += cl->reader->emmblocked[i]; skipped += cl->reader->emmskipped[i]; written += cl->reader->emmwritten[i]; } snprintf(emmtext, 16, "%3d|%3d|%3d|%3d", written > 999? 999 : written, skipped > 999? 999 : skipped, blocked > 999? 999 : blocked, error > 999? 999 : error); } #ifdef MODULE_CCCAM else if(cl->typ == 'p' && iscccam ){ struct cc_data *rcc = cl->cc; if(rcc){ LLIST *cards = rcc->cards; if (cards) { int32_t cnt = ll_count(cards); int32_t locals = rcc->num_hop1; snprintf(emmtext, 16, " %3d/%3d card%s", locals, cnt, (cnt > 1)? "s ": " "); } } else { snprintf(emmtext, 16, " No cards "); } } #endif else { snprintf(emmtext, 16, " "); } } if(days == 0) { fprintf(fpsave,"%s%d | %-10.10s | %02d:%02d:%02d |%s| %s\n", type, idx, label, hours, mins, secs, emmtext, status); } else { fprintf(fpsave,"%s%d | %-10.10s |% 3dd %02d:%02d:%02d |%s| %s\n", type, idx, label, days, hours, mins, secs, emmtext, status); } free(emmtext); } } fprintf(fpsave,"---+------------+--------------+---+---+---+--++----\n"); // Reader/Proxy table end // Usertable start fprintf(fpsave,"Typ| Label | Channel | Time\n"); fprintf(fpsave,"---+------------+-----------------------------+-----\n"); /* //Testclient fprintf(fpsave,"%s%d | %-10.10s | %-10.10s:%-17.17s| % 4d\n", "U", 1, "test", "Sky De", "Discovery Channel", 568); */ for ( i=0, cl=first_client; cl ; cl=cl->next, i++) { seconds = now - cl->lastecm; if (cl->typ == 'c' && seconds < 15){ type = "U"; idx = count_u; label = cl->account->usr; count_u++; get_servicename(cl, cl->last_srvid, cl->last_caid, channame); fprintf(fpsave,"%s%d | %-10.10s | %-10.10s:%-17.17s| % 4d\n", type, idx, label, cl->last_srvidptr && cl->last_srvidptr->prov ? cl->last_srvidptr->prov : "", cl->last_srvidptr && cl->last_srvidptr->name ? cl->last_srvidptr->name : "", cl->cwlastresptime); } } fprintf(fpsave,"---+------------+-----------------------------+-----\n"); // Usertable end fclose(fpsave); } idx = 0; cs_sleepms(cfg.lcd_write_intervall * 1000); cnt++; if(rename(tmpfile, targetfile) < 0) cs_log("An error occured while writing oscam.lcd file %s.", targetfile); } }
static void cs_sigpipe(void) { if (cs_dblevel & D_ALL_DUMP) cs_log("Got sigpipe signal -> captured"); }
//Format: //caid:prov:srvid:pid:chid:ecmlen=caid:prov:srvid:pid:chid:ecmlen[,validfrom,validto] //validfrom: default=-2000 //validto: default=4000 //valid time if found in cache static struct s_cacheex_matcher *cacheex_matcher_read_int(void) { FILE *fp = open_config_file(cs_cacheex_matcher); if(!fp) { return NULL; } char token[1024]; unsigned char type; int32_t i, ret, count = 0; struct s_cacheex_matcher *new_cacheex_matcher = NULL, *entry, *last = NULL; uint32_t line = 0; while(fgets(token, sizeof(token), fp)) { line++; if(strlen(token) <= 1) { continue; } if(token[0] == '#' || token[0] == '/') { continue; } if(strlen(token) > 100) { continue; } for(i = 0; i < (int)strlen(token); i++) { if((token[i] == ':' || token[i] == ' ') && token[i + 1] == ':') { memmove(token + i + 2, token + i + 1, strlen(token) - i + 1); token[i + 1] = '0'; } if(token[i] == '#' || token[i] == '/') { token[i] = '\0'; break; } } type = 'm'; uint32_t caid = 0, provid = 0, srvid = 0, pid = 0, chid = 0, ecmlen = 0; uint32_t to_caid = 0, to_provid = 0, to_srvid = 0, to_pid = 0, to_chid = 0, to_ecmlen = 0; int32_t valid_from = -2000, valid_to = 4000; ret = sscanf(token, "%c:%4x:%6x:%4x:%4x:%4x:%4X=%4x:%6x:%4x:%4x:%4x:%4X,%4d,%4d", &type, &caid, &provid, &srvid, &pid, &chid, &ecmlen, &to_caid, &to_provid, &to_srvid, &to_pid, &to_chid, &to_ecmlen, &valid_from, &valid_to); type = tolower(type); if(ret < 7 || type != 'm') { continue; } if(!cs_malloc(&entry, sizeof(struct s_cacheex_matcher))) { fclose(fp); return new_cacheex_matcher; } count++; entry->line = line; entry->type = type; entry->caid = caid; entry->provid = provid; entry->srvid = srvid; entry->pid = pid; entry->chid = chid; entry->ecmlen = ecmlen; entry->to_caid = to_caid; entry->to_provid = to_provid; entry->to_srvid = to_srvid; entry->to_pid = to_pid; entry->to_chid = to_chid; entry->to_ecmlen = to_ecmlen; entry->valid_from = valid_from; entry->valid_to = valid_to; cs_debug_mask(D_TRACE, "cacheex-matcher: %c: %04X:%06X:%04X:%04X:%04X:%02X = %04X:%06X:%04X:%04X:%04X:%02X valid %d/%d", entry->type, entry->caid, entry->provid, entry->srvid, entry->pid, entry->chid, entry->ecmlen, entry->to_caid, entry->to_provid, entry->to_srvid, entry->to_pid, entry->to_chid, entry->to_ecmlen, entry->valid_from, entry->valid_to); if(!new_cacheex_matcher) { new_cacheex_matcher = entry; last = new_cacheex_matcher; } else { last->next = entry; last = entry; } } if(count) { cs_log("%d entries read from %s", count, cs_cacheex_matcher); } fclose(fp); return new_cacheex_matcher; }
void cs_restart_oscam(void) { exit_oscam=99; cs_log("restart oscam requested"); }
int csa_donewpw(void *source, int cargc, char **cargv) { reguser *rup; nick *sender=source; unsigned int same=0; time_t t; int pq; if (cargc<3) { chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "newpass"); return CMD_ERROR; } if (!(rup=getreguserfromnick(sender))) return CMD_ERROR; if (!checkpassword(rup, cargv[0])) { chanservstdmessage(sender, QM_AUTHFAIL); cs_log(sender,"NEWPASS FAIL username %s bad password %s",rup->username,cargv[0]); return CMD_ERROR; } if (strcmp(cargv[1],cargv[2])) { chanservstdmessage(sender, QM_PWDONTMATCH); /* Sorry, passwords do not match */ cs_log(sender,"NEWPASS FAIL username %s new passwords don't match (%s vs %s)",rup->username,cargv[1],cargv[2]); return CMD_ERROR; } if (!strcmp(cargv[0],cargv[1])) { /* If they are the same then continue anyway but don't send the hook later. */ same=1; } pq = csa_checkpasswordquality(cargv[1]); if(pq == QM_PWTOSHORT) { chanservstdmessage(sender, QM_PWTOSHORT); /* new password too short */ cs_log(sender,"NEWPASS FAIL username %s password too short %s (%zu characters)",rup->username,cargv[1],strlen(cargv[1])); return CMD_ERROR; } else if(pq == QM_PWTOWEAK) { chanservstdmessage(sender, QM_PWTOWEAK); /* new password is weak */ cs_log(sender,"NEWPASS FAIL username %s password too weak %s",rup->username,cargv[1]); return CMD_ERROR; } else if(pq == QM_PWTOLONG) { chanservstdmessage(sender, QM_PWTOLONG); /* new password too long */ cs_log(sender,"NEWPASS FAIL username %s password too long %s",rup->username,cargv[1]); return CMD_ERROR; } else if(pq == QM_PWINVALID) { chanservstdmessage(sender, QM_PWINVALID); cs_log(sender,"NEWPASS FAIL username %s password invalid %s",rup->username,cargv[1]); return CMD_ERROR; } else if(pq == -1) { /* all good */ } else { chanservsendmessage(sender, "unknown error in newpass.c... contact #help"); return CMD_ERROR; } t=time(NULL); if(!UHasStaffPriv(rup)) { if(rup->lockuntil && rup->lockuntil > t) { chanservstdmessage(sender, QM_ACCOUNTLOCKED, rup->lockuntil); return CMD_ERROR; } rup->lockuntil=t+7*24*3600; } else { rup->lockuntil=0; } if(rup->lastemail) { freesstring(rup->lastemail); rup->lastemail=NULL; } rup->lastpasschange=t; csdb_accounthistory_insert(sender, rup->password, cargv[1], NULL, NULL); setpassword(rup, cargv[1]); rup->lastauth=time(NULL); chanservstdmessage(sender, QM_PWCHANGED); cs_log(sender,"NEWPASS OK username %s", rup->username); #ifdef AUTHGATE_WARNINGS if(UHasOperPriv(rup)) chanservsendmessage(sender, "WARNING FOR PRIVILEGED USERS: you MUST go to https://auth.quakenet.org and login successfully to update the cache, if you do not your old password will still be usable in certain circumstances."); #endif csdb_updateuser(rup); csdb_createmail(rup, QMAIL_NEWPW); if (!same) triggerhook(HOOK_CHANSERV_PWCHANGE, sender); return CMD_OK; }