source: trunk/src/sh_html.c @ 481

Last change on this file since 481 was 481, checked in by katerina, 6 years ago

Enhancements and fixes for tickets #374, #375, #376, #377, #378, and #379.

File size: 13.1 KB
RevLine 
[1]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
[131]36#include <unistd.h>
[1]37
38
39#ifdef SH_WITH_SERVER
40
41
42#include "samhain.h"
[481]43#include "sh_xfer.h"
[1]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;
[131]93#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
94  struct tm    time_tm;
95#endif
[1]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    {
[248]108      fd = sl_open_read (FIL__, __LINE__, p, SL_YESPRIV);
[1]109      SH_FREE(p);
110    }
111
112  if (!SL_ISERROR(fd))
113    {
[34]114      while (!SL_ISERROR(status) && sh_unix_getline (fd, line, sizeof(line)) > 0) 
[1]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    {
[34]127      qstr = sh_util_basename(DEFAULT_HTML_FILE);
[1]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        {
[131]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
[1]157          time_ptr   = localtime (&(server_status.start));
[131]158#endif
[1]159          if (time_ptr != NULL) 
[383]160            strftime (ts1, 80, _("%d-%m-%Y %H:%M:%S"), time_ptr);
[481]161          else
162            sl_strlcpy(ts1, _("01-01-1970 00:00:00"), sizeof(ts1));
[1]163          now = time(NULL);
[131]164#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
165          time_ptr   = localtime_r (&now, &time_tm);
166#else
[1]167          time_ptr   = localtime (&now);
[131]168#endif
[1]169          if (time_ptr != NULL) 
[383]170            strftime (ts2, 80, _("%d-%m-%Y %H:%M:%S"), time_ptr);
[481]171          else
172            sl_strlcpy(ts2, _("01-01-1970 00:00:00"), sizeof(ts2));
[1]173
174          sl_snprintf(outline, 1023, 
175                      _("<p>Time:<BR>Now: %s<BR>Start: %s</p>"), 
176                      ts2, ts1);
177          status = 
178            sl_write_line (ticket, outline, sl_strlen(outline));
179        }
180      if (!SL_ISERROR(status))
181        {
182          sl_snprintf(outline, 1023, 
183                      _("<p>Connections (max. %d simultaneous):"\
184                        "<BR>Now: %d<BR>Total: %ld</p>"),
185                      server_status.conn_max,
186                      server_status.conn_open,
187                      server_status.conn_total);
188          status = 
189            sl_write_line (ticket, outline, sl_strlen(outline));
190          if (server_status.last > (time_t) 0)
191            {
[131]192#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
193              time_ptr   = localtime_r (&(server_status.last), &time_tm);
194#else
[1]195              time_ptr   = localtime (&(server_status.last));
[131]196#endif
[1]197              if (time_ptr != NULL) 
[383]198                strftime (ts1, 80, _("%d-%m-%Y %H:%M:%S"), time_ptr);
[481]199              else
200                sl_strlcpy(ts1, _("01-01-1970 00:00:00"), sizeof(ts1));
[1]201              sl_snprintf(outline, 1023, 
202                          _("<p>Last connection at %s</p>"), 
203                          ts1);
204              status = 
205                sl_write_line (ticket, outline, sl_strlen(outline));
206            }
207        }
208      if (!SL_ISERROR(status))
209        status = 
210          sl_write_line (ticket, 
211                         _("<center><table cellpadding=5 cellspacing=2 border=2>"),
212                         sizeof("<center><table cellpadding=5 cellspacing=2 border=2>")-1);
213    }
214
215  if (SL_ISERROR(status))
216    SL_RETURN((-1), _("sh_html_head"));
217
218  SL_RETURN((0), _("sh_html_head"));
219}
220
221static
222int sh_html_foot(SL_TICKET ticket)
223{
224  long      status = SL_ENONE;
225  SL_TICKET fd = (-1);
226  char      line[512];
227  char * p;
228
229  SL_ENTER(_("sh_html_foot"));
230
231  p = sh_util_strconcat(DEFAULT_DATAROOT, _("/foot.html"), NULL);
232
233  if (p)
234    {
[248]235      fd = sl_open_read (FIL__, __LINE__, p, SL_YESPRIV);
[1]236      SH_FREE(p);
237    }
238
239  if (!SL_ISERROR(fd))
240    {
[34]241      while (!SL_ISERROR(status) && sh_unix_getline (fd, line, sizeof(line)) > 0) 
[1]242        {
243          status = sl_write_line (ticket, line, sl_strlen(line));
244        }
245      sl_close(fd);
246    }
247  else
248    {
249      status =   sl_write_line (ticket, _("</table></center></BODY></HTML>"),
250                                sizeof("</table></center></BODY></HTML>")-1);
251    }
252  if (SL_ISERROR(status))
253    SL_RETURN((-1), _("sh_html_foot"));
254
255  SL_RETURN((0), _("sh_html_foot"));
256}
257
258
259static 
260char * replace_tab (const char * line, char * host, char * status, 
261                    char * timestamp)
262{
263  st_format rep_serv_tab[] = {
264    { 'H', S_FMT_STRING,  0, 0, NULL},
265    { 'S', S_FMT_STRING,  0, 0, NULL},
266    { 'T', S_FMT_STRING,  0, 0, NULL},
267    {'\0', S_FMT_ULONG,   0, 0, NULL},
268  };
269  char * p;
270
271  SL_ENTER(_("replace_tab"));
272
273  rep_serv_tab[0].data_str = host;
274  rep_serv_tab[1].data_str = status;
275  rep_serv_tab[2].data_str = timestamp;
276
277  p = sh_util_formatted(line, rep_serv_tab);
278  SL_RETURN(p, _("replace_tab"));
279}
280
281static char * entry_orig = NULL;
282static size_t entry_size = 0;
283
284static
[170]285int sh_html_get_entry (void)
[1]286{
287  long      retval = SL_ENONE;
288  SL_TICKET fd = (-1);
289  char      line[512];
290  size_t    line_size;
291  size_t    add_size = 0;
292  char *    p;
293
294  SL_ENTER(_("sh_html_get_entry"));
295
296  p = sh_util_strconcat(DEFAULT_DATAROOT, _("/entry.html"), NULL);
297
298  entry_size = 0;
299  if (entry_orig != NULL)
300    {
301      free (entry_orig);
302      entry_orig = NULL;
303      entry_size = 0;
304    }
305
306  if (p)
307    {
[248]308      fd = sl_open_read (FIL__, __LINE__, p, SL_YESPRIV);
[1]309      SH_FREE(p);
310    }
311  if (!SL_ISERROR(fd))
312    {
[34]313      while (!SL_ISERROR(retval) && sh_unix_getline (fd, line, sizeof(line)) > 0) 
[1]314        {
315          line_size = sl_strlen(line);
316          add_size  = 0;
317          if (entry_orig != NULL)
318            {
[473]319              char * ptr = realloc(entry_orig,           /* free() ok     */
[22]320                                   entry_size + line_size + 1);
[473]321              if (ptr) {
322                entry_orig = ptr;
323                add_size = line_size; 
324              } else {
325                { free(entry_orig); entry_orig = NULL; }
326              }
[1]327            }
328          else
329            {
[454]330              entry_orig = calloc(1, line_size + 1);        /* free() ok     */
[22]331              if (entry_orig) { entry_orig[0] = '\0'; add_size = line_size; }
[1]332            }
333          if (!entry_orig)
334            {
335              entry_size = 0;
[383]336              /* add_size   = 0; *//* never read */
[1]337              SL_RETURN( 0, _("sh_html_get_entry"));
338            }
339
[22]340          sl_strlcat(&entry_orig[entry_size], line, line_size + 1);
[1]341          entry_size += add_size;
[25]342          SH_VALIDATE_EQ(entry_orig[entry_size], '\0');
[1]343        }
344      sl_close(fd);
345    }
346  SL_RETURN( entry_size, _("sh_html_get_entry"));
347}
348
349static
350int sh_html_entry (SL_TICKET ticket, 
351                   char * host, char * status, char * timestamp, int flag)
352{
353  char      outline[1024];
354  long      retval = SL_ENONE;
355
356  char    * formatted;
357
358  SL_ENTER(_("sh_html_entry"));
359
360  if (entry_size > 0 && entry_orig != NULL)
361    {
362      formatted = replace_tab(entry_orig, host, status, timestamp);
363      if (formatted)
364        {
365          retval = sl_write_line (ticket, formatted, sl_strlen(formatted));
366          SH_FREE(formatted);
367        }
368    }
369  else
370    {
371      sl_snprintf(outline, 1023, 
372                  _("<tr><td>%s</td><td>%s</td><td>%s</td></tr>"),
373                  host, status, timestamp);
374      retval =  sl_write_line (ticket, outline, sl_strlen(outline));
375    }
376
377  /* write a status line
378   */
379  if ((flag == 1) && (!SL_ISERROR(retval)))
380    {
381      sl_snprintf(outline, 1023, 
382                  _("<!-- \n[STATUS:] %s %s %s\n -->"),
383                  host, status, timestamp);
384      retval =  sl_write_line (ticket, outline, sl_strlen(outline));
385    }
386
387  if (SL_ISERROR(retval))
388    SL_RETURN((-1), _("sh_html_entry"));
389
390  SL_RETURN((0), _("sh_html_entry"));
391}
392
393typedef struct _sort_arr {
394  char msg[TIM_MAX];
395  char tim[TIM_MAX];
396} sort_arr;
397
398static sort_arr sort_stat[CLT_MAX]; 
399
400static
401int comp_arr (const void * ao, const void * bo)
402{
[170]403  const sort_arr * a;
404  const sort_arr * b;
[1]405
406  if (ao == NULL && bo == NULL)
407    return 0;
408  else if (ao == NULL && bo != NULL)
409    return (-1);
410  else if (ao != NULL && bo == NULL)
411    return (1);
412
[170]413  a = (const sort_arr *) ao;
414  b = (const sort_arr *) bo;
[1]415
416  return ((-1) * sl_strcmp(a->tim, b->tim));
417}
418
419static
420int sh_html_print_one (SL_TICKET ticket, client_t   * top)
421{
422  int status;
423  int clt_status;
[481]424  unsigned int i, n;
[1]425
426  SL_ENTER(_("sh_html_print_one"));
427
428  if (top == NULL)
429    SL_RETURN((0), _("sh_html_print_one"));
430
431  clt_status = top->status_now;
432  status = sh_html_entry (ticket, 
433                          top->hostname, 
434                          _(clt_stat[clt_status]), 
435                          top->timestamp[clt_status], 
436                          1);
437
438  n = 0;
439
440  if (clt_status != CLT_INACTIVE)
441    {
442      for (i = 1; i < CLT_MAX; ++i)
443        {
444          if (top->status_arr[i] != CLT_INACTIVE)
445            {
446              clt_status = top->status_arr[i];
447              sl_strlcpy(sort_stat[n].msg, _(clt_stat[clt_status]),  TIM_MAX);
448              sl_strlcpy(sort_stat[n].tim, top->timestamp[clt_status],TIM_MAX);
449              ++n;
450            }
451        }
452    }
453
454  if (n > 0)
455    {
456      qsort(&(sort_stat[0]), n, sizeof(sort_arr), comp_arr);
457         
458      for (i = 1; i < n; ++i)
459        {
460          status = sh_html_entry (ticket, 
461                                  " ", 
462                                  sort_stat[i].msg,
463                                  sort_stat[i].tim,
464                                  0);
465        }
466    }
467
468  if (SL_ISERROR(status))
469    SL_RETURN((-1), _("sh_html_print_one"));
470
471  SL_RETURN((0), _("sh_html_print_one"));
472}
473
474#include "zAVLTree.h"
475
476int sh_html_write(void  * inptr)
477{
478  long fd;
479  zAVLCursor avlcursor;
480  client_t * item;
481  zAVLTree * top = (zAVLTree *) inptr;
482
483  SL_ENTER(_("sh_html_write"));
484
485  if (0 != (fd = tf_trust_check (DEFAULT_HTML_FILE, SL_YESPRIV)))
486    {
487      sh_error_handle((-1), FIL__, __LINE__, fd, MSG_E_TRUST,
488                      (long) sh.effective.uid,
489                      DEFAULT_HTML_FILE);
490      SL_RETURN((-1), _("sh_html_write"));
491    } 
492
493
[248]494  fd = sl_open_write_trunc (FIL__, __LINE__, DEFAULT_HTML_FILE, SL_YESPRIV);
[1]495
496  if (SL_ISERROR(fd))
497    {
498      sh_error_handle((-1), FIL__, __LINE__, fd, MSG_E_ACCESS,
499                      (long) sh.effective.uid,
500                      DEFAULT_HTML_FILE);
501      SL_RETURN((-1), _("sh_html_write"));
502    } 
503
504  sh_html_get_entry();
505
506  sh_html_head(fd);
507  for (item = (client_t *) zAVLFirst(&avlcursor, top); item;
508       item = (client_t *) zAVLNext(&avlcursor))
509    sh_html_print_one (fd, item);
510  sh_html_foot(fd);
511  sl_close(fd);
512
513  SL_RETURN((0), _("sh_html_write"));
514}
515
[415]516int sh_html_zero()
517{
518  long fd;
519
520  SL_ENTER(_("sh_html_zero"));
521
522  if (0 != (fd = tf_trust_check (DEFAULT_HTML_FILE, SL_YESPRIV)))
523    {
524      SL_RETURN((-1), _("sh_html_zero"));
525    }
526
527  fd = sl_open_write_trunc (FIL__, __LINE__, DEFAULT_HTML_FILE, SL_YESPRIV);
528
529  if (SL_ISERROR(fd))
530    {
531     SL_RETURN((-1), _("sh_html_zero"));
532    }
533
534  sh_html_head(fd);
535  sh_html_foot(fd);
536
537  sl_close(fd);
538
539  SL_RETURN((0), _("sh_html_zero"));
540}
541
[1]542/* SH_WITH_SERVER */
543#endif
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
Note: See TracBrowser for help on using the repository browser.