Skip to content

Commit

Permalink
*Fix: emmcache truncated last 3 bytes of cached EMM
Browse files Browse the repository at this point in the history
*Update: support large EMMs
*Update: verify EMM length

git-svn-id: http://streamboard.de.vu/svn/oscam/trunk@11069 4b0bc96b-bc66-0410-9d44-ebda105a78c1
  • Loading branch information
Aeon authored and Aeon committed Oct 31, 2015
1 parent 047af06 commit 0f07ad0
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 18 deletions.
2 changes: 1 addition & 1 deletion module-camd35.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ static void camd35_process_emm(uchar *buf, int buflen, int emmlen)
{ return; }
memset(&epg, 0, sizeof(epg));
epg.emmlen = emmlen;
if(epg.emmlen < 0 || epg.emmlen > MAX_EMM_SIZE)
if(epg.emmlen < 3 || epg.emmlen > MAX_EMM_SIZE)
{ return; }
memcpy(epg.caid, buf + 10, 2);
memcpy(epg.provid, buf + 12 , 4);
Expand Down
2 changes: 1 addition & 1 deletion module-newcamd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,7 @@ static void newcamd_process_emm(uchar *buf, int32_t len)

memset(&epg, 0, sizeof(epg));

epg.emmlen = buf[2] + 3;
epg.emmlen = SCT_LEN(buf);
if(epg.emmlen > MAX_EMM_SIZE || epg.emmlen > len)
{ return; }

Expand Down
2 changes: 1 addition & 1 deletion oscam-emm-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ int32_t emm_edit_cache(uchar *emmd5, EMM_PACKET *ep, bool add)
{ return count; }
memcpy(c->emmd5, emmd5, MD5_DIGEST_LENGTH);
c->type = ep->type;
c->len = ep->emm[2];
c->len = SCT_LEN(ep->emm);
cs_ftime(&c->firstseen);
c->lastseen = c->firstseen;
memcpy(c->emm, ep->emm, c->len);
Expand Down
35 changes: 22 additions & 13 deletions oscam-emm.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ static void reader_log_emm(struct s_reader *reader, EMM_PACKET *ep, int32_t coun
{ tps = &tpe; }

rdr_log(reader, "%s emmtype=%s, len=%d (hex: 0x%02X), cnt=%d: %s (%"PRId64" ms)",
username(ep->client), typedesc[ep->type], ep->emm[2], ep->emm[2], count, rtxt[rc], comp_timeb(&tpe, tps));
username(ep->client), typedesc[ep->type], SCT_LEN(ep->emm)-3, SCT_LEN(ep->emm)-3, count, rtxt[rc], comp_timeb(&tpe, tps));
}

if(rc)
Expand Down Expand Up @@ -274,7 +274,7 @@ static void saveemm(struct s_reader *aureader, EMM_PACKET *ep, const char *proce
{
time(&rawtime);
localtime_r(&rawtime, &timeinfo); // to access LOCAL date/time info
int32_t emm_length = ((ep->emm[1] & 0x0f) << 8) | ep->emm[2];
int32_t emm_length = SCT_LEN(ep->emm);
strftime(buf, sizeof(buf), "%Y/%m/%d %H:%M:%S", &timeinfo);
switch(ep->type)
{
Expand All @@ -298,10 +298,10 @@ static void saveemm(struct s_reader *aureader, EMM_PACKET *ep, const char *proce
}
else
{
if(cs_malloc(&tmp2, (emm_length + 3) * 2 + 1))
if(cs_malloc(&tmp2, emm_length * 2 + 1))
{
fprintf(fp_log, "%s %s ", buf, cs_hexdump(0, ep->hexserial, 8, tmp, sizeof(tmp)));
fprintf(fp_log, "%s %s\n", cs_hexdump(0, ep->emm, emm_length + 3, tmp2, (emm_length + 3) * 2 + 1), proceded);
fprintf(fp_log, "%s %s\n", cs_hexdump(0, ep->emm, emm_length, tmp2, emm_length * 2 + 1), proceded);
NULLFREE(tmp2);
rdr_log(aureader, "Successfully added EMM to %s", token_log);
}
Expand All @@ -318,8 +318,9 @@ void do_emm(struct s_client *client, EMM_PACKET *ep)
bool lastseendone = false;

struct s_reader *aureader = NULL;
uint16_t sct_len;

if(ep->emmlen < 0)
if(ep->emmlen < 3)
{
cs_log("EMM size %d invalid, ignored! client %s", ep->emmlen, username(client));
return;
Expand All @@ -330,6 +331,14 @@ void do_emm(struct s_client *client, EMM_PACKET *ep)
cs_log("EMM size %d > Max EMM size %d, ignored! client %s", ep->emmlen, MAX_EMM_SIZE, username(client));
return;
}

sct_len = SCT_LEN(ep->emm);
if(sct_len > ep->emmlen)
{
cs_log("Real EMM size %d > EMM size %d, ignored! client %s", sct_len, ep->emmlen, username(client));
return;
}
ep->emmlen = sct_len;

cs_log_dump_dbg(D_EMM, ep->emm, ep->emmlen, "emm:");

Expand Down Expand Up @@ -363,8 +372,8 @@ void do_emm(struct s_client *client, EMM_PACKET *ep)
rdr_log(aureader, "%s emmtype=%s, len=%d (hex: 0x%02X), idx=0, cnt=1: audisabled (0 ms)",
client->account->usr,
typtext[ep->type],
ep->emm[2],
ep->emm[2]);
SCT_LEN(ep->emm)-3,
SCT_LEN(ep->emm)-3);
}
continue;
}
Expand Down Expand Up @@ -488,7 +497,7 @@ void do_emm(struct s_client *client, EMM_PACKET *ep)
}

