Ejemplo n.º 1
0
static int32_t cacheex_add_to_cache_int(struct s_client *cl, ECM_REQUEST *er, int8_t csp)
{
	if(er->rc >= E_NOTFOUND) { return 0; }

	if(!cl)
		{ return 0; }
	if(!csp && cl->reader && cl->reader->cacheex.mode != 2)  //from reader
	{
		cs_log_dbg(D_CACHEEX, "CACHEX received, but disabled for %s", username(cl));
		return 0;
	}
	if(!csp && !cl->reader && cl->account && cl->account->cacheex.mode != 3)  //from user
	{
		cs_log_dbg(D_CACHEEX, "CACHEX received, but disabled for %s", username(cl));
		return 0;
	}
	if(!csp && !cl->reader && !cl->account)    //not active!
	{
		cs_log_dbg(D_CACHEEX, "CACHEX received, but invalid client state %s", username(cl));
		return 0;
	}

	uint8_t i, c;
	uint8_t null = 0;
	for(i = 0; i < 16; i += 4)
	{
		c = ((er->cw[i] + er->cw[i + 1] + er->cw[i + 2]) & 0xff);
		null |= (er->cw[i] | er->cw[i + 1] | er->cw[i + 2]);
		if(er->cw[i + 3] != c)
		{
			cs_log_dump_dbg(D_CACHEEX, er->cw, 16, "push received cw with chksum error from %s", csp ? "csp" : username(cl));
			cl->cwcacheexerr++;
			if(cl->account)
				{ cl->account->cwcacheexerr++; }
			return 0;
		}
	}

	if(null == 0 || chk_is_null_CW(er->cw))
	{
		cs_log_dump_dbg(D_CACHEEX, er->cw, 16, "push received null cw from %s", csp ? "csp" : username(cl));
		cl->cwcacheexerr++;
		if(cl->account)
			{ cl->account->cwcacheexerr++; }
		return 0;
	}


	if(get_odd_even(er)==0){
		cs_log_dbg(D_CACHEEX, "push received ecm with null odd/even byte from %s", csp ? "csp" : username(cl));
		cl->cwcacheexerr++;
		if(cl->account)
			{ cl->account->cwcacheexerr++; }
		return 0;
	}


	if(!chk_halfCW(er, er->cw)){
		log_cacheex_cw(er, "bad half cw");

		cl->cwcacheexerr++;
		if(cl->account)
			{ cl->account->cwcacheexerr++; }
		return 0;
	}


	er->grp |= cl->grp;  //ok for mode2 reader too: cl->reader->grp
	er->rc = E_CACHEEX;
	er->cacheex_src = cl;
	er->selected_reader = cl->reader;
	er->client = NULL; //No Owner! So no fallback!

	if(check_client(cl))
	{
		cl->cwcacheexgot++;
		if(cl->account)
			{ cl->account->cwcacheexgot++; }
		first_client->cwcacheexgot++;
	}

	cacheex_add_hitcache(cl, er);  //we have to call it before add_cache, because in chk_process we could remove it!
	add_cache(er);
	cacheex_add_stats(cl, er->caid, er->srvid, er->prid, 1);

	cs_writelock(__func__, &ecm_pushed_deleted_lock);
	er->next = ecm_pushed_deleted;
	ecm_pushed_deleted = er;
	cs_writeunlock(__func__, &ecm_pushed_deleted_lock);

	return 1;  //NO free, we have to wait cache push out stuff ends.
}
Ejemplo n.º 2
0
static void
nfsauth_access(auth_req *argp, auth_res *result)
{
	struct netconfig *nconf;
	struct nd_hostservlist *clnames = NULL;
	struct netbuf nbuf;
	struct share *sh;
	char tmp[MAXIPADDRLEN];
	char *host = NULL;

	result->auth_perm = NFSAUTH_DENIED;

	/*
	 * Convert the client's address to a hostname
	 */
	nconf = getnetconfigent(argp->req_netid);
	if (nconf == NULL) {
		syslog(LOG_ERR, "No netconfig entry for %s", argp->req_netid);
		return;
	}

	nbuf.len = argp->req_client.n_len;
	nbuf.buf = argp->req_client.n_bytes;

	if (netdir_getbyaddr(nconf, &clnames, &nbuf)) {
		host = &tmp[0];
		if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
			struct sockaddr_in *sa;

			/* LINTED pointer alignment */
			sa = (struct sockaddr_in *)nbuf.buf;
			(void) inet_ntoa_r(sa->sin_addr, tmp);
		} else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
			struct sockaddr_in6 *sa;
			/* LINTED pointer */
			sa = (struct sockaddr_in6 *)nbuf.buf;
			(void) inet_ntop(AF_INET6, sa->sin6_addr.s6_addr,
				    tmp, INET6_ADDRSTRLEN);
		}
		clnames = anon_client(host);
	}

	/*
	 * Now find the export
	 */
	sh = findentry(argp->req_path);
	if (sh == NULL) {
		syslog(LOG_ERR, "%s not exported", argp->req_path);
		goto done;
	}

	result->auth_perm = check_client(sh, &nbuf, clnames, argp->req_flavor);

	sharefree(sh);

	if (result->auth_perm == NFSAUTH_DENIED) {
		syslog(LOG_ERR, "%s denied access to %s",
			clnames->h_hostservs[0].h_host, argp->req_path);
	}

