/* Replacement of fprintf which adds necessary whitespace to fill up the varname to a fixed width. If varname is longer than CONFVARWIDTH, no whitespace is added*/ void fprintf_conf(FILE *f, const char *varname, const char *fmtstring, ...) { int32_t varlen = strlen(varname); int32_t max = (varlen > CONFVARWIDTH) ? varlen : CONFVARWIDTH; char varnamebuf[max + 3]; char *ptr = varnamebuf + varlen; va_list argptr; cs_strncpy(varnamebuf, varname, sizeof(varnamebuf)); while(varlen < CONFVARWIDTH) { ptr[0] = ' '; ++ptr; ++varlen; } cs_strncpy(ptr, "= ", sizeof(varnamebuf) - (ptr - varnamebuf)); if(fwrite(varnamebuf, sizeof(char), strlen(varnamebuf), f)) { if(strlen(fmtstring) > 0) { va_start(argptr, fmtstring); vfprintf(f, fmtstring, argptr); va_end(argptr); } } }
/* Gets the tmp dir */ char *get_tmp_dir(void) { if(cs_tmpdir[0]) { return cs_tmpdir; } #if defined(__CYGWIN__) char *d = getenv("TMPDIR"); if(!d || !d[0]) { d = getenv("TMP"); } if(!d || !d[0]) { d = getenv("TEMP"); } if(!d || !d[0]) { getcwd(cs_tmpdir, sizeof(cs_tmpdir) - 1); } cs_strncpy(cs_tmpdir, d, sizeof(cs_tmpdir)); char *p = cs_tmpdir; while(*p) { p++; } p--; if(*p != '/' && *p != '\\') { strcat(cs_tmpdir, "/"); } strcat(cs_tmpdir, "_oscam"); #else cs_strncpy(cs_tmpdir, "/tmp/.oscam", sizeof(cs_tmpdir)); #endif mkdir(cs_tmpdir, S_IRWXU); return cs_tmpdir; }
int main(int argc, char**argv) { int n, opt, port = 0, accountok = 0; struct sockaddr_in servaddr; socklen_t len; char mbuf[1000]; unsigned char md5tmp[MD5_DIGEST_LENGTH]; while ((opt = getopt(argc, argv, "a:p:")) != -1) { switch (opt) { case 'a': { char *ptr = strtok(optarg, ":"); cs_strncpy((char *)&cl_user, ptr, sizeof(cl_user)); ptr = strtok(NULL, ":"); if(ptr) { cs_strncpy((char *)&cl_passwd, ptr, sizeof(cl_passwd)); accountok = 1; } break; } case 'p': port = atoi(optarg); break; default: fprintf(stderr, "Usage: %s -a <user>:<password> -p <port>\n", argv[0]); exit(0); } } if(port == 0 || accountok == 0){ fprintf(stderr, "Usage: %s -a <user>:<password> -p <port>\n", argv[0]); exit(0); } cl_sockfd = socket(AF_INET,SOCK_DGRAM,0); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(port); bind(cl_sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); aes_set_key(&cl_aes_keys, (char *) MD5(cl_passwd, strlen((char *)cl_passwd), md5tmp)); for (;;){ len = sizeof(cl_socket); n = recvfrom(cl_sockfd,mbuf,sizeof(mbuf),0,(struct sockaddr *)&cl_socket,&len); camd35_recv(mbuf, n); if(mbuf[0] == 0 || mbuf[0] == 3) { camd35_process_ecm(mbuf, n); } else { cs_log("unknown/not implemented camd35 command! (%d) n=%d", mbuf[0], n); } } }
static void chk_entry4sidtab(char *value, struct s_sidtab *sidtab, int32_t what) { int32_t i, b; char *ptr, *saveptr1 = NULL; uint16_t *slist = (uint16_t *) 0; uint32_t *llist = (uint32_t *) 0; uint32_t caid; char buf[strlen(value) + 1]; cs_strncpy(buf, value, sizeof(buf)); b = (what == 1) ? sizeof(uint32_t) : sizeof(uint16_t); for(i = 0, ptr = strtok_r(value, ",", &saveptr1); ptr; ptr = strtok_r(NULL, ",", &saveptr1)) { caid = a2i(ptr, b); if(!errno) { i++; } } //if (!i) return(0); if(b == sizeof(uint16_t)) { if(!cs_malloc(&slist, i * sizeof(uint16_t))) { return; } } else { if(!cs_malloc(&llist, i * sizeof(uint32_t))) { return; } } cs_strncpy(value, buf, sizeof(buf)); for(i = 0, ptr = strtok_r(value, ",", &saveptr1); ptr; ptr = strtok_r(NULL, ",", &saveptr1)) { caid = a2i(ptr, b); if(errno) { continue; } if(b == sizeof(uint16_t)) { slist[i++] = (uint16_t) caid; } else { llist[i++] = caid; } } switch(what) { case 0: add_garbage(sidtab->caid); sidtab->caid = slist; sidtab->num_caid = i; break; case 1: add_garbage(sidtab->provid); sidtab->provid = llist; sidtab->num_provid = i; break; case 2: add_garbage(sidtab->srvid); sidtab->srvid = slist; sidtab->num_srvid = i; break; } }
static void monitor_send_info(char *txt, int32_t last) { static int32_t seq=0, counter=0; static char btxt[256] = {0}; char buf[8]; if (txt) { if (!btxt[0]) { counter=0; txt[2]='B'; } else counter++; snprintf(buf, sizeof(buf), "%03d", counter); memcpy(txt+4, buf, 3); txt[3]='0'+seq; } else if (!last) return; if (!last) { if (btxt[0]) monitor_send(btxt); cs_strncpy(btxt, txt, sizeof(btxt)); return; } if (txt && btxt[0]) { monitor_send(btxt); txt[2]='E'; cs_strncpy(btxt, txt, sizeof(btxt)); } else { if (txt) cs_strncpy(btxt, txt, sizeof(btxt)); btxt[2]=(btxt[2]=='B') ? 'S' : 'E'; } if (btxt[0]) { monitor_send(btxt); seq=(seq+1)%10; } btxt[0]=0; }
static void http_dyndns_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { int i; if(value) { char *ptr, *saveptr1 = NULL; memset(cfg.http_dyndns, 0, sizeof(cfg.http_dyndns)); for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < MAX_HTTP_DYNDNS) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++) { trim(ptr); cs_strncpy((char *)cfg.http_dyndns[i], ptr, sizeof(cfg.http_dyndns[i])); } return; } if(strlen((const char *)(cfg.http_dyndns[0])) > 0 || cfg.http_full_cfg) { fprintf_conf(f, token, "%s", ""); // it should not have \n at the end for(i = 0; i < MAX_HTTP_DYNDNS; i++) { if(cfg.http_dyndns[i][0]) { fprintf(f, "%s%s", i > 0 ? "," : "", cfg.http_dyndns[i]); } } fprintf(f, "\n"); } }
static void monitor_process_details_master(char *buf, uint32_t pid){ snprintf(buf, 256, "Version=%sr%s", CS_VERSION, CS_SVN_VERSION); monitor_send_details(buf, pid); snprintf(buf, 256, "System=%s", CS_TARGET); monitor_send_details(buf, pid); snprintf(buf, 256, "DebugLevel=%d", cs_dblevel); monitor_send_details(buf, pid); snprintf(buf, 256, "MaxClients=UNLIMITED"); monitor_send_details(buf, pid); snprintf(buf, 256, "ClientMaxIdle=%d sec", cfg.cmaxidle); monitor_send_details(buf, pid); if( cfg.max_log_size ) snprintf(buf + 200, 56, "%d Kb", cfg.max_log_size); else cs_strncpy(buf + 200, "unlimited", 56); snprintf(buf, 256, "MaxLogsize=%s", buf + 200); monitor_send_details(buf, pid); snprintf(buf, 256, "ClientTimeout=%u ms", cfg.ctimeout); monitor_send_details(buf, pid); snprintf(buf, 256, "CacheDelay=%d ms", cfg.delay); monitor_send_details(buf, pid); if( cfg.cwlogdir ) { snprintf(buf, 256, "CwlogDir=%s", cfg.cwlogdir); monitor_send_details(buf, pid); } if( cfg.preferlocalcards ) { snprintf(buf, 256, "PreferlocalCards=%d", cfg.preferlocalcards); monitor_send_details(buf, pid); } if( cfg.waitforcards ) { snprintf(buf, 256, "WaitforCards=%d", cfg.waitforcards); monitor_send_details(buf, pid); } snprintf(buf, 256, "LogFile=%s", cfg.logfile); monitor_send_details(buf, pid); if( cfg.mailfile ) { snprintf(buf, 256, "MailFile=%s", cfg.mailfile); monitor_send_details(buf, pid); } if( cfg.usrfile ) { snprintf(buf, 256, "UsrFile=%s", cfg.usrfile); monitor_send_details(buf, pid); } monitor_send_details(buf, pid); snprintf(buf, 256, "Sleep=%d", cfg.tosleep); monitor_send_details(buf, pid); snprintf(buf, 256, "Monitorport=%d", cfg.mon_port); monitor_send_details(buf, pid); snprintf(buf, 256, "Nice=%d", cfg.nice); monitor_send_details(buf, pid); #ifdef WEBIF snprintf(buf, 256, "Restartmode=%d", cs_get_restartmode()); monitor_send_details(buf, pid); #else snprintf(buf, 256, "Restartmode=%s", "no"); monitor_send_details(buf, pid); #endif // monitor_send_details(buf, pid); }
static void reader_label_fn(const char *token, char *value, void *setting, FILE *f) { struct s_reader *rdr = setting; if(value) { int i, found = 0; if(!strlen(value)) { return; } for(i = 0; i < (int)strlen(value); i++) { if(value[i] == ' ') { value[i] = '_'; found++; } } if(found) { fprintf(stderr, "Configuration reader: corrected label to %s\n", value); } cs_strncpy(rdr->label, value, sizeof(rdr->label)); return; } fprintf_conf(f, token, "%s\n", rdr->label); }
static void device_fn(const char *token, char *value, void *setting, FILE *f) { struct s_reader *rdr = setting; int32_t isphysical = !is_network_reader(rdr); if(value) { int32_t i; char *ptr, *saveptr1 = NULL; for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 3) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++) { trim(ptr); switch(i) { case 0: cs_strncpy(rdr->device, ptr, sizeof(rdr->device)); break; case 1: rdr->r_port = atoi(ptr); break; case 2: rdr->l_port = atoi(ptr); break; } } return; } fprintf_conf(f, token, "%s", rdr->device); // it should not have \n at the end if((rdr->r_port || cfg.http_full_cfg) && !isphysical) { fprintf(f, ",%d", rdr->r_port); } if((rdr->l_port || cfg.http_full_cfg) && !isphysical && strncmp(reader_get_type_desc(rdr, 0), "cccam", 5)) { fprintf(f, ",%d", rdr->l_port); } fprintf(f, "\n"); }
static int32_t init_oscam_ser_device(struct s_client *cl) { char *device = cl->serialdata->oscam_ser_device; speed_t baud = cl->serialdata->oscam_ser_baud; int32_t port = cl->serialdata->oscam_ser_port; int32_t fd; // network connection to a TCP-exposed serial port if (port > 0) { cs_strncpy(cl->reader->device, device, sizeof(cl->reader->device)); cl->reader->r_port = cl->port = port; fd = network_tcp_connection_open(cl->reader); if (fd < 0) return 0; else return fd; } else // standard serial port connection { fd=open(device, O_RDWR | O_NOCTTY | O_SYNC | O_NONBLOCK); if (fd>0) { fcntl(fd, F_SETFL, 0); if (oscam_ser_set_serial_device(fd, baud)<0) cs_log("ERROR ioctl"); if (tcflush(fd, TCIOFLUSH)<0) cs_log("ERROR flush"); } else { fd=0; cs_log("ERROR opening %s (errno=%d %s)", device, errno, strerror(errno)); } return(fd); } }
void log_list_thread(void) { char buf[LOG_BUF_SIZE]; log_running = 1; set_thread_name(__func__); do { log_list_queued = 0; LL_ITER it = ll_iter_create(log_list); struct s_log *log; while((log = ll_iter_next_remove(&it))) { int8_t do_flush = ll_count(log_list) == 0; //flush on writing last element cs_strncpy(buf, log->txt, LOG_BUF_SIZE); if(log->direct_log) { cs_write_log(buf, do_flush); } else { write_to_log(buf, log, do_flush); } NULLFREE(log->txt); NULLFREE(log); } if(!log_list_queued) // The list is empty, sleep until new data comes in and we are woken up sleepms_on_cond(&log_thread_sleep_cond_mutex, &log_thread_sleep_cond, 60 * 1000); } while(log_running); ll_destroy(log_list); log_list = NULL; }
static int32_t camd35_auth_client(struct s_client *cl, uchar *ucrc) { int32_t rc = 1; uint32_t crc; struct s_auth *account; unsigned char md5tmp[MD5_DIGEST_LENGTH]; if(cl->upwd[0]) { return (memcmp(cl->ucrc, ucrc, 4) ? 1 : 0); } cl->crypted = 1; crc = (((ucrc[0] << 24) | (ucrc[1] << 16) | (ucrc[2] << 8) | ucrc[3]) & 0xffffffffL); for(account = cfg.account; (account) && (!cl->upwd[0]); account = account->next) if(crc == crc32(0L, MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH)) { rc = cs_auth_client(cl, account, NULL); if(!rc) { memcpy(cl->ucrc, ucrc, 4); cs_strncpy((char *)cl->upwd, account->pwd, sizeof(cl->upwd)); if (!aes_set_key_alloc(&cl->aes_keys, (char *) MD5(cl->upwd, strlen((char *)cl->upwd), md5tmp))) { return 1; } return 0; } } return (rc); }
static void write_to_log_int(char *txt, int8_t header_len) { #if !defined(WEBIF) && !defined(MODULE_MONITOR) if(cfg.disablelog) { return; } #endif char *newtxt = cs_strdup(txt); if(!newtxt) { return; } struct s_log *log; if(!cs_malloc(&log, sizeof(struct s_log))) { NULLFREE(newtxt); return; } log->txt = newtxt; log->header_len = header_len; log->direct_log = 0; struct s_client *cl = cur_client(); log->cl_usr = ""; if(!cl) { log->cl_text = "undef"; log->cl_typ = ' '; } else { switch(cl->typ) { case 'c': case 'm': if(cl->account) { log->cl_text = cl->account->usr; log->cl_usr = cl->account->usr; } else { log->cl_text = ""; } break; case 'p': case 'r': log->cl_text = cl->reader ? cl->reader->label : ""; break; default: log->cl_text = "server"; break; } log->cl_typ = cl->typ; } if(exit_oscam == 1 || cfg.disablelog) //Exit or log disabled. if disabled, just display on webif/monitor { char buf[LOG_BUF_SIZE]; cs_strncpy(buf, log->txt, LOG_BUF_SIZE); write_to_log(buf, log, 1); NULLFREE(log->txt); NULLFREE(log); } else { log_list_add(log); } }
void *init_oscam_ser(struct s_client *UNUSED(cl), uchar *UNUSED(mbuf), int32_t module_idx) { char sdevice[512]; int32_t ret; struct s_thread_param param; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, PTHREAD_STACK_SIZE); oscam_init_serialdata(¶m.serialdata); if(cfg.ser_device) { cs_strncpy(sdevice, cfg.ser_device, sizeof(sdevice)); } else { memset(sdevice, 0, sizeof(sdevice)); } param.module_idx = module_idx; char *p; pthread_t temp; char cltype = 'c'; //now auto should work if(bcopy_end == -1) //mutex should be initialized only once { pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); bcopy_end = 0; } while((p = strrchr(sdevice, ';'))) { *p = 0; if(!(p + 1) || (!(p + 1)[0])) { return NULL; } if(!oscam_ser_parse_url(p + 1, ¶m.serialdata, &cltype)) { return NULL; } ret = pthread_create(&temp, &attr, oscam_ser_fork, (void *) ¶m); if(ret) { cs_log("ERROR: can't create serial reader thread (errno=%d %s)", ret, strerror(ret)); pthread_attr_destroy(&attr); return NULL; } else { oscam_wait_ser_fork(); pthread_detach(temp); } } if(!sdevice[0]) { return NULL; } if(!oscam_ser_parse_url(sdevice, ¶m.serialdata, &cltype)) { return NULL; } ret = pthread_create(&temp, &attr, oscam_ser_fork, (void *) ¶m); if(ret) { cs_log("ERROR: can't create serial reader thread (errno=%d %s)", ret, strerror(ret)); pthread_attr_destroy(&attr); return NULL; } else { oscam_wait_ser_fork(); pthread_detach(temp); } pthread_attr_destroy(&attr); return NULL; }
static void monitor_send_login(void){ char buf[64]; struct s_client *cur_cl = cur_client(); if (cur_cl->auth && cur_cl->account) snprintf(buf, sizeof(buf), "[A-0000]1|%s logged in\n", cur_cl->account->usr); else cs_strncpy(buf, "[A-0000]0|not logged in\n", sizeof(buf)); monitor_send_info(buf, 1); }
void config_list_set_defaults(const struct config_list *clist, void *config_data) { const struct config_list *c; for (c = clist; c->opt_type != OPT_UNKNOWN; c++) { void *var = config_data + c->var_offset; switch (c->opt_type) { case OPT_INT8: { *(int8_t *)var = c->def.d_int8; break; } case OPT_UINT8: { *(uint8_t *)var = c->def.d_uint8; break; } case OPT_INT32: { *(int32_t *)var = c->def.d_int32; break; } case OPT_UINT32: { *(uint32_t *)var = c->def.d_uint32; break; } case OPT_STRING: { char **scfg = var; NULLFREE(*scfg); if (c->def.d_char) *scfg = cs_strdup(c->def.d_char); break; } case OPT_SSTRING: { char *scfg = var; scfg[0] = '\0'; if (c->def.d_char && strlen(c->def.d_char)) cs_strncpy(scfg, c->def.d_char, c->str_size); break; } case OPT_HEX_ARRAY: { uint8_t *hex_array = var; memset(hex_array, 0, c->def.array_size); break; } case OPT_FUNC: { c->ops.process_fn((const char *)c->config_name, "", var, NULL); break; } case OPT_FUNC_EXTRA: { c->ops.process_fn_extra((const char *)c->config_name, "", var, c->def.d_extra, NULL); break; } case OPT_SAVE_FUNC: case OPT_FIXUP_FUNC: case OPT_UNKNOWN: continue; } } return; }
/* Creates the master client of OSCam and inits some global variables/mutexes. */ void init_first_client(void) { // get username OScam is running under struct passwd pwd; struct passwd *pwdbuf; bool ok; #ifdef __ANDROID__ pwdbuf = getpwuid(getuid()); // This is safe if (pwdbuf) { memcpy(&pwd, pwdbuf, sizeof(pwd)); ok = 1; } #else char buf[256]; ok = getpwuid_r(getuid(), &pwd, buf, sizeof(buf), &pwdbuf) == 0; #endif if (ok) { if (cs_malloc(&processUsername, strlen(pwd.pw_name) + 1)) cs_strncpy(processUsername, pwd.pw_name, strlen(pwd.pw_name) + 1); else processUsername = "******"; } else { processUsername = "******"; } if (!cs_malloc(&first_client, sizeof(struct s_client))) { fprintf(stderr, "Could not allocate memory for master client, exiting..."); exit(1); } memset(first_client_hashed, 0, sizeof(first_client_hashed)); int32_t bucket = (uintptr_t)first_client/16 % CS_CLIENT_HASHBUCKETS; first_client_hashed[bucket] = first_client; first_client->next = NULL; //terminate clients list with NULL first_client->login = time(NULL); first_client->typ = 's'; first_client->thread = pthread_self(); set_localhost_ip(&first_client->ip); struct s_auth *null_account; if (!cs_malloc(&null_account, sizeof(struct s_auth))) { fprintf(stderr, "Could not allocate memory for master account, exiting..."); exit(1); } first_client->account = null_account; if (pthread_setspecific(getclient, first_client)) { fprintf(stderr, "Could not setspecific getclient in master process, exiting..."); exit(1); } }
static void * oscam_ser_fork(void *pthreadparam) { struct s_thread_param *pparam = (struct s_thread_param *) pthreadparam; struct s_client *cl=create_client(get_null_ip()); pthread_setspecific(getclient, cl); cl->thread=pthread_self(); cl->typ='c'; cl->module_idx = pparam->module_idx; cl->account=first_client->account; if (!cl->serialdata && !cs_malloc(&cl->serialdata, sizeof(struct s_serial_client))) return NULL; set_thread_name(__func__); oscam_init_serialdata(cl->serialdata); oscam_copy_serialdata(cl->serialdata, &pparam->serialdata); if (cl->serialdata->oscam_ser_port > 0) { // reader struct for serial network connection struct s_reader *newrdr; if (!cs_malloc(&newrdr, sizeof(struct s_reader))) return NULL; memset(newrdr, 0, sizeof(struct s_reader)); newrdr->client = cl; newrdr->ph = *serial_ph; cl->reader = newrdr; cs_strncpy(cl->reader->label, "network-socket", sizeof(cl->reader->label)); } cs_log("serial: initialized (%s@%s)", cl->serialdata->oscam_ser_proto>P_MAX ? "auto" : proto_txt[cl->serialdata->oscam_ser_proto], cl->serialdata->oscam_ser_device); pthread_mutex_lock(&mutex); bcopy_end = 1; pthread_mutex_unlock(&mutex); pthread_cond_signal(&cond); while(1) { cl->login=time((time_t *)0); cl->pfd=init_oscam_ser_device(cl); if (cl->pfd) oscam_ser_server(); else cs_sleepms(60000); // retry in 1 min. (USB-Device ?) if (cl->pfd) close(cl->pfd); } NULLFREE(cl->serialdata); NULLFREE(cl->reader); return NULL; }
void log_list_thread(void) { char buf[LOG_BUF_SIZE]; int last_count=ll_count(log_list), count, grow_count=0, write_count; do { LL_ITER it = ll_iter_create(log_list); struct s_log *log; write_count = 0; while ((log=ll_iter_next_remove(&it))) { int8_t do_flush = ll_count(log_list) == 0; //flush on writing last element cs_strncpy(buf, log->txt, LOG_BUF_SIZE); if (log->direct_log) cs_write_log(buf, do_flush); else write_to_log(buf, log, do_flush); free(log->txt); free(log); //If list is faster growing than we could write to file, drop list: write_count++; if (write_count%10000 == 0) { //check every 10000 writes: count = ll_count(log_list); if (count > last_count) { grow_count++; if (grow_count > 5) { //5 times still growing cs_write_log("------------->logging temporary disabled (30s) - too much data!\n", 1); cfg.disablelog = 1; ll_iter_reset(&it); while ((log=ll_iter_next_remove(&it))) { //clear log free(log->txt); free(log); } cs_sleepms(30*1000); cfg.disablelog = 0; grow_count = 0; last_count = 0; break; } } else grow_count = 0; last_count = count; } } cs_sleepms(250); } while(1); }
static void gbox_msg_txt_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { int len = 0; if (value) { len = strlen(value); if (len > GBOX_MAX_MSG_TXT) { len = GBOX_MAX_MSG_TXT; } cs_strncpy(cfg.gbox_msg_txt,value, len+1); return; } if ((cfg.gbox_msg_txt[0]!='\0') && cfg.gbox_save_gsms) { fprintf_conf(f, token, "%s\n", cfg.gbox_msg_txt); } }
static void monitor_logsend(char *flag){ if (!flag) return; //no arg struct s_client *cur_cl = cur_client(); if (strcmp(flag, "on")) { if (strcmp(flag, "onwohist")) { cur_cl->log=0; return; } } if (cur_cl->log) // already on return; int32_t i, d = 0; if (!strcmp(flag, "on") && cfg.loghistorysize){ char *t_loghistptr = loghistptr, *ptr1 = NULL; if(loghistptr >= loghist + (cfg.loghistorysize) - 1) t_loghistptr = loghist; int32_t l1 = strlen(t_loghistptr+1) + 2; char *lastpos = loghist + (cfg.loghistorysize)-1; for (ptr1 = t_loghistptr + l1, i=0; i<200; i++, ptr1 = ptr1+l1) { l1 = strlen(ptr1)+1; if (!d && ((ptr1 >= lastpos) || (l1 < 2))) { ptr1 = loghist; l1 = strlen(ptr1)+1; d++; } if (d && ((ptr1 >= t_loghistptr) || (l1 < 2))) break; char p_usr[32], p_txt[512]; size_t pos1 = strcspn(ptr1, "\t") + 1; cs_strncpy(p_usr, ptr1 , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1); if ((p_usr[0]) && ((cur_cl->monlvl > 1) || (cur_cl->account && !strcmp(p_usr, cur_cl->account->usr)))) { snprintf(p_txt, sizeof(p_txt), "[LOG%03d]%s", cur_cl->logcounter, ptr1+pos1); cur_cl->logcounter=(cur_cl->logcounter + 1) % 1000; monitor_send(p_txt); } } } cur_cl->log=1; }
void chk_cltab(char *classasc, CLASSTAB *clstab) { int32_t max_an = 0, max_bn = 0; char *ptr1, *saveptr1 = NULL, *classasc_org; CLASSTAB newclstab, oldclstab; memset(&newclstab, 0, sizeof(newclstab)); newclstab.an = newclstab.bn = 0; if(!cs_malloc(&classasc_org, sizeof(char)*strlen(classasc)+1)) { return; } cs_strncpy(classasc_org, classasc, sizeof(char)*strlen(classasc)+1); for(ptr1 = strtok_r(classasc, ",", &saveptr1); ptr1; ptr1 = strtok_r(NULL, ",", &saveptr1)) { ptr1 = trim(ptr1); if(ptr1[0] == '!') { max_bn++; } else { max_an++; } } if(max_an && !cs_malloc(&newclstab.aclass, sizeof(uchar)*max_an)) { NULLFREE(classasc_org); return; } if(max_bn && !cs_malloc(&newclstab.bclass, sizeof(uchar)*max_bn)) { NULLFREE(newclstab.aclass); NULLFREE(classasc_org); return; } classasc = classasc_org; for(ptr1 = strtok_r(classasc, ",", &saveptr1); ptr1; ptr1 = strtok_r(NULL, ",", &saveptr1)) { ptr1 = trim(ptr1); if(ptr1[0] == '!') { newclstab.bclass[newclstab.bn++] = (uchar)a2i(ptr1 + 1, 2); } else { newclstab.aclass[newclstab.an++] = (uchar)a2i(ptr1, 2); } } NULLFREE(classasc_org); memcpy(&oldclstab, clstab, sizeof(CLASSTAB)); memcpy(clstab, &newclstab, sizeof(CLASSTAB)); NULLFREE(oldclstab.aclass); NULLFREE(oldclstab.bclass); }
void log_list_thread() { char buf[LOG_BUF_SIZE]; while (1) { LL_ITER it = ll_iter_create(log_list); struct s_log *log; while ((log=ll_iter_next_remove(&it))) { int8_t do_flush = ll_count(log_list) == 0; //flush on writing last element cs_strncpy(buf, log->txt, LOG_BUF_SIZE); if (log->direct_log) cs_write_log(buf, do_flush); else write_to_log(buf, log, do_flush); free(log->txt); free(log); } cs_sleepms(50); } }
void module_radegast(struct s_module *ph) { static PTAB ptab; //since there is always only 1 radegast server running, this is threadsafe ptab.ports[0].s_port = cfg.rad_port; ph->ptab = &ptab; ph->ptab->nports = 1; cs_strncpy(ph->desc, "radegast", sizeof(ph->desc)); ph->type=MOD_CONN_TCP; ph->listenertype = LIS_RADEGAST; ph->multi=0; ph->watchdog=1; ph->s_ip=cfg.rad_srvip; ph->s_handler=radegast_server; ph->recv=radegast_recv; ph->send_dcw=radegast_send_dcw; ph->c_multi=0; ph->c_init=radegast_cli_init; ph->c_recv_chk=radegast_recv_chk; ph->c_send_ecm=radegast_send_ecm; ph->num=R_RADEGAST; }
static void find_conf_dir(void) { static const char* confdirs[] = { "/etc/tuxbox/config/", "/etc/tuxbox/config/oscam/", "/var/tuxbox/config/", "/usr/keys/", "/var/keys/", "/var/etc/oscam/", "/var/etc/", "/var/oscam/", "/config/oscam/", NULL }; char conf_file[128+16]; int32_t i; if(cs_confdir[strlen(cs_confdir) - 1] != '/') { strcat(cs_confdir, "/"); } if(snprintf(conf_file, sizeof(conf_file), "%soscam.conf", cs_confdir) < 0) { return; } if(!access(conf_file, F_OK)) { return; } for(i=0; confdirs[i] != NULL; i++) { if(snprintf(conf_file, sizeof(conf_file), "%soscam.conf", confdirs[i]) < 0) { return; } if (!access(conf_file, F_OK)) { cs_strncpy(cs_confdir, confdirs[i], sizeof(cs_confdir)); return; } } }
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); }
static void write_to_log_int(char *txt, int8_t header_len) { struct s_log *log = cs_malloc(&log, sizeof(struct s_log), 0); log->txt = strnew(txt); log->header_len = header_len; log->direct_log = 0; struct s_client *cl = cur_client(); log->cl_usr = ""; if (!cl){ log->cl_text = "undef"; log->cl_typ = ' '; } else { switch(cl->typ) { case 'c': case 'm': if(cl->account) { log->cl_text = cl->account->usr; log->cl_usr = cl->account->usr; } else log->cl_text = ""; break; case 'p': case 'r': log->cl_text = cl->reader ? cl->reader->label : ""; break; default: log->cl_text = "server"; break; } log->cl_typ = cl->typ; } if(exit_oscam == 1){ char buf[LOG_BUF_SIZE]; cs_strncpy(buf, log->txt, LOG_BUF_SIZE); write_to_log(buf, log, 1); free(log->txt); free(log); } else ll_append(log_list, log); }
static int32_t camd35_auth_client(struct s_client *cl, uchar *ucrc) { int32_t rc = 1, no_delay = 1; uint32_t crc; struct s_auth *account; unsigned char md5tmp[MD5_DIGEST_LENGTH]; if(cl->upwd[0]) { return (memcmp(cl->ucrc, ucrc, 4) ? 1 : 0); } cl->crypted = 1; crc = (((ucrc[0] << 24) | (ucrc[1] << 16) | (ucrc[2] << 8) | ucrc[3]) & 0xffffffffL); for(account = cfg.account; (account) && (!cl->upwd[0]); account = account->next) if(crc == crc32(0L, MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH)) { rc = cs_auth_client(cl, account, NULL); if(!rc) { memcpy(cl->ucrc, ucrc, 4); cs_strncpy((char *)cl->upwd, account->pwd, sizeof(cl->upwd)); if (!aes_set_key_alloc(&cl->aes_keys, (char *) MD5(cl->upwd, strlen((char *)cl->upwd), md5tmp))) { return 1; } #ifdef CS_CACHEEX if(cl->account->cacheex.mode < 2) #endif if(!cl->is_udp && cl->tcp_nodelay == 0) { setsockopt(cl->udp_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_delay, sizeof(no_delay)); cl->tcp_nodelay = 1; } return 0; } } return (rc); }
void cs_log_config(void) { uchar buf[20]; if (cfg.nice!=99) snprintf((char *)buf, sizeof(buf), ", nice=%d", cfg.nice); else buf[0]='\0'; cs_log_nolock("version=%s, build #%s, system=%s%s", CS_VERSION, CS_SVN_VERSION, CS_TARGET, buf); cs_log_nolock("client max. idle=%d sec, debug level=%d, filter_sensitive=%d", cfg.cmaxidle, cs_dblevel, log_remove_sensitive); if( cfg.max_log_size ) snprintf((char *)buf, sizeof(buf), "%d Kb", cfg.max_log_size); else cs_strncpy((char *)buf, "unlimited", sizeof(buf)); #if defined(WEBIF) || defined(MODULE_MONITOR) cs_log_nolock("max. logsize=%s, loghistorysize=%d bytes", buf, cfg.loghistorysize); #else cs_log_nolock("max. logsize=%s bytes", buf); #endif cs_log_nolock("client timeout=%u ms, fallback timeout=%u ms, cache delay=%d ms", cfg.ctimeout, cfg.ftimeout, cfg.delay); }
static void parse_cmdline_params(int argc, char **argv) { int i; while ((i = getopt_long(argc, argv, short_options, long_options, NULL)) != EOF) { if (i == '?') fprintf(stderr, "ERROR: Unknown command line parameter: %s\n", argv[optind - 1]); switch(i) { case 'a': // --crash-dump cs_dump_stack = 1; break; case 'B': // --pidfile oscam_pidfile = optarg; break; case 'b': // --daemon bg = 1; break; case 'c': // --config-dir cs_strncpy(cs_confdir, optarg, sizeof(cs_confdir)); break; case 'd': // --debug cs_dblevel = atoi(optarg); break; case 'g': // --gcollect gbdb = atoi(optarg); break; case 'h': // --help show_usage(); exit(EXIT_SUCCESS); break; case 'I': // --syslog-ident syslog_ident = optarg; break; case 'p': // --pending-ecm max_pending = atoi(optarg) <= 0 ? 32 : MIN(atoi(optarg), 255); break; case 'r': // --restart if (config_enabled(WEBIF)) { cs_restart_mode = atoi(optarg); } break; case 'S': // --show-sensitive log_remove_sensitive = !log_remove_sensitive; break; case 's': // --capture-segfaults cs_capture_SEGV = 1; break; case 't': { // --temp-dir mkdir(optarg, S_IRWXU); int j = open(optarg, O_RDONLY); if (j >= 0) { close(j); cs_strncpy(cs_tmpdir, optarg, sizeof(cs_tmpdir)); } else { printf("WARNING: Temp dir does not exist. Using default value.\n"); } break; } case 'u': // --utf8 if (config_enabled(WEBIF)) { cs_http_use_utf8 = 1; printf("WARNING: Web interface UTF-8 mode enabled. Carefully read documentation as bugs may arise.\n"); } break; case 'V': // --build-info write_versionfile(true); exit(EXIT_SUCCESS); break; case 'w': // --wait cs_waittime = strtoul(optarg, NULL, 10); break; } } }