示例#1
0
文件: OSEmu.c 项目: jackuzzy/OSEmu
static void camd35_request_emm(void)
{
	uchar mbuf[1024];

	uint16_t au_caid = 0x0500;

	memset(mbuf, 0, sizeof(mbuf));
	mbuf[2] = mbuf[3] = 0xff;           // must not be zero
	
	i2b_buf(4, 0x00030B00, &mbuf[12]);

	mbuf[0] = 5;
	mbuf[1] = 111;
	if(au_caid)
	{
		mbuf[39] = 1;                   // no. caids
		mbuf[20] = au_caid >> 8;        // caid's (max 8)
		mbuf[21] = au_caid & 0xff;

		mbuf[47] = 0;

		mbuf[128] = 1; //EMM_GLOBAL
		mbuf[129] = 0; //EMM_SHARED
		mbuf[130] = 0; //EMM_UNIQUE
	}
	else        // disable emm
		{ mbuf[20] = mbuf[39] = mbuf[40] = mbuf[47] = mbuf[49] = 1; }
示例#2
0
static int32_t __camd35_send(struct s_client *cl, uchar *buf, int32_t buflen, int answer_awaited)
{
	int32_t l;
	unsigned char rbuf[REQ_SIZE + 15 + 4], *sbuf = rbuf + 4;

	if(!cl->udp_fd || !cl->crypted) { return (-1); }  //exit if no fd or aes key not set!

	//Fix ECM len > 255
	if(buflen <= 0)
		{ buflen = ((buf[0] == 0) ? (((buf[21] & 0x0f) << 8) | buf[22]) + 3 : buf[1]); }
	l = 20 + (((buf[0] == 3) || (buf[0] == 4)) ? 0x34 : 0) + buflen;
	memcpy(rbuf, cl->ucrc, 4);
	memcpy(sbuf, buf, l);
	memset(sbuf + l, 0xff, 15); // set unused space to 0xff for newer camd3's
	i2b_buf(4, crc32(0L, sbuf + 20, buflen), sbuf + 4);
	l = boundary(4, l);
	cs_log_dump_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, sbuf, l, "send %d bytes to %s", l, username(cl));
	aes_encrypt_idx(cl->aes_keys, sbuf, l);

	int32_t status;
	if(cl->is_udp)
	{
		status = sendto(cl->udp_fd, rbuf, l + 4, 0, (struct sockaddr *)&cl->udp_sa, cl->udp_sa_len);
		if(status == -1) { set_null_ip(&SIN_GET_ADDR(cl->udp_sa)); }
	}
	else
	{
		status = send(cl->udp_fd, rbuf, l + 4, 0);

		if(cl->typ == 'p' && cl->reader)
		{
			if(status == -1) { network_tcp_connection_close(cl->reader, "can't send"); }
		}
		else if(cl->typ == 'c')
		{
			if(status == -1) { cs_disconnect_client(cl); }
		}
	}
	if(status != -1)
	{
		if(cl->reader && answer_awaited)
		{
			cl->reader->last_s = time(NULL);
		}
		if(cl->reader && !answer_awaited)
		{
			cl->reader->last_s = cl->reader->last_g = time(NULL);
		}
		cl->last = time(NULL);

	}
	return status;
}
示例#3
0
static int32_t viaccess_get_emm_type(EMM_PACKET *ep, struct s_reader * rdr)
{
	uint32_t provid=0;
	rdr_debug_mask(rdr, D_EMM, "Entered viaccess_get_emm_type ep->emm[0]=%02x",ep->emm[0]);

	if (ep->emm[3] == 0x90 && ep->emm[4] == 0x03) {
		provid = ep->emm[5] << 16 | ep->emm[6] << 8 | (ep->emm[7] & 0xFE);
		i2b_buf(4, provid, ep->provid);
	}

	switch (ep->emm[0]) {
case 0x88:
	ep->type=UNIQUE;
	memset(ep->hexserial, 0, 8);
	memcpy(ep->hexserial, ep->emm + 4, 4);
	rdr_debug_mask(rdr, D_EMM, "UNIQUE");
	return(!memcmp(rdr->hexserial + 1, ep->hexserial, 4));

case 0x8A:
case 0x8B:
	ep->type=GLOBAL;
	rdr_debug_mask(rdr, D_EMM, "GLOBAL");
	return 1;

case 0x8C:
case 0x8D:
	ep->type=SHARED;
	rdr_debug_mask(rdr, D_EMM, "SHARED (part)");
	return 0;

case 0x8E:
	ep->type=SHARED;
	memset(ep->hexserial, 0, 8);
	memcpy(ep->hexserial, ep->emm + 3, 3);
	rdr_debug_mask(rdr, D_EMM, "SHARED");

	//check for provider as serial (cccam only?)
	int8_t i;
	for (i=0;i<rdr->nprov;i++) {
		if (!memcmp(&rdr->prid[i][1], ep->hexserial, 3))
			return 1;
	}
	return(!memcmp(&rdr->sa[0][0], ep->hexserial, 3));

default:
	ep->type = UNKNOWN;
	rdr_debug_mask(rdr, D_EMM, "UNKNOWN");
	return 1;
	}
}
示例#4
0
文件: OSEmu.c 项目: jahntheman/OSEmu
static void camd35_request_emm(uint16_t caid, uint32_t provider, uint8_t* hexserial,
							   uint8_t emm_global, uint8_t emm_shared, uint8_t emm_unique)
{
	uint8_t mbuf[1024];
	uint8_t prid[4];

	memset(mbuf, 0, sizeof(mbuf));
	mbuf[2] = mbuf[3] = 0xff;           // must not be zero

	i2b_buf(4, provider, &mbuf[12]);

	mbuf[0] = 5;
	mbuf[1] = 111;
	if(caid)
	{
		mbuf[39] = 1;                // no. caids
		mbuf[20] = caid >> 8;        // caid's (max 8)
		mbuf[21] = caid & 0xff;

		memcpy(mbuf + 40, hexserial, 6);
		mbuf[47] = 1;

		prid[0] = provider >> 24;
		prid[1] = provider >> 16;
		prid[2] = provider >> 8;
		prid[3] = provider & 0xFF;

		if((caid >= 0x1700 && caid <= 0x1799)  ||  // Betacrypt
				(caid >= 0x0600 && caid <= 0x0699))    // Irdeto (don't know if this is correct, cause I don't own a IRDETO-Card)
		{
			mbuf[48 + (0 * 5)] = prid[0];
			memcpy(&mbuf[50 + (0 * 5)], &prid[1], 3);
		}
		else
		{
			mbuf[48 + (0 * 5)] = prid[2];
			mbuf[49 + (0 * 5)] = prid[3];
		}

		mbuf[127] = 0; //EMM_UNKNOWN
		mbuf[128] = emm_global; //EMM_GLOBAL
		mbuf[129] = emm_shared; //EMM_SHARED
		mbuf[130] = emm_unique; //EMM_UNIQUE
	}
	else        // disable emm
	{ mbuf[20] = mbuf[39] = mbuf[40] = mbuf[47] = mbuf[49] = 1; }
示例#5
0
文件: OSEmu.c 项目: jahntheman/OSEmu
static int32_t camd35_send(uint8_t *buf, int32_t buflen)
{
	int32_t l, status;
	unsigned char rbuf[REQ_SIZE + 15 + 4], *sbuf = rbuf + 4;

	//Fix ECM len > 255
	if(buflen <= 0)
	{ buflen = ((buf[0] == 0) ? (((buf[21] & 0x0f) << 8) | buf[22]) + 3 : buf[1]); }
	l = 20 + (((buf[0] == 3) || (buf[0] == 4)) ? 0x34 : 0) + buflen;
	memcpy(rbuf, cl_ucrc, 4);
	memcpy(sbuf, buf, l);
	memset(sbuf + l, 0xff, 15); // set unused space to 0xff for newer camd3's
	i2b_buf(4, crc32(0, sbuf + 20, buflen), sbuf + 4);
	l = boundary(4, l);
	cs_log_dbg(0, "send %d bytes to client", l);
	aes_encrypt_idx(&cl_aes_keys, sbuf, l);

	status = sendto(cl_sockfd, rbuf, l + 4, 0, (struct sockaddr *)&cl_socket, sizeof(cl_socket));
	return status;
}
示例#6
0
int32_t monitor_send_idx(struct s_client *cl, char *txt)
{
	int32_t l;
	unsigned char buf[256+32];
	if (!cl->udp_fd)
		return -1;
	struct timespec req_ts;
	req_ts.tv_sec = 0;
	req_ts.tv_nsec = 500000;
	nanosleep (&req_ts, NULL);//avoid lost udp-pakkets
	if (!cl->crypted)
		return sendto(cl->udp_fd, txt, strlen(txt), 0, (struct sockaddr *)&cl->udp_sa, cl->udp_sa_len);
	buf[0]='&';
	buf[9]=l=strlen(txt);
	l=boundary(4, l+5)+5;
	memcpy(buf+1, cl->ucrc, 4);
	cs_strncpy((char *)buf+10, txt, sizeof(buf)-10);
	uchar tmp[10];
	memcpy(buf+5, i2b_buf(4, crc32(0L, buf+10, l-10), tmp), 4);
	aes_encrypt_idx(cl, buf+5, l-5);
	return sendto(cl->udp_fd, buf, l, 0, (struct sockaddr *)&cl->udp_sa, cl->udp_sa_len);
}
示例#7
0
static int32_t oscam_ser_send_ecm(struct s_client *client, ECM_REQUEST *er, uchar *buf)
{
	char *tmp;
	switch(client->serialdata->oscam_ser_proto)
	{
	case P_HSIC:
		memset(buf, 0, 12);
		buf[0] = 2;
		i2b_buf(2, er->caid, buf + 1);
		i2b_buf(3, er->prid, buf + 3);
		i2b_buf(2, er->pid, buf + 6);
		i2b_buf(2, er->srvid, buf + 10);
		memcpy(buf + 12, er->ecm, er->ecmlen);
		oscam_ser_send(client, buf, 12 + er->ecmlen);
		break;
	case P_BOMBA:
		oscam_ser_send(client, er->ecm, er->ecmlen);
		break;
	case P_DSR95:
		if(cs_malloc(&tmp, er->ecmlen * 2 + 1))
		{
			if(client->serialdata->dsr9500type == P_DSR_WITHSID)
			{
				snprintf((char *)buf, 512, "%c%08X%04X%s%04X\n\r",
						 3, er->prid, er->caid, cs_hexdump(0, er->ecm, er->ecmlen, tmp, er->ecmlen * 2 + 1), er->srvid);
				oscam_ser_send(client, buf, (er->ecmlen << 1) + 19); // 1 + 8 + 4 + l*2 + 4 + 2
			}
			else
			{
				snprintf((char *)buf, 512, "%c%08X%04X%s\n\r",
						 3, er->prid, er->caid, cs_hexdump(0, er->ecm, er->ecmlen, tmp, er->ecmlen * 2 + 1));
				oscam_ser_send(client, buf, (er->ecmlen << 1) + 15); // 1 + 8 + 4 + l*2 + 2
			}
			free(tmp);
		}
		break;
	case P_ALPHA:
		buf[0] = 0x80;
		i2b_buf(2, 2 + er->ecmlen, buf + 1);
		i2b_buf(2, er->caid, buf + 3);
		memcpy(buf + 5, er->ecm, er->ecmlen);
		oscam_ser_send(client, buf, oscam_ser_alpha_convert(buf, 5 + er->ecmlen));
		break;
	}
	return (0);
}
示例#8
0
static void oscam_ser_send_dcw(struct s_client *client, ECM_REQUEST *er)
{
  uchar mbuf[23];
  int32_t i;
  uchar crc;
  struct s_serial_client *serialdata=cur_client()->serialdata;
  if (er->rc<E_NOTFOUND)		// found
    switch(serialdata->connected)
    {
      case P_HSIC:
        for (i=0, crc=HSIC_CRC; i<16; i++)
          crc^=er->cw[i];
        memset(mbuf   , 0x04  ,  2);
        memset(mbuf+2 , 0x3a  ,  2);
        memcpy(mbuf+4 , er->cw, 16);
        memcpy(mbuf+20, &crc  ,  1);
        memset(mbuf+21, 0x1b  ,  2);
        oscam_ser_send(client, mbuf, 23);
        break;
      case P_SSSP:
        mbuf[0]=0xF2;
        mbuf[1]=0;
        mbuf[2]=16;
        memcpy(mbuf+3, er->cw, 16);
        oscam_ser_send(client, mbuf, 19);
        if (!serialdata->sssp_fix)
        {
          mbuf[0]=0xF1;
          mbuf[1]=0;
          mbuf[2]=2;
          i2b_buf(2, er->pid, mbuf + 3);
          oscam_ser_send(client, mbuf, 5);
          serialdata->sssp_fix=1;
        }
        break;
      case P_GBOX:
      case P_BOMBA:
        oscam_ser_send(client, er->cw, 16);
        break;
      case P_DSR95:
        mbuf[0]=4;
        memcpy(mbuf+1, er->cw, 16);
        oscam_ser_send(client, mbuf, 17);
        if( serialdata->dsr9500type==P_DSR_GNUSMAS )
        {
          serialdata->samsung_0a=0;
          for( i=1; i<17; i++ )
            if( mbuf[i]==0x0A )
              serialdata->samsung_0a++;
          serialdata->samsung_dcw++;
        }
        break;
      case P_GS:
        mbuf[0]=0x03;
        mbuf[1]=0x08;
        mbuf[2]=0x10;
        mbuf[3]=0x00;
        memcpy(mbuf+4, er->cw, 16);
        oscam_ser_send(client, mbuf, 20);
        break;
      case P_ALPHA:
        mbuf[0]=0x88;
        mbuf[1]=0x00;
        mbuf[2]=0x10;
        memcpy(mbuf+3, er->cw, 16);
        oscam_ser_send(client, mbuf, 19);
        break;
    }
  else			// not found
    switch(serialdata->connected)
    {
      case P_GS:
        mbuf[0]=0x03;
        mbuf[1]=0x09;
        mbuf[2]=0x00;
        mbuf[3]=0x00;
        oscam_ser_send(client, mbuf, 4);
        break;
    }
  serialdata->serial_errors=0; // clear error counter
}
static int32_t cc_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

	if(cl->reader)
	{
		if(!cl->reader->tcp_connected)
			{ cc_cli_connect(cl); }
	}

	struct cc_data *cc = cl->cc;
	if(!cc || !cl->udp_fd)
	{
		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; }

	// build ecm message
	//buf[0] = er->caid >> 8;
	//buf[1] = er->caid & 0xff;
	//buf[2] = er->prid >> 24;
	//buf[3] = er->prid >> 16;
	//buf[4] = er->prid >> 8;
	//buf[5] = er->prid & 0xff;
	//buf[10] = er->srvid >> 8;
	//buf[11] = er->srvid & 0xff;
	buf[12] = (sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) & 0xff;
	buf[13] = (sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) >> 8;
	//buf[12] = 0;
	//buf[13] = 0;
	buf[14] = rc;

	i2b_buf(2, er->caid, buf + 0);
	i2b_buf(4, er->prid, buf + 2);
	i2b_buf(2, er->srvid, buf + 10);

	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, cc->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 = cc_cmd_send(cl, buf, size + 20, MSG_CACHE_PUSH);
	if(res > 0)   // cache-ex is pushing out, so no receive but last_g should be updated otherwise disconnect!
	{
		if(cl->reader)
			{ cl->reader->last_s = cl->reader->last_g = time((time_t *)0); } // correct
		if(cl) { cl->last = time(NULL); }
	}
	NULLFREE(buf);
	return res;
}
void cc_cacheex_filter_out(struct s_client *cl)
{
	struct s_reader *rdr = (cl->typ == 'c') ? NULL : cl->reader;
	int i = 0, j;
	CECSPVALUETAB *filter;
	//minimal size, keep it <= 512 for max UDP packet size without fragmentation
	int32_t size = 482;
	uint8_t buf[482];
	memset(buf, 0, sizeof(buf));

	//mode==2 send filters from rdr
	if(rdr && rdr->cacheex.mode == 2)
	{
		filter = &rdr->cacheex.filter_caidtab;
	}
	//mode==3 send filters from acc
	else if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode == 3)
	{
		filter = &cl->account->cacheex.filter_caidtab;
	}
	else {
		return;
	}

	i2b_buf(2, filter->n, buf + i);
	i += 2;

	int32_t max_filters = 30;
	for(j=0; j<max_filters; j++)
	{
		if(j<CS_MAXCAIDTAB)
		{
			i2b_buf(4, filter->caid[j], buf + i);
		}
		i += 4;
	}

	for(j=0; j<max_filters && j<CS_MAXCAIDTAB; j++)
	{
		if(j<CS_MAXCAIDTAB)
		{
			i2b_buf(4, filter->cmask[j], buf + i);
		}
		i += 4;
	}

	for(j=0; j<max_filters && j<CS_MAXCAIDTAB; j++)
	{
		if(j<CS_MAXCAIDTAB)
		{
			i2b_buf(4, filter->prid[j], buf + i);
		}
		i += 4;
	}

	for(j=0; j<max_filters && j<CS_MAXCAIDTAB; j++)
	{
		if(j<CS_MAXCAIDTAB)
		{
			i2b_buf(4, filter->srvid[j], buf + i);
		}
		i += 4;
	}

	cs_log_dbg(D_CACHEEX, "cacheex: sending push filter request to %s", username(cl));
	cc_cmd_send(cl, buf, size, MSG_CACHE_FILTER);
}
示例#11
0
static void camd35_request_emm(ECM_REQUEST *er)
{
	int32_t i;
	time_t now;
	uchar mbuf[1024];
	struct s_client *cl = cur_client();
	struct s_reader *aureader = NULL, *rdr = NULL;

	if(er->selected_reader && !er->selected_reader->audisabled && ll_contains(cl->aureader_list, er->selected_reader))
		{ aureader = er->selected_reader; }

	if(!aureader && cl->aureader_list)
	{
		LL_ITER itr = ll_iter_create(cl->aureader_list);
		while((rdr = ll_iter_next(&itr)))
		{
			if(emm_reader_match(rdr, er->caid, er->prid))
			{
				aureader = rdr;
				break;
			}
		}
	}

	if(!aureader)
		{ return; }  // TODO

	uint16_t au_caid = aureader->caid;

	if(!au_caid && caid_is_bulcrypt(er->caid)) // Bulcrypt has 2 caids and aureader->caid can't be used. Use ECM_REQUEST caid for AU.
		{ au_caid = er->caid; }

	time(&now);
	if(!memcmp(cl->lastserial, aureader->hexserial, 8))
		if(llabs(now - cl->last) < 180) { return; }

	memcpy(cl->lastserial, aureader->hexserial, 8);
	cl->last = now;

	if(au_caid)
	{
		cl->disable_counter = 0;
		cs_log("%s emm-request sent (reader=%s, caid=%04X, auprovid=%06X)",
			   username(cur_client()), aureader->label, au_caid,
			   aureader->auprovid ? aureader->auprovid : b2i(4, aureader->prid[0]));
	}
	else if(cl->disable_counter > 2)
		{ return; }
	else
		{ cl->disable_counter++; }

	memset(mbuf, 0, sizeof(mbuf));
	mbuf[2] = mbuf[3] = 0xff;           // must not be zero
	i2b_buf(2, er->srvid, mbuf + 8);

	//override request provid with auprovid if set in CMD05
	if(aureader->auprovid)
	{
		if(aureader->auprovid != er->prid)
			{ i2b_buf(4, aureader->auprovid, mbuf + 12); }
		else
			{ i2b_buf(4, er->prid, mbuf + 12); }
	}
	else
	{
		i2b_buf(4, er->prid, mbuf + 12);
	}

	i2b_buf(2, er->pid, mbuf + 16);
	mbuf[0] = 5;
	mbuf[1] = 111;
	if(au_caid)
	{
		mbuf[39] = 1;                           // no. caids
		mbuf[20] = au_caid >> 8;        // caid's (max 8)
		mbuf[21] = au_caid & 0xff;
		memcpy(mbuf + 40, aureader->hexserial, 6);  // serial now 6 bytes
		mbuf[47] = aureader->nprov;
		for(i = 0; i < aureader->nprov; i++)
		{
			if((au_caid >= 0x1700 && au_caid <= 0x1799)  ||  // Betacrypt
					(au_caid >= 0x0600 && au_caid <= 0x0699))    // Irdeto (don't know if this is correct, cause I don't own a IRDETO-Card)
			{
				mbuf[48 + (i * 5)] = aureader->prid[i][0];
				memcpy(&mbuf[50 + (i * 5)], &aureader->prid[i][1], 3);
			}
			else
			{
				mbuf[48 + (i * 5)] = aureader->prid[i][2];
				mbuf[49 + (i * 5)] = aureader->prid[i][3];
				memcpy(&mbuf[50 + (i * 5)], &aureader->sa[i][0], 4); // for conax we need at least 4 Bytes
			}
		}
		//we think client/server protocols should deliver all information, and only readers should discard EMM
		mbuf[128] = (aureader->blockemm & EMM_GLOBAL && !(aureader->saveemm & EMM_GLOBAL)) ? 0 : 1;
		mbuf[129] = (aureader->blockemm & EMM_SHARED && !(aureader->saveemm & EMM_SHARED)) ? 0 : 1;
		mbuf[130] = (aureader->blockemm & EMM_UNIQUE && !(aureader->saveemm & EMM_UNIQUE)) ? 0 : 1;
		mbuf[127] = (aureader->blockemm & EMM_UNKNOWN && !(aureader->saveemm & EMM_UNKNOWN)) ? 0 : 1;
	}
	else        // disable emm
		{ mbuf[20] = mbuf[39] = mbuf[40] = mbuf[47] = mbuf[49] = 1; }
示例#12
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;
}
示例#13
0
static int32_t ghttp_capmt_notify(struct s_client *client, struct demux_s *demux)
{
	uchar req[640], lenhdr[64] = "";
	uchar *pids = NULL;
	uchar *end;
	char *encauth = NULL;
	int32_t ret;
	int8_t i, pids_len = 0, offs = 0;
	s_ghttp *context = (s_ghttp *)client->ghttp;

	if(!context) { return -1; }

	cs_debug_mask(D_CLIENT, "%s: capmt %x-%x-%x %d pids on adapter %d mask %x dmx index %d", client->reader->label, demux->onid, demux->tsid, demux->program_number, demux->ECMpidcount, demux->adapter_index, demux->ca_mask, demux->demux_index);

	if(demux->ECMpidcount > 0)
	{
		if(cs_malloc(&pids, demux->ECMpidcount * 8))
		{
			pids_len = demux->ECMpidcount * 8;
			for(i = 0; i < demux->ECMpidcount; i++)
			{
				i2b_buf(2, demux->ECMpids[i].ECM_PID, pids + offs);
				i2b_buf(2, demux->ECMpids[i].CAID, pids + (offs += 2));
				i2b_buf(4, demux->ECMpids[i].PROVID, pids + (offs += 2));
				offs += 4;
			}
			snprintf((char *)lenhdr, sizeof(lenhdr), "\r\nContent-Length: %d", pids_len);
		}
		else { return -1; }
	}

	if(!context->host_id) { context->host_id = (uchar *)cs_strdup(client->reader->device); }

	encauth = _ghttp_basic_auth(client);

	if(encauth)    // basic auth login
	{
		ret = snprintf((char *)req, sizeof(req), "%s /api/p/%x/%x/%x/%x/%x HTTP/1.1\r\nHost: %s\r\nAuthorization: Basic %s%s\r\n\r\n", ((pids_len > 0) ? "POST" : "GET"), demux->onid, demux->tsid, demux->program_number, demux->ECMpidcount, demux->enigma_namespace, context->host_id, encauth, lenhdr);
		free(encauth);
	}
	else
	{
		if(context->session_id)    // session exists
		{
			ret = snprintf((char *)req, sizeof(req), "%s /api/p/%s/%x/%x/%x/%x/%x HTTP/1.1\r\nHost: %s%s\r\n\r\n", ((pids_len > 0) ? "POST" : "GET"), context->session_id, demux->onid, demux->tsid, demux->program_number, demux->ECMpidcount, demux->enigma_namespace, context->host_id, lenhdr);
		}
		else     // no credentials configured, assume no session required
		{
			ret = snprintf((char *)req, sizeof(req), "%s /api/p/%x/%x/%x/%x/%x HTTP/1.1\r\nHost: %s%s\r\n\r\n", ((pids_len > 0) ? "POST" : "GET"), demux->onid, demux->tsid, demux->program_number, demux->ECMpidcount, demux->enigma_namespace, context->host_id, lenhdr);
		}
	}
	end = req + ret;
	if(pids_len > 0)
	{
		memcpy(end, pids, pids_len);
		cs_debug_mask(D_CLIENT, "%s: new unscrambling detected, switching to post", client->reader->label);
		_set_pid_status(context->post_contexts, demux->onid, demux->tsid, demux->program_number, 0);
	}
	cs_ddump_mask(D_CLIENT, pids, pids_len, "%s: sending capmt ecm pids - %s /api/p/%x/%x/%x/%x/%x", client->reader->label, (pids_len > 0) ? "POST" : "GET", demux->onid, demux->tsid, demux->program_number, demux->ECMpidcount, demux->enigma_namespace);

	ret = ghttp_send(client, req, ret + pids_len);

	if(pids_len > 0) { free(pids); }

	return 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;
}
/**
 * send push filter
 */