done:
	freenetconfigent(nconf);
	if (clnames)
		netdir_free(clnames, ND_HOSTSERVLIST);
}
Ejemplo n.º 3
0
/**
 * cacheex modes:
 *
 * cacheex=1 CACHE PULL:
 * Situation: oscam A reader1 has cacheex=1, oscam B account1 has cacheex=1
 *   oscam A gets a ECM request, reader1 send this request to oscam B, oscam B checks his cache
 *   a. not found in cache: return NOK
 *   a. found in cache: return OK+CW
 *   b. not found in cache, but found pending request: wait max cacheexwaittime and check again
 *   oscam B never requests new ECMs
 *
 *   CW-flow: B->A
 *
 * cacheex=2 CACHE PUSH:
 * Situation: oscam A reader1 has cacheex=2, oscam B account1 has cacheex=2
 *   if oscam B gets a CW, its pushed to oscam A
 *   reader has normal functionality and can request ECMs
 *
 *   Problem: oscam B can only push if oscam A is connected
 *   Problem or feature?: oscam A reader can request ecms from oscam B
 *
 *   CW-flow: B->A
 *
 */
void cacheex_cache_push(ECM_REQUEST *er)
{
	if(er->rc >= E_NOTFOUND) { return; }

	//cacheex=2 mode: push (server->remote)
	struct s_client *cl;
	cs_readlock(__func__, &clientlist_lock);
	for(cl = first_client->next; cl; cl = cl->next)
	{
		if(check_client(cl) && er->cacheex_src != cl)
		{
			if(get_module(cl)->num == R_CSP)    // always send to csp cl
			{
				if(!er->cacheex_src || cfg.csp.allow_reforward) { cacheex_cache_push_to_client(cl, er); }  // but not if the origin was cacheex (might loop)
			}
			else if(cl->typ == 'c' && !cl->dup && cl->account && cl->account->cacheex.mode == 2)      //send cache over user
			{
				if(get_module(cl)->c_cache_push  // cache-push able
						&& (!er->grp || (cl->grp & er->grp)) //Group-check
						/****  OUTGOING FILTER CHECK ***/
						&& (!er->selected_reader || !cacheex_reader(er->selected_reader) || !cfg.block_same_name || strcmp(username(cl), er->selected_reader->label)) //check reader mode-1 loopback by same name
						&& (!er->selected_reader || !cacheex_reader(er->selected_reader) || !cfg.block_same_ip || (check_client(er->selected_reader->client) && !IP_EQUAL(cl->ip, er->selected_reader->client->ip))) //check reader mode-1 loopback by same ip
						&& (!cl->account->cacheex.drop_csp || checkECMD5(er))  //cacheex_drop_csp-check
						&& chk_ctab(er->caid, &cl->ctab)  					 //Caid-check
						&& (!checkECMD5(er) || chk_ident_filter(er->caid, er->prid, &cl->ftab))	 	 //Ident-check (not for csp: prid=0 always!)
						&& chk_srvid(cl, er) //Service-check
						&& chk_csp_ctab(er, &cl->account->cacheex.filter_caidtab) //cacheex_ecm_filter			
				  )
				{
					cacheex_cache_push_to_client(cl, er);
				}
			}
		}
	}
	cs_readunlock(__func__, &clientlist_lock);


	//cacheex=3 mode: reverse push (reader->server)
	cs_readlock(__func__, &readerlist_lock);
	cs_readlock(__func__, &clientlist_lock);
	struct s_reader *rdr;
	for(rdr = first_active_reader; rdr; rdr = rdr->next)
	{
		cl = rdr->client;
		if(check_client(cl) && er->cacheex_src != cl && rdr->cacheex.mode == 3)    //send cache over reader
		{
			if(rdr->ph.c_cache_push     // cache-push able
					&& (!er->grp || (rdr->grp & er->grp)) //Group-check
					/****  OUTGOING FILTER CHECK ***/
					&& (!er->selected_reader || !cacheex_reader(er->selected_reader) || !cfg.block_same_name || strcmp(username(cl), er->selected_reader->label)) //check reader mode-1 loopback by same name
					&& (!er->selected_reader || !cacheex_reader(er->selected_reader) || !cfg.block_same_ip || (check_client(er->selected_reader->client) && !IP_EQUAL(cl->ip, er->selected_reader->client->ip))) //check reader mode-1 loopback by same ip
					&& (!rdr->cacheex.drop_csp || checkECMD5(er))  		 //cacheex_drop_csp-check
					&& chk_ctab(er->caid, &rdr->ctab)  					 //Caid-check
					&& (!checkECMD5(er) || chk_ident_filter(er->caid, er->prid, &rdr->ftab))	 	 //Ident-check (not for csp: prid=0 always!)
					&& chk_srvid(cl, er) //Service-check
					&& chk_csp_ctab(er, &rdr->cacheex.filter_caidtab) //cacheex_ecm_filter					
			  )
			{
				cacheex_cache_push_to_client(cl, er);
			}
		}
	}
	cs_readunlock(__func__, &clientlist_lock);
	cs_readunlock(__func__, &readerlist_lock);
}
Ejemplo n.º 4
0
bool cacheex_is_match_alias(struct s_client *cl, ECM_REQUEST *er)
{
	return check_client(cl) && cl->account && cl->account->cacheex.mode == 1 && is_cacheex_matcher_matching(NULL, er);
}
Ejemplo n.º 5
0
static void *chkcache_process(void)
{
	set_thread_name(__func__);

	time_t timeout;
	struct ecm_request_t *er, *ecm;
	uint8_t add_hitcache_er;
	struct s_reader *cl_rdr;
	struct s_reader *rdr;
	struct s_ecm_answer *ea;
	struct s_client *cex_src=NULL;
	struct s_write_from_cache *wfc=NULL;

	while(cacheex_running)
	{
		cs_readlock(__func__, &ecmcache_lock);
		for(er = ecmcwcache; er; er = er->next)
		{
			timeout = time(NULL)-((cfg.ctimeout+500)/1000+1);
			if(er->tps.time < timeout)
				{ break; }

			if(er->rc<E_UNHANDLED || er->readers_timeout_check)  //already answered
				{ continue; }

			//********  CHECK IF FOUND ECM IN CACHE
			ecm = check_cache(er, er->client);
			if(ecm)     //found in cache
			{
				//check for add_hitcache
				if(ecm->cacheex_src)   //cw from cacheex
				{
					if((er->cacheex_wait_time && !er->cacheex_wait_time_expired) || !er->cacheex_wait_time)   //only when no wait_time expires (or not wait_time)
					{

						//add_hitcache already called, but we check if we have to call it for these (er) caid|prid|srvid
						if(ecm->prid!=er->prid || ecm->srvid!=er->srvid)
						{
							cex_src = ecm->cacheex_src && is_valid_client(ecm->cacheex_src) && !ecm->cacheex_src->kill ?  ecm->cacheex_src : NULL; //here we should be sure cex client has not been freed!
							if(cex_src){  //add_hitcache only if client is really active
								add_hitcache_er=1;
								cl_rdr = cex_src->reader;
								if(cl_rdr && cl_rdr->cacheex.mode == 2)
								{
									for(ea = er->matching_rdr; ea; ea = ea->next)
									{
										rdr = ea->reader;
										if(cl_rdr == rdr && ((ea->status & REQUEST_ANSWERED) == REQUEST_ANSWERED))
										{
											cs_log_dbg(D_CACHEEX|D_CSP|D_LB,"{client %s, caid %04X, prid %06X, srvid %04X} [CACHEEX] skip ADD self request!", (check_client(er->client)?er->client->account->usr:"******"),er->caid, er->prid, er->srvid);
											add_hitcache_er=0; //don't add hit cache, reader requested self
										}
									}
								}

								if(add_hitcache_er)
									{ cacheex_add_hitcache(cex_src, er); }  //USE cacheex client (to get correct group) and ecm from requesting client (to get correct caid|prid|srvid)!!!
							}
						}

					}
					else
					{
						//add_hitcache already called, but we have to remove it because cacheex not coming before wait_time
						if(ecm->prid==er->prid && ecm->srvid==er->srvid)
							{ cacheex_del_hitcache(ecm); }
					}
				}
				//END check for add_hitcache

				if(check_client(er->client))
				{
					wfc=NULL;
					if(!cs_malloc(&wfc, sizeof(struct s_write_from_cache)))
					{
						NULLFREE(ecm);
						continue;
					}

					wfc->er_new=er;
					wfc->er_cache=ecm;

					if(!add_job(er->client, ACTION_ECM_ANSWER_CACHE, wfc, sizeof(struct s_write_from_cache)))   //write_ecm_answer_fromcache
					{
						NULLFREE(ecm);
						continue;
					}
				}
				else
					{ NULLFREE(ecm); }
			}
		}
		cs_readunlock(__func__, &ecmcache_lock);

		cs_sleepms(10);
	}

	return NULL;
}
Ejemplo n.º 6
0
void cacheex_timeout(ECM_REQUEST *er)
{
	if(er->cacheex_wait_time_expired)
		return;
	er->cacheex_wait_time_expired = 1;
	if(er->rc >= E_UNHANDLED)
	{
		cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} cacheex timeout! ", (check_client(er->client) ? er->client->account->usr : "******"), er->caid, er->prid, er->srvid);
		//if check_cw mode=0, first try to get cw from cache without check counter!
		CWCHECK check_cw = get_cwcheck(er);
		if(!check_cw.mode)
		{
			struct ecm_request_t *ecm=NULL;
			ecm = check_cache(er, er->client);
			if(ecm)     //found in cache
			{
				struct s_write_from_cache *wfc=NULL;
				if(!cs_malloc(&wfc, sizeof(struct s_write_from_cache)))
				{
					NULLFREE(ecm);
					return;
				}
				wfc->er_new=er;
				wfc->er_cache=ecm;
				if(!add_job(er->client, ACTION_ECM_ANSWER_CACHE, wfc, sizeof(struct s_write_from_cache)))  //write_ecm_answer_fromcache
					{ NULLFREE(ecm); }
				return;
			}
		}
		//check if "normal" readers selected, if not send NOT FOUND!
		//cacheex1-client (having always no "normal" reader), or not-cacheex-1 client with no normal readers available (or filtered by LB)
		if( (er->reader_count + er->fallback_reader_count - er->cacheex_reader_count) <= 0 )
		{
			if(!cfg.wait_until_ctimeout){
				er->rc = E_NOTFOUND;
				er->selected_reader = NULL;
				er->rcEx = 0;
				cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} cacheex timeout: NO \"normal\" readers... not_found! ", (check_client(er->client) ? er->client->account->usr : "******"), er->caid, er->prid, er->srvid);
				send_dcw(er->client, er);
				return;
			}
		}
		else
		{
			if(er->stage < 2){
				debug_ecm(D_TRACE, "request for %s %s", username(er->client), buf);
				request_cw_from_readers(er, 0);
			}
		}
	}
}
Ejemplo n.º 7
0
void cacheex_mode1_delay(ECM_REQUEST *er)
{
	if(!er->cacheex_wait_time_expired
	   && er->cacheex_mode1_delay
	   && er->cacheex_reader_count > 0
	   && !er->stage
	   && er->rc >= E_UNHANDLED)
	{
		cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} cacheex_mode1_delay timeout! ", (check_client(er->client) ? er->client->account->usr : "******"), er->caid, er->prid, er->srvid);
		request_cw_from_readers(er, 1); // setting stop_stage=1, we request only cacheex mode 1 readers. Others are requested at cacheex timeout!
	}
}
Ejemplo n.º 8
0
static void
scanner_thread (struct arglist *globals)
{
  struct arglist *prefs = arg_get_value (globals, "preferences");
  char asciiaddr[INET6_ADDRSTRLEN], x509_dname[512] = { '\0' };
  int opt = 1, soc2 = -1, nice_retval, family, soc;
  void *addr = arg_get_value (globals, "client_address");
  struct sockaddr_in *saddr = NULL;
  struct sockaddr_in6 *s6addr = NULL;

  family = GPOINTER_TO_SIZE (arg_get_value (globals, "family"));
  soc = GPOINTER_TO_SIZE (arg_get_value (globals, "global_socket"));
  if (family == AF_INET)
    {
      saddr = (struct sockaddr_in *) addr;
      inet_ntop (AF_INET,  &saddr->sin_addr, asciiaddr, sizeof(asciiaddr));
    }
  else
    {
      s6addr = (struct sockaddr_in6 *) addr;
      inet_ntop (AF_INET6, &s6addr->sin6_addr, asciiaddr, sizeof (asciiaddr));
    }
  proctitle_set ("openvassd: Serving %s", asciiaddr);

  /* Everyone runs with a nicelevel of 10 */
  if (preferences_benice (prefs))
    {
      errno = 0;
      nice_retval = nice (10);
      if (nice_retval == -1 && errno != 0)
        {
          log_write ("Unable to renice process: %d", errno);
        }
    }

  /* Close the scanner thread - it is useless for us now */
  close (global_iana_socket);

  soc2 = ovas_scanner_context_attach (ovas_scanner_ctx, soc);
  if (soc2 < 0)
    goto shutdown_and_exit;

  /* FIXME: The pre-gnutls code optionally printed information about
   * the peer's certificate at this point.
   */

  setsockopt (soc, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof (opt));
  /* arg_set_value *replaces* an existing value, but it shouldn't fail here */
  (void) arg_set_value (globals, "global_socket", -1, GSIZE_TO_POINTER (soc2));

  if (comm_init (soc2) < 0)
    {
      close_stream_connection (soc);
      exit (0);
    }

  /* Get X.509 cert subject name */
  if (get_x509_dname (soc2, x509_dname, sizeof (x509_dname)) != 0)
    goto shutdown_and_exit;

  if (!check_client (x509_dname))
    {
      auth_printf (globals, "Bad login attempt !\n");
      log_write ("bad login attempt from %s\n", asciiaddr);
      goto shutdown_and_exit;
    }
  handle_client (globals);

shutdown_and_exit:
  if (soc2 >= 0)
    close_stream_connection (soc2);
  else
    {
      shutdown (soc, 2);
      close (soc);
    }

  /* Kill left overs */
  end_daemon_mode ();
  exit (0);
}
Ejemplo n.º 9
0
static int32_t cacheex_add_to_cache_int(struct s_client *cl, ECM_REQUEST *er, int8_t csp)
{
	if(er->rc >= E_NOTFOUND) { return 0; }

	if(!cl)
		{ return 0; }
	if(!csp && cl->reader && cl->reader->cacheex.mode != 2)  //from reader
	{
		cs_log_dbg(D_CACHEEX, "CACHEX received, but disabled for %s", username(cl));
		return 0;
	}
	if(!csp && !cl->reader && cl->account && cl->account->cacheex.mode != 3)  //from user
	{
		cs_log_dbg(D_CACHEEX, "CACHEX received, but disabled for %s", username(cl));
		return 0;
	}
	if(!csp && !cl->reader && !cl->account)    //not active!
	{
		cs_log_dbg(D_CACHEEX, "CACHEX received, but invalid client state %s", username(cl));
		return 0;
	}

	if(!cfg.disablecrccws && ((cl->typ == 'c' && !cl->account->disablecrccacheex) || ( cl->typ == 'p' && !cl->reader->disablecrccws)))
	{
		uint8_t selectedForIgnChecksum = chk_if_ignore_checksum(er, &cfg.disablecrccws_only_for);
		if(cl->typ == 'c')
		{
			selectedForIgnChecksum += chk_if_ignore_checksum(er, &cl->account->disablecrccacheex_only_for);
		}
		if(cl->typ == 'p')
		{
			selectedForIgnChecksum += chk_if_ignore_checksum(er, &cl->reader->disablecrccws_only_for);
		}
		if(!selectedForIgnChecksum)
		{
			uint8_t i, c;
			for(i = 0; i < 16; i += 4)
			{
				c = ((er->cw[i] + er->cw[i + 1] + er->cw[i + 2]) & 0xff);

				if(er->cw[i + 3] != c)
				{
					cs_log_dump_dbg(D_CACHEEX, er->cw, 16, "push received cw with chksum error from %s", csp ? "csp" : username(cl));
					cl->cwcacheexerr++;
					if(cl->account)
						{ cl->account->cwcacheexerr++; }
					return 0;
				}
			}
		}
	}

	// Skip check for BISS1 - cw could be indeed zero
	// Skip check for BISS2 - we use the extended cw, so the "simple" cw is always zero
	if(chk_is_null_CW(er->cw) && !caid_is_biss(er->caid))
	{
		cs_log_dump_dbg(D_CACHEEX, er->cw, 16, "push received null cw from %s", csp ? "csp" : username(cl));
		cl->cwcacheexerr++;
		if(cl->account)
			{ cl->account->cwcacheexerr++; }
		return 0;
	}

	// Don't check for BISS1 and BISS2 mode 1/E or fake caid (ECM is fake for them)
	// Don't check for BISS2 mode CA (ECM table is always 0x80)
	if(!caid_is_biss(er->caid) && !caid_is_fake(er->caid) && get_odd_even(er) == 0)
	{
		cs_log_dbg(D_CACHEEX, "push received ecm with null odd/even byte from %s", csp ? "csp" : username(cl));
		cl->cwcacheexerr++;
		if(cl->account)
			{ cl->account->cwcacheexerr++; }
		return 0;
	}

	if(!chk_halfCW(er, er->cw))
	{
		log_cacheex_cw(er, "bad half cw");
		cl->cwcacheexerr++;
		if(cl->account)
			{ cl->account->cwcacheexerr++; }
		return 0;
	}

	if((csp && cfg.csp.block_fakecws) || (cl->reader && cl->reader->cacheex.block_fakecws)
			|| (!cl->reader && cl->account && cl->account->cacheex.block_fakecws))
	{
		if(chk_is_fakecw(er->cw))
		{
			cs_log_dbg(D_CACHEEX, "push received fake cw from %s", csp ? "csp" : username(cl));
			cl->cwcacheexerr++;
			if(cl->account)
				{ cl->account->cwcacheexerr++; }
			return 0;
		}
	}

	er->grp |= cl->grp; // ok for mode2 reader too: cl->reader->grp
	er->rc = E_CACHEEX;
	er->cacheex_src = cl;
	er->selected_reader = cl->reader;
	er->client = NULL; // No Owner! So no fallback!

	if(check_client(cl))
	{
		cl->cwcacheexgot++;
		if(cl->account)
			{ cl->account->cwcacheexgot++; }
		first_client->cwcacheexgot++;
	}

	cacheex_add_hitcache(cl, er); // we have to call it before add_cache, because in chk_process we could remove it!
	add_cache(er);
	cacheex_add_stats(cl, er->caid, er->srvid, er->prid, 1);

	cs_writelock(__func__, &ecm_pushed_deleted_lock);
	er->next = ecm_pushed_deleted;
	ecm_pushed_deleted = er;
	cs_writeunlock(__func__, &ecm_pushed_deleted_lock);

	return 1; // NO free, we have to wait cache push out stuff ends.
}