Exemplo n.º 1
0
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");
	}
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}	
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
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();
		}
	}
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
/************************************************************************************************************************
 *       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);
}
Exemplo n.º 11
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);
}
Exemplo n.º 12
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);
}
Exemplo n.º 13
0
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(&currentflags, 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;
}
Exemplo n.º 14
0
static void cs_master_alarm(void)
{
  cs_log("PANIC: master deadlock!");
  fprintf(stderr, "PANIC: master deadlock!");
  fflush(stderr);
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
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(&para, 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;
}
Exemplo n.º 18
0
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]));
}
Exemplo n.º 19
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);
}
Exemplo n.º 20
0
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;
}
Exemplo n.º 21
0
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);
}
Exemplo n.º 22
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;
}
Exemplo n.º 23
0
void cs_exit_oscam(void) {
	exit_oscam = 1;
	cs_log("exit oscam requested");
}
Exemplo n.º 24
0
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);
}
Exemplo n.º 25
0
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);
}
Exemplo n.º 26
0
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);

	}

}
Exemplo n.º 27
0
static void cs_sigpipe(void)
{
	if (cs_dblevel & D_ALL_DUMP)
		cs_log("Got sigpipe signal -> captured");
}
Exemplo n.º 28
0
//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;
}
Exemplo n.º 29
0
void cs_restart_oscam(void) {
	exit_oscam=99;
	cs_log("restart oscam requested");
}
Exemplo n.º 30
0
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;
}