Beispiel #1
0
void cardreader_process_ecm(struct s_reader *reader, struct s_client *cl, ECM_REQUEST *er)
{

	cs_log_dump_dbg(D_ATR, er->ecm, er->ecmlen, "ecm:");

	struct timeb tps, tpe;
	struct s_ecm_answer ea;
	memset(&ea, 0, sizeof(struct s_ecm_answer));
	
	cs_ftime(&tps);
	int32_t rc = cardreader_do_ecm(reader, er, &ea);
	cs_ftime(&tpe);
	
	rdr_log_dbg(reader, D_READER, "%s: cardreader_do_ecm returned rc=%d (ERROR=%d)", __func__, rc, ERROR);

	ea.rc = E_FOUND; //default assume found
	ea.rcEx = 0; //no special flag

	if(rc == ERROR)
	{
		char buf[CS_SERVICENAME_SIZE];
		rdr_log_dbg(reader, D_READER, "Error processing ecm for caid %04X, provid %06X, srvid %04X, servicename: %s",
					   er->caid, er->prid, er->srvid, get_servicename(cl, er->srvid, er->prid, er->caid, buf, sizeof(buf)));
		ea.rc = E_NOTFOUND;
		ea.rcEx = 0;
		ICC_Async_DisplayMsg(reader, "Eer");
	}

	if(rc == E_CORRUPT)
	{
		char buf[CS_SERVICENAME_SIZE];
		rdr_log_dbg(reader, D_READER, "Error processing ecm for caid %04X, provid %06X, srvid %04X, servicename: %s",
					   er->caid, er->prid, er->srvid, get_servicename(cl, er->srvid, er->prid, er->caid, buf, sizeof(buf)));
		ea.rc = E_NOTFOUND;
		ea.rcEx = E2_WRONG_CHKSUM; //flag it as wrong checksum
		memcpy(ea.msglog, "Invalid ecm type for card", 25);
	}

	write_ecm_answer(reader, er, ea.rc, ea.rcEx, ea.cw, ea.msglog, ea.tier, &ea.cw_ex);
	
	cl->lastecm = time((time_t *)0);
	char ecmd5[17 * 3];
	cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));

	rdr_log_dbg(reader, D_READER, "ecm hash: %s real time: %"PRId64" ms", ecmd5, comp_timeb(&tpe, &tps));
	
	reader_post_process(reader);
}
void cardreader_process_ecm(struct s_reader *reader, struct s_client *cl, ECM_REQUEST *er) {
	if (ecm_ratelimit_check(reader, er, 1) != OK) {
		rdr_debug_mask(reader, D_READER, "%s: ratelimit check failed.", __func__);
		return; // reader_mode = 1: checkout ratelimiter in reader mode so srvid can be replaced
	}
	cs_ddump_mask(D_ATR, er->ecm, er->ecmlen, "ecm:");

	struct timeb tps, tpe;
	cs_ftime(&tps);

	struct s_ecm_answer ea;
	memset(&ea, 0, sizeof(struct s_ecm_answer));

	int32_t rc = cardreader_do_ecm(reader, er, &ea);
	rdr_debug_mask(reader, D_READER, "%s: cardreader_do_ecm returned rc=%d (ERROR=%d)", __func__, rc, ERROR);

	ea.rc = E_FOUND; //default assume found
	ea.rcEx = 0; //no special flag

	if (rc == ERROR) {
		char buf[32];
		rdr_debug_mask(reader, D_READER, "Error processing ecm for caid %04X, srvid %04X, servicename: %s",
			er->caid, er->srvid, get_servicename(cl, er->srvid, er->caid, buf));
		ea.rc = E_NOTFOUND;
		ea.rcEx = 0;
		ICC_Async_DisplayMsg(reader, "Eer");
	}

	if (rc == E_CORRUPT) {
		char buf[32];
		rdr_debug_mask(reader, D_READER, "Error processing ecm for caid %04X, srvid %04X, servicename: %s",
			er->caid, er->srvid, get_servicename(cl, er->srvid, er->caid, buf));
		ea.rc = E_NOTFOUND;
		ea.rcEx = E2_WRONG_CHKSUM; //flag it as wrong checksum
		memcpy (ea.msglog,"Invalid ecm type for card",25);
	}
	cs_ftime(&tpe);
	cl->lastecm=time((time_t*)0);
	char ecmd5[17*3];                
    cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));

	rdr_debug_mask(reader, D_READER, "ecm hash: %s real time: %ld ms",
		ecmd5, 1000 * (tpe.time - tps.time) + tpe.millitm - tps.millitm);

	write_ecm_answer(reader, er, ea.rc, ea.rcEx, ea.cw, ea.msglog);

	reader_post_process(reader);
}
Beispiel #3
0
/*
 * This function writes the current CW from ECM struct to a cwl file.
 * The filename is re-calculated and file re-opened every time.
 * This will consume a bit cpu time, but nothing has to be stored between
 * each call. If not file exists, a header is prepended
 */
