Example #1
0
static void camd35_process_ecm(uchar *buf, int buflen) {
    ECM_REQUEST er;
    if (!buf || buflen < 23)
        return;
    uint16_t ecmlen = (((buf[21] & 0x0f)<< 8) | buf[22])+3;
    if (ecmlen + 20 > buflen)
        return;
    er.ecmlen = ecmlen;
    er.srvid = b2i(2, buf+ 8);
    er.caid = b2i(2, buf+10);
    er.prid = b2i(4, buf+12);
    memcpy(er.ecm, buf + 20, er.ecmlen);

    if (!ProcessECM(er.caid,er.ecm,er.cw)) {
        er.rc = E_FOUND;
    } else er.rc = E_NOTFOUND;

    if (er.rc == E_NOTFOUND) {
        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 (buf[0]==3)
            memmove(buf + 20 + 16, buf + 20 + buf[1], 0x34);
        buf[0]++;
        buf[1] = 16;
        memcpy(buf+20, er.cw, buf[1]);
    }
    camd35_send(buf, 0);
}
/**
 * request remote id
 */
void camd35_cacheex_push_request_remote_id(struct s_client *cl)
{
	uint8_t rbuf[32];//minimal size
	memset(rbuf, 0, sizeof(rbuf));
	rbuf[0] = 0x3d;
	rbuf[1] = 12;
	rbuf[2] = 0;
	memcpy(rbuf + 20, camd35_node_id, 8);
	cs_log_dbg(D_CACHEEX, "cacheex: sending id request to %s", username(cl));
	camd35_send(cl, rbuf, 12); //send adds +20
}
/**
 * send own id
 */
