3 # include "csgbox/gbox.h"
4 # define CS_VERSION_X CS_VERSION "-gbx-" GBXVERSION
6 # define CS_VERSION_X CS_VERSION
11 static void monitor_check_ip()
17 for (p_ip
=cfg
->mon_allowed
; (p_ip
) && (!ok
); p_ip
=p_ip
->next
)
18 ok
=((client
[cs_idx
].ip
>=p_ip
->ip
[0]) && (client
[cs_idx
].ip
<=p_ip
->ip
[1]));
21 cs_auth_client((struct s_auth
*)0, "invalid ip");
26 static void monitor_auth_client(char *usr
, char *pwd
)
28 struct s_auth
*account
;
33 cs_auth_client((struct s_auth
*)0, NULL
);
36 for (account
=cfg
->account
, auth
=0; (account
) && (!auth
);)
39 auth
=!(strcmp(usr
, account
->usr
) | strcmp(pwd
, account
->pwd
));
41 account
=account
->next
;
45 cs_auth_client((struct s_auth
*)0, "invalid account");
48 if (cs_auth_client(account
, NULL
))
52 static int secmon_auth_client(uchar
*ucrc
)
55 struct s_auth
*account
;
59 int s
=memcmp(client
[cs_idx
].ucrc
, ucrc
, 4);
61 cs_log("wrong user-crc or garbage !?");
64 client
[cs_idx
].crypted
=1;
65 crc
=(ucrc
[0]<<24) | (ucrc
[1]<<16) | (ucrc
[2]<<8) | ucrc
[3];
66 for (account
=cfg
->account
; (account
) && (!auth
); account
=account
->next
)
67 if ((account
->monlvl
) &&
68 (crc
==crc32(0L, MD5(account
->usr
, strlen(account
->usr
), NULL
), 16)))
70 memcpy(client
[cs_idx
].ucrc
, ucrc
, 4);
71 aes_set_key(MD5(account
->pwd
, strlen(account
->pwd
), NULL
));
72 if (cs_auth_client(account
, NULL
))
78 cs_auth_client((struct s_auth
*)0, "invalid user");
84 int monitor_send_idx(int idx
, char *txt
)
87 unsigned char buf
[256+32];
88 if (!client
[idx
].udp_fd
)
90 usleep(500L); // avoid lost udp-pakets ..
91 if (!client
[idx
].crypted
)
92 return(sendto(client
[idx
].udp_fd
, txt
, strlen(txt
), 0,
93 (struct sockaddr
*)&client
[idx
].udp_sa
,
94 sizeof(client
[idx
].udp_sa
)));
98 memcpy(buf
+1, client
[idx
].ucrc
, 4);
100 memcpy(buf
+5, i2b(4, crc32(0L, buf
+10, l
-10)), 4);
101 aes_encrypt_idx(idx
, buf
+5, l
-5);
102 return(sendto(client
[idx
].udp_fd
, buf
, l
, 0,
103 (struct sockaddr
*)&client
[idx
].udp_sa
,
104 sizeof(client
[idx
].udp_sa
)));
107 #define monitor_send(t) monitor_send_idx(cs_idx, t)
109 static int monitor_recv(uchar
*buf
, int l
)
112 uchar nbuf
[3] = { 'U', 0, 0 };
114 static uchar
*bbuf
=NULL
;
117 bbuf
=(uchar
*)malloc(l
);
120 cs_log("Cannot allocate memory (errno=%d)", errno
);
125 memcpy(buf
, bbuf
, n
=bpos
);
127 n
=recv_from_udpipe(buf
, l
);
129 if (!n
) return(buf
[0]=0);
133 if (n
<21) // 5+16 is minimum
135 cs_log("packet to short !");
138 if (!secmon_auth_client(buf
+1))
140 aes_decrypt(buf
+5, 16);
141 bsize
=boundary(4, buf
[9]+5)+5;
142 // cs_log("n=%d bsize=%d", n, bsize);
145 // cs_log("DO >>>> copy-back");
146 memcpy(bbuf
, buf
+bsize
, bpos
=n
-bsize
);
148 write(client
[cs_idx
].ufd
, nbuf
, sizeof(nbuf
)); // trigger new event
152 cs_log("packet-size mismatch !");
155 aes_decrypt(buf
+21, n
-21);
156 if (memcmp(buf
+5, i2b(4, crc32(0L, buf
+10, n
-10)), 4))
158 cs_log("CRC error ! wrong password ?");
162 memmove(buf
, buf
+10, n
);
169 if ((p
=strchr(buf
, 10)) && (bpos
=n
-(p
-buf
)-1))
171 memcpy(bbuf
, p
+1, bpos
);
173 write(client
[cs_idx
].ufd
, nbuf
, sizeof(nbuf
)); // trigger new event
177 if (n
=strlen(trim(buf
)))
178 client
[cs_idx
].last
=time((time_t *) 0);
182 static void monitor_send_info(char *txt
, int last
)
184 static int seq
=0, counter
=0;
185 static char btxt
[256] = {0};
196 sprintf(buf
, "%03.3d", counter
);
197 memcpy(txt
+4, buf
, 3);
206 if (btxt
[0]) monitor_send(btxt
);
207 strncpy(btxt
, txt
, sizeof(btxt
));
215 strncpy(btxt
, txt
, sizeof(btxt
));
220 strncpy(btxt
, txt
, sizeof(btxt
));
221 btxt
[2]=(btxt
[2]=='B') ? 'S' : 'E';
232 static int cs_idx2ridx(int idx
)
235 for (i
=0; i
<CS_MAXREADER
; i
++)
236 if (reader
[i
].cs_idx
==idx
)
241 static char *monitor_get_srvname(int id
)
243 struct s_srvid
*this=cfg
->srvid
;
244 static char name
[83];
245 for (name
[0]=0; this && (this->next
) && (!name
[0]); this=this->next
)
247 strncpy(name
, this->name
, 32);
248 if (!name
[0]) sprintf(name
, "[%04X]", id
);
249 if (!id
) name
[0]='\0';
253 static char *monitor_get_proto(int idx
)
257 switch(client
[idx
].typ
)
259 case 's': ctyp
="server" ; break;
260 case 'n': ctyp
="resolver" ; break;
261 case 'l': ctyp
="logger" ; break;
263 case 'r': if ((i
=cs_idx2ridx(idx
))<0) // should never happen
264 ctyp
=(client
[idx
].typ
=='p') ? "proxy" : "reader";
267 switch(reader
[i
].typ
) // TODO like ph
269 case R_MOUSE
: ctyp
="mouse"; break;
270 case R_INTERN
: ctyp
="intern"; break;
271 case R_CAMD35
: ctyp
="camd 3.5x";break;
272 case R_CAMD33
: ctyp
="camd 3.3x";break;
273 case R_NEWCAMD
: ctyp
="newcamd"; break;
274 case R_RADEGAST
: ctyp
="radegast"; break;
275 case R_SERIAL
: ctyp
="serial"; break;
276 case R_GBOX
: ctyp
="gbox"; break;
277 default : ctyp
="unknown"; break;
281 default : ctyp
=ph
[client
[idx
].ctyp
].desc
;
286 static char *monitor_client_info(char id
, int i
)
288 static char sbuf
[256];
293 char ldate
[16], ltime
[16], *usr
;
294 int lsec
, isec
, cnr
, con
, cau
;
299 if ((cfg
->mon_hideclient_to
<= 0) ||
300 (((now
-client
[i
].lastecm
)/60)<cfg
->mon_hideclient_to
) ||
301 (((now
-client
[i
].lastemm
)/60)<cfg
->mon_hideclient_to
) ||
302 (client
[i
].typ
!='c'))
304 lsec
=now
-client
[i
].login
;
305 isec
=now
-client
[i
].last
;
307 if (((client
[i
].typ
=='r') || (client
[i
].typ
=='p')) &&
308 (con
=cs_idx2ridx(i
))>=0)
309 usr
=reader
[con
].label
;
313 if ((client
[i
].tosleep
) &&
314 (now
-client
[i
].lastswitch
>client
[i
].tosleep
))
322 if( (cau
=client
[i
].au
+1) )
323 if ((now
-client
[i
].lastemm
)/60>cfg
->mon_aulow
)
325 lt
=localtime(&client
[i
].login
);
326 sprintf(ldate
, "%2d.%02d.%02d",
327 lt
->tm_mday
, lt
->tm_mon
+1, lt
->tm_year
% 100);
328 sprintf(ltime
, "%2d:%02d:%02d",
329 lt
->tm_hour
, lt
->tm_min
, lt
->tm_sec
);
330 sprintf(sbuf
, "[%c--CCC]%d|%c|%d|%s|%d|%d|%s|%d|%s|%s|%s|%d|%04X:%04X|%s|%d|%d\n",
331 id
, client
[i
].pid
, client
[i
].typ
, cnr
, usr
, cau
, client
[i
].crypted
,
332 cs_inet_ntoa(client
[i
].ip
), client
[i
].port
, monitor_get_proto(i
),
333 ldate
, ltime
, lsec
, client
[i
].last_caid
, client
[i
].last_srvid
,
334 monitor_get_srvname(client
[i
].last_srvid
), isec
, con
);
340 static void monitor_process_info()
346 for (i
=0; i
<CS_MAXPID
; i
++)
347 if ((cfg
->mon_hideclient_to
<= 0) ||
348 (((now
-client
[i
].lastecm
)/60)<cfg
->mon_hideclient_to
) ||
349 (((now
-client
[i
].lastemm
)/60)<cfg
->mon_hideclient_to
) ||
350 (client
[i
].typ
!='c'))
353 if ((client
[cs_idx
].monlvl
<2) && (client
[i
].typ
!='s'))
355 if ((strcmp(client
[cs_idx
].usr
, client
[i
].usr
)) ||
356 ((client
[i
].typ
!='c') && (client
[i
].typ
!='m')))
359 monitor_send_info(monitor_client_info('I', i
), 0);
361 monitor_send_info(NULL
, 1);
364 static void monitor_send_details(char *txt
, int pid
)
367 snprintf(buf
, 255, "[D-----]%d|%s\n", pid
, txt
);
368 monitor_send_info(buf
, 0);
371 static void monitor_process_details_master(char *buf
, int pid
)
374 sprintf(buf
+200, ", nice=%d", cfg
->nice
);
377 sprintf(buf
, "version=%s, system=%s%s", CS_VERSION_X
, cs_platform(buf
+100), buf
+200);
378 monitor_send_details(buf
, pid
);
380 sprintf(buf
, "max. clients=%d, client max. idle=%d sec", CS_MAXPID
-2, cfg
->cmaxidle
);
381 monitor_send_details(buf
, pid
);
383 if( cfg
->max_log_size
)
384 sprintf(buf
+200, "%d Kb", cfg
->max_log_size
);
386 strcpy(buf
+200, "unlimited");
387 sprintf(buf
, "max. logsize=%s", buf
+200);
388 monitor_send_details(buf
, pid
);
390 sprintf(buf
, "client timeout=%d sec, cache delay=%d msec", cfg
->ctimeout
, cfg
->delay
);
391 monitor_send_details(buf
, pid
);
394 // sprintf(buf, "shared memory initialized (size=%d, fd=%d)", shmsize, shmid);
396 // sprintf(buf, "shared memory initialized (size=%d, id=%d)", shmsize, shmid);
398 // monitor_send_details(buf, pid);
401 #ifdef CS_RDR_INIT_HIST
402 static void monitor_process_details_reader(int pid
, int idx
)
406 if ((r_idx
=cs_idx2ridx(idx
))>=0)
407 for (p
=reader
[r_idx
].init_history
; *p
; p
+=strlen(p
)+1)
408 monitor_send_details(p
, pid
);
410 monitor_send_details("Missing reader index !", pid
);
414 static void monitor_process_details(char *arg
)
419 if ((idx
=idx_from_pid(pid
=atoi(arg
)))<0)
420 monitor_send_details("Invalid PID", pid
);
423 monitor_send_info(monitor_client_info('D', idx
), 0);
424 switch(client
[idx
].typ
)
427 monitor_process_details_master(sbuf
, pid
);
432 #ifdef CS_RDR_INIT_HIST
433 monitor_process_details_reader(pid
, idx
);
440 monitor_send_info(NULL
, 1);
443 static void monitor_send_login(void)
447 sprintf(buf
, "[A-0000]1|%s logged in\n", client
[cs_idx
].usr
);
449 strcpy(buf
, "[A-0000]0|not logged in\n");
450 monitor_send_info(buf
, 1);
453 static void monitor_login(char *usr
)
456 if ((usr
) && (pwd
=strchr(usr
, ' ')))
459 monitor_auth_client(trim(usr
), trim(pwd
));
461 monitor_auth_client(NULL
, NULL
);
462 monitor_send_login();
465 static void monitor_logsend(char *flag
)
470 if (strcmp(flag
, "on"))
472 client
[cs_idx
].log
=0;
475 if (client
[cs_idx
].log
) // already on
478 for (i
=(*loghistidx
+3) % CS_MAXLOGHIST
; i
!=*loghistidx
; i
=(i
+1) % CS_MAXLOGHIST
)
481 p_usr
=(char *)(loghist
+(i
*CS_LOGHISTSIZE
));
484 ((client
[cs_idx
].monlvl
>1) || (!strcmp(p_usr
, client
[cs_idx
].usr
))))
487 sprintf(sbuf
, "%03.3d", client
[cs_idx
].logcounter
);
488 client
[cs_idx
].logcounter
=(client
[cs_idx
].logcounter
+1) % 1000;
489 memcpy(p_txt
+4, sbuf
, 3);
494 client
[cs_idx
].log
=1;
497 static int monitor_process_request(char *req
)
500 char *cmd
[]={"login", "exit", "log", "status", "shutdown", "reload", "details"};
501 // char *cmd[]={"login", "exit", "log", "status", "shutdown", "reload"};
503 if( (arg
=strchr(req
, ' ')) )
509 if ((!auth
) && (strcmp(req
, cmd
[0])))
511 for (rc
=1, i
=0; i
<7; i
++)
512 if (!strcmp(req
, cmd
[i
]))
516 case 0: monitor_login(arg
); break;
518 case 2: monitor_logsend(arg
); break;
519 case 3: monitor_process_info(); break;
520 case 4: if (client
[cs_idx
].monlvl
>3)
521 kill(client
[0].pid
, SIGQUIT
);
523 case 5: if (client
[cs_idx
].monlvl
>2)
524 kill(client
[0].pid
, SIGHUP
);
526 case 6: monitor_process_details(arg
); break;
534 static void monitor_server()
537 client
[cs_idx
].typ
='m';
538 while (((n
=process_input(mbuf
, sizeof(mbuf
), cfg
->cmaxidle
))>=0) &&
539 monitor_process_request(mbuf
));
540 cs_disconnect_client();
543 void module_monitor(struct s_module
*ph
)
546 ptab
.ports
[0].s_port
= cfg
->mon_port
;
548 ph
->ptab
->nports
= 1;
550 if (cfg
->mon_aulow
<1)
552 strcpy(ph
->desc
, "monitor");
553 ph
->type
=MOD_CONN_UDP
;
556 ph
->s_ip
=cfg
->mon_srvip
;
557 ph
->s_handler
=monitor_server
;
558 ph
->recv
=monitor_recv
;
559 // ph->send_dcw=NULL;