source: trunk/src/sh_html.c @ 452

Last change on this file since 452 was 415, checked in by katerina, 9 years ago

Fixes for tickets #314, #315, #316, #317, #318, #319, #320, and #321.

File size: 12.8 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              entry_orig = realloc(entry_orig,           /* free() ok     */
314                                   entry_size + line_size + 1);
315              if (entry_orig) { add_size = line_size; }
316            }
317          else
318            {
319              entry_orig = malloc(line_size + 1);        /* free() ok     */
320              if (entry_orig) { entry_orig[0] = '\0'; add_size = line_size; }
321            }
322          if (!entry_orig)
323            {
324              entry_size = 0;
325              /* add_size   = 0; *//* never read */
326              SL_RETURN( 0, _("sh_html_get_entry"));
327            }
328
329          sl_strlcat(&entry_orig[entry_size], line, line_size + 1);
330          entry_size += add_size;
331          SH_VALIDATE_EQ(entry_orig[entry_size], '\0');
332        }
333      sl_close(fd);
334    }
335  SL_RETURN( entry_size, _("sh_html_get_entry"));
336}
337
338static
339int sh_html_entry (SL_TICKET ticket, 
340                   char * host, char * status, char * timestamp, int flag)
341{
342  char      outline[1024];
343  long      retval = SL_ENONE;
344
345  char    * formatted;
346
347  SL_ENTER(_("sh_html_entry"));
348
349  if (entry_size > 0 && entry_orig != NULL)
350    {
351      formatted = replace_tab(entry_orig, host, status, timestamp);
352      if (formatted)
353        {
354          retval = sl_write_line (ticket, formatted, sl_strlen(formatted));
355          SH_FREE(formatted);
356        }
357    }
358  else
359    {
360      sl_snprintf(outline, 1023, 
361                  _("<tr><td>%s</td><td>%s</td><td>%s</td></tr>"),
362                  host, status, timestamp);
363      retval =  sl_write_line (ticket, outline, sl_strlen(outline));
364    }
365
366  /* write a status line
367   */
368  if ((flag == 1) && (!SL_ISERROR(retval)))
369    {
370      sl_snprintf(outline, 1023, 
371                  _("<!-- \n[STATUS:] %s %s %s\n -->"),
372                  host, status, timestamp);
373      retval =  sl_write_line (ticket, outline, sl_strlen(outline));
374    }
375
376  if (SL_ISERROR(retval))
377    SL_RETURN((-1), _("sh_html_entry"));
378
379  SL_RETURN((0), _("sh_html_entry"));
380}
381
382typedef struct _sort_arr {
383  char msg[TIM_MAX];
384  char tim[TIM_MAX];
385} sort_arr;
386
387static sort_arr sort_stat[CLT_MAX]; 
388
389static
390int comp_arr (const void * ao, const void * bo)
391{
392  const sort_arr * a;
393  const sort_arr * b;
394
395  if (ao == NULL && bo == NULL)
396    return 0;
397  else if (ao == NULL && bo != NULL)
398    return (-1);
399  else if (ao != NULL && bo == NULL)
400    return (1);
401
402  a = (const sort_arr *) ao;
403  b = (const sort_arr *) bo;
404
405  return ((-1) * sl_strcmp(a->tim, b->tim));
406}
407
408static
409int sh_html_print_one (SL_TICKET ticket, client_t   * top)
410{
411  int status;
412  int clt_status;
413  int i, n;
414
415  SL_ENTER(_("sh_html_print_one"));
416
417  if (top == NULL)
418    SL_RETURN((0), _("sh_html_print_one"));
419
420  clt_status = top->status_now;
421  status = sh_html_entry (ticket, 
422                          top->hostname, 
423                          _(clt_stat[clt_status]), 
424                          top->timestamp[clt_status], 
425                          1);
426
427  n = 0;
428
429  if (clt_status != CLT_INACTIVE)
430    {
431      for (i = 1; i < CLT_MAX; ++i)
432        {
433          if (top->status_arr[i] != CLT_INACTIVE)
434            {
435              clt_status = top->status_arr[i];
436              sl_strlcpy(sort_stat[n].msg, _(clt_stat[clt_status]),  TIM_MAX);
437              sl_strlcpy(sort_stat[n].tim, top->timestamp[clt_status],TIM_MAX);
438              ++n;
439            }
440        }
441    }
442
443  if (n > 0)
444    {
445      qsort(&(sort_stat[0]), n, sizeof(sort_arr), comp_arr);
446         
447      for (i = 1; i < n; ++i)
448        {
449          status = sh_html_entry (ticket, 
450                                  " ", 
451                                  sort_stat[i].msg,
452                                  sort_stat[i].tim,
453                                  0);
454        }
455    }
456
457  if (SL_ISERROR(status))
458    SL_RETURN((-1), _("sh_html_print_one"));
459
460  SL_RETURN((0), _("sh_html_print_one"));
461}
462
463#include "zAVLTree.h"
464
465int sh_html_write(void  * inptr)
466{
467  long fd;
468  zAVLCursor avlcursor;
469  client_t * item;
470  zAVLTree * top = (zAVLTree *) inptr;
471
472  SL_ENTER(_("sh_html_write"));
473
474  if (0 != (fd = tf_trust_check (DEFAULT_HTML_FILE, SL_YESPRIV)))
475    {
476      sh_error_handle((-1), FIL__, __LINE__, fd, MSG_E_TRUST,
477                      (long) sh.effective.uid,
478                      DEFAULT_HTML_FILE);
479      SL_RETURN((-1), _("sh_html_write"));
480    } 
481
482
483  fd = sl_open_write_trunc (FIL__, __LINE__, DEFAULT_HTML_FILE, SL_YESPRIV);
484
485  if (SL_ISERROR(fd))
486    {
487      sh_error_handle((-1), FIL__, __LINE__, fd, MSG_E_ACCESS,
488                      (long) sh.effective.uid,
489                      DEFAULT_HTML_FILE);
490      SL_RETURN((-1), _("sh_html_write"));
491    } 
492
493  sh_html_get_entry();
494
495  sh_html_head(fd);
496  for (item = (client_t *) zAVLFirst(&avlcursor, top); item;
497       item = (client_t *) zAVLNext(&avlcursor))
498    sh_html_print_one (fd, item);
499  sh_html_foot(fd);
500  sl_close(fd);
501
502  SL_RETURN((0), _("sh_html_write"));
503}
504
505int sh_html_zero()
506{
507  long fd;
508
509  SL_ENTER(_("sh_html_zero"));
510
511  if (0 != (fd = tf_trust_check (DEFAULT_HTML_FILE, SL_YESPRIV)))
512    {
513      SL_RETURN((-1), _("sh_html_zero"));
514    }
515
516  fd = sl_open_write_trunc (FIL__, __LINE__, DEFAULT_HTML_FILE, SL_YESPRIV);
517
518  if (SL_ISERROR(fd))
519    {
520     SL_RETURN((-1), _("sh_html_zero"));
521    }
522
523  sh_html_head(fd);
524  sh_html_foot(fd);
525
526  sl_close(fd);
527
528  SL_RETURN((0), _("sh_html_zero"));
529}
530
531/* SH_WITH_SERVER */
532#endif
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
Note: See TracBrowser for help on using the repository browser.