void camd35_cacheex_push_send_own_id(struct s_client *cl, uint8_t *mbuf)
{
	uint8_t rbuf[32]; //minimal size
	if(!cl->crypted) { return; }
	cs_log_dbg(D_CACHEEX, "cacheex: received id request from node %" PRIu64 "X %s", cacheex_node_id(mbuf + 20), username(cl));
	memset(rbuf, 0, sizeof(rbuf));
	rbuf[0] = 0x3e;
	rbuf[1] = 12;
	rbuf[2] = 0;
	memcpy(rbuf + 20, camd35_node_id, 8);
	cs_log_dbg(D_CACHEEX, "cacheex: sending own id %" PRIu64 "X request %s", cacheex_node_id(camd35_node_id), username(cl));
	camd35_send(cl, rbuf, 12); //send adds +20
}
static void camd35_process_ecm(uchar *buf, int buflen){
	ECM_REQUEST er;
	if (!buf || buflen < 23)
		return;
	uint16_t ecmlen = (((buf[21] & 0x0f)<< 8) | buf[22])+3;
	if (ecmlen + 20 > buflen)
		return;
	er.ecmlen = ecmlen;
	er.srvid = b2i(2, buf+ 8);
	er.caid = b2i(2, buf+10);
	er.prid = b2i(4, buf+12);
	er.rc = buf[3];
	
	ProcessECM(er.caid,buf + 20,er.cw);

	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;
	}
	if ((er.rc == E_NOTFOUND) || (er.rc == E_INVALID)) {
		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 (buf[0]==3)
			memmove(buf + 20 + 16, buf + 20 + buf[1], 0x34);
		buf[0]++;
		buf[1] = 16;
		memcpy(buf+20, er.cw, buf[1]);
	}
	camd35_send(buf, 0);
}
Example #5
0
static void camd35_process_ecm(uchar *buf, int buflen){
	ECM_REQUEST er;
	if (!buf || buflen < 23)
		return;
	uint16_t ecmlen = (((buf[21] & 0x0f)<< 8) | buf[22])+3;
	if (ecmlen + 20 > buflen)
		return;
	er.ecmlen = ecmlen;
	er.srvid = b2i(2, buf+ 8);
	er.caid = b2i(2, buf+10);
	er.prid = b2i(4, buf+12);
	memcpy(er.ecm, buf + 20, er.ecmlen);
	
	// ========================================================================
	// HANDLE ECM HERE! Following 5 lines are just here for testing!
	// ========================================================================
	cs_log("SRVID: %04X", er.srvid);
	cs_log("CAID: %04X", er.caid);
	cs_log("PRID: %04X", er.prid);
	er.rc = E_FOUND;
	memset(&er.cw, 0x02, sizeof(er.cw));
	
	if (er.rc == E_NOTFOUND){
		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 (buf[0]==3)
			memmove(buf + 20 + 16, buf + 20 + buf[1], 0x34);
		buf[0]++;
		buf[1] = 16;
		memcpy(buf+20, er.cw, buf[1]);
	}
	camd35_send(buf, 0);
}
Example #6
0
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);
}
static int32_t camd35_cacheex_push_out(struct s_client *cl, struct ecm_request_t *er)
{
	int8_t rc = (er->rc < E_NOTFOUND) ? E_FOUND : er->rc;
	if(rc != E_FOUND && rc != E_UNHANDLED) { return -1; }  //Maybe later we could support other rcs

	//E_FOUND     : we have the CW,
	//E_UNHANDLED : incoming ECM request

	if(cl->reader)
	{
		if(!camd35_tcp_connect(cl))
		{
			cs_log_dbg(D_CACHEEX, "cacheex: not connected %s -> no push", username(cl));
			return (-1);
		}
	}

	uint32_t size = sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw) + sizeof(uint8_t) +
					(ll_count(er->csp_lastnodes) + 1) * 8;
	unsigned char *buf;
	if(!cs_malloc(&buf, size + 20))  //camd35_send() adds +20
		{ return -1; }

	buf[0] = 0x3f; //New Command: Cache-push
	buf[1] = size & 0xff;
	buf[2] = size >> 8;
	buf[3] = rc;

	i2b_buf(2, er->srvid, buf + 8);
	i2b_buf(2, er->caid, buf + 10);
	i2b_buf(4, er->prid, buf + 12);
	//i2b_buf(2, er->idx, buf + 16); // Not relevant...?

	if(er->cwc_cycletime && er->cwc_next_cw_cycle < 2)
	{
		buf[18] = er->cwc_cycletime; // contains cwc stage3 cycletime
		if(er->cwc_next_cw_cycle == 1)
		{ buf[18] = (buf[18] | 0x80); } // set bit 8 to high

		if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode)
			{ cl->account->cwc_info++; }
		else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode))
			{ cl->cwc_info++; }

		cs_log_dbg(D_CWC, "CWC (CE) push to %s cycletime: %isek - nextcwcycle: CW%i for %04X@%06X:%04X", username(cl), er->cwc_cycletime, er->cwc_next_cw_cycle, er->caid, er->prid, er->srvid);
	}

	buf[19] = er->ecm[0] != 0x80 && er->ecm[0] != 0x81 ? 0 : er->ecm[0];

	uint8_t *ofs = buf + 20;

	//write oscam ecmd5:
	memcpy(ofs, er->ecmd5, sizeof(er->ecmd5)); //16
	ofs += sizeof(er->ecmd5);

	//write csp hashcode:
	i2b_buf(4, htonl(er->csp_hash), ofs);
	ofs += 4;

	//write cw:
	memcpy(ofs, er->cw, sizeof(er->cw)); //16
	ofs += sizeof(er->cw);

	//write node count:
	*ofs = ll_count(er->csp_lastnodes) + 1;
	ofs++;

	//write own node:
	memcpy(ofs, camd35_node_id, 8);
	ofs += 8;

	//write other nodes:
	LL_LOCKITER *li = ll_li_create(er->csp_lastnodes, 0);
	uint8_t *node;
	while((node = ll_li_next(li)))
	{
		memcpy(ofs, node, 8);
		ofs += 8;
	}
	ll_li_destroy(li);

	int32_t res = camd35_send(cl, buf, size);
	NULLFREE(buf);
	return res;
}