Пример #1
0
int pandora_auth_client(struct s_client *cl, IN_ADDR_T ip) {
	int ok;
	struct s_auth *account;

#ifdef IPV6SUPPORT
	// FIXME: Add IPv6 support
	(void)ip; // Prevent warning about unused var "ip"
#else
	if (!cl->pand_ignore_ecm && cfg.pand_allowed) {
		struct s_ip *p_ip;
		for (ok = 0, p_ip = cfg.pand_allowed; (p_ip) && (!ok); p_ip
				= p_ip->next)
			ok = ((ip >= p_ip->ip[0]) && (ip <= p_ip->ip[1]));

		if (!ok) {
			cs_auth_client(cl, (struct s_auth *) 0, "IP not allowed");
			return 0;
		}
	}
#endif

	for (ok = 0, account = cfg.account; cfg.pand_usr && account && !ok; account = account->next) {
		ok = streq(cfg.pand_usr, account->usr);
		if (ok && cs_auth_client(cl, account, NULL))
			cs_disconnect_client(cl);
	}
	if (!ok)
		cs_auth_client(cl, (struct s_auth *) (-1), NULL);
	return ok;
}
Пример #2
0
static int32_t secmon_auth_client(uchar *ucrc)
{
	uint32_t crc;
	struct s_auth *account;
	struct s_client *cur_cl = cur_client();
	unsigned char md5tmp[MD5_DIGEST_LENGTH];

	if (cur_cl->auth)
	{
		int32_t s=memcmp(cur_cl->ucrc, ucrc, 4);
		if (s)
			cs_log("wrong user-crc or garbage !?");
		return !s;
	}
	cur_cl->crypted=1;
	crc=(ucrc[0]<<24) | (ucrc[1]<<16) | (ucrc[2]<<8) | ucrc[3];
	for (account=cfg.account; (account) && (!cur_cl->auth); account=account->next)
		if ((account->monlvl) &&
				(crc==crc32(0L, MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH)))
		{
			memcpy(cur_cl->ucrc, ucrc, 4);
			aes_set_key(cur_cl, (char *)MD5((unsigned char *)ESTR(account->pwd), strlen(ESTR(account->pwd)), md5tmp));
			if (cs_auth_client(cur_cl, account, NULL))
				return -1;
			cur_cl->auth=1;
		}
	if (!cur_cl->auth)
	{
		cs_auth_client(cur_cl, (struct s_auth *)0, "invalid user");
		return -1;
	}
	return cur_cl->auth;
}
Пример #3
0
static void radegast_auth_client(IN_ADDR_T ip)
{
  int32_t ok;
  struct s_auth *account;
  struct s_client *cl = cur_client();

  ok = check_ip(cfg.rad_allowed, ip);

  if (!ok)
  {
    cs_log ("radegast: IP not allowed");
    cs_auth_client(cl, (struct s_auth *)0, NULL);
    cs_disconnect_client(cl);
  }

  for (ok = 0, account = cfg.account; cfg.rad_usr && account && !ok; account = account->next)
  {
    ok = streq(cfg.rad_usr, account->usr);
    if (ok && cs_auth_client(cl, account, NULL))
       cs_disconnect_client(cl);
  }

  if (!ok)
    cs_auth_client(cl, ok ? account : (struct s_auth *)(-1), "radegast");
}
Пример #4
0
static void radegast_auth_client(in_addr_t ip)
{
  int32_t ok;
  struct s_auth *account;
  struct s_client *cl = cur_client();

  ok = check_ip(cfg.rad_allowed, ip);

  if (!ok)
  {
    cs_log ("radegast: IP not allowed");
    cs_auth_client(cl, (struct s_auth *)0, NULL);
    cs_disconnect_client(cl);
  }

  for (ok=0, account=cfg.account; (cfg.rad_usr[0]) && (account) && (!ok); account=account->next)
  {
    ok=(!strcmp(cfg.rad_usr, account->usr));
    if (ok && cs_auth_client(cl, account, NULL))
       cs_disconnect_client(cl);
  }

  if (!ok)
    cs_auth_client(cl, ok ? account : (struct s_auth *)(-1), "radegast");
}
Пример #5
0
static int8_t monitor_auth_client(char *usr, char *pwd)
{
	struct s_auth *account;
	struct s_client *cur_cl = cur_client();

	if (cur_cl->auth) return 0;
	if ((!usr) || (!pwd))
	{
		cs_auth_client(cur_cl, (struct s_auth *)0, NULL);
		return -1;
	}
	for (account=cfg.account, cur_cl->auth=0; (account) && (!cur_cl->auth);)
	{
		if (account->monlvl)
			cur_cl->auth = streq(usr, account->usr) && streq(pwd, account->pwd);
		if (!cur_cl->auth)
			account=account->next;
	}
	if (!cur_cl->auth)
	{
		cs_auth_client(cur_cl, (struct s_auth *)0, "invalid account");
		return -1;
	}
	if (cs_auth_client(cur_cl, account, NULL))
		return -1;
	return 0;
}
Пример #6
0
static int32_t camd35_auth_client(struct s_client *cl, uchar *ucrc)
{
	int32_t rc = 1;
	uint32_t crc;
	struct s_auth *account;
	unsigned char md5tmp[MD5_DIGEST_LENGTH];

	if(cl->upwd[0])
		{ return (memcmp(cl->ucrc, ucrc, 4) ? 1 : 0); }
	cl->crypted = 1;
	crc = (((ucrc[0] << 24) | (ucrc[1] << 16) | (ucrc[2] << 8) | ucrc[3]) & 0xffffffffL);
	for(account = cfg.account; (account) && (!cl->upwd[0]); account = account->next)
		if(crc == crc32(0L, MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH))
		{
			rc = cs_auth_client(cl, account, NULL);
			if(!rc)
			{
				memcpy(cl->ucrc, ucrc, 4);
				cs_strncpy((char *)cl->upwd, account->pwd, sizeof(cl->upwd));
				if (!aes_set_key_alloc(&cl->aes_keys, (char *) MD5(cl->upwd, strlen((char *)cl->upwd), md5tmp)))
				{
					return 1;
				}
				return 0;
			}
		}
	return (rc);
}
Пример #7
0
static int8_t monitor_check_ip(void)
{
	int32_t ok=0;
	struct s_client *cur_cl = cur_client();

	if (cur_cl->auth) return 0;
	ok = check_ip(cfg.mon_allowed, cur_cl->ip);
	if (!ok)
	{
		cs_auth_client(cur_cl, (struct s_auth *)0, "invalid ip");
		return -1;
	}
	return 0;
}
Пример #8
0
static void radegast_auth_client(in_addr_t ip)
{
  int32_t ok;
  struct s_auth *account;

  ok = check_ip(cfg.rad_allowed, ip);

  if (!ok)
  {
    cs_auth_client(cur_client(), (struct s_auth *)0, NULL);
    cs_exit(0);
  }

  for (ok=0, account=cfg.account; (cfg.rad_usr[0]) && (account) && (!ok); account=account->next)
  {
    ok=(!strcmp(cfg.rad_usr, account->usr));
    if (ok && cs_auth_client(cur_client(), account, NULL))
      cs_exit(0);
  }

  if (!ok)
    cs_auth_client(cur_client(), (struct s_auth *)(-1), NULL);
}
Пример #9
0
static void gbox_auth_client(struct s_client *cli)
{
	struct s_client *cl = switch_client_proxy(cli);
	if(cl->typ == 'p' && cl->gbox && cl->reader)
	{
		cli->crypted = 1; //display as crypted
		cli->gbox = cl->gbox; //point to the same gbox as proxy
		cli->reader = cl->reader; //point to the same reader as proxy

		struct s_auth *account = get_account_by_name(gbox_username(cl));
		if(account)
		{
			cs_auth_client(cli, account, NULL);
			cli->account = account;
			cli->grp = account->grp;
		}
	}
	return ;
}
Пример #10
0
static void oscam_ser_auth_client(int32_t proto)
{
  int32_t ok = 0;
  struct s_serial_client *serialdata=cur_client()->serialdata;
  // After reload base account ptrs may be placed in other address,
  // and we may can't find it in this process.
  // Simply save valid account.
  struct s_auth *account=0;

  if (serialdata->connected==proto)
    return;
  if (serialdata->connected)
    oscam_ser_disconnect();
  serialdata->connected=proto;

  for (ok=0, account=cfg.account; (account) && (!ok); account=account->next)
    if( (ok=!strcmp(serialdata->oscam_ser_usr, account->usr)) )
      break;
  cs_auth_client(cur_client(), ok ? account : (struct s_auth *)(-1), proto_txt[serialdata->connected]);
}
Пример #11
0
static int32_t camd35_auth_client(struct s_client *cl, uchar *ucrc)
{
	int32_t rc = 1, no_delay = 1;
	uint32_t crc;
	struct s_auth *account;
	unsigned char md5tmp[MD5_DIGEST_LENGTH];

	if(cl->upwd[0])
		{ return (memcmp(cl->ucrc, ucrc, 4) ? 1 : 0); }
	cl->crypted = 1;
	crc = (((ucrc[0] << 24) | (ucrc[1] << 16) | (ucrc[2] << 8) | ucrc[3]) & 0xffffffffL);
	for(account = cfg.account; (account) && (!cl->upwd[0]); account = account->next)
		if(crc == crc32(0L, MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH))
		{
			rc = cs_auth_client(cl, account, NULL);
			if(!rc)
			{
				memcpy(cl->ucrc, ucrc, 4);
				cs_strncpy((char *)cl->upwd, account->pwd, sizeof(cl->upwd));
				if (!aes_set_key_alloc(&cl->aes_keys, (char *) MD5(cl->upwd, strlen((char *)cl->upwd), md5tmp)))
				{
					return 1;
				}
				
				#ifdef CS_CACHEEX
				if(cl->account->cacheex.mode < 2)
				#endif
				if(!cl->is_udp && cl->tcp_nodelay == 0)
				{
					setsockopt(cl->udp_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_delay, sizeof(no_delay));
					cl->tcp_nodelay = 1;
				}
				
				return 0;
			}
		}
	return (rc);
}
Пример #12
0
static int32_t camd35_recv(struct s_client *client, uchar *buf, int32_t l)
{
	int32_t rc, s, rs, n = 0, buflen = 0, len = 0;
	for(rc = rs = s = 0; !rc; s++)
	{
		switch(s)
		{
		case 0:
			if(!client->udp_fd) { return (-9); }
			if(client->is_udp && client->typ == 'c')
			{
				rs = recv_from_udpipe(buf);
			}
			else
			{
				//read minimum packet size (4 byte ucrc + 32 byte data) to detect packet size (tcp only)

				//rs = cs_recv(client->udp_fd, buf, client->is_udp ? l : 36, 0);
				if(client->is_udp){
					while (1){
					rs = cs_recv(client->udp_fd, buf, l, 0);
						if (rs < 0){
							if(errno == EINTR) { continue; }  // try again in case of interrupt
							if(errno == EAGAIN) { continue; }  //EAGAIN needs select procedure again
							cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "ERROR: %s (errno=%d %s)", __func__, errno, strerror(errno));
							break;
						}else {break;}
					}
				}else{
					int32_t tot=36, readed=0;
					rs = 0;
					do
					{
						readed = cs_recv(client->udp_fd, buf+rs, tot, 0);
						if (readed < 0){
							if(errno == EINTR) { continue; }  // try again in case of interrupt
							if(errno == EAGAIN) { continue; }  //EAGAIN needs select procedure again
							cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "ERROR: %s (errno=%d %s)", __func__, errno, strerror(errno));
							break;
						}
						if (readed == 0){ // nothing to read left!
							rc = -5;
							break;
						}
						if (readed > 0){ // received something, add it!
							tot-=readed;
						rs+=readed;
						}
					}
					while(tot!=0);
				}

			}
			if(rs < 36)
			{	
				if(rc != -5)
					{ rc = -1; }
				goto out;
			}
			break;
		case 1:
			switch(camd35_auth_client(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(client->aes_keys, buf, rs);
			if(rs != boundary(4, rs))
				cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER,
							  "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);
			if(!(client->is_udp && client->typ == 'c') && (rs < n) && ((n - 32) > 0))
			{

				//len = cs_recv(client->udp_fd, buf+32, n-32, 0); // read the rest of the packet
				int32_t tot=n-32, readed=0;
				len = 0;
				do{
					readed = cs_recv(client->udp_fd, buf+32+len, tot, 0); // read the rest of the packet
					if (readed < 0){
						if(errno == EINTR) { continue; }  // try again in case of interrupt
						if(errno == EAGAIN) { continue; }  //EAGAIN needs select procedure again
						cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "ERROR: %s (errno=%d %s)", __func__, errno, strerror(errno));
						break;
					}
					if (readed == 0){ // nothing to read left!
						break;
					}
					if (readed > 0){ // received something, add it!
					tot-=readed;
					len+=readed;
					}
				}
				while(tot!=0);


				if(len > 0)
				{
					rs += len;
					aes_decrypt(client->aes_keys, buf + 32, len);
				}
				if(len < 0)
				{
					rc = -1;
					goto out;
				}
			}

			cs_log_dump_dbg(client->typ == 'c' ? D_CLIENT : D_READER,
						  buf, rs, "received %d bytes from %s", rs, remote_txt());

			if(n < rs)
				cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER,
							  "ignoring %d bytes of garbage", rs - n);
			else if(n > rs) { rc = -3; }
			break;
		case 3:
			if(crc32(0L, buf + 20, buflen) != b2i(4, buf + 4)) { rc = -4; }
			if(!rc) { rc = n; }
			break;
		}
	}

out:
	if((rs > 0) && ((rc == -1) || (rc == -2)))
	{
		cs_log_dump_dbg(client->typ == 'c' ? D_CLIENT : D_READER, buf, rs,
					  "received %d bytes from %s (native)", rs, remote_txt());
	}
	if(rc >= 0) { client->last = time(NULL); }  // last client action is now
	switch(rc)
	{
		//case 0:   break;
	case -1:
		cs_log("packet is too small (received %d bytes, expected %d bytes)", rs, l);
		break;
	case -2:
		if(cs_auth_client(client, 0, "unknown user"))
			{ cs_disconnect_client(client); }
		break;
	case -3:
		cs_log("incomplete request !");
		break;
	case -4:
		cs_log("checksum error (wrong password ?)");
		break;
	case -5:
		cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "connection closed");
		break;		
		//default:  cs_log_dbg(D_TRACE, "camd35_recv returns rc=%d", rc); break;
	}

	return (rc);
}
Пример #13
0
void * azbox_main_thread(void *cli) {
	struct s_client * client = (struct s_client *) cli;
	client->thread=pthread_self();
	pthread_setspecific(getclient, cli);
	dvbapi_client=cli;

	struct s_auth *account;
	int32_t ok = 0;
	for (account = cfg.account; account; account=account->next) {
		if ((ok = streq(cfg.dvbapi_usr, account->usr)))
			break;
	}
	cs_auth_client(client, ok ? account : (struct s_auth *)(-1), "dvbapi");

	dvbapi_read_priority();

	openxcas_msg_t msg;
	int32_t ret;
	while ((ret = openxcas_get_message(&msg, 0)) >= 0) {
		cs_sleepms(10);

		if (ret) {
			openxcas_stream_id = msg.stream_id;
			openxcas_seq = msg.sequence;

			switch(msg.cmd) {
				case OPENXCAS_SELECT_CHANNEL:
					cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_SELECT_CHANNEL");

					// parse channel info
					struct stOpenXCASChannel chan;
					memcpy(&chan, msg.buf, msg.buf_len);

					cs_log(LOG_PREFIX "channel change: sid = %x, vpid = %x. apid = %x", chan.service_id, chan.v_pid, chan.a_pid);

					openxcas_video_pid = chan.v_pid;
					openxcas_audio_pid = chan.a_pid;
					openxcas_data_pid = chan.d_pid;
					break;
				case OPENXCAS_START_PMT_ECM:
					cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_START_PMT_ECM");

					 // parse pmt
					uchar *dest;
					if (!cs_malloc(&dest, msg.buf_len + 7 - 12 - 4))
						break;

					memcpy(dest, "\x00\xFF\xFF\x00\x00\x13\x00", 7);

					dest[1] = msg.buf[3];
					dest[2] = msg.buf[4];
					dest[5] = msg.buf[11]+1;

					memcpy(dest + 7, msg.buf + 12, msg.buf_len - 12 - 4);

					dvbapi_parse_capmt(dest, 7 + msg.buf_len - 12 - 4, -1, NULL);
					free(dest);

					unsigned char mask[12];
					unsigned char comp[12];
					memset(&mask, 0x00, sizeof(mask));
					memset(&comp, 0x00, sizeof(comp));

					mask[0] = 0xfe;
					comp[0] = 0x80;

					if ((ret = openxcas_add_filter(msg.stream_id, OPENXCAS_FILTER_ECM, 0, 0xffff, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ecm_callback)) < 0)
						cs_log(LOG_PREFIX "unable to add ecm filter");
					else
						cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm filter added, pid = %x, caid = %x", openxcas_ecm_pid, 0);

					if (openxcas_start_filter(msg.stream_id, msg.sequence, OPENXCAS_FILTER_ECM) < 0)
						cs_log(LOG_PREFIX "unable to start ecm filter");
					else
						cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm filter started");

					if (!openxcas_create_cipher_ex(msg.stream_id, openxcas_seq, 0, openxcas_ecm_pid, openxcas_video_pid, 0xffff, openxcas_audio_pid, 0xffff, 0xffff, 0xffff))
						cs_log(LOG_PREFIX "failed to create cipher ex");
					else
						cs_debug_mask(D_DVBAPI, LOG_PREFIX "cipher created");
					break;
				case OPENXCAS_STOP_PMT_ECM:
					cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_STOP_PMT_ECM");
					openxcas_stop_filter(msg.stream_id, OPENXCAS_FILTER_ECM);
					openxcas_remove_filter(msg.stream_id, OPENXCAS_FILTER_ECM);
					openxcas_stop_filter_ex(msg.stream_id, msg.sequence, openxcas_filter_idx);
					openxcas_destory_cipher_ex(msg.stream_id, msg.sequence);
					memset(&demux, 0, sizeof(demux));
					break;
				case OPENXCAS_ECM_CALLBACK:
					cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_ECM_CALLBACK");
					struct stOpenXCAS_Data data;
					memcpy(&data, msg.buf, msg.buf_len);
					if (!openxcas_busy)
					  openxcas_filter_callback(msg.stream_id, msg.sequence, OPENXCAS_FILTER_ECM, &data);
					break;
				case OPENXCAS_PID_FILTER_CALLBACK:
					cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_PID_FILTER_CALLBACK");
					openxcas_filter_callback_ex(msg.stream_id, msg.sequence, (struct stOpenXCAS_Data *)msg.buf);
					break;
				case OPENXCAS_QUIT:
					cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_QUIT");
					openxcas_close();
					cs_log(LOG_PREFIX "exited");
					return NULL;
					break;
				case OPENXCAS_UKNOWN_MSG:
				default:
					cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_UKNOWN_MSG (%d)", msg.cmd);
					//cs_ddump_mask(D_DVBAPI, &msg, sizeof(msg), "msg dump:");
					break;
			}
		}
	}
	cs_log(LOG_PREFIX "invalid message");
	return NULL;
}