void camd35_cacheex_send_push_filter(struct s_client *cl, uint8_t mode)
{
	struct s_reader *rdr = cl->reader;
	int i = 20, j;
	CECSPVALUETAB *filter;
	//maximum size: 20+255
	uint8_t buf[20+242];
	memset(buf, 0, sizeof(buf));
	buf[0] = 0x3c;
	buf[1] = 0xf2;

	//mode==2 send filters from rdr
	if(mode == 2 && rdr)
	{
		filter = &rdr->cacheex.filter_caidtab;
	}
	//mode==3 send filters from acc
	else if(mode == 3 && cl->typ == 'c' && cl->account)
	{
		filter = &cl->account->cacheex.filter_caidtab;
	}
	else {
		return;
	}

	i2b_buf(2, filter->n, buf + i);
	i += 2;

	int32_t max_filters = 15;
	for(j=0; j<max_filters; j++)
	{
		if(j<CS_MAXCAIDTAB)
		{
			i2b_buf(4, filter->caid[j], buf + i);
		}
		i += 4;
	}

	for(j=0; j<max_filters && j<CS_MAXCAIDTAB; j++)
	{
		if(j<CS_MAXCAIDTAB)
		{
			i2b_buf(4, filter->cmask[j], buf + i);
		}
		i += 4;
	}

	for(j=0; j<max_filters && j<CS_MAXCAIDTAB; j++)
	{
		if(j<CS_MAXCAIDTAB)
		{
			i2b_buf(4, filter->prid[j], buf + i);
		}
		i += 4;
	}

	for(j=0; j<max_filters && j<CS_MAXCAIDTAB; j++)
	{
		if(j<CS_MAXCAIDTAB)
		{
			i2b_buf(4, filter->srvid[j], buf + i);
		}
		i += 4;
	}

	cs_log_dbg(D_CACHEEX, "cacheex: sending push filter request to %s", username(cl));
	camd35_send_without_timeout(cl, buf, 242); //send adds +20
}