source: trunk/src/sh_err_log.c @ 459

Last change on this file since 459 was 459, checked in by katerina, 7 years ago

Fix for ticket #360 (free on null pointer).

File size: 31.9 KB
Line 
1/* SAMHAIN file system integrity testing                                   */
2/* Copyright (C) 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 <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <unistd.h>
26#include <time.h>
27
28#include "samhain.h"
29#include "sh_error.h"
30#include "sh_utils.h"
31#include "sh_tiger.h"
32
33#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
34#include <sys/mman.h>
35#endif
36
37
38#undef  FIL__
39#define FIL__  _("sh_err_log.c")
40
41#undef  FIX_XML
42#define FIX_XML 1
43
44#define MYSIGLEN (2*KEY_LEN + 32)
45
46typedef struct _sh_log_buf {
47  char   signature[KEY_LEN+1];
48  char   timestamp[KEY_LEN+1];
49#ifdef SH_USE_XML
50  char   sig[MYSIGLEN];
51#endif
52  char * msg;
53} sh_sh_log_buf;
54
55extern struct  _errFlags  errFlags;
56
57#define CHK_KEY 0
58#define CHK_FIL 1
59#define CHK_NON 2
60
61static int get_key_from_file(char * path, char * keyid, char * key)
62{
63  SL_TICKET  fd;
64  char * buf;
65  char * bufc;
66
67  if (path[strlen(path)-1] == '\n')
68    path[strlen(path)-1] = '\0';
69
70  /* open the file, then check it
71   */
72  if ( SL_ISERROR(fd = sl_open_read (FIL__, __LINE__, path, SL_NOPRIV)))
73    {
74      fprintf(stderr, _("Could not open file <%s>\n"), path);
75      _exit (EXIT_FAILURE);
76    }
77
78  buf     = SH_ALLOC( (size_t)(SH_BUFSIZE+1));
79  bufc    = SH_ALLOC( (size_t)(SH_MAXBUF+1));
80
81  while (1 == 1)
82    {
83      buf[0]  = '\0';
84      bufc[0] = '\0';
85
86      /* find start of next key
87       */
88      while (0 != sl_strncmp(buf, _("-----BEGIN LOGKEY-----"),
89                             sizeof("-----BEGIN LOGKEY-----")-1)) 
90        {
91          (void) sh_unix_getline (fd, buf, SH_BUFSIZE);
92          if (buf[0] == '\0')
93            {
94              /* End of file reached, return.
95               */
96              (void) fflush(stdout);
97              (void) sl_close(fd);
98              return -1; 
99            }
100        }
101
102      /* read key
103       */
104      (void) sh_unix_getline (fd, buf, SH_BUFSIZE);
105
106      if (0 == sl_strncmp(keyid, &buf[KEY_LEN], strlen(keyid)))
107        {
108          (void) sl_strlcpy(key, buf, KEY_LEN+1);
109          (void) sl_close(fd);
110          return 0;
111        }
112    }
113         
114  /*@notreached@*/
115}
116
117static int just_list = S_FALSE;
118
119int sh_error_logverify_mod (const char * s)
120{
121  just_list = S_TRUE;
122  if (s)      /* compiler warning (unused var) fix */
123    return 0;
124  else
125    return 0;
126} 
127
128int sh_error_logverify (const char * s)
129{
130  SL_TICKET fd;
131  int len;
132  int status;
133  int count =  0;
134  int start = -1;
135  char * buf;
136  char * bufc;
137#ifdef SH_USE_XML
138  char * ptr;
139  int fixed_xml = S_TRUE;
140  char c_start;
141#endif
142  char signature[64];
143  char key[KEY_LEN+2];
144  char path[KEY_LEN+1];
145  char timestamp[64];
146  char c_cont;
147  int  chk_mode = CHK_KEY;
148  char hashbuf[KEYBUF_SIZE];
149
150  sh_error_logoff();
151
152  if (s == NULL || sl_strlen(s) >= PATH_MAX)
153    {
154      fprintf(stderr, _("FAIL: msg=\"Invalid input\", path=\"%s\"\n"), s);
155      _exit (EXIT_FAILURE);
156    }
157
158  /* Open the file, then check it.
159   */
160  if (0 != sl_is_suid())
161    {
162      fprintf(stderr, _("Cannot open file %s in suid mode\n"), s);
163      _exit (EXIT_FAILURE);
164    }
165
166  if ( SL_ISERROR(fd = sl_open_read (FIL__, __LINE__, s, SL_NOPRIV)) )
167    {
168      fprintf(stderr, 
169              _("FAIL: msg=\"File not accessible\", error=\"%ld\", path=\"%s\"\n"), fd, s);
170      _exit (EXIT_FAILURE);
171    }
172
173  /* Find space value.
174   */
175  c_cont  = ' ';
176#ifdef SH_STEALTH
177  c_cont ^= XOR_CODE;
178#endif
179
180#ifdef SH_USE_XML
181  c_start  = '<';
182#ifdef SH_STEALTH
183  c_start ^= XOR_CODE;
184#endif
185#endif
186
187  buf  = (char *) SH_ALLOC( 2*SH_MSG_BUF+1 );
188  bufc = (char *) SH_ALLOC( 2*SH_MSG_BUF+1 );
189
190  while (1 == 1) 
191    {
192      /* get the log message
193       */
194      if (sh_unix_getline (fd, buf, (2*SH_MSG_BUF)) < 0) 
195        break;
196
197      len = (int) sl_strlen(buf);
198
199#ifdef SH_USE_XML
200#ifdef SH_STEALTH
201      if (0 == sl_strncmp (buf, N_("<trail>"), 7)) 
202#else
203      if (0 == sl_strncmp (buf, _("<trail>"),  7)) 
204#endif
205#else
206#ifdef SH_STEALTH
207      if (0 == sl_strncmp (buf, N_("[SOF]"), 5)) 
208#else
209      if (0 == sl_strncmp (buf, _("[SOF]"),  5)) 
210#endif
211#endif
212        {
213          if (just_list == S_TRUE)
214            {
215#ifdef SH_STEALTH
216              sh_do_decode (buf, sl_strlen(buf));
217#endif
218              fprintf (stdout, _("%s\n"), buf);
219            }
220
221          /* Found start of audit trail, read first line.
222           */
223          start = 1;
224          do {
225            if ( sh_unix_getline (fd, buf, (2*SH_MSG_BUF)) < 0)
226              break;
227          } while (buf[0] == '\0' || buf[0] == '\n');
228          len = (int) sl_strlen(buf);
229
230          if (just_list == S_TRUE)
231            {
232#ifdef SH_STEALTH
233              if (buf[0] != '\n') 
234                sh_do_decode (buf, sl_strlen(buf));
235#endif
236              fprintf (stdout, _("%s\n"), buf);
237              start = 0;
238            }
239
240          ++count;
241        }
242      else if (buf[0] == '\n'
243#ifdef SH_USE_XML
244               ||
245#ifdef SH_STEALTH
246               0 == sl_strncmp(buf, N_("</trail>"), 7)
247#else
248               0 == sl_strncmp(buf,  _("</trail>"), 7)
249#endif
250#endif
251               )
252        {
253          if (just_list == S_TRUE)
254            {
255#ifdef SH_STEALTH
256              if (buf[0] != '\n') 
257                sh_do_decode (buf, sl_strlen(buf));
258#endif
259              fprintf (stdout, _("%s\n"), buf);
260            }
261
262          /* A newline.
263           */
264          ++count;
265          continue;
266        }
267      else if (start == 0)
268        {
269          /* We are inside an audit trail.
270           */
271          ++count;
272          if (just_list == S_TRUE)
273            {
274#ifdef SH_STEALTH
275              sh_do_decode (buf, sl_strlen(buf));
276#endif
277              fprintf (stdout, _("%s\n"), buf);
278              continue;
279            }
280        }
281      else
282        {
283          /* No start-of-file found yet.
284           */
285          continue;
286        }
287
288      if (just_list == S_TRUE)
289        continue;
290
291      /* Check for a continuation line.
292       */
293      while (1 == 1)
294        {
295          do {
296            if ( sh_unix_getline (fd, bufc, (2*SH_MSG_BUF)) < 0)
297              break;
298          } while (bufc[0] == '\0' || bufc[0] == '\n');
299          ++count;
300          if (bufc[0] == c_cont) 
301            {
302              /* A continuation line. Add the newline.
303               */
304              (void) sl_strlcat(buf, "\n", 2*SH_MSG_BUF+1);
305              ++len;
306              (void) sl_strlcat(buf, bufc, 2*SH_MSG_BUF+1);
307              len += (int) sl_strlen(bufc);
308            }
309          else
310            {
311              /* No continuation line. Use it as signature.
312               * A48014C05604EF7C9472330E85453E704024943E556163C2
313               */
314#ifdef SH_USE_XML
315#ifdef SH_STEALTH
316              if (bufc[0] == c_start) /* FIX XML */
317#else
318              if (bufc[0] == c_start)
319#endif
320                {
321                  (void) sl_strlcpy(signature, &bufc[5], KEY_LEN+1);
322                  fixed_xml = S_TRUE;
323                }
324              else
325                {
326                  (void) sl_strlcpy(signature, &bufc[4], KEY_LEN+1);
327                  fixed_xml = S_FALSE;
328                }
329              if (sl_strlen(bufc) > (KEY_LEN+18))
330                {
331#ifdef SH_STEALTH
332                  if (bufc[0] == c_start) /* FIX XML */
333#else
334                  if (bufc[0] == c_start)
335#endif
336                    (void) sl_strlcpy(timestamp, &bufc[KEY_LEN+5], 64);
337                  else
338                    (void) sl_strlcpy(timestamp, &bufc[KEY_LEN+4], 64);
339#ifdef SH_STEALTH
340                  ptr = strchr(timestamp, c_start);
341#else
342                  ptr = strchr(timestamp, c_start);
343#endif
344                  if (ptr) *ptr = '\0';
345                }
346              break;
347#else
348              sl_strlcpy(signature, bufc, KEY_LEN+1);
349              if (sl_strlen(bufc) > KEY_LEN)
350                sl_strlcpy(timestamp, &bufc[KEY_LEN], 64);
351              break;
352#endif
353            }
354        }
355     
356      /* Get starting key from command line.
357       */   
358      if (start == 1) 
359        {
360         
361          /* Get the timestamp.
362           */
363         
364#ifdef SH_STEALTH
365          sh_do_decode (timestamp, sl_strlen(timestamp));
366#endif
367          key[0] = '\0';
368         
369        findKey:
370         
371          if (chk_mode != CHK_FIL)
372            {
373              /* Ask for the key.
374               */
375              chk_mode = CHK_KEY;
376              fprintf(stdout, _("\nNew audit trail (%s), enter key|keyfile: "),
377                      /*@-usedef@*/timestamp/*@+usedef@*/);
378              key[0] = '\0';
379             
380              while (strlen(key) < KEY_LEN ) 
381                { 
382                  if (key[0] != '\n' && key[0] != '\0')
383                    fprintf(stdout, "%s",_("New audit trail, enter key: "));
384                  else if (key[0] == '\n')
385                    {
386                      (void) sl_strlcpy(key, 
387                                        sh_tiger_hash(NULL, TIGER_DATA, 0, 
388                                                      hashbuf, sizeof(hashbuf)), 
389                                        KEY_LEN+1);
390                      chk_mode = CHK_NON;
391                      break;
392                    }
393                  (void) fflush(stdout); 
394                  key[0] = '\0';
395                  if (NULL != fgets(key, sizeof(key), stdin))
396                    {
397                      if (key[0] != '\n') 
398                        {
399                          if (key[strlen(key) - 1] == '\n')
400                            key[strlen(key) - 1] = '\0';
401                        }
402                      if (key[0] == '/')
403                        {
404                          chk_mode = CHK_FIL;
405                          (void) sl_strlcpy(path, key, KEY_LEN+1); 
406                          break;
407                        }
408                    }
409                }
410            }
411          /* we now have either a key (chk_mode == CHK_NON|CHK_KEY)
412           * or a file (chk_mode == CHK_FIL)
413           */
414          if (chk_mode == CHK_FIL)
415            {
416              fprintf(stdout, _("\nAudit trail (%s), searching file %s\n"), 
417                      /*@-usedef@*/timestamp, path/*@+usedef@*/);
418              if (-1 == get_key_from_file(path, timestamp, key))
419                {
420                  chk_mode = CHK_KEY;
421                  fprintf(stdout, "%s",_("Key not found in file\n"));
422                  goto findKey;
423                }
424            }
425         
426         
427          sh_util_encode(key, buf, 1, 'B');
428          start = 0;
429        } 
430      else
431        { 
432          /* Iterate the key.
433           */
434          (void) sl_strlcpy (key, 
435                             sh_tiger_hash (key, TIGER_DATA, KEY_LEN,
436                                            hashbuf, sizeof(hashbuf)), 
437                             KEY_LEN+1);
438        }
439     
440      (void) sl_strlcat ( buf, key, 2*SH_MSG_BUF + 1);
441     
442#ifdef SH_STEALTH
443      sh_do_decode (signature, sl_strlen(signature));
444#endif
445     
446      status = sl_strncmp (signature, 
447                           sh_tiger_hash (buf, TIGER_DATA, 
448                                          (unsigned long) sl_strlen(buf),
449                                          hashbuf, sizeof(hashbuf)),
450                           KEY_LEN);
451     
452      buf[len] = '\0';    /* do not print out the key */
453#ifdef SH_STEALTH
454      sh_do_decode (buf, sl_strlen(buf));
455#endif
456     
457      if (status != 0) 
458        {
459#ifdef SH_USE_XML
460          if (chk_mode == CHK_NON)
461            {
462              if (fixed_xml == S_FALSE)
463                fprintf (stdout, _("XFAIL: line=%05d %s/log>\n"), 
464                         count-1, buf);
465              else
466                fprintf (stdout, _("XFAIL: line=%05d %s</log>\n"), 
467                         count-1, buf);
468            }
469          else
470            {
471              if (fixed_xml == S_FALSE)
472                fprintf (stdout, _("FAIL:  line=%05d %s/log>\n"), 
473                         count-1, buf);
474              else
475                fprintf (stdout, _("FAIL:  line=%05d %s</log>\n"), 
476                         count-1, buf);
477            }
478#else
479          if (chk_mode == CHK_NON)
480            fprintf (stdout, _("XFAIL: line=%5d %s\n"), count-1, buf);
481          else
482            fprintf (stdout, _("FAIL:  line=%5d %s\n"), count-1, buf);
483#endif
484        }
485      else
486        {
487#ifdef SH_USE_XML
488          if (fixed_xml == S_FALSE)
489            fprintf (stdout, _("PASS:  line=%05d %s/log>\n"),  count-1, buf);
490          else
491            fprintf (stdout, _("PASS:  line=%05d %s</log>\n"), count-1, buf);
492#else
493          fprintf (stdout, _("PASS:  line=%5d %s\n"), count-1, buf);
494#endif   
495        }
496    }
497
498  /* Cleanup and exit.
499   */
500  (void) sl_close (fd);
501  SH_FREE  (buf);
502  SH_FREE  (bufc);
503  (void) fflush   (stdout);
504  _exit    (EXIT_SUCCESS);
505
506  /* Make compilers happy.
507   */
508  /*@notreached@*/
509  return 0; 
510}
511
512/********************************************************************
513 *
514 *  Runtime code
515 *
516 ********************************************************************/
517static
518int sh_log_open (char * inet_peer, 
519                 char * logfile, int * service_failure, SL_TICKET * fildesc)
520{
521  SL_TICKET            fd = -1;
522  long int             status;
523  char               * tmp = NULL;
524  uid_t                uid;
525  size_t               len;
526  char               * lockfile = NULL;
527
528  SL_ENTER(_("sh_log_open"));
529
530  /* open/create the file, then check it
531   */
532
533  if (  0 !=  (status = tf_trust_check (logfile, SL_YESPRIV))
534        && (*service_failure) == 0)
535    {
536      tmp  = sh_util_safe_name (logfile);
537      sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_TRUST,
538                      (long) sh.effective.uid, tmp);
539    }
540
541  if (status == 0)
542    {
543      fd = sl_open_write (FIL__, __LINE__, logfile, SL_YESPRIV);
544      if (SL_ISERROR(fd))
545        {
546          tmp  = sh_util_safe_name (logfile);
547          (void) sl_get_euid(&uid);
548          if ((*service_failure) == 0)
549            sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_E_ACCESS,
550                             (long) uid, tmp);
551          status = -1;
552        }
553    }
554
555
556  if (status == 0 && inet_peer == NULL )
557    {
558      status = sh_unix_write_lock_file(logfile);
559      if (status < 0)
560        {
561          tmp  = sh_util_safe_name (logfile);
562          len      = sl_strlen(tmp);
563          if (sl_ok_adds (6, len))
564            len += 6;
565          lockfile = SH_ALLOC(len);
566          (void) sl_strlcpy(lockfile,        tmp, len);
567          (void) sl_strlcat(lockfile, _(".lock"), len);
568          (void) sl_get_euid(&uid);
569          if ((*service_failure) == 0)
570            sh_error_handle ((-1), FIL__, __LINE__, status, MSG_LOCKED,
571                             (long) uid, tmp, lockfile);
572          status = -1;
573          SH_FREE(lockfile);
574          (void) sl_close(fd);
575        }
576    }
577
578  if (status == 0)
579    {
580      status = sl_forward(fd); 
581      if (SL_ISERROR(status))
582        {
583          tmp  = sh_util_safe_name (logfile);
584          (void) sl_get_euid(&uid);
585          if ((*service_failure) == 0)
586            sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_ACCESS,
587                             (long) uid, tmp);
588          status = -1;
589          (void) sl_close(fd);
590        }
591    }
592 
593  if (status < 0)
594    {
595      if ((*service_failure) == 0) {
596        sh_error_handle ((-1), FIL__, __LINE__, status, MSG_SRV_FAIL,
597                         _("logfile"), tmp);
598        (*service_failure) = 1;
599      }
600      if (tmp)
601        SH_FREE(tmp);
602      SL_RETURN(-1, _("sh_log_open"));
603    }
604
605  *fildesc         = fd;
606  *service_failure = 0;
607  SL_RETURN(0, _("sh_log_open"));
608}
609
610typedef struct lfstc {
611  char          * logfile;
612  int             service_failure;
613  int             log_start;
614  char            sigkey_old[KEY_LEN+1];
615  char            sigkey_new[KEY_LEN+1];
616  char            crypto[KEY_LEN+1];
617  struct  lfstc * next;
618} open_logfile;
619
620static open_logfile * logfile_list = NULL;
621
622static int flag_sep_log = S_FALSE;
623
624#ifdef SH_WITH_SERVER
625int set_flag_sep_log (const char * str)
626{
627  return sh_util_flagval(str, &flag_sep_log);
628}
629#endif
630
631/*
632 *   --- Log error message to log file. ---
633 */
634int  sh_log_file (/*@null@*/char *errmsg, /*@null@*/char * inet_peer)
635{
636  int                  store1;
637  int                  store2;
638  int                  store3;
639  int                  store4;
640  int                  store5;
641  int                  store6;
642  int                  store7;
643  int                  store8;
644
645  SL_TICKET            fd = -1;
646  size_t               status;
647  struct _sh_log_buf   log_msg;
648
649  char                 logfile[SH_PATHBUF+SH_MINIBUF+2];
650  open_logfile       * current = logfile_list; 
651  open_logfile       * next    = NULL;
652  char               * sigkey_new;
653  char               * sigkey_old;
654  char               * crypto;
655  char                 hashbuf[KEYBUF_SIZE];
656
657  SL_ENTER(_("sh_log_file"));
658
659  if (errFlags.HaveLog == BAD)  /* paranoia */ 
660    SL_RETURN((-1), _("sh_log_file"));
661
662#ifdef SH_USE_XML
663  if (NULL == errmsg)
664    {
665      while (current != NULL)
666        {
667          /* don't write second EOF mark
668           */
669          if (current->log_start != S_TRUE && sh.flag.islocked == GOOD)
670            {
671              /* Don't use inet_peer == NULL, userwise a lock file will
672               * be created.
673               */
674              (void) sh_log_open ("\0", 
675                                  current->logfile, 
676                                  &(current->service_failure), &fd);
677         
678#ifdef SH_STEALTH
679              (void) sl_write_line (fd, N_("</trail>"), 7);
680              (void) sl_write (fd, "\n", 1);
681              (void) sl_sync(fd);
682#else
683              (void) sl_write_line (fd, _("</trail>\n"),  8);
684              (void) sl_sync(fd);
685#endif
686              (void) sl_close(fd);
687              /* sh_unix_rm_lock_file (current->logfile); */
688            }
689          next    = current->next;
690          SH_FREE(current->logfile);
691          SH_FREE(current);
692          current = next;
693        }
694      logfile_list = NULL;
695      SL_RETURN( 0, _("sh_log_file"));
696    }
697#else
698  if (NULL == errmsg)
699    {
700      while (current != NULL)
701        {
702          /* sh_unix_rm_lock_file (current->logfile); */
703          next    = current->next;
704          SH_FREE(current->logfile);
705          SH_FREE(current);
706          current = next;
707        }
708      logfile_list = NULL;
709      SL_RETURN( 0, _("sh_log_file"));
710    }
711#endif
712
713  (void) sl_strlcpy (logfile, sh.srvlog.name, sizeof(logfile));
714  if (inet_peer != NULL && flag_sep_log == S_TRUE)
715    {
716      (void) sl_strlcat (logfile, ".",       sizeof(logfile));
717      (void) sl_strlcat (logfile, inet_peer, sizeof(logfile));
718    }
719
720  if (sh.flag.log_start == S_TRUE)
721    {
722      while (current != NULL)
723        {
724          current->log_start = S_TRUE;
725          current = current->next;
726        }
727      sh.flag.log_start    = S_FALSE;
728      current = logfile_list;
729    }
730
731  while (current != NULL)
732    {
733      if (strcmp(logfile, current->logfile) == 0)
734        break;
735      current = current->next;
736    }
737
738  if (current == NULL)
739    {
740      current                  = SH_ALLOC(sizeof(open_logfile));
741      current->logfile         = SH_ALLOC(strlen(logfile) + 1);
742      (void) sl_strlcpy(current->logfile, logfile, strlen(logfile) + 1);
743      current->service_failure = 0;
744      current->log_start       = S_TRUE;
745      memset(current->sigkey_old, (int)'\0', KEY_LEN+1);
746      memset(current->sigkey_new, (int)'\0', KEY_LEN+1);
747      memset(current->crypto,     (int)'\0', KEY_LEN+1);
748      current->next            = logfile_list;
749      logfile_list             = current;
750    }
751
752  if (0 != sh_log_open (inet_peer, current->logfile, 
753                        &(current->service_failure), &fd))
754    {
755      SL_RETURN ((-1), _("sh_log_file"));
756    }
757
758
759  /* --- Allocate storage and mlock it. ---
760   */
761
762  status      =  sl_strlen (errmsg);
763  if (!sl_ok_adds(status, (2*KEY_LEN)) || !sl_ok_adds((2*KEY_LEN + status),32))
764    {
765      sl_close(fd);
766      SL_RETURN ((-1), _("sh_log_file"));
767    }
768     
769  log_msg.msg = (char *) SH_ALLOC ((size_t) (2*KEY_LEN + status + 32)); 
770
771#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
772  if (skey->mlock_failed == SL_FALSE) 
773    {
774      if ( (-1) == sh_unix_mlock( FIL__, __LINE__, log_msg.msg, 
775                                  (size_t)(2*KEY_LEN + status + 32) ) ) 
776        {
777          skey->mlock_failed = SL_TRUE;
778#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
779          sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK); 
780#endif
781        }
782    }
783#else
784  if (skey->mlock_failed == SL_FALSE) 
785    {
786      skey->mlock_failed = SL_TRUE;
787#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
788      sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK);
789#endif
790    }
791#endif
792
793  /* --- Write the start marker. ---
794   */
795
796  if (current->log_start == S_TRUE) 
797    {
798#ifdef SH_USE_XML
799#ifdef SH_STEALTH
800      (void) sl_write (fd, "\n", 1);
801      (void) sl_write_line (fd, N_("<trail>"), 7);
802      (void) sl_sync(fd);
803#else
804      (void) sl_write_line (fd, _("\n<trail>"),  8);
805      (void) sl_sync(fd);
806#endif
807#else
808#ifdef SH_STEALTH
809      (void) sl_write (fd, "\n", 1);
810      (void) sl_write_line (fd, N_("[SOF]"), 5);
811      (void) sl_sync(fd);
812#else
813      (void) sl_write_line (fd, _("\n[SOF]"),  6);
814      (void) sl_sync(fd);
815#endif
816#endif
817    }
818
819  /* reserve KEY_LEN chars at end for key
820   */
821  (void) sl_strlcpy (log_msg.msg, errmsg, (size_t) status+1 );
822
823
824#ifdef SH_USE_XML
825  /* cut the trailing "/>"
826   */
827  if (log_msg.msg[status-2] == '/')
828    {
829#ifdef FIX_XML
830      log_msg.msg[status-2] = ' '; /* ' ' FIX XML */
831      log_msg.msg[status-1] = '>'; /* '>' FIX XML */
832#else
833      log_msg.msg[status-2] = '>'; /* ' ' FIX XML */
834      log_msg.msg[status-1] = '<'; /* '>' FIX XML */
835#endif
836      log_msg.msg[status]   = '\0';
837    }
838  else if (status >= 6 && log_msg.msg[status-5] == '/' && 
839           log_msg.msg[status-6] == '<')
840    {
841#ifdef FIX_XML
842      log_msg.msg[status-6]   = '\0';
843      status -= 6;
844#else
845      log_msg.msg[status-5]   = '\0';
846      status -= 5;
847#endif
848    }
849#endif
850
851
852#ifdef SH_STEALTH
853  sh_do_encode (log_msg.msg, status);
854#endif
855
856  if (flag_sep_log == S_TRUE && inet_peer != NULL)
857    {
858      sigkey_old = current->sigkey_old;
859      sigkey_new = current->sigkey_new;
860      crypto     = current->crypto;
861    }
862  else
863    {
864      sigkey_old = skey->sigkey_old;
865      sigkey_new = skey->sigkey_new;
866      crypto     = skey->crypt;      /* flawfinder: ignore */
867    }
868
869  /* write the signature
870   */
871  if (current->log_start == S_TRUE) 
872    {
873      if (sh.real.user[0] == '\0') 
874        (void) sh_unix_getUser();
875
876      /* Initialize the key.
877       */
878      (void) sh_util_keyinit(sigkey_old, KEY_LEN+1);
879
880      /* Hash the key to make sure it has the correct format.
881       */
882      (void) sl_strlcpy(sigkey_new, 
883                        sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN,
884                                       hashbuf, sizeof(hashbuf)), 
885                        KEY_LEN+1);
886
887      /* Copy it to 'crypt' for encryption.
888       */
889      (void) sl_strlcpy(crypto, sigkey_new, KEY_LEN+1);
890
891      /* Use message and compiled-in key to encrypt.
892       */
893      BREAKEXIT(sh_util_encode);
894      sh_util_encode(crypto, log_msg.msg, 0, 'B');
895
896      /* Send out the key.
897       */
898      (void) sh_unix_time(0, log_msg.timestamp, KEY_LEN+1); 
899
900      store1               = errFlags.loglevel;
901      store2               = errFlags.sysloglevel;
902      store3               = errFlags.printlevel;
903      store4               = errFlags.exportlevel;
904      store5               = errFlags.maillevel;
905      store6               = errFlags.externallevel;
906      store7               = errFlags.databaselevel;
907      store8               = errFlags.preludelevel;
908
909      /* mail the key
910       */
911      errFlags.loglevel       = SH_ERR_NOT;
912      errFlags.sysloglevel    = SH_ERR_NOT;
913      errFlags.printlevel     = SH_ERR_NOT;
914      errFlags.exportlevel    = SH_ERR_NOT;
915      errFlags.externallevel  = SH_ERR_NOT;
916      errFlags.databaselevel  = SH_ERR_NOT;
917      errFlags.preludelevel   = SH_ERR_NOT;
918
919      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY_MAIL,
920                       sh.prg_name, crypto, 
921                       crypto, log_msg.timestamp);
922
923      /* send to other allowed channels
924       */
925      errFlags.maillevel      = SH_ERR_NOT;
926      /* errFlags.printlevel     = store3; */
927      errFlags.exportlevel    = store4;
928      errFlags.externallevel  = store6;
929      errFlags.databaselevel  = store7;
930      errFlags.preludelevel   = store8;
931
932      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY,
933                       sh.prg_name, crypto);
934
935      /* Cleanup.
936       */
937      errFlags.loglevel       = store1;
938      errFlags.sysloglevel    = store2;
939      errFlags.printlevel     = store3;
940      errFlags.exportlevel    = store4;
941      errFlags.maillevel      = store5;
942      errFlags.externallevel  = store6;
943      errFlags.databaselevel  = store7;
944
945
946      memset (crypto, (int) '\0', KEY_LEN);
947      sh.flag.log_start    = S_FALSE; 
948      current->log_start   = S_FALSE;
949    } 
950  else 
951    {
952      log_msg.timestamp[0] = '\0';
953      (void) sl_strlcpy (sigkey_new, 
954                         sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN, 
955                                        hashbuf, sizeof(hashbuf)),
956                         KEY_LEN+1);
957    }
958
959  /* --- Sign the message with the signature key. ---
960   */
961  sh_tiger_hash (log_msg.msg, TIGER_DATA,
962                 (unsigned long)(status + KEY_LEN), 
963                 (char *) hashbuf, (size_t) sizeof(hashbuf));
964
965  (void) sl_strlcat (log_msg.msg, sigkey_new, (size_t)(status + KEY_LEN + 2));
966  (void) sl_strlcpy (log_msg.signature,
967                     sh_tiger_hash (log_msg.msg, (TigerType) TIGER_DATA,
968                                    (unsigned long)(status + KEY_LEN), 
969                                    hashbuf, sizeof(hashbuf)),
970                     KEY_LEN+1);
971  (void) sl_strlcpy (sigkey_old, sigkey_new, KEY_LEN+1); 
972
973  /*@-usedef@*/
974#ifdef SH_USE_XML
975  if (log_msg.timestamp[0] != '\0')
976    sl_snprintf(log_msg.sig, sizeof(log_msg.sig),
977#ifdef FIX_XML
978                _("\n<sig>%s%s</sig></log>\n"),          /* <sig> FIX XML */
979#else
980                _("\nsig>%s%s</sig></log>\n"),          /* <sig> FIX XML */
981#endif
982                log_msg.signature, log_msg.timestamp);
983  else
984    sl_snprintf(log_msg.sig, sizeof(log_msg.sig),
985#ifdef FIX_XML
986                _("\n<sig>%s</sig></log>\n"),            /* <sig> FIX XML */
987#else
988                _("\nsig>%s</sig></log>\n"),            /* <sig> FIX XML */
989#endif
990                log_msg.signature);
991  /*@+usedef@*/
992
993#ifdef SH_STEALTH
994  /* don't encode the line breaks (0 + last char)
995   */
996  sh_do_encode (&log_msg.sig[1], (sl_strlen(log_msg.sig)-2) );
997#endif
998#else
999#ifdef SH_STEALTH
1000  sh_do_encode (log_msg.signature, KEY_LEN);
1001  sh_do_encode (log_msg.timestamp, sl_strlen(log_msg.timestamp));
1002#endif
1003#endif
1004 
1005#ifdef SH_USE_XML
1006  log_msg.msg[status] = '\0';
1007  (void) sl_strlcat (log_msg.msg,   log_msg.sig, 
1008                     (size_t)(status + 2*KEY_LEN + 32));
1009#ifdef SH_STEALTH
1010  if (NULL != sl_strstr(log_msg.msg, N_("EXIT")) &&
1011      NULL == sl_strstr(log_msg.msg, N_("remote_host")))
1012    {
1013      (void) sl_strlcat (log_msg.msg,  N_("</trail>"), 
1014                         (size_t)(status + 2*KEY_LEN + 32)); 
1015#else
1016  if (NULL != sl_strstr(log_msg.msg,  _("msg=\"EXIT\"")) &&
1017      NULL == sl_strstr(log_msg.msg,  _("remote_host")))
1018    {
1019      (void) sl_strlcat (log_msg.msg,   _("</trail>"), 
1020                         (size_t)(status + 2*KEY_LEN + 32)); 
1021#endif
1022     
1023      (void) sl_strlcat (log_msg.msg,   _("\n"), 
1024                         (size_t)(status + 2*KEY_LEN + 32)); 
1025      current->log_start = S_TRUE;
1026    }
1027#else
1028  log_msg.msg[status] = '\0';
1029  (void) sl_strlcat (log_msg.msg,              "\n", 
1030                     (size_t)(status + KEY_LEN + 2));
1031  (void) sl_strlcat (log_msg.msg, log_msg.signature, 
1032                     (size_t)(status + KEY_LEN + 2));
1033  if (log_msg.timestamp[0] != '\0')
1034    (void) sl_strlcat (log_msg.msg, log_msg.timestamp, 
1035                       (size_t)(status + 2*KEY_LEN + 2));
1036  (void) sl_strlcat (log_msg.msg,              "\n", 
1037                     (size_t)(status + 2*KEY_LEN + 3));
1038#endif
1039 
1040  /* --- Write out the record. ---
1041   */
1042  (void) sl_write (fd, log_msg.msg, (long) strlen(log_msg.msg));
1043  (void) sl_sync  (fd);
1044  (void) sl_close (fd);
1045
1046  /* --- Clean up and free record. ---
1047   */
1048  memset (log_msg.msg,       (int)'\0', (size_t)(status + 2*KEY_LEN + 32));
1049  memset (log_msg.signature, (int)'\0', KEY_LEN);
1050  (void) sh_unix_munlock (log_msg.msg, 
1051                          (size_t)(status + 2*KEY_LEN + 32));
1052  SH_FREE(log_msg.msg);
1053
1054  SL_RETURN (0, _("sh_log_file"));
1055}
1056
1057/* >>>>>>>>>>>>>>>>>>>>>>>>>>>> efile <<<<<<<<<<<<<<<<<< */
1058
1059static char * gEfile = NULL;
1060static int    gFail  = 0;
1061static long   gGid   = 0;
1062
1063int sh_efile_group(const char * str)
1064{
1065  int  fail;
1066  long gid = sh_group_to_gid(str, &fail);
1067
1068  if (fail < 0)
1069    {
1070      return -1;
1071    }
1072  gGid = gid;
1073  return 0;
1074}
1075
1076
1077int sh_efile_path(const char * str) 
1078{
1079  if (!str || !strcmp(str, _("none")))
1080    {
1081      if (gEfile)
1082        SH_FREE(gEfile);
1083      gEfile = NULL;
1084    }
1085  else if (str[0] != '/')
1086    {
1087      return -1;
1088    }
1089  else
1090    {
1091      if (gEfile)
1092        SH_FREE(gEfile);
1093      gEfile = sh_util_strdup(str);
1094    }
1095  gFail = 0;
1096  return 0;
1097}
1098
1099/* write lock for filename
1100 */
1101static int sh_efile_lock (char * filename, int flag)
1102{
1103  extern int get_the_fd (SL_TICKET ticket);
1104  size_t len;
1105  int    res = -1;
1106  char myPid[64];
1107  SL_TICKET  fd;
1108  char * lockfile;
1109  int    status;
1110
1111  sprintf (myPid, "%ld\n", (long) sh.pid);             /* known to fit  */
1112
1113  if (filename == NULL)
1114    return res;
1115
1116  len = sl_strlen(filename);
1117  if (sl_ok_adds(len, 6))
1118    len += 6;
1119  lockfile = SH_ALLOC(len);
1120  sl_strlcpy(lockfile, filename,   len);
1121  sl_strlcat(lockfile, _(".lock"), len);
1122
1123  if (  0 !=  (status = tf_trust_check (lockfile, SL_YESPRIV))
1124        && gFail == 0)
1125    {
1126      char * tmp  = sh_util_safe_name (lockfile);
1127      sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_TRUST,
1128                           (long) sh.effective.uid, tmp);
1129      ++gFail;
1130      SH_FREE(tmp);
1131    }
1132
1133  if (status == 0)
1134    {
1135      if (flag == 0)
1136        {
1137          /* --- Delete the lock file. ---
1138           */
1139          res = retry_aud_unlink (FIL__, __LINE__, lockfile);
1140        }
1141      else
1142        {
1143          unsigned int count = 0;
1144
1145          /* fails if file exists
1146           */
1147          do {
1148            fd = sl_open_safe_rdwr (FIL__, __LINE__, 
1149                                    lockfile, SL_YESPRIV);
1150            if (SL_ISERROR(fd))
1151              {
1152                retry_msleep(0, 100);
1153                ++count;
1154              }
1155
1156          } while (SL_ISERROR(fd) && count < 3);
1157     
1158          if (!SL_ISERROR(fd))
1159            {
1160              int filed;
1161
1162              res = sl_write (fd, myPid, sl_strlen(myPid));
1163              filed = get_the_fd(fd);
1164              fchmod (filed, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
1165              sl_close (fd);
1166            }
1167          else
1168            {
1169              static int nFail = 0;
1170
1171              if (nFail == 0)
1172                {
1173                  char errmsg[1024];
1174                  char * tmp  = sh_util_safe_name (lockfile);
1175                 
1176                  sl_snprintf(errmsg, sizeof(errmsg), 
1177                              _("Error creating lockfile %s"),
1178                              tmp);
1179                 
1180                  sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, 
1181                                   0, MSG_E_SUBGEN,
1182                                   errmsg, _("sh_efile_lock"));
1183                  ++nFail;
1184                  SH_FREE(tmp);
1185                }
1186            }
1187        }
1188    }
1189
1190  SH_FREE(lockfile);
1191  return res;
1192}
1193
1194static size_t gSave[6] = { 0 };
1195
1196static void sh_efile_clear()
1197{
1198  int i;
1199
1200  for (i = 0; i < 6; ++i)
1201    gSave[i] = 0;
1202  return;
1203}
1204
1205static void sh_efile_load(size_t * tmp)
1206{
1207  int i;
1208
1209  if (SL_TRUE == sl_ok_adds (gSave[0], sh.statistics.bytes_hashed))
1210    gSave[0] += sh.statistics.bytes_hashed;
1211  if (SL_TRUE == sl_ok_adds (gSave[1], sh.statistics.dirs_checked))
1212    gSave[1] += sh.statistics.dirs_checked;
1213  if (SL_TRUE == sl_ok_adds (gSave[2], sh.statistics.files_checked))
1214    gSave[2] += sh.statistics.files_checked;
1215  if (SL_TRUE == sl_ok_adds (gSave[3], sh.statistics.files_report))
1216    gSave[3] += sh.statistics.files_report;
1217  if (SL_TRUE == sl_ok_adds (gSave[4], sh.statistics.files_error))
1218    gSave[4] += sh.statistics.files_error;
1219  if (SL_TRUE == sl_ok_adds (gSave[5], sh.statistics.files_nodir))
1220    gSave[5] += sh.statistics.files_nodir;
1221
1222  for (i = 0; i < 6; ++i)
1223    tmp[i] = gSave[i];
1224  return;
1225}
1226
1227void sh_efile_report()
1228{
1229  extern int get_the_fd (SL_TICKET ticket);
1230  SL_TICKET     fd;
1231  char         *efile;
1232  int           status = -1;
1233
1234  if (gEfile)
1235    {
1236      size_t tmp[6];
1237
1238      sh_efile_load(tmp);
1239
1240      efile = sh_util_strdup(gEfile);
1241     
1242      if (sh_efile_lock (efile, 1) < 0)
1243        goto end;
1244
1245      if (  0 !=  (status = tf_trust_check (efile, SL_YESPRIV))
1246            && gFail == 0)
1247        {
1248          char * tmp  = sh_util_safe_name (efile);
1249          sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_TRUST,
1250                           (long) sh.effective.uid, tmp);
1251          ++gFail;
1252          SH_FREE(tmp);
1253        }
1254     
1255      if (status == 0)
1256        {
1257          fd = sl_open_write (FIL__, __LINE__, efile, SL_YESPRIV);
1258
1259          if (!SL_ISERROR(fd))
1260            {
1261              char report[511];
1262              char tstamp[TIM_MAX];
1263
1264              time_t now = time(NULL);
1265              int  filed = get_the_fd(fd);
1266
1267              (void) sh_unix_time (now, tstamp, sizeof(tstamp));
1268#ifdef HAVE_LONG_LONG
1269              sl_snprintf(report, sizeof(report), 
1270                          _("%s %lld %ld %ld %ld %ld %ld %ld\n"),
1271                          tstamp,
1272                          (long long) now,
1273                          (long) tmp[0], (long) tmp[1], (long) tmp[2], 
1274                          (long) tmp[3], (long) tmp[4], (long) tmp[5]);
1275#else
1276              sl_snprintf(report, sizeof(report), 
1277                          _("%s %ld %ld %ld %ld %ld %ld %ld\n"),
1278                          tstamp,
1279                          (long) now,
1280                          (long) tmp[0], (long) tmp[1], (long) tmp[2], 
1281                          (long) tmp[3], (long) tmp[4], (long) tmp[5]);
1282#endif
1283                         
1284              status = sl_forward(fd);
1285              if (!SL_ISERROR(status))
1286                status = sl_write (fd, report,  strlen(report));
1287              (void) sl_sync(fd);
1288
1289              /* make group writeable, such that nagios can truncate */
1290              fchmod (filed, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
1291              status = fchown (filed, -1, gGid);
1292              if (status < 0)
1293                {
1294                  int  errnum = errno;
1295                  static int nFail = 0;
1296                  if (nFail == 0)
1297                    {
1298                      char errmsg[1024];
1299                      char buf[256];
1300                      char * tmp  = sh_util_safe_name (efile);
1301
1302                      sl_snprintf(errmsg, sizeof(errmsg), 
1303                                  _("Error changing group of %s to %ld: %s"),
1304                                  tmp, gGid, 
1305                                  sh_error_message (errnum, buf, sizeof(buf)));
1306                      sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, 
1307                                       errnum, MSG_E_SUBGEN,
1308                                       errmsg, _("sh_efile_report"));
1309                      ++nFail;
1310                      SH_FREE(tmp);
1311                    }
1312                }
1313
1314              (void) sl_close(fd);
1315            }
1316          else
1317            {
1318              status = -1;
1319            }
1320        }
1321 
1322      (void) sh_efile_lock (efile, 0);
1323    end:
1324      SH_FREE(efile);
1325
1326      if (!SL_ISERROR(status))
1327        {
1328          sh_efile_clear();
1329        }
1330    }
1331  return;
1332}
Note: See TracBrowser for help on using the repository browser.