void logCWtoFile(ECM_REQUEST *er, uchar *cw){
	FILE *pfCWL;
	char srvname[128];
	/* %s / %s   _I  %04X  _  %s  .cwl  */
	char buf[256 + sizeof(srvname)];
	char date[9];
	unsigned char  i, parity, writeheader = 0;
	time_t t;
	struct tm timeinfo;

	/*
	* search service name for that id and change characters
	* causing problems in file name
	*/

	get_servicename(cur_client(), er->srvid, er->caid, srvname);

	for (i = 0; srvname[i]; i++)
		if (srvname[i] == ' ') srvname[i] = '_';

	/* calc log file name */
	time(&t);
	localtime_r(&t, &timeinfo);
	strftime(date, sizeof(date), "%Y%m%d", &timeinfo);
	snprintf(buf, sizeof(buf), "%s/%s_I%04X_%s.cwl", cfg.cwlogdir, date, er->srvid, srvname);

	/* open failed, assuming file does not exist, yet */
	if((pfCWL = fopen(buf, "r")) == NULL) {
		writeheader = 1;
	} else {
	/* we need to close the file if it was opened correctly */
		fclose(pfCWL);
	}

	if ((pfCWL = fopen(buf, "a+")) == NULL) {
		/* maybe this fails because the subdir does not exist. Is there a common function to create it?
			for the moment do not print32_t to log on every ecm
			cs_log(""error opening cw logfile for writing: %s (errno=%d %s)", buf, errno, strerror(errno)); */
		return;
	}
	if (writeheader) {
		/* no global macro for cardserver name :( */
		fprintf(pfCWL, "# OSCam cardserver v%s - http://streamboard.de.vu/oscam/\n", CS_VERSION);
		fprintf(pfCWL, "# control word log file for use with tsdec offline decrypter\n");
		strftime(buf, sizeof(buf),"DATE %Y-%m-%d, TIME %H:%M:%S, TZ %Z\n", &timeinfo);
		fprintf(pfCWL, "# %s", buf);
		fprintf(pfCWL, "# CAID 0x%04X, SID 0x%04X, SERVICE \"%s\"\n", er->caid, er->srvid, srvname);
	}

	parity = er->ecm[0]&1;
	fprintf(pfCWL, "%d ", parity);
	for (i = parity * 8; i < 8 + parity * 8; i++)
		fprintf(pfCWL, "%02X ", cw[i]);
	/* better use incoming time er->tps rather than current time? */
	strftime(buf,sizeof(buf),"%H:%M:%S\n", &timeinfo);
	fprintf(pfCWL, "# %s", buf);
	fflush(pfCWL);
	fclose(pfCWL);
}
Beispiel #4
0
void cs_statistics(struct s_client * client)
{
	if (!cfg.disableuserfile){
		time_t t;
		struct tm lt;
		char buf[LOG_BUF_SIZE];

		float cwps;

		time(&t);
		localtime_r(&t, &lt);
		if (client->cwfound+client->cwnot>0)
		{
			cwps=client->last-client->login;
			cwps/=client->cwfound+client->cwnot;
		}
		else
			cwps=0;

		char channame[32];
		if(cfg.mon_appendchaninfo)
			get_servicename(client, client->last_srvid,client->last_caid, channame);
		else
			channame[0] = '\0';

		int32_t lsec;
		if ((client->last_caid == 0xFFFF) && (client->last_srvid == 0xFFFF))
			lsec = client->last - client->login; //client leave calc total duration
		else
			lsec = client->last - client->lastswitch;

		int32_t secs = 0, fullmins = 0, mins = 0, fullhours = 0;

		if((lsec > 0) && (lsec < 1000000)) {
			secs = lsec % 60;
			if (lsec > 60) {
				fullmins = lsec / 60;
				mins = fullmins % 60;
				if(fullmins > 60) {
					fullhours = fullmins / 60;
				}
			}
		}

		/* statistics entry start with 's' to filter it out on other end of pipe
		 * so we can use the same Pipe as Log
		 */
		snprintf(buf, sizeof(buf), "s%02d.%02d.%02d %02d:%02d:%02d %3.1f %s %s %d %d %d %d %d %d %d %ld %ld %02d:%02d:%02d %s %04X:%04X %s\n",
				lt.tm_mday, lt.tm_mon+1, lt.tm_year%100,
				lt.tm_hour, lt.tm_min, lt.tm_sec, cwps,
				client->account->usr,
				cs_inet_ntoa(client->ip),
				client->port,
				client->cwfound,
				client->cwcache,
				client->cwnot,
				client->cwignored,
				client->cwtout,
				client->cwtun,
				client->login,
				client->last,
				fullhours, mins, secs,
				ph[client->ctyp].desc,
				client->last_caid,
				client->last_srvid,
				channame);

		cs_write_log_int(buf);
	}
}
Beispiel #5
0
static void refresh_lcd_file(void) {
	char targetfile[256];
	char tmpfile[256];
	char channame[32];

	if(cfg.lcd_output_path == NULL){
		snprintf(targetfile, sizeof(targetfile),"%s%s", get_tmp_dir(), "/oscam.lcd");
		snprintf(tmpfile, sizeof(tmpfile), "%s%s.tmp", get_tmp_dir(), "/oscam.lcd");
	} else {
		snprintf(targetfile, sizeof(targetfile),"%s%s", cfg.lcd_output_path, "/oscam.lcd");
		snprintf(tmpfile, sizeof(tmpfile), "%s%s.tmp", cfg.lcd_output_path, "/oscam.lcd");
	}

	int8_t iscccam = 0;
	int32_t seconds = 0, secs = 0, fullmins = 0, mins = 0, fullhours = 0, hours = 0,	days = 0;
	time_t now = time((time_t*)0);


	while(running) {
		now = time((time_t*)0);
		int16_t cnt = 0, idx = 0, count_r = 0, count_p = 0, count_u = 0;
		FILE *fpsave;

		if((fpsave = fopen(tmpfile, "w"))){

			idx = 0;
			int16_t i;
			char *type;
			char *label;
			char *status;

			// Statuslines start
			secs = 0; fullmins = 0; mins = 0; fullhours = 0; hours = 0; days = 0;

			seconds = now - first_client->login;
			secs = seconds % 60;
			if (seconds > 60) {
				fullmins = seconds / 60;
				mins = fullmins % 60;
				if(fullmins > 60) {
					fullhours = fullmins / 60;
					hours = fullhours % 24;
					days = fullhours / 24;
				}
			}

			fprintf(fpsave,"Version: %s\n", CS_VERSION);
			fprintf(fpsave,"Revision: %s\n", CS_SVN_VERSION);
			if(days == 0)
				fprintf(fpsave, "up: %02d:%02d:%02d\n", hours, mins, secs);
			else
				fprintf(fpsave, "up: %02dd %02d:%02d:%02d\n", days, hours, mins, secs);
			fprintf(fpsave,"totals: %d/%d/%d/%d/%d/%d\n", first_client->cwfound, first_client->cwnot, first_client->cwignored, first_client->cwtout, first_client->cwcache, first_client->cwtun);
			fprintf(fpsave,"uptime: %d\n", seconds);
			// Statuslines end

			// Readertable head
			fprintf(fpsave,"Typ| Label      | Idle         | w | s | b | e | St\n");
			fprintf(fpsave,"---+------------+--------------+---+---+---+---+----\n");

			struct s_client *cl;

			// Reader/Proxy table start
			for ( i=0, cl=first_client; cl ; cl=cl->next, i++) {

				if ((cl->typ=='r' || cl->typ=='p') && ((now - cl->last) < 20 || !cfg.lcd_hide_idle)){
					type = "";
					label = "";
					status = "OFF";
					secs = 0; fullmins = 0; mins = 0; fullhours = 0; hours = 0; days = 0;

					seconds = now - cl->last;

					if (cl->typ == 'r'){
						type = "R";
						idx = count_r;
						label = cl->reader->label;
						if (cl->reader->card_status == CARD_INSERTED)
							status = "OK";
						count_r++;
					}

					else if (cl->typ == 'p'){
						type = "P";
						iscccam = 0;
						idx = count_p;
						label = cl->reader->label;
						if ((strncmp(monitor_get_proto(cl), "cccam", 5) == 0))
							iscccam = 1;

						if (cl->reader->card_status == CARD_INSERTED)
							status = "CON";

						count_p++;
					}


					secs = seconds % 60;
					if (seconds > 60) {
						fullmins = seconds / 60;
						mins = fullmins % 60;
						if(fullmins > 60) {
							fullhours = fullmins / 60;
							hours = fullhours % 24;
							days = fullhours / 24;
						}
					}

					int16_t written = 0, skipped = 0, blocked = 0, error = 0;

					char *emmtext;
					if(cs_malloc(&emmtext, 16 * sizeof(char), -1)){
						if(cl->typ == 'r' || !iscccam ){
							for (i=0; i<4; i++) {
								error += cl->reader->emmerror[i];
								blocked += cl->reader->emmblocked[i];
								skipped += cl->reader->emmskipped[i];
								written += cl->reader->emmwritten[i];
							}
							snprintf(emmtext, 16, "%3d|%3d|%3d|%3d",
									written > 999? 999 : written,
									skipped > 999? 999 : skipped,
									blocked > 999? 999 : blocked,
									error > 999? 999 : error);

						}
#ifdef MODULE_CCCAM
						else if(cl->typ == 'p' && iscccam ){
							struct cc_data *rcc = cl->cc;
							if(rcc){
								LLIST *cards = rcc->cards;
								if (cards) {
									int32_t cnt = ll_count(cards);
									int32_t locals = rcc->num_hop1;
									snprintf(emmtext, 16, " %3d/%3d card%s", locals, cnt, (cnt > 1)? "s ": "  ");
								}
							} else {
								snprintf(emmtext, 16, "   No cards    ");
							}
						}
#endif
						else {
							snprintf(emmtext, 16, "               ");
						}

					}

					if(days == 0) {
						fprintf(fpsave,"%s%d | %-10.10s |     %02d:%02d:%02d |%s| %s\n",
								type, idx, label, hours, mins,
								secs, emmtext, status);
					} else {
						fprintf(fpsave,"%s%d | %-10.10s |% 3dd %02d:%02d:%02d |%s| %s\n",
								type, idx, label, days, hours, mins,
								secs, emmtext, status);
					}
					free(emmtext);
				}
			}

			fprintf(fpsave,"---+------------+--------------+---+---+---+--++----\n");
			// Reader/Proxy table end


			// Usertable start
			fprintf(fpsave,"Typ| Label      | Channel                     | Time\n");
			fprintf(fpsave,"---+------------+-----------------------------+-----\n");

			/*
			//Testclient
			fprintf(fpsave,"%s%d | %-10.10s | %-10.10s:%-17.17s| % 4d\n",
					"U",
					1,
					"test",
					"Sky De",
					"Discovery Channel",
					568);

			*/

			for ( i=0, cl=first_client; cl ; cl=cl->next, i++) {

				seconds = now - cl->lastecm;

				if (cl->typ == 'c' && seconds < 15){
					type = "U";
					idx = count_u;
					label = cl->account->usr;
					count_u++;

					get_servicename(cl, cl->last_srvid, cl->last_caid, channame);
					fprintf(fpsave,"%s%d | %-10.10s | %-10.10s:%-17.17s| % 4d\n",
							type,
							idx,
							label,
							cl->last_srvidptr && cl->last_srvidptr->prov ? cl->last_srvidptr->prov : "",
									cl->last_srvidptr && cl->last_srvidptr->name ? cl->last_srvidptr->name : "",
											cl->cwlastresptime);

				}
			}
			fprintf(fpsave,"---+------------+-----------------------------+-----\n");
			// Usertable end
			fclose(fpsave);
		}

		idx = 0;
		cs_sleepms(cfg.lcd_write_intervall * 1000);
		cnt++;

		if(rename(tmpfile, targetfile) < 0)
			cs_log("An error occured while writing oscam.lcd file %s.", targetfile);

	}

}
Beispiel #6
0
static char *monitor_client_info(char id, struct s_client *cl, char *sbuf){
	char channame[32];
	sbuf[0] = '\0';

	if (cl){
		char ldate[16], ltime[16], *usr;
		int32_t lsec, isec, con, cau, lrt =- 1;
		time_t now;
		struct tm lt;
		now=time((time_t*)0);

		if	((cfg.hideclient_to <= 0) ||
				(now-cl->lastecm < cfg.hideclient_to) ||
				(now-cl->lastemm < cfg.hideclient_to) ||
				(cl->typ != 'c'))
		{
			lsec = now - cl->login;
			isec = now - cl->last;
			usr = username(cl);
			if (cl->dup)
				con = 2;
			else
				if ((cl->tosleep) && (now-cl->lastswitch>cl->tosleep))
					con = 1;
				else
					con = 0;

			// no AU reader == 0 / AU ok == 1 / Last EMM > aulow == -1
			if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r') {

				if ((cl->typ == 'c' && ll_count(cl->aureader_list) == 0) ||
						((cl->typ == 'p' || cl->typ == 'r') && cl->reader->audisabled))
					cau = 0;

				else if ((now-cl->lastemm) / 60 > cfg.aulow)
					cau = (-1);

				else
					cau = 1;

			} else {
				cau = 0;
			}

			if( cl->typ == 'r')
			{
				int32_t i;
				struct s_reader *rdr;
				for (i=0,rdr=first_active_reader; rdr ; rdr=rdr->next, i++)
					if (cl->reader == rdr)
						lrt=i;

				if( lrt >= 0 )
					lrt = 10 + cl->reader->card_status;
			}
			else
                lrt = cl->cwlastresptime;
			localtime_r(&cl->login, &lt);
			snprintf(ldate, sizeof(ldate), "%02d.%02d.%02d", lt.tm_mday, lt.tm_mon+1, lt.tm_year % 100);
			int32_t cnr=get_threadnum(cl);
			snprintf(ltime, sizeof(ldate), "%02d:%02d:%02d", lt.tm_hour, lt.tm_min, lt.tm_sec);
			snprintf(sbuf, 256, "[%c--CCC]%8X|%c|%d|%s|%d|%d|%s|%d|%s|%s|%s|%d|%04X:%04X|%s|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d\n",
					id, cl->tid, cl->typ, cnr, usr, cau, cl->crypted,
					cs_inet_ntoa(cl->ip), cl->port, client_get_proto(cl),
					ldate, ltime, lsec, cl->last_caid, cl->last_srvid,
					get_servicename(cl, cl->last_srvid, cl->last_caid, channame), isec, con,
                                        cl->cwfound, cl->cwnot, cl->cwcache, cl->cwignored,
                                        cl->cwtout, cl->emmok, cl->emmnok, lrt);
		}
	}
	return sbuf;
}
Beispiel #7
0
void cs_statistics(struct s_client *client)
{
	if(!cfg.disableuserfile)
	{
		struct tm lt;
		char buf[LOG_BUF_SIZE];

		float cwps;

		time_t walltime = cs_time();
		localtime_r(&walltime, &lt);
		if(client->cwfound + client->cwnot > 0)
		{
			cwps = client->last - client->login;
			cwps /= client->cwfound + client->cwnot;
		}
		else
			{ cwps = 0; }

		char channame[CS_SERVICENAME_SIZE];
		get_servicename(client, client->last_srvid, client->last_provid, client->last_caid, channame, sizeof(channame));

		int32_t lsec;
		if((client->last_caid == NO_CAID_VALUE) && (client->last_srvid == NO_SRVID_VALUE))
			{ lsec = client->last - client->login; } //client leave calc total duration
		else
			{ lsec = client->last - client->lastswitch; }

		int32_t secs = 0, fullmins = 0, mins = 0, fullhours = 0;

		if((lsec > 0) && (lsec < 1000000))
		{
			secs = lsec % 60;
			if(lsec > 60)
			{
				fullmins = lsec / 60;
				mins = fullmins % 60;
				if(fullmins > 60)
				{
					fullhours = fullmins / 60;
				}
			}
		}

		/* statistics entry start with 's' to filter it out on other end of pipe
		 * so we can use the same Pipe as Log
		 */
		snprintf(buf, sizeof(buf), "s%02d.%02d.%02d %02d:%02d:%02d %3.1f %s %s %d %d %d %d %d %d %d %ld %ld %02d:%02d:%02d %s %04X@%06X:%04X %s\n",
				 lt.tm_mday, lt.tm_mon + 1, lt.tm_year % 100,
				 lt.tm_hour, lt.tm_min, lt.tm_sec, cwps,
				 client->account->usr,
				 cs_inet_ntoa(client->ip),
				 client->port,
				 client->cwfound,
				 client->cwcache,
				 client->cwnot,
				 client->cwignored,
				 client->cwtout,
				 client->cwtun,
				 client->login,
				 client->last,
				 fullhours, mins, secs,
				 get_module(client)->desc,
				 client->last_caid,
				 client->last_provid,
				 client->last_srvid,
				 channame);

		cs_write_log_int(buf);
	}
}