// if not already blocked we check for block by len
if(!is_blocked) { is_blocked = cs_emmlen_is_blocked(aureader, ep->emm[2]) ; }
if(!is_blocked) { is_blocked = cs_emmlen_is_blocked(aureader, SCT_LEN(ep->emm)-3) ; }

if(is_blocked != 0)
{
Expand All @@ -504,8 +513,8 @@ void do_emm(struct s_client *client, EMM_PACKET *ep)
rdr_log(aureader, "%s emmtype=%s, len=%d (hex: 0x%02X), idx=0, cnt=%d: blocked (0 ms)",
client->account->usr,
typtext[ep->type],
ep->emm[2],
ep->emm[2],
SCT_LEN(ep->emm)-3,
SCT_LEN(ep->emm)-3,
is_blocked);
}
saveemm(aureader, ep, "blocked");
Expand All @@ -527,7 +536,7 @@ void do_emm(struct s_client *client, EMM_PACKET *ep)
{
unsigned char md5tmp[MD5_DIGEST_LENGTH];

MD5(ep->emm, ep->emm[2], md5tmp);
MD5(ep->emm, SCT_LEN(ep->emm), md5tmp);

struct s_emmcache *emmcache = find_emm_cache(md5tmp); // check emm cache
if(emmcache && !lastseendone)
Expand Down Expand Up @@ -585,7 +594,7 @@ int32_t reader_do_emm(struct s_reader *reader, EMM_PACKET *ep)
uint16_t caid = b2i(2, ep->caid);
if(reader->cachemm && !caid_is_irdeto(caid))
{
MD5(ep->emm, ep->emm[2], md5tmp);
MD5(ep->emm, SCT_LEN(ep->emm), md5tmp);
int64_t gone = comp_timeb(&tps, &last_emm_clean);
if(gone > (int64_t)1000*60*60*24*30 || gone < 0) // dont run every time, only on first emm oscam is started and then every 30 days
{
Expand Down Expand Up @@ -700,7 +709,7 @@ void do_emm_from_file(struct s_reader *reader)
eptmp->caid[1] = reader->caid & 0xFF;
if(reader->nprov > 0)
{ memcpy(eptmp->provid, reader->prid[0], sizeof(eptmp->provid)); }
eptmp->emmlen = eptmp->emm[2] + 3;
eptmp->emmlen = SCT_LEN(eptmp->emm);
}
const struct s_cardsystem *csystem = get_cardsystem_by_caid(reader->caid);
if(csystem && csystem->get_emm_type && !csystem->get_emm_type(eptmp, reader))
Expand Down
2 changes: 1 addition & 1 deletion reader-griffin.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ static int32_t griffin_get_emm_type(EMM_PACKET *ep, struct s_reader *rdr)
static int32_t griffin_do_emm(struct s_reader *rdr, EMM_PACKET *ep)
{
def_resp
griffin_cmd(GRIFFIN_CMD_SEND_EMM, ep->emm, ep->emm[2] + 3, 2);
griffin_cmd(GRIFFIN_CMD_SEND_EMM, ep->emm, SCT_LEN(ep->emm), 2);
return OK;
}

Expand Down
2 changes: 1 addition & 1 deletion reader-tongfang.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ static int32_t tongfang_do_emm(struct s_reader *reader, EMM_PACKET *ep)
def_resp;
int32_t write_len;

if(ep->emm[2] < 5) { return ERROR; }
if(SCT_LEN(ep->emm) < 8) { return ERROR; }

write_len = ep->emm[15] + 5;
memcpy(emm_cmd, ep->emm + 11, write_len);
Expand Down

0 comments on commit 0f07ad0

Please sign in to comment.