source: trunk/src/sh_html.c @ 473

Last change on this file since 473 was 473, checked in by katerina, 7 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.