Example #1
0
static int pandora_recv(struct s_client *cl, uchar *buf, int32_t l) {
	int ret;

	if (!cl->udp_fd)
		return (-9);
	if (cl->typ != 'c')
		ret = recv_from_udpipe(buf);
	else {
		ret = recvfrom(cl->udp_fd, buf, l, 0, (struct sockaddr *)&cl->udp_sa, &cl->udp_sa_len);
	}
	if (ret < 1)
		return (-1);

	simple_crypt(buf, ret, cl->pand_md5_key, 16);
	cl->last = time((time_t *) 0);

	if (cl->typ != 'c')
		pandora_process_request(cl, buf, ret);
	return (ret);
}
Example #2
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);
}
Example #3
0
static int32_t monitor_recv(struct s_client * client, uchar *buf, int32_t l)
{
	int32_t n;
	uchar nbuf[3] = { 'U', 0, 0 };
	static int32_t bpos=0, res = 0;
	static uchar *bbuf=NULL;
	if (!bbuf)
	{
		if (!cs_malloc(&bbuf, l))
			return 0;
	}
	if (bpos)
		memcpy(buf, bbuf, n=bpos);
	else
		n=recv_from_udpipe(buf);
	bpos=0;
	if (!n) return buf[0]=0;
	if (buf[0]=='&')
	{
		int32_t bsize;
		if (n<21)	// 5+16 is minimum
		{
			cs_log("packet too small!");
			return buf[0]=0;
		}
		res = secmon_auth_client(buf+1);
		if (res == -1) {
			cs_disconnect_client(client);
			return 0;
		}
		if (!res)
			return buf[0]=0;
		aes_decrypt(client, buf+5, 16);
		bsize=boundary(4, buf[9]+5)+5;
		// cs_log("n=%d bsize=%d", n, bsize);
		if (n>bsize)
		{
			// cs_log("DO >>>> copy-back");
			memcpy(bbuf, buf+bsize, bpos=n-bsize);
			n=bsize;
			uchar *nbuf_cpy;
			if (cs_malloc(&nbuf_cpy, sizeof(nbuf))) {
				memcpy(nbuf_cpy, nbuf, sizeof(nbuf));
				add_job(client, ACTION_CLIENT_UDP, &nbuf_cpy, sizeof(nbuf));
			}
		}
		else if (n<bsize)
		{
			cs_log("packet-size mismatch !");
			return buf[0]=0;
		}
		aes_decrypt(client, buf+21, n-21);
		uchar tmp[10];
		if (memcmp(buf+5, i2b_buf(4, crc32(0L, buf+10, n-10), tmp), 4))
		{
			cs_log("CRC error ! wrong password ?");
			return buf[0]=0;
		}
		n=buf[9];
		memmove(buf, buf+10, n);
	}
	else
	{
		uchar *p;
		if (monitor_check_ip() == -1) {
			cs_disconnect_client(client);
			return 0;
		}
		buf[n]='\0';
		if ((p=(uchar *)strchr((char *)buf, 10)) && (bpos=n-(p-buf)-1))
		{
			memcpy(bbuf, p+1, bpos);
			n=p-buf;
			uchar *nbuf_cpy;
			if (cs_malloc(&nbuf_cpy, sizeof(nbuf))) {
				memcpy(nbuf_cpy, nbuf, sizeof(nbuf));
				add_job(client, ACTION_CLIENT_UDP, &nbuf_cpy, sizeof(nbuf));
			}
		}
	}
	buf[n]='\0';
	n=strlen(trim((char *)buf));
	if (n) client->last=time((time_t *) 0);
	return n;
}