source: branches/samhain_3_1/src/sh_html.c@ 512

Last change on this file since 512 was 473, checked in by katerina, 9 years ago

Fix for ticket #371 (use cppcheck instead of uno for static checking).

File size: 12.9 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999, 2000 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
10/* */
11/* This program is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14/* GNU General Public License for more details. */
15/* */
16/* You should have received a copy of the GNU General Public License */
17/* along with this program; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config_xor.h"
21
22#include <string.h>
23#include <stdio.h>
24#include <stdlib.h>
25
26#if TIME_WITH_SYS_TIME
27#include <sys/time.h>
28#include <time.h>
29#else
30#if HAVE_SYS_TIME_H
31#include <sys/time.h>
32#else
33#include <time.h>
34#endif
35#endif
36#include <unistd.h>
37
38
39#ifdef SH_WITH_SERVER
40
41
42#include "samhain.h"
43#include "sh_forward.h"
44#include "sh_error.h"
45#include "sh_unix.h"
46#include "sh_utils.h"
47#include "sh_html.h"
48
49#undef FIL__
50#define FIL__ _("sh_html.c")
51
52
53s_stat server_status;
54
55
56
57static
58char * replace_stat (char * line)
59{
60 st_format rep_serv_tab[] = {
61 { 'T', S_FMT_TIME, 0, 0, NULL},
62 { 'S', S_FMT_TIME, 0, 0, NULL},
63 { 'L', S_FMT_TIME, 0, 0, NULL},
64 { 'O', S_FMT_ULONG, 0, 0, NULL},
65 { 'A', S_FMT_ULONG, 0, 0, NULL},
66 { 'M', S_FMT_ULONG, 0, 0, NULL},
67 {'\0', S_FMT_ULONG, 0, 0, NULL},
68 };
69
70 rep_serv_tab[0].data_ulong = (unsigned long) time(NULL);
71 rep_serv_tab[1].data_ulong = server_status.start;
72 rep_serv_tab[2].data_ulong = server_status.last;
73 rep_serv_tab[3].data_ulong = server_status.conn_open;
74 rep_serv_tab[4].data_ulong = server_status.conn_total;
75 rep_serv_tab[5].data_ulong = server_status.conn_max;
76
77 return (sh_util_formatted(line, rep_serv_tab));
78}
79
80
81static
82int sh_html_head(SL_TICKET ticket)
83{
84 long status = SL_ENONE;
85 SL_TICKET fd = (-1);
86 char line[512];
87 char endhead[512];
88 char outline[1024];
89 char ts1[81];
90 char ts2[81];
91 time_t now;
92 struct tm * time_ptr;
93#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
94 struct tm time_tm;
95#endif
96
97 char * formatted;
98 char * qstr;
99
100 char * p;
101
102 SL_ENTER(_("sh_html_head"));
103
104 p = sh_util_strconcat(DEFAULT_DATAROOT, _("/head.html"), NULL);
105
106 if (p)
107 {
108 fd = sl_open_read (FIL__, __LINE__, p, SL_YESPRIV);
109 SH_FREE(p);
110 }
111
112 if (!SL_ISERROR(fd))
113 {
114 while (!SL_ISERROR(status) && sh_unix_getline (fd, line, sizeof(line)) > 0)
115 {
116 formatted = replace_stat (line);
117 if (formatted)
118 {
119 status = sl_write_line (ticket, formatted, sl_strlen(formatted));
120 SH_FREE(formatted);
121 }
122 }
123 sl_close(fd);
124 }
125 else
126 {
127 qstr = sh_util_basename(DEFAULT_HTML_FILE);
128 if (qstr != NULL)
129 {
130 sl_snprintf(endhead, 511,
131 _("<meta http-equiv=%crefresh%c content=%c120; URL=./%s%c></HEAD><BODY>"),
132 34, 34, 34, qstr, 34);
133 SH_FREE(qstr);
134 }
135 else
136 {
137 sl_snprintf(endhead, 511, _("</HEAD><BODY>"));
138 }
139
140 status =
141 sl_write_line (ticket,
142 _("<HTML><HEAD><TITLE>Report</TITLE>"),
143 sizeof("<HTML><HEAD><TITLE>Report</TITLE>")-1);
144 if (!SL_ISERROR(status))
145 status =
146 sl_write_line (ticket, endhead, strlen(endhead));
147 if (!SL_ISERROR(status))
148 status =
149 sl_write_line (ticket,
150 _("<H1>Samhain Server Report</H1>"),
151 sizeof("<H1>Samhain Server Report</H1>")-1);
152 if (!SL_ISERROR(status))
153 {
154#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
155 time_ptr = localtime_r (&(server_status.start), &time_tm);
156#else
157 time_ptr = localtime (&(server_status.start));
158#endif
159 if (time_ptr != NULL)
160 strftime (ts1, 80, _("%d-%m-%Y %H:%M:%S"), time_ptr);
161 now = time(NULL);
162#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
163 time_ptr = localtime_r (&now, &time_tm);
164#else
165 time_ptr = localtime (&now);
166#endif
167 if (time_ptr != NULL)
168 strftime (ts2, 80, _("%d-%m-%Y %H:%M:%S"), time_ptr);
169
170 sl_snprintf(outline, 1023,
171 _("<p>Time:<BR>Now: %s<BR>Start: %s</p>"),
172 ts2, ts1);
173 status =
174 sl_write_line (ticket, outline, sl_strlen(outline));
175 }
176 if (!SL_ISERROR(status))
177 {
178 sl_snprintf(outline, 1023,
179 _("<p>Connections (max. %d simultaneous):"\
180 "<BR>Now: %d<BR>Total: %ld</p>"),
181 server_status.conn_max,
182 server_status.conn_open,
183 server_status.conn_total);
184 status =
185 sl_write_line (ticket, outline, sl_strlen(outline));
186 if (server_status.last > (time_t) 0)
187 {
188#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
189 time_ptr = localtime_r (&(server_status.last), &time_tm);
190#else
191 time_ptr = localtime (&(server_status.last));
192#endif
193 if (time_ptr != NULL)
194 strftime (ts1, 80, _("%d-%m-%Y %H:%M:%S"), time_ptr);
195 sl_snprintf(outline, 1023,
196 _("<p>Last connection at %s</p>"),
197 ts1);
198 status =
199 sl_write_line (ticket, outline, sl_strlen(outline));
200 }
201 }
202 if (!SL_ISERROR(status))
203 status =
204 sl_write_line (ticket,
205 _("<center><table cellpadding=5 cellspacing=2 border=2>"),
206 sizeof("<center><table cellpadding=5 cellspacing=2 border=2>")-1);
207 }
208
209 if (SL_ISERROR(status))
210 SL_RETURN((-1), _("sh_html_head"));
211
212 SL_RETURN((0), _("sh_html_head"));
213}
214
215static
216int sh_html_foot(SL_TICKET ticket)
217{
218 long status = SL_ENONE;
219 SL_TICKET fd = (-1);
220 char line[512];
221 char * p;
222
223 SL_ENTER(_("sh_html_foot"));
224
225 p = sh_util_strconcat(DEFAULT_DATAROOT, _("/foot.html"), NULL);
226
227 if (p)
228 {
229 fd = sl_open_read (FIL__, __LINE__, p, SL_YESPRIV);
230 SH_FREE(p);
231 }
232
233 if (!SL_ISERROR(fd))
234 {
235 while (!SL_ISERROR(status) && sh_unix_getline (fd, line, sizeof(line)) > 0)
236 {
237 status = sl_write_line (ticket, line, sl_strlen(line));
238 }
239 sl_close(fd);
240 }
241 else
242 {
243 status = sl_write_line (ticket, _("</table></center></BODY></HTML>"),
244 sizeof("</table></center></BODY></HTML>")-1);
245 }
246 if (SL_ISERROR(status))
247 SL_RETURN((-1), _("sh_html_foot"));
248
249 SL_RETURN((0), _("sh_html_foot"));
250}
251
252
253static
254char * replace_tab (const char * line, char * host, char * status,
255 char * timestamp)
256{
257 st_format rep_serv_tab[] = {
258 { 'H', S_FMT_STRING, 0, 0, NULL},
259 { 'S', S_FMT_STRING, 0, 0, NULL},
260 { 'T', S_FMT_STRING, 0, 0, NULL},
261 {'\0', S_FMT_ULONG, 0, 0, NULL},
262 };
263 char * p;
264
265 SL_ENTER(_("replace_tab"));
266
267 rep_serv_tab[0].data_str = host;
268 rep_serv_tab[1].data_str = status;
269 rep_serv_tab[2].data_str = timestamp;
270
271 p = sh_util_formatted(line, rep_serv_tab);
272 SL_RETURN(p, _("replace_tab"));
273}
274
275static char * entry_orig = NULL;
276static size_t entry_size = 0;
277
278static
279int sh_html_get_entry (void)
280{
281 long retval = SL_ENONE;
282 SL_TICKET fd = (-1);
283 char line[512];
284 size_t line_size;
285 size_t add_size = 0;
286 char * p;
287
288 SL_ENTER(_("sh_html_get_entry"));
289
290 p = sh_util_strconcat(DEFAULT_DATAROOT, _("/entry.html"), NULL);
291
292 entry_size = 0;
293 if (entry_orig != NULL)
294 {
295 free (entry_orig);
296 entry_orig = NULL;
297 entry_size = 0;
298 }
299
300 if (p)
301 {
302 fd = sl_open_read (FIL__, __LINE__, p, SL_YESPRIV);
303 SH_FREE(p);
304 }
305 if (!SL_ISERROR(fd))
306 {
307 while (!SL_ISERROR(retval) && sh_unix_getline (fd, line, sizeof(line)) > 0)
308 {
309 line_size = sl_strlen(line);
310 add_size = 0;
311 if (entry_orig != NULL)
312 {
313 char * ptr = realloc(entry_orig, /* free() ok */
314 entry_size + line_size + 1);
315 if (ptr) {
316 entry_orig = ptr;
317 add_size = line_size;
318 } else {
319 { free(entry_orig); entry_orig = NULL; }
320 }
321 }
322 else
323 {
324 entry_orig = calloc(1, line_size + 1); /* free() ok */
325 if (entry_orig) { entry_orig[0] = '\0'; add_size = line_size; }
326 }
327 if (!entry_orig)
328 {
329 entry_size = 0;
330 /* add_size = 0; *//* never read */
331 SL_RETURN( 0, _("sh_html_get_entry"));
332 }
333
334 sl_strlcat(&entry_orig[entry_size], line, line_size + 1);
335 entry_size += add_size;
336 SH_VALIDATE_EQ(entry_orig[entry_size], '\0');
337 }
338 sl_close(fd);
339 }
340 SL_RETURN( entry_size, _("sh_html_get_entry"));
341}
342
343static
344int sh_html_entry (SL_TICKET ticket,
345 char * host, char * status, char * timestamp, int flag)
346{
347 char outline[1024];
348 long retval = SL_ENONE;
349
350 char * formatted;
351
352 SL_ENTER(_("sh_html_entry"));
353
354 if (entry_size > 0 && entry_orig != NULL)
355 {
356 formatted = replace_tab(entry_orig, host, status, timestamp);
357 if (formatted)
358 {
359 retval = sl_write_line (ticket, formatted, sl_strlen(formatted));
360 SH_FREE(formatted);
361 }
362 }
363 else
364 {
365 sl_snprintf(outline, 1023,
366 _("<tr><td>%s</td><td>%s</td><td>%s</td></tr>"),
367 host, status, timestamp);
368 retval = sl_write_line (ticket, outline, sl_strlen(outline));
369 }
370
371 /* write a status line
372 */
373 if ((flag == 1) && (!SL_ISERROR(retval)))
374 {
375 sl_snprintf(outline, 1023,
376 _("<!-- \n[STATUS:] %s %s %s\n -->"),
377 host, status, timestamp);
378 retval = sl_write_line (ticket, outline, sl_strlen(outline));
379 }
380
381 if (SL_ISERROR(retval))
382 SL_RETURN((-1), _("sh_html_entry"));
383
384 SL_RETURN((0), _("sh_html_entry"));
385}
386
387typedef struct _sort_arr {
388 char msg[TIM_MAX];
389 char tim[TIM_MAX];
390} sort_arr;
391
392static sort_arr sort_stat[CLT_MAX];
393
394static
395int comp_arr (const void * ao, const void * bo)
396{
397 const sort_arr * a;
398 const sort_arr * b;
399
400 if (ao == NULL && bo == NULL)
401 return 0;
402 else if (ao == NULL && bo != NULL)
403 return (-1);
404 else if (ao != NULL && bo == NULL)
405 return (1);
406
407 a = (const sort_arr *) ao;
408 b = (const sort_arr *) bo;
409
410 return ((-1) * sl_strcmp(a->tim, b->tim));
411}
412
413static
414int sh_html_print_one (SL_TICKET ticket, client_t * top)
415{
416 int status;
417 int clt_status;
418 int i, n;
419
420 SL_ENTER(_("sh_html_print_one"));
421
422 if (top == NULL)
423 SL_RETURN((0), _("sh_html_print_one"));
424
425 clt_status = top->status_now;
426 status = sh_html_entry (ticket,
427 top->hostname,
428 _(clt_stat[clt_status]),
429 top->timestamp[clt_status],
430 1);
431
432 n = 0;
433
434 if (clt_status != CLT_INACTIVE)
435 {
436 for (i = 1; i < CLT_MAX; ++i)
437 {
438 if (top->status_arr[i] != CLT_INACTIVE)
439 {
440 clt_status = top->status_arr[i];
441 sl_strlcpy(sort_stat[n].msg, _(clt_stat[clt_status]), TIM_MAX);
442 sl_strlcpy(sort_stat[n].tim, top->timestamp[clt_status],TIM_MAX);
443 ++n;
444 }
445 }
446 }
447
448 if (n > 0)
449 {
450 qsort(&(sort_stat[0]), n, sizeof(sort_arr), comp_arr);
451
452 for (i = 1; i < n; ++i)
453 {
454 status = sh_html_entry (ticket,
455 " ",
456 sort_stat[i].msg,
457 sort_stat[i].tim,
458 0);
459 }
460 }
461
462 if (SL_ISERROR(status))
463 SL_RETURN((-1), _("sh_html_print_one"));
464
465 SL_RETURN((0), _("sh_html_print_one"));
466}
467
468#include "zAVLTree.h"
469
470int sh_html_write(void * inptr)
471{
472 long fd;
473 zAVLCursor avlcursor;
474 client_t * item;
475 zAVLTree * top = (zAVLTree *) inptr;
476
477 SL_ENTER(_("sh_html_write"));
478
479 if (0 != (fd = tf_trust_check (DEFAULT_HTML_FILE, SL_YESPRIV)))
480 {
481 sh_error_handle((-1), FIL__, __LINE__, fd, MSG_E_TRUST,
482 (long) sh.effective.uid,
483 DEFAULT_HTML_FILE);
484 SL_RETURN((-1), _("sh_html_write"));
485 }
486
487
488 fd = sl_open_write_trunc (FIL__, __LINE__, DEFAULT_HTML_FILE, SL_YESPRIV);
489
490 if (SL_ISERROR(fd))
491 {
492 sh_error_handle((-1), FIL__, __LINE__, fd, MSG_E_ACCESS,
493 (long) sh.effective.uid,
494 DEFAULT_HTML_FILE);
495 SL_RETURN((-1), _("sh_html_write"));
496 }
497
498 sh_html_get_entry();
499
500 sh_html_head(fd);
501 for (item = (client_t *) zAVLFirst(&avlcursor, top); item;
502 item = (client_t *) zAVLNext(&avlcursor))
503 sh_html_print_one (fd, item);
504 sh_html_foot(fd);
505 sl_close(fd);
506
507 SL_RETURN((0), _("sh_html_write"));
508}
509
510int sh_html_zero()
511{
512 long fd;
513
514 SL_ENTER(_("sh_html_zero"));
515
516 if (0 != (fd = tf_trust_check (DEFAULT_HTML_FILE, SL_YESPRIV)))
517 {
518 SL_RETURN((-1), _("sh_html_zero"));
519 }
520
521 fd = sl_open_write_trunc (FIL__, __LINE__, DEFAULT_HTML_FILE, SL_YESPRIV);
522
523 if (SL_ISERROR(fd))
524 {
525 SL_RETURN((-1), _("sh_html_zero"));
526 }
527
528 sh_html_head(fd);
529 sh_html_foot(fd);
530
531 sl_close(fd);
532
533 SL_RETURN((0), _("sh_html_zero"));
534}
535
536/* SH_WITH_SERVER */
537#endif
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
Note: See TracBrowser for help on using the repository browser.