source: trunk/module-monitor.c@ 8455

Last change on this file since 8455 was 8455, checked in by gf, 9 years ago

Make ptab in struct s_module embedded not a pointer.

This blows up bss (static) memory nearly twice but we'll get that
back and lots more once we slim down struct s_port in the next
commit.

  • Property svn:eol-style set to LF
File size: 23.2 KB
Line 
1#include "globals.h"
2#ifdef MODULE_MONITOR
3#include "cscrypt/md5.h"
4#include "module-monitor.h"
5#include "oscam-aes.h"
6#include "oscam-client.h"
7#include "oscam-config.h"
8#include "oscam-conf-chk.h"
9#include "oscam-net.h"
10#include "oscam-reader.h"
11#include "oscam-string.h"
12#include "oscam-work.h"
13
14extern char *entitlement_type[];
15extern char *loghist;
16extern char *loghistptr;
17
18static int8_t monitor_check_ip(void)
19{
20 int32_t ok=0;
21 struct s_client *cur_cl = cur_client();
22
23 if (cur_cl->auth) return 0;
24 ok = check_ip(cfg.mon_allowed, cur_cl->ip);
25 if (!ok)
26 {
27 cs_auth_client(cur_cl, (struct s_auth *)0, "invalid ip");
28 return -1;
29 }
30 return 0;
31}
32
33static int8_t monitor_auth_client(char *usr, char *pwd)
34{
35 struct s_auth *account;
36 struct s_client *cur_cl = cur_client();
37
38 if (cur_cl->auth) return 0;
39 if ((!usr) || (!pwd))
40 {
41 cs_auth_client(cur_cl, (struct s_auth *)0, NULL);
42 return -1;
43 }
44 for (account=cfg.account, cur_cl->auth=0; (account) && (!cur_cl->auth);)
45 {
46 if (account->monlvl)
47 cur_cl->auth = streq(usr, account->usr) && streq(pwd, account->pwd);
48 if (!cur_cl->auth)
49 account=account->next;
50 }
51 if (!cur_cl->auth)
52 {
53 cs_auth_client(cur_cl, (struct s_auth *)0, "invalid account");
54 return -1;
55 }
56 if (cs_auth_client(cur_cl, account, NULL))
57 return -1;
58 return 0;
59}
60
61static int32_t secmon_auth_client(uchar *ucrc)
62{
63 uint32_t crc;
64 struct s_auth *account;
65 struct s_client *cur_cl = cur_client();
66 unsigned char md5tmp[MD5_DIGEST_LENGTH];
67
68 if (cur_cl->auth)
69 {
70 int32_t s=memcmp(cur_cl->ucrc, ucrc, 4);
71 if (s)
72 cs_log("wrong user-crc or garbage !?");
73 return !s;
74 }
75 cur_cl->crypted=1;
76 crc=(ucrc[0]<<24) | (ucrc[1]<<16) | (ucrc[2]<<8) | ucrc[3];
77 for (account=cfg.account; (account) && (!cur_cl->auth); account=account->next)
78 if ((account->monlvl) &&
79 (crc==crc32(0L, MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH)))
80 {
81 memcpy(cur_cl->ucrc, ucrc, 4);
82 aes_set_key(cur_cl, (char *)MD5((unsigned char *)ESTR(account->pwd), strlen(ESTR(account->pwd)), md5tmp));
83 if (cs_auth_client(cur_cl, account, NULL))
84 return -1;
85 cur_cl->auth=1;
86 }
87 if (!cur_cl->auth)
88 {
89 cs_auth_client(cur_cl, (struct s_auth *)0, "invalid user");
90 return -1;
91 }
92 return cur_cl->auth;
93}
94
95int32_t monitor_send_idx(struct s_client *cl, char *txt)
96{
97 int32_t l;
98 unsigned char buf[256+32];
99 if (!cl->udp_fd)
100 return -1;
101 struct timespec req_ts;
102 req_ts.tv_sec = 0;
103 req_ts.tv_nsec = 500000;
104 nanosleep (&req_ts, NULL);//avoid lost udp-pakkets
105 if (!cl->crypted)
106 return sendto(cl->udp_fd, txt, strlen(txt), 0, (struct sockaddr *)&cl->udp_sa, cl->udp_sa_len);
107 buf[0]='&';
108 buf[9]=l=strlen(txt);
109 l=boundary(4, l+5)+5;
110 memcpy(buf+1, cl->ucrc, 4);
111 cs_strncpy((char *)buf+10, txt, sizeof(buf)-10);
112 uchar tmp[10];
113 memcpy(buf+5, i2b_buf(4, crc32(0L, buf+10, l-10), tmp), 4);
114 aes_encrypt_idx(cl, buf+5, l-5);
115 return sendto(cl->udp_fd, buf, l, 0, (struct sockaddr *)&cl->udp_sa, cl->udp_sa_len);
116}
117
118#define monitor_send(t) monitor_send_idx(cur_client(), t)
119
120static int32_t monitor_recv(struct s_client * client, uchar *buf, int32_t l)
121{
122 int32_t n;
123 uchar nbuf[3] = { 'U', 0, 0 };
124 static int32_t bpos=0, res = 0;
125 static uchar *bbuf=NULL;
126 if (!bbuf)
127 {
128 if (!cs_malloc(&bbuf, l))
129 return 0;
130 }
131 if (bpos)
132 memcpy(buf, bbuf, n=bpos);
133 else
134 n=recv_from_udpipe(buf);
135 bpos=0;
136 if (!n) return buf[0]=0;
137 if (buf[0]=='&')
138 {
139 int32_t bsize;
140 if (n<21) // 5+16 is minimum
141 {
142 cs_log("packet too small!");
143 return buf[0]=0;
144 }
145 res = secmon_auth_client(buf+1);
146 if (res == -1) {
147 cs_disconnect_client(client);
148 return 0;
149 }
150 if (!res)
151 return buf[0]=0;
152 aes_decrypt(client, buf+5, 16);
153 bsize=boundary(4, buf[9]+5)+5;
154 // cs_log("n=%d bsize=%d", n, bsize);
155 if (n>bsize)
156 {
157 // cs_log("DO >>>> copy-back");
158 memcpy(bbuf, buf+bsize, bpos=n-bsize);
159 n=bsize;
160 uchar *nbuf_cpy;
161 if (cs_malloc(&nbuf_cpy, sizeof(nbuf))) {
162 memcpy(nbuf_cpy, nbuf, sizeof(nbuf));
163 add_job(client, ACTION_CLIENT_UDP, &nbuf_cpy, sizeof(nbuf));
164 }
165 }
166 else if (n<bsize)
167 {
168 cs_log("packet-size mismatch !");
169 return buf[0]=0;
170 }
171 aes_decrypt(client, buf+21, n-21);
172 uchar tmp[10];
173 if (memcmp(buf+5, i2b_buf(4, crc32(0L, buf+10, n-10), tmp), 4))
174 {
175 cs_log("CRC error ! wrong password ?");
176 return buf[0]=0;
177 }
178 n=buf[9];
179 memmove(buf, buf+10, n);
180 }
181 else
182 {
183 uchar *p;
184 if (monitor_check_ip() == -1) {
185 cs_disconnect_client(client);
186 return 0;
187 }
188 buf[n]='\0';
189 if ((p=(uchar *)strchr((char *)buf, 10)) && (bpos=n-(p-buf)-1))
190 {
191 memcpy(bbuf, p+1, bpos);
192 n=p-buf;
193 uchar *nbuf_cpy;
194 if (cs_malloc(&nbuf_cpy, sizeof(nbuf))) {
195 memcpy(nbuf_cpy, nbuf, sizeof(nbuf));
196 add_job(client, ACTION_CLIENT_UDP, &nbuf_cpy, sizeof(nbuf));
197 }
198 }
199 }
200 buf[n]='\0';
201 n=strlen(trim((char *)buf));
202 if (n) client->last=time((time_t *) 0);
203 return n;
204}
205
206static void monitor_send_info(char *txt, int32_t last)
207{
208 static int32_t seq=0, counter=0;
209 static char btxt[256] = {0};
210 char buf[8];
211 if (txt)
212 {
213 if (!btxt[0])
214 {
215 counter=0;
216 txt[2]='B';
217 }
218 else
219 counter++;
220 snprintf(buf, sizeof(buf), "%03d", counter);
221 memcpy(txt+4, buf, 3);
222 txt[3]='0'+seq;
223 }
224 else
225 if (!last)
226 return;
227
228 if (!last)
229 {
230 if (btxt[0]) monitor_send(btxt);
231 cs_strncpy(btxt, txt, sizeof(btxt));
232 return;
233 }
234
235 if (txt && btxt[0])
236 {
237 monitor_send(btxt);
238 txt[2]='E';
239 cs_strncpy(btxt, txt, sizeof(btxt));
240 }
241 else
242 {
243 if (txt)
244 cs_strncpy(btxt, txt, sizeof(btxt));
245 btxt[2]=(btxt[2]=='B') ? 'S' : 'E';
246 }
247
248 if (btxt[0])
249 {
250 monitor_send(btxt);
251 seq=(seq+1)%10;
252 }
253 btxt[0]=0;
254}
255
256static char *monitor_client_info(char id, struct s_client *cl, char *sbuf){
257 char channame[32];
258 sbuf[0] = '\0';
259
260 if (cl){
261 char ldate[16], ltime[16], *usr;
262 int32_t lsec, isec, con, cau, lrt =- 1;
263 time_t now;
264 struct tm lt;
265 now=time((time_t*)0);
266
267 if ((cfg.hideclient_to <= 0) ||
268 (now-cl->lastecm < cfg.hideclient_to) ||
269 (now-cl->lastemm < cfg.hideclient_to) ||
270 (cl->typ != 'c'))
271 {
272 lsec = now - cl->login;
273 isec = now - cl->last;
274 usr = username(cl);
275 if (cl->dup)
276 con = 2;
277 else
278 if ((cl->tosleep) && (now-cl->lastswitch>cl->tosleep))
279 con = 1;
280 else
281 con = 0;
282
283 // no AU reader == 0 / AU ok == 1 / Last EMM > aulow == -1
284 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r') {
285
286 if ((cl->typ == 'c' && ll_count(cl->aureader_list) == 0) ||
287 ((cl->typ == 'p' || cl->typ == 'r') && cl->reader->audisabled))
288 cau = 0;
289
290 else if ((now-cl->lastemm) / 60 > cfg.aulow)
291 cau = (-1);
292
293 else
294 cau = 1;
295
296 } else {
297 cau = 0;
298 }
299
300 if( cl->typ == 'r')
301 {
302 int32_t i;
303 struct s_reader *rdr;
304 for (i=0,rdr=first_active_reader; rdr ; rdr=rdr->next, i++)
305 if (cl->reader == rdr)
306 lrt=i;
307
308 if( lrt >= 0 )
309 lrt = 10 + cl->reader->card_status;
310 }
311 else
312 lrt = cl->cwlastresptime;
313 localtime_r(&cl->login, &lt);
314 snprintf(ldate, sizeof(ldate), "%02d.%02d.%02d", lt.tm_mday, lt.tm_mon+1, lt.tm_year % 100);
315 int32_t cnr=get_threadnum(cl);
316 snprintf(ltime, sizeof(ldate), "%02d:%02d:%02d", lt.tm_hour, lt.tm_min, lt.tm_sec);
317 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",
318 id, cl->tid, cl->typ, cnr, usr, cau, cl->crypted,
319 cs_inet_ntoa(cl->ip), cl->port, client_get_proto(cl),
320 ldate, ltime, lsec, cl->last_caid, cl->last_srvid,
321 get_servicename(cl, cl->last_srvid, cl->last_caid, channame), isec, con,
322 cl->cwfound, cl->cwnot, cl->cwcache, cl->cwignored,
323 cl->cwtout, cl->emmok, cl->emmnok, lrt);
324 }
325 }
326 return sbuf;
327}
328
329static void monitor_process_info(void) {
330 time_t now = time((time_t*)0);
331 char sbuf[256];
332
333 struct s_client *cl, *cur_cl = cur_client();
334
335 for (cl=first_client; cl ; cl=cl->next) {
336 if ((cfg.hideclient_to <= 0) ||
337 ( now-cl->lastecm < cfg.hideclient_to) ||
338 ( now-cl->lastemm < cfg.hideclient_to) ||
339 ( cl->typ != 'c')){
340 if ((cur_cl->monlvl < 2) && (cl->typ != 's')) {
341 if ((cur_cl->account && cl->account && strcmp(cur_cl->account->usr, cl->account->usr)) ||
342 ((cl->typ != 'c') && (cl->typ != 'm')))
343 continue;
344 }
345 monitor_send_info(monitor_client_info('I', cl, sbuf), 0);
346 }
347 }
348 monitor_send_info(NULL, 1);
349}
350
351static void monitor_send_details(char *txt, uint32_t tid){
352 char buf[256];
353 snprintf(buf, 255, "[D-----]%8X|%s\n", tid, txt);
354 monitor_send_info(buf, 0);
355}
356
357static void monitor_send_details_version(void) {
358 char buf[256];
359 snprintf(buf, sizeof(buf), "[V-0000]version=%s, build=%s, system=%s\n", CS_VERSION, CS_SVN_VERSION, CS_TARGET);
360 monitor_send_info(buf, 1);
361}
362
363static void monitor_send_keepalive_ack(void) {
364 char buf[32];
365 snprintf(buf, sizeof(buf), "[K-0000]keepalive_ack\n");
366 monitor_send_info(buf, 1);
367}
368
369static void monitor_process_details_master(char *buf, uint32_t pid){
370 snprintf(buf, 256, "Version=%sr%s", CS_VERSION, CS_SVN_VERSION);
371 monitor_send_details(buf, pid);
372 snprintf(buf, 256, "System=%s", CS_TARGET);
373 monitor_send_details(buf, pid);
374 snprintf(buf, 256, "DebugLevel=%d", cs_dblevel);
375 monitor_send_details(buf, pid);
376 snprintf(buf, 256, "MaxClients=UNLIMITED");
377 monitor_send_details(buf, pid);
378 snprintf(buf, 256, "ClientMaxIdle=%d sec", cfg.cmaxidle);
379 monitor_send_details(buf, pid);
380 if( cfg.max_log_size )
381 snprintf(buf + 200, 56, "%d Kb", cfg.max_log_size);
382 else
383 cs_strncpy(buf + 200, "unlimited", 56);
384 snprintf(buf, 256, "MaxLogsize=%s", buf + 200);
385 monitor_send_details(buf, pid);
386 snprintf(buf, 256, "ClientTimeout=%u ms", cfg.ctimeout);
387 monitor_send_details(buf, pid);
388 snprintf(buf, 256, "CacheDelay=%d ms", cfg.delay);
389 monitor_send_details(buf, pid);
390 if( cfg.cwlogdir ) {
391 snprintf(buf, 256, "CwlogDir=%s", cfg.cwlogdir);
392 monitor_send_details(buf, pid);
393 }
394 if( cfg.preferlocalcards ) {
395 snprintf(buf, 256, "PreferlocalCards=%d", cfg.preferlocalcards);
396 monitor_send_details(buf, pid);
397 }
398 if( cfg.waitforcards ) {
399 snprintf(buf, 256, "WaitforCards=%d", cfg.waitforcards);
400 monitor_send_details(buf, pid);
401 }
402 snprintf(buf, 256, "LogFile=%s", cfg.logfile);
403 monitor_send_details(buf, pid);
404 if( cfg.mailfile ) {
405 snprintf(buf, 256, "MailFile=%s", cfg.mailfile);
406 monitor_send_details(buf, pid);
407 }
408 if( cfg.usrfile ) {
409 snprintf(buf, 256, "UsrFile=%s", cfg.usrfile);
410 monitor_send_details(buf, pid);
411 }
412 monitor_send_details(buf, pid);
413 snprintf(buf, 256, "Sleep=%d", cfg.tosleep);
414 monitor_send_details(buf, pid);
415 snprintf(buf, 256, "Monitorport=%d", cfg.mon_port);
416 monitor_send_details(buf, pid);
417 snprintf(buf, 256, "Nice=%d", cfg.nice);
418 monitor_send_details(buf, pid);
419#ifdef WEBIF
420 snprintf(buf, 256, "Restartmode=%d", cs_get_restartmode());
421 monitor_send_details(buf, pid);
422#else
423 snprintf(buf, 256, "Restartmode=%s", "no");
424 monitor_send_details(buf, pid);
425#endif
426
427 // monitor_send_details(buf, pid);
428}
429
430
431static void monitor_process_details_reader(struct s_client *cl) {
432 char tbuffer1[64], tbuffer2[64], buf[256] = { 0 }, tmpbuf[256] = { 0 }, valid_to[32] = { 0 };
433 struct s_reader *rdr = cl->reader;
434 if (!rdr) {
435 monitor_send_details("Reader do not exist or it is not started.", cl->tid);
436 return;
437 }
438
439 if (rdr->card_valid_to) {
440 struct tm vto_t;
441 localtime_r(&rdr->card_valid_to, &vto_t);
442 strftime(valid_to, sizeof(valid_to) - 1, "%Y-%m-%d", &vto_t);
443 } else {
444 strncpy(valid_to, "n/a", 3);
445 }
446
447 snprintf(tmpbuf, sizeof(tmpbuf) - 1, "Cardsystem: %s Reader: %s ValidTo: %s HexSerial: %s ATR: %s",
448 rdr->csystem.desc,
449 rdr->label,
450 valid_to,
451 cs_hexdump(1, rdr->hexserial, 8, tbuffer2, sizeof(tbuffer2)),
452 rdr->card_atr_length
453 ? cs_hexdump(1, rdr->card_atr, rdr->card_atr_length, buf, sizeof(buf))
454 : ""
455 );
456 monitor_send_details(tmpbuf, cl->tid);
457
458 if (!rdr->ll_entitlements) {
459 monitor_send_details("No entitlements for the reader.", cl->tid);
460 return;
461 }
462
463 S_ENTITLEMENT *item;
464 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
465 time_t now = (time(NULL) / 84600) * 84600;
466
467 while ((item = ll_iter_next(&itr))) {
468 struct tm start_t, end_t;
469
470 localtime_r(&item->start, &start_t);
471 localtime_r(&item->end , &end_t);
472
473 strftime(tbuffer1, sizeof(tbuffer1) - 1, "%Y-%m-%d %H:%M %z", &start_t);
474 strftime(tbuffer2, sizeof(tbuffer2) - 1, "%Y-%m-%d %H:%M %z", &end_t);
475
476 char *entresname = get_tiername(item->id & 0xFFFF, item->caid, buf);
477 if (!entresname[0])
478 entresname = get_provider(item->caid, item->provid, buf, sizeof(buf));
479
480 snprintf(tmpbuf, sizeof(tmpbuf) - 1, "%s Type: %s CAID: %04X Provid: %06X ID: %08X%08X Class: %08X StartDate: %s ExpireDate: %s Name: %s",
481 item->end > now ? "active " : "expired",
482 entitlement_type[item->type],
483 item->caid,
484 item->provid,
485 (uint32_t)(item->id >> 32),
486 (uint32_t)(item->id),
487 item->class,
488 tbuffer1,
489 tbuffer2,
490 entresname
491 );
492 monitor_send_details(tmpbuf, cl->tid);
493 }
494}
495
496
497static void monitor_process_details(char *arg){
498 uint32_t tid = 0; //using threadid 8 positions hex see oscam-log.c //FIXME untested but pid isnt working anyway with threading
499 struct s_client *cl = NULL, *cl1;
500 char sbuf[256];
501
502 if (!arg)
503 cl = first_client; // no arg - show master
504 else {
505 if (sscanf(arg,"%X",&tid) == 1) {
506 for (cl1=first_client; cl1 ; cl1=cl1->next)
507 if (cl1->tid==tid){
508 cl=cl1;
509 break;
510 }
511 }
512 }
513
514 if (!cl)
515 monitor_send_details("Invalid TID", tid);
516 else
517 {
518 //monitor_send_info(monitor_client_info('D', idx), 0); //FIXME
519 switch(cl->typ)
520 {
521 case 's':
522 monitor_process_details_master(sbuf, cl->tid);
523 break;
524 case 'c': case 'm':
525 monitor_send_details(monitor_client_info(1, cl, sbuf), cl->tid);
526 break;
527 case 'r':
528 monitor_process_details_reader(cl);//with client->typ='r' client->ridx is always filled and valid, so no need checking
529 break;
530 case 'p':
531 monitor_send_details(monitor_client_info(1, cl, sbuf), cl->tid);
532 break;
533 }
534 }
535 monitor_send_info(NULL, 1);
536}
537
538static void monitor_send_login(void){
539 char buf[64];
540 struct s_client *cur_cl = cur_client();
541 if (cur_cl->auth && cur_cl->account)
542 snprintf(buf, sizeof(buf), "[A-0000]1|%s logged in\n", cur_cl->account->usr);
543 else
544 cs_strncpy(buf, "[A-0000]0|not logged in\n", sizeof(buf));
545 monitor_send_info(buf, 1);
546}
547
548static void monitor_login(char *usr){
549 char *pwd=NULL;
550 int8_t res = 0;
551 if ((usr) && (pwd=strchr(usr, ' ')))
552 *pwd++=0;
553 if (pwd)
554 res = monitor_auth_client(trim(usr), trim(pwd));
555 else
556 res = monitor_auth_client(NULL, NULL);
557
558 if (res == -1) {
559 cs_disconnect_client(cur_client());
560 return;
561 }
562 monitor_send_login();
563}
564
565static void monitor_logsend(char *flag){
566 if (!flag) return; //no arg
567
568 struct s_client *cur_cl = cur_client();
569 if (strcmp(flag, "on")) {
570 if (strcmp(flag, "onwohist")) {
571 cur_cl->log=0;
572 return;
573 }
574 }
575
576 if (cur_cl->log) // already on
577 return;
578
579 int32_t i, d = 0;
580 if (!strcmp(flag, "on") && cfg.loghistorysize){
581 char *t_loghistptr = loghistptr, *ptr1 = NULL;
582 if(loghistptr >= loghist + (cfg.loghistorysize) - 1)
583 t_loghistptr = loghist;
584 int32_t l1 = strlen(t_loghistptr+1) + 2;
585 char *lastpos = loghist + (cfg.loghistorysize)-1;
586
587 for (ptr1 = t_loghistptr + l1, i=0; i<200; i++, ptr1 = ptr1+l1) {
588 l1 = strlen(ptr1)+1;
589 if (!d && ((ptr1 >= lastpos) || (l1 < 2))) {
590 ptr1 = loghist;
591 l1 = strlen(ptr1)+1;
592 d++;
593 }
594
595 if (d && ((ptr1 >= t_loghistptr) || (l1 < 2)))
596 break;
597
598 char p_usr[32], p_txt[512];
599 size_t pos1 = strcspn(ptr1, "\t") + 1;
600
601 cs_strncpy(p_usr, ptr1 , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
602
603 if ((p_usr[0]) && ((cur_cl->monlvl > 1) || (cur_cl->account && !strcmp(p_usr, cur_cl->account->usr)))) {
604 snprintf(p_txt, sizeof(p_txt), "[LOG%03d]%s", cur_cl->logcounter, ptr1+pos1);
605 cur_cl->logcounter=(cur_cl->logcounter + 1) % 1000;
606 monitor_send(p_txt);
607 }
608 }
609 }
610
611 cur_cl->log=1;
612}
613
614static void monitor_set_debuglevel(char *flag){
615 if (flag) {
616 cs_dblevel = atoi(flag);
617#ifndef WITH_DEBUG
618 cs_log("*** Warning: Debug Support not compiled in ***");
619#else
620 cs_log("%s debug_level=%d", "all", cs_dblevel);
621#endif
622 }
623}
624
625static void monitor_get_account(void) {
626 struct s_auth *account;
627 char buf[256];
628 int32_t count = 0;
629
630 for (account=cfg.account; (account); account=account->next){
631 count++;
632 snprintf(buf, sizeof(buf), "[U-----]%s\n", account->usr);
633 monitor_send_info(buf, 0);
634 }
635 snprintf(buf, sizeof(buf), "[U-----] %i User registered\n", count);
636 monitor_send_info(buf, 1);
637 return;
638}
639
640static void monitor_set_account(char *args){
641 struct s_auth *account;
642 char delimiter[] = " =";
643 char *ptr, *saveptr1 = NULL;
644 int32_t argidx, i, found;
645 char *argarray[3];
646 static const char *token[]={"au", "sleep", "uniq", "monlevel", "group", "services", "betatunnel", "ident", "caid", "chid", "class", "hostname", "expdate", "keepalive", "disabled"};
647 int32_t tokencnt = sizeof(token)/sizeof(char *);
648 char buf[256], tmp[64];
649
650 argidx = 0;
651 found = 0;
652
653 snprintf(tmp, sizeof(tmp), "%s",args);
654 snprintf(buf, sizeof(buf), "[S-0000]setuser: %s check\n", tmp);
655 monitor_send_info(buf, 0);
656
657 ptr = strtok_r(args, delimiter, &saveptr1);
658
659 // resolve arguments
660 while(ptr != NULL) {
661 argarray[argidx]=trim(ptr);
662 ptr = strtok_r(NULL, delimiter, &saveptr1);
663 argidx++;
664 }
665
666 if(argidx != 3) {
667 snprintf(buf, sizeof(buf), "[S-0000]setuser: %s failed - wrong number of parameters (%d)\n",tmp, argidx);
668 monitor_send_info(buf, 0);
669 snprintf(buf, sizeof(buf), "[S-0000]setuser: %s end\n", tmp);
670 monitor_send_info(buf, 1);
671 return;
672 }
673
674 //search account
675 for (account=cfg.account; (account) ; account=account->next){
676 if (!strcmp(argarray[0], account->usr)){
677 found = 1;
678 break;
679 }
680 }
681
682 if (found != 1){
683 snprintf(buf, sizeof(buf), "[S-0000]setuser: %s failed - user %s not found\n",tmp , argarray[0]);
684 monitor_send_info(buf, 0);
685 snprintf(buf, sizeof(buf), "[S-0000]setuser: %s end\n", tmp);
686 monitor_send_info(buf, 1);
687 return;
688 }
689
690 found = -1;
691 for (i = 0; i < tokencnt; i++){
692 if (!strcmp(argarray[1], token[i])){
693 // preparing the parameters before re-load
694 switch(i) {
695
696 case 6: clear_tuntab(&account->ttab); break; //betatunnel
697
698 case 8: clear_caidtab(&account->ctab); break; //Caid
699 }
700 found = i;
701 }
702 }
703
704 if (found < 0){
705 snprintf(buf, sizeof(buf), "[S-0000]setuser: parameter %s not exist. possible values:\n", argarray[1]);
706 monitor_send_info(buf, 0);
707 for (i = 0; i < tokencnt; i++){
708 snprintf(buf, sizeof(buf), "[S-0000]%s\n", token[i]);
709 monitor_send_info(buf, 0);
710 }
711 snprintf(buf, sizeof(buf),"[S-0000]setuser: %s end\n", tmp);
712 monitor_send_info(buf, 1);
713 return;
714 } else {
715 chk_account(token[found], argarray[2], account);
716 }
717
718 if (write_userdb()==0)
719 cs_reinit_clients(cfg.account);
720
721 snprintf(buf, sizeof(buf),"[S-0000]setuser: %s done - param %s set to %s\n", tmp, argarray[1], argarray[2]);
722 monitor_send_info(buf, 1);
723}
724
725static void monitor_set_server(char *args){
726 char delimiter[] = "=";
727 char *ptr, *saveptr1;
728 int32_t argidx, i;
729 char *argarray[3];
730 static const char *token[]={"clienttimeout", "fallbacktimeout", "clientmaxidle", "cachedelay", "bindwait", "netprio", "sleep", "unlockparental", "serialreadertimeout", "maxlogsize", "showecmdw", "waitforcards", "preferlocalcards"};
731 char buf[256];
732
733 argidx=0;
734 ptr = strtok_r(args, delimiter, &saveptr1);
735
736 // resolve arguments
737 while(ptr != NULL) {
738 argarray[argidx]=trim(ptr);
739 ptr = strtok_r(NULL, delimiter, &saveptr1);
740 argidx++;
741 }
742
743 if(argidx != 2) {
744 snprintf(buf, sizeof(buf),"[S-0000]setserver failed - wrong number of parameters (%d)\n", argidx);
745 monitor_send_info(buf, 1);
746 return;
747 }
748
749 trim(argarray[0]);
750 trim(argarray[1]);
751 strtolower(argarray[0]);
752
753 for (i = 0; i < 13; i++)
754 if (!strcmp(argarray[0], token[i])) break;
755
756 if (i < 13){
757 config_set("global", token[i], argarray[1]);
758 snprintf(buf, sizeof(buf), "[S-0000]setserver done - param %s set to %s\n", argarray[0], argarray[1]);
759 monitor_send_info(buf, 1);
760 } else {
761 snprintf(buf, sizeof(buf), "[S-0000]setserver failed - parameter %s not exist\n", argarray[0]);
762 monitor_send_info(buf, 1);
763 return;
764 }
765
766 if (cfg.ftimeout>=cfg.ctimeout) {
767 cfg.ftimeout = cfg.ctimeout - 100;
768 snprintf(buf, sizeof(buf), "[S-0000]setserver WARNING: fallbacktimeout adjusted to %u ms\n", cfg.ftimeout);
769 monitor_send_info(buf, 1);
770 }
771 if(cfg.ftimeout < cfg.srtimeout) {
772 cfg.ftimeout = cfg.srtimeout + 100;
773 snprintf(buf, sizeof(buf), "[S-0000]setserver WARNING: fallbacktimeout adjusted to %u ms\n", cfg.ftimeout);
774 monitor_send_info(buf, 1);
775 }
776 if(cfg.ctimeout < cfg.srtimeout) {
777 cfg.ctimeout = cfg.srtimeout + 100;
778 snprintf(buf, sizeof(buf), "[S-0000]setserver WARNING: clienttimeout adjusted to %u ms\n", cfg.ctimeout);
779 monitor_send_info(buf, 1);
780 }
781 //kill(first_client->pid, SIGUSR1);
782}
783
784#ifdef WEBIF
785static void monitor_restart_server(void) {
786 cs_restart_oscam();
787}
788#endif
789
790static void monitor_list_commands(const char *args[], int32_t cmdcnt){
791 int32_t i;
792 for (i = 0; i < cmdcnt; i++) {
793 char buf[64];
794 snprintf(buf, sizeof(buf), "[S-0000]commands: %s\n", args[i]);
795 if(i < cmdcnt-1)
796 monitor_send_info(buf, 0);
797 else
798 monitor_send_info(buf, 1);
799 }
800}
801
802static int32_t monitor_process_request(char *req)
803{
804 int32_t i, rc;
805 static const char *cmd[] = {"login",
806 "exit",
807 "log",
808 "status",
809 "shutdown",
810 "reload",
811 "details",
812 "version",
813 "debug",
814 "getuser",
815 "setuser",
816 "setserver",
817 "commands",
818 "keepalive",
819 "reread"
820#ifdef WEBIF
821 ,"restart"
822#endif
823 };
824
825 int32_t cmdcnt = sizeof(cmd)/sizeof(char *); // Calculate the amount of items in array
826 char *arg;
827 struct s_client *cur_cl = cur_client();
828
829 if( (arg = strchr(req, ' ')) ) { *arg++ = 0; trim(arg); }
830 //trim(req);
831 if ((!cur_cl->auth) && (strcmp(req, cmd[0]))) monitor_login(NULL);
832
833 for (rc=1, i = 0; i < cmdcnt; i++)
834 if (!strcmp(req, cmd[i])) {
835 switch(i) {
836 case 0: monitor_login(arg); break; // login
837 case 1: cs_exit(0); break; // exit
838 case 2: monitor_logsend(arg); break; // log
839 case 3: monitor_process_info(); break; // status
840 case 4: if (cur_cl->monlvl > 3) cs_exit_oscam(); break; // shutdown
841 case 5: if (cur_cl->monlvl > 2) cs_accounts_chk(); break; // reload
842 case 6: monitor_process_details(arg); break; // details
843 case 7: monitor_send_details_version(); break; // version
844 case 8: if (cur_cl->monlvl > 3) monitor_set_debuglevel(arg); break; // debuglevel
845 case 9: if (cur_cl->monlvl > 3) monitor_get_account(); break; // getuser
846 case 10: if (cur_cl->monlvl > 3) monitor_set_account(arg); break; // setuser
847 case 11: if (cur_cl->monlvl > 3) monitor_set_server(arg); break; // setserver
848 case 12: if (cur_cl->monlvl > 3) monitor_list_commands(cmd, cmdcnt); break; // list commands
849 case 13: if (cur_cl->monlvl > 3) monitor_send_keepalive_ack(); break; // keepalive
850 case 14: { char buf[64];snprintf(buf, sizeof(buf), "[S-0000]reread\n");monitor_send_info(buf, 1); cs_card_info(); break; } // reread
851#ifdef WEBIF
852 case 15: if (cur_cl->monlvl > 3) monitor_restart_server(); break; // keepalive
853#endif
854 default: continue;
855 }
856 break;
857 }
858 return rc;
859}
860
861static void * monitor_server(struct s_client * client, uchar *mbuf, int32_t UNUSED(n)) {
862 client->typ='m';
863 monitor_process_request((char *)mbuf);
864
865 return NULL;
866}
867
868void module_monitor(struct s_module *ph){
869 ph->ptab.nports = 1;
870 ph->ptab.ports[0].s_port = cfg.mon_port;
871 ph->desc = "monitor";
872 ph->type=MOD_CONN_UDP;
873 IP_ASSIGN(ph->s_ip, cfg.mon_srvip);
874 ph->s_handler = monitor_server;
875 ph->recv = monitor_recv;
876 // ph->send_dcw=NULL;
877}
878#endif
Note: See TracBrowser for help on using the repository browser.