예제 #1
0
파일: OSEmu.c 프로젝트: jackuzzy/OSEmu
static void camd35_process_emm(uchar *buf, int buflen)
{
	uint32_t keysAdded = 0;
	uint16_t emmlen = 0;
	
	if(!buf || buflen < 23)
		{ return; }
		
	emmlen = (((buf[21] & 0x0f) << 8) | buf[22]) + 3;
	if(emmlen + 20 > buflen)
		{ return; }
		
	cs_log_debug("ProcessEMM CAID: %X", (buf[10] << 8) | buf[11]);
	cs_log_hexdump("ProcessEMM: ", buf+20, emmlen);
	
	if(ProcessEMM((buf[10] << 8) | buf[11],
      (buf[12] << 24) | (buf[13] << 16) | (buf[14] << 8) | buf[15],buf+20,&keysAdded)) {
	  cs_log_debug("EMM nok");
	}
	else {
	  cs_log_debug("EMM ok");
    }	
}
예제 #2
0
파일: OSEmu.c 프로젝트: FFTEAM/osemu
static int32_t camd35_recv(uchar *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_debug("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_debug("received %d bytes from client", rs);

			if(n < rs)
				cs_log_debug("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_hexdump("camd35 checksum failed for packet: ", buf, rs);
				cs_log_debug("checksum: %X", b2i(4, buf+4)); 
			}
			if(!rc) { rc = n; }
			break;
		}
	}

out:
	if((rs > 0) && ((rc == -1) || (rc == -2)))
	{
		cs_log_debug("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);
}
예제 #3
0
파일: OSEmu.c 프로젝트: jackuzzy/OSEmu
static void camd35_process_ecm(uchar *buf, int buflen)
{
	ECM_REQUEST er;
	uint16_t ecmlen = 0;
	
	if(!buf || buflen < 23)
		{ return; }
	
	ecmlen = (((buf[21] & 0x0f) << 8) | buf[22]) + 3;
	if(ecmlen + 20 > buflen)
		{ return; }
	
	memset(&er, 0, sizeof(ECM_REQUEST));
    er.rc = E_UNHANDLED;
	er.ecmlen = ecmlen;
	er.srvid = b2i(2, buf + 8);
	er.caid = b2i(2, buf + 10);
	er.prid = b2i(4, buf + 12);
	
	cs_log_debug("ProcessECM CAID: %X", er.caid);
	cs_log_hexdump("ProcessECM: ", buf+20, ecmlen);
	
	if(ProcessECM(er.caid,buf+20,er.cw)) {
	  er.rc = E_NOTFOUND;
	  cs_log_debug("CW not found");
	}
	else {
	  er.rc = E_FOUND;
	  cs_log_hexdump("Found CW: ", er.cw, 16);
    }
    
	if((er.rc == E_NOTFOUND || (er.rc == E_INVALID)) && !suppresscmd08)
	{
		buf[0] = 0x08;
		buf[1] = 2;
		memset(buf + 20, 0, buf[1]);
		buf[22] = er.rc; //put rc in byte 22 - hopefully don't break legacy camd3
	}
	else if(er.rc == E_STOPPED)
	{
		buf[0] = 0x08;
		buf[1] = 2;
		buf[20] = 0;
		/*
		 * the second Databyte should be forseen for a sleeptime in minutes
		 * whoever knows the camd3 protocol related to CMD08 - please help!
		 * on tests this don't work with native camd3
		 */
		buf[21] = 0;
		cs_log("client stop request send");
	}
	else
	{
		// Send CW
		if((er.rc < E_NOTFOUND) || (er.rc == E_FAKE))
		{
			if(buf[0] == 3)
				{ memmove(buf + 20 + 16, buf + 20 + buf[1], 0x34); }
			buf[0]++;
			buf[1] = 16;
			memcpy(buf + 20, er.cw, buf[1]);
		}
		else
		{
			// Send old CMD44 to prevent cascading problems with older mpcs/oscam versions
			buf[0] = 0x44;
			buf[1] = 0;
		}
	}
	camd35_send(buf, 0);
}