source: trunk/src/sh_err_log.c @ 133

Last change on this file since 133 was 133, checked in by rainer, 12 years ago

Reentrant checksum/hash functions.

File size: 25.7 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
27#include "samhain.h"
28#include "sh_error.h"
29#include "sh_utils.h"
30#include "sh_tiger.h"
31
32#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
33#include <sys/mman.h>
34#endif
35
36
37#undef  FIL__
38#define FIL__  _("sh_err_log.c")
39
40#undef  FIX_XML
41#define FIX_XML 1
42
43#define MYSIGLEN (2*KEY_LEN + 32)
44
45typedef struct _sh_log_buf {
46  char   signature[KEY_LEN+1];
47  char   timestamp[KEY_LEN+1];
48#ifdef SH_USE_XML
49  char   sig[MYSIGLEN];
50#endif
51  char * msg;
52} sh_sh_log_buf;
53
54extern struct  _errFlags  errFlags;
55
56#define CHK_KEY 0
57#define CHK_FIL 1
58#define CHK_NON 2
59
60static int get_key_from_file(char * path, char * keyid, char * key)
61{
62  SL_TICKET  fd;
63  char * buf;
64  char * bufc;
65
66  if (path[strlen(path)-1] == '\n')
67    path[strlen(path)-1] = '\0';
68
69  /* open the file, then check it
70   */
71  if ( SL_ISERROR(fd = sl_open_read (path, SL_NOPRIV)))
72    {
73      fprintf(stderr, _("Could not open file <%s>\n"), path);
74      _exit (EXIT_FAILURE);
75    }
76
77  buf     = SH_ALLOC( (size_t)(SH_BUFSIZE+1));
78  bufc    = SH_ALLOC( (size_t)(SH_MAXBUF+1));
79
80  while (1 == 1)
81    {
82      buf[0]  = '\0';
83      bufc[0] = '\0';
84
85      /* find start of next key
86       */
87      while (0 != sl_strncmp(buf, _("-----BEGIN LOGKEY-----"),
88                             sizeof("-----BEGIN LOGKEY-----")-1)) 
89        {
90          (void) sh_unix_getline (fd, buf, SH_BUFSIZE);
91          if (buf[0] == '\0')
92            {
93              /* End of file reached, return.
94               */
95              (void) fflush(stdout);
96              (void) sl_close(fd);
97              return -1; 
98            }
99        }
100
101      /* read key
102       */
103      (void) sh_unix_getline (fd, buf, SH_BUFSIZE);
104
105      if (0 == sl_strncmp(keyid, &buf[KEY_LEN], strlen(keyid)))
106        {
107          (void) sl_strlcpy(key, buf, KEY_LEN+1);
108          (void) sl_close(fd);
109          return 0;
110        }
111    }
112         
113  /*@notreached@*/
114}
115
116static int just_list = S_FALSE;
117
118int sh_error_logverify_mod (const char * s)
119{
120  just_list = S_TRUE;
121  if (s)      /* compiler warning (unused var) fix */
122    return 0;
123  else
124    return 0;
125} 
126
127int sh_error_logverify (const char * s)
128{
129  SL_TICKET fd;
130  int len;
131  int status;
132  int count =  0;
133  int start = -1;
134  char * buf;
135  char * bufc;
136#ifdef SH_USE_XML
137  char * ptr;
138  int fixed_xml = S_TRUE;
139  char c_start;
140#endif
141  char signature[64];
142  char key[KEY_LEN+2];
143  char path[KEY_LEN+1];
144  char timestamp[64];
145  char c_cont;
146  int  chk_mode = CHK_KEY;
147  char hashbuf[KEYBUF_SIZE];
148
149  sh_error_logoff();
150
151  if (s == NULL || sl_strlen(s) >= PATH_MAX)
152    {
153      fprintf(stderr, _("FAIL: msg=\"Invalid input\", path=\"%s\"\n"), s);
154      _exit (EXIT_FAILURE);
155    }
156
157  /* Open the file, then check it.
158   */
159  if (0 != sl_is_suid())
160    {
161      fprintf(stderr, _("Cannot open file %s in suid mode\n"), s);
162      _exit (EXIT_FAILURE);
163    }
164
165  if ( SL_ISERROR(fd = sl_open_read (s, SL_NOPRIV)) )
166    {
167      fprintf(stderr, 
168              _("FAIL: msg=\"File not accessible\", error=\"%ld\", path=\"%s\"\n"), fd, s);
169      _exit (EXIT_FAILURE);
170    }
171
172  /* Find space value.
173   */
174  c_cont  = ' ';
175#ifdef SH_STEALTH
176  c_cont ^= XOR_CODE;
177#endif
178
179#ifdef SH_USE_XML
180  c_start  = '<';
181#ifdef SH_STEALTH
182  c_start ^= XOR_CODE;
183#endif
184#endif
185
186  buf  = (char *) SH_ALLOC( 2*SH_BUFSIZE+1 );
187  bufc = (char *) SH_ALLOC( 2*SH_BUFSIZE+1 );
188
189  while (1 == 1) 
190    {
191      /* get the log message
192       */
193      if (sh_unix_getline (fd, buf, (2*SH_BUFSIZE)) < 0) 
194        break;
195
196      len = (int) sl_strlen(buf);
197
198#ifdef SH_USE_XML
199#ifdef SH_STEALTH
200      if (0 == sl_strncmp (buf, N_("<trail>"), 7)) 
201#else
202      if (0 == sl_strncmp (buf, _("<trail>"),  7)) 
203#endif
204#else
205#ifdef SH_STEALTH
206      if (0 == sl_strncmp (buf, N_("[SOF]"), 5)) 
207#else
208      if (0 == sl_strncmp (buf, _("[SOF]"),  5)) 
209#endif
210#endif
211        {
212          if (just_list == S_TRUE)
213            {
214#ifdef SH_STEALTH
215              sh_do_decode (buf, sl_strlen(buf));
216#endif
217              fprintf (stdout, _("%s\n"), buf);
218            }
219
220          /* Found start of audit trail, read first line.
221           */
222          start = 1;
223          do {
224            if ( sh_unix_getline (fd, buf, (2*SH_BUFSIZE)) < 0)
225              break;
226          } while (buf[0] == '\0' || buf[0] == '\n');
227          len = (int) sl_strlen(buf);
228
229          if (just_list == S_TRUE)
230            {
231#ifdef SH_STEALTH
232              if (buf[0] != '\n') 
233                sh_do_decode (buf, sl_strlen(buf));
234#endif
235              fprintf (stdout, _("%s\n"), buf);
236              start = 0;
237            }
238
239          ++count;
240        }
241      else if (buf[0] == '\n'
242#ifdef SH_USE_XML
243               ||
244#ifdef SH_STEALTH
245               0 == sl_strncmp(buf, N_("</trail>"), 7)
246#else
247               0 == sl_strncmp(buf,  _("</trail>"), 7)
248#endif
249#endif
250               )
251        {
252          if (just_list == S_TRUE)
253            {
254#ifdef SH_STEALTH
255              if (buf[0] != '\n') 
256                sh_do_decode (buf, sl_strlen(buf));
257#endif
258              fprintf (stdout, _("%s\n"), buf);
259            }
260
261          /* A newline.
262           */
263          ++count;
264          continue;
265        }
266      else if (start == 0)
267        {
268          /* We are inside an audit trail.
269           */
270          ++count;
271          if (just_list == S_TRUE)
272            {
273#ifdef SH_STEALTH
274              sh_do_decode (buf, sl_strlen(buf));
275#endif
276              fprintf (stdout, _("%s\n"), buf);
277              continue;
278            }
279        }
280      else
281        {
282          /* No start-of-file found yet.
283           */
284          continue;
285        }
286
287      if (just_list == S_TRUE)
288        continue;
289
290      /* Check for a continuation line.
291       */
292      while (1 == 1)
293        {
294          do {
295            if ( sh_unix_getline (fd, bufc, (2*SH_BUFSIZE)) < 0)
296              break;
297          } while (bufc[0] == '\0' || bufc[0] == '\n');
298          ++count;
299          if (bufc[0] == c_cont) 
300            {
301              /* A continuation line. Add the newline.
302               */
303              (void) sl_strlcat(buf, "\n", 2*SH_BUFSIZE+1);
304              ++len;
305              (void) sl_strlcat(buf, bufc, 2*SH_BUFSIZE+1);
306              len += (int) sl_strlen(bufc);
307            }
308          else
309            {
310              /* No continuation line. Use it as signature.
311               * A48014C05604EF7C9472330E85453E704024943E556163C2
312               */
313#ifdef SH_USE_XML
314#ifdef SH_STEALTH
315              if (bufc[0] == c_start) /* FIX XML */
316#else
317              if (bufc[0] == c_start)
318#endif
319                {
320                  (void) sl_strlcpy(signature, &bufc[5], KEY_LEN+1);
321                  fixed_xml = S_TRUE;
322                }
323              else
324                {
325                  (void) sl_strlcpy(signature, &bufc[4], KEY_LEN+1);
326                  fixed_xml = S_FALSE;
327                }
328              if (sl_strlen(bufc) > (KEY_LEN+18))
329                {
330#ifdef SH_STEALTH
331                  if (bufc[0] == c_start) /* FIX XML */
332#else
333                  if (bufc[0] == c_start)
334#endif
335                    (void) sl_strlcpy(timestamp, &bufc[KEY_LEN+5], 64);
336                  else
337                    (void) sl_strlcpy(timestamp, &bufc[KEY_LEN+4], 64);
338#ifdef SH_STEALTH
339                  ptr = strchr(timestamp, c_start);
340#else
341                  ptr = strchr(timestamp, c_start);
342#endif
343                  if (ptr) *ptr = '\0';
344                }
345              break;
346#else
347              sl_strlcpy(signature, bufc, KEY_LEN+1);
348              if (sl_strlen(bufc) > KEY_LEN)
349                sl_strlcpy(timestamp, &bufc[KEY_LEN], 64);
350              break;
351#endif
352            }
353        }
354     
355      /* Get starting key from command line.
356       */   
357      if (start == 1) 
358        {
359         
360          /* Get the timestamp.
361           */
362         
363#ifdef SH_STEALTH
364          sh_do_decode (timestamp, sl_strlen(timestamp));
365#endif
366          key[0] = '\0';
367         
368        findKey:
369         
370          if (chk_mode != CHK_FIL)
371            {
372              /* Ask for the key.
373               */
374              chk_mode = CHK_KEY;
375              fprintf(stdout, _("\nNew audit trail (%s), enter key|keyfile: "),
376                      /*@-usedef@*/timestamp/*@+usedef@*/);
377              key[0] = '\0';
378             
379              while (sl_strlen(key) < KEY_LEN ) 
380                { 
381                  if (key[0] != '\n' && key[0] != '\0')
382                    fprintf(stdout, _("New audit trail, enter key: "));
383                  else if (key[0] == '\n')
384                    {
385                      (void) sl_strlcpy(key, 
386                                        sh_tiger_hash(NULL, TIGER_DATA, 0, 
387                                                      hashbuf, sizeof(hashbuf)), 
388                                        KEY_LEN+1);
389                      chk_mode = CHK_NON;
390                      break;
391                    }
392                  (void) fflush(stdout); 
393                  key[0] = '\0';
394                  (void) fgets(key, sizeof(key), stdin);
395                  if (key[0] != '\n') 
396                    {
397                      if (key[strlen(key) - 1] == '\n')
398                        key[strlen(key) - 1] = '\0';
399                    }
400                  if (key[0] == '/')
401                    {
402                      chk_mode = CHK_FIL;
403                      (void) sl_strlcpy(path, key, KEY_LEN+1); 
404                      break;
405                    }
406                }
407            }
408          /* we now have either a key (chk_mode == CHK_NON|CHK_KEY)
409           * or a file (chk_mode == CHK_FIL)
410           */
411          if (chk_mode == CHK_FIL)
412            {
413              fprintf(stdout, _("\nAudit trail (%s), searching file %s\n"), 
414                      /*@-usedef@*/timestamp, path/*@+usedef@*/);
415              if (-1 == get_key_from_file(path, timestamp, key))
416                {
417                  chk_mode = CHK_KEY;
418                  fprintf(stdout, _("Key not found in file\n"));
419                  goto findKey;
420                }
421            }
422         
423         
424          sh_util_encode(key, buf, 1, 'B');
425          start = 0;
426        } 
427      else
428        { 
429          /* Iterate the key.
430           */
431          (void) sl_strlcpy (key, 
432                             sh_tiger_hash (key, TIGER_DATA, KEY_LEN,
433                                            hashbuf, sizeof(hashbuf)), 
434                             KEY_LEN+1);
435        }
436     
437      (void) sl_strlcat ( buf, key, 2*SH_BUFSIZE + 1);
438     
439#ifdef SH_STEALTH
440      sh_do_decode (signature, sl_strlen(signature));
441#endif
442     
443      status = sl_strncmp (signature, 
444                           sh_tiger_hash (buf, TIGER_DATA, 
445                                          (unsigned long) sl_strlen(buf),
446                                          hashbuf, sizeof(hashbuf)),
447                           KEY_LEN);
448     
449      buf[len] = '\0';    /* do not print out the key */
450#ifdef SH_STEALTH
451      sh_do_decode (buf, sl_strlen(buf));
452#endif
453     
454      if (status != 0) 
455        {
456#ifdef SH_USE_XML
457          if (chk_mode == CHK_NON)
458            {
459              if (fixed_xml == S_FALSE)
460                fprintf (stdout, _("XFAIL: line=%05d %s/log>\n"), 
461                         count-1, buf);
462              else
463                fprintf (stdout, _("XFAIL: line=%05d %s</log>\n"), 
464                         count-1, buf);
465            }
466          else
467            {
468              if (fixed_xml == S_FALSE)
469                fprintf (stdout, _("FAIL:  line=%05d %s/log>\n"), 
470                         count-1, buf);
471              else
472                fprintf (stdout, _("FAIL:  line=%05d %s</log>\n"), 
473                         count-1, buf);
474            }
475#else
476          if (chk_mode == CHK_NON)
477            fprintf (stdout, _("XFAIL: line=%5d %s\n"), count-1, buf);
478          else
479            fprintf (stdout, _("FAIL:  line=%5d %s\n"), count-1, buf);
480#endif
481        }
482      else
483        {
484#ifdef SH_USE_XML
485          if (fixed_xml == S_FALSE)
486            fprintf (stdout, _("PASS:  line=%05d %s/log>\n"),  count-1, buf);
487          else
488            fprintf (stdout, _("PASS:  line=%05d %s</log>\n"), count-1, buf);
489#else
490          fprintf (stdout, _("PASS:  line=%5d %s\n"), count-1, buf);
491#endif   
492        }
493    }
494
495  /* Cleanup and exit.
496   */
497  (void) sl_close (fd);
498  SH_FREE  (buf);
499  SH_FREE  (bufc);
500  (void) fflush   (stdout);
501  _exit    (EXIT_SUCCESS);
502
503  /* Make compilers happy.
504   */
505  /*@notreached@*/
506  return 0; 
507}
508
509/********************************************************************
510 *
511 *  Runtime code
512 *
513 ********************************************************************/
514static
515int sh_log_open (char * inet_peer, 
516                 char * logfile, int * service_failure, SL_TICKET * fildesc)
517{
518  SL_TICKET            fd = -1;
519  long int             status;
520  char               * tmp = NULL;
521  uid_t                uid;
522  size_t               len;
523  char               * lockfile = NULL;
524
525  SL_ENTER(_("sh_log_open"));
526
527  /* open/create the file, then check it
528   */
529
530  if (  0 !=  (status = tf_trust_check (logfile, SL_YESPRIV))
531        && (*service_failure) == 0)
532    {
533      tmp  = sh_util_safe_name (logfile);
534      sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_TRUST,
535                      (long) sh.effective.uid, tmp);
536    }
537
538  if (status == 0)
539    {
540      fd = sl_open_write (logfile, SL_YESPRIV);
541      if (SL_ISERROR(fd))
542        {
543          tmp  = sh_util_safe_name (logfile);
544          (void) sl_get_euid(&uid);
545          if ((*service_failure) == 0)
546            sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_E_ACCESS,
547                             (long) uid, tmp);
548          status = -1;
549        }
550    }
551
552
553  if (status == 0 && inet_peer == NULL )
554    {
555      status = sh_unix_write_lock_file(logfile);
556      if (status < 0)
557        {
558          tmp  = sh_util_safe_name (logfile);
559          len      = sl_strlen(tmp);
560          if (sl_ok_adds (6, len))
561            len += 6;
562          lockfile = SH_ALLOC(len);
563          (void) sl_strlcpy(lockfile,        tmp, len);
564          (void) sl_strlcat(lockfile, _(".lock"), len);
565          (void) sl_get_euid(&uid);
566          if ((*service_failure) == 0)
567            sh_error_handle ((-1), FIL__, __LINE__, status, MSG_LOCKED,
568                             (long) uid, tmp, lockfile);
569          status = -1;
570          SH_FREE(lockfile);
571          (void) sl_close(fd);
572        }
573    }
574
575  if (status == 0)
576    {
577      status = sl_forward(fd); 
578      if (SL_ISERROR(status))
579        {
580          tmp  = sh_util_safe_name (logfile);
581          (void) sl_get_euid(&uid);
582          if ((*service_failure) == 0)
583            sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_ACCESS,
584                             (long) uid, tmp);
585          status = -1;
586          (void) sl_close(fd);
587        }
588    }
589 
590  if (status < 0)
591    {
592      if ((*service_failure) == 0) {
593        sh_error_handle ((-1), FIL__, __LINE__, status, MSG_SRV_FAIL,
594                         _("logfile"), tmp);
595        (*service_failure) = 1;
596      }
597      SH_FREE(tmp);
598      SL_RETURN(-1, _("sh_log_open"));
599    }
600
601  *fildesc         = fd;
602  *service_failure = 0;
603  SL_RETURN(0, _("sh_log_open"));
604}
605
606typedef struct lfstc {
607  char          * logfile;
608  int             service_failure;
609  int             log_start;
610  char            sigkey_old[KEY_LEN+1];
611  char            sigkey_new[KEY_LEN+1];
612  char            crypto[KEY_LEN+1];
613  struct  lfstc * next;
614} open_logfile;
615
616static open_logfile * logfile_list = NULL;
617
618static int flag_sep_log = S_FALSE;
619
620#ifdef SH_WITH_SERVER
621int set_flag_sep_log (const char * str)
622{
623  return sh_util_flagval(str, &flag_sep_log);
624}
625#endif
626
627/*
628 *   --- Log error message to log file. ---
629 */
630int  sh_log_file (/*@null@*/char *errmsg, /*@null@*/char * inet_peer)
631{
632  int                  store1;
633  int                  store2;
634  int                  store3;
635  int                  store4;
636  int                  store5;
637  int                  store6;
638  int                  store7;
639  int                  store8;
640
641  SL_TICKET            fd = -1;
642  size_t               status;
643  struct _sh_log_buf   log_msg;
644
645  char                 logfile[SH_PATHBUF+SH_MINIBUF+2];
646  open_logfile       * current = logfile_list; 
647  open_logfile       * next    = NULL;
648  char               * sigkey_new;
649  char               * sigkey_old;
650  char               * crypto;
651
652  SL_ENTER(_("sh_log_file"));
653
654  if (errFlags.HaveLog == BAD)  /* paranoia */ 
655    SL_RETURN((-1), _("sh_log_file"));
656
657#ifdef SH_USE_XML
658  if (NULL == errmsg)
659    {
660      while (current != NULL)
661        {
662          /* don't write second EOF mark
663           */
664          if (current->log_start != S_TRUE)
665            {
666              /* Don't use inet_peer == NULL, userwise a lock file will
667               * be created.
668               */
669              (void) sh_log_open ("\0", 
670                                  current->logfile, 
671                                  &(current->service_failure), &fd);
672         
673#ifdef SH_STEALTH
674              (void) sl_write_line (fd, N_("</trail>"), 7);
675              (void) sl_write (fd, "\n", 1);
676              (void) sl_sync(fd);
677#else
678              (void) sl_write_line (fd, _("</trail>\n"),  8);
679              (void) sl_sync(fd);
680#endif
681              (void) sl_close(fd);
682              /* sh_unix_rm_lock_file (current->logfile); */
683            }
684          next    = current->next;
685          SH_FREE(current->logfile);
686          SH_FREE(current);
687          current = next;
688        }
689      logfile_list = NULL;
690      SL_RETURN( 0, _("sh_log_file"));
691    }
692#else
693  if (NULL == errmsg)
694    {
695      while (current != NULL)
696        {
697          /* sh_unix_rm_lock_file (current->logfile); */
698          next    = current->next;
699          SH_FREE(current->logfile);
700          SH_FREE(current);
701          current = next;
702        }
703      logfile_list = NULL;
704      SL_RETURN( 0, _("sh_log_file"));
705    }
706#endif
707
708  (void) sl_strlcpy (logfile, sh.srvlog.name, sizeof(logfile));
709  if (inet_peer != NULL && flag_sep_log == S_TRUE)
710    {
711      (void) sl_strlcat (logfile, ".",       sizeof(logfile));
712      (void) sl_strlcat (logfile, inet_peer, sizeof(logfile));
713    }
714
715  if (sh.flag.log_start == S_TRUE)
716    {
717      while (current != NULL)
718        {
719          current->log_start = S_TRUE;
720          current = current->next;
721        }
722      sh.flag.log_start    = S_FALSE;
723      current = logfile_list;
724    }
725
726  while (current != NULL)
727    {
728      if (strcmp(logfile, current->logfile) == 0)
729        break;
730      current = current->next;
731    }
732
733  if (current == NULL)
734    {
735      current                  = SH_ALLOC(sizeof(open_logfile));
736      current->logfile         = SH_ALLOC(strlen(logfile) + 1);
737      (void) sl_strlcpy(current->logfile, logfile, strlen(logfile) + 1);
738      current->service_failure = 0;
739      current->log_start       = S_TRUE;
740      memset(current->sigkey_old, (int)'\0', KEY_LEN+1);
741      memset(current->sigkey_new, (int)'\0', KEY_LEN+1);
742      memset(current->crypto,     (int)'\0', KEY_LEN+1);
743      current->next            = logfile_list;
744      logfile_list             = current;
745    }
746
747  if (0 != sh_log_open (inet_peer, current->logfile, 
748                        &(current->service_failure), &fd))
749    {
750      SL_RETURN ((-1), _("sh_log_file"));
751    }
752
753
754  /* --- Allocate storage and mlock it. ---
755   */
756
757  status      =  sl_strlen (errmsg);
758  if (!sl_ok_adds(status, (2*KEY_LEN)) || !sl_ok_adds((2*KEY_LEN + status),32))
759    {
760      SL_RETURN ((-1), _("sh_log_file"));
761    }
762     
763  log_msg.msg = (char *) SH_ALLOC ((size_t) (2*KEY_LEN + status + 32)); 
764
765#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
766  if (skey->mlock_failed == SL_FALSE) 
767    {
768      if ( (-1) == sh_unix_mlock( FIL__, __LINE__, log_msg.msg, 
769                                  (size_t)(2*KEY_LEN + status + 32) ) ) 
770        {
771          skey->mlock_failed = SL_TRUE;
772#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
773          sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK); 
774#endif
775        }
776    }
777#else
778  if (skey->mlock_failed == SL_FALSE) 
779    {
780      skey->mlock_failed = SL_TRUE;
781#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
782      sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK);
783#endif
784    }
785#endif
786
787  /* --- Write the start marker. ---
788   */
789
790  if (current->log_start == S_TRUE) 
791    {
792#ifdef SH_USE_XML
793#ifdef SH_STEALTH
794      (void) sl_write (fd, "\n", 1);
795      (void) sl_write_line (fd, N_("<trail>"), 7);
796      (void) sl_sync(fd);
797#else
798      (void) sl_write_line (fd, _("\n<trail>"),  8);
799      (void) sl_sync(fd);
800#endif
801#else
802#ifdef SH_STEALTH
803      (void) sl_write (fd, "\n", 1);
804      (void) sl_write_line (fd, N_("[SOF]"), 5);
805      (void) sl_sync(fd);
806#else
807      (void) sl_write_line (fd, _("\n[SOF]"),  6);
808      (void) sl_sync(fd);
809#endif
810#endif
811    }
812
813  /* reserve KEY_LEN chars at end for key
814   */
815  (void) sl_strlcpy (log_msg.msg, errmsg, (size_t) status+1 );
816
817
818#ifdef SH_USE_XML
819  /* cut the trailing "/>"
820   */
821  if (log_msg.msg[status-2] == '/')
822    {
823#ifdef FIX_XML
824      log_msg.msg[status-2] = ' '; /* ' ' FIX XML */
825      log_msg.msg[status-1] = '>'; /* '>' FIX XML */
826#else
827      log_msg.msg[status-2] = '>'; /* ' ' FIX XML */
828      log_msg.msg[status-1] = '<'; /* '>' FIX XML */
829#endif
830      log_msg.msg[status]   = '\0';
831    }
832  else if (status >= 6 && log_msg.msg[status-5] == '/' && 
833           log_msg.msg[status-6] == '<')
834    {
835#ifdef FIX_XML
836      log_msg.msg[status-6]   = '\0';
837      status -= 6;
838#else
839      log_msg.msg[status-5]   = '\0';
840      status -= 5;
841#endif
842    }
843#endif
844
845
846#ifdef SH_STEALTH
847  sh_do_encode (log_msg.msg, status);
848#endif
849
850  if (flag_sep_log == S_TRUE && inet_peer != NULL)
851    {
852      sigkey_old = current->sigkey_old;
853      sigkey_new = current->sigkey_new;
854      crypto     = current->crypto;
855    }
856  else
857    {
858      sigkey_old = skey->sigkey_old;
859      sigkey_new = skey->sigkey_new;
860      crypto     = skey->crypt;      /* flawfinder: ignore */
861    }
862
863  /* write the signature
864   */
865  if (current->log_start == S_TRUE) 
866    {
867      char hashbuf[KEYBUF_SIZE];
868
869      if (sh.real.user[0] == '\0') 
870        (void) sh_unix_getUser();
871
872      /* Initialize the key.
873       */
874      (void) sh_util_keyinit(sigkey_old, KEY_LEN+1);
875
876      /* Hash the key to make sure it has the correct format.
877       */
878      (void) sl_strlcpy(sigkey_new, 
879                        sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN,
880                                       hashbuf, sizeof(hashbuf)), 
881                        KEY_LEN+1);
882
883      /* Copy it to 'crypt' for encryption.
884       */
885      (void) sl_strlcpy(crypto, sigkey_new, KEY_LEN+1);
886
887      /* Use message and compiled-in key to encrypt.
888       */
889      BREAKEXIT(sh_util_encode);
890      sh_util_encode(crypto, log_msg.msg, 0, 'B');
891
892      /* Send out the key.
893       */
894      (void) sh_unix_time(0, log_msg.timestamp, KEY_LEN+1); 
895
896      store1               = errFlags.loglevel;
897      store2               = errFlags.sysloglevel;
898      store3               = errFlags.printlevel;
899      store4               = errFlags.exportlevel;
900      store5               = errFlags.maillevel;
901      store6               = errFlags.externallevel;
902      store7               = errFlags.databaselevel;
903      store8               = errFlags.preludelevel;
904
905      /* mail the key
906       */
907      errFlags.loglevel       = SH_ERR_NOT;
908      errFlags.sysloglevel    = SH_ERR_NOT;
909      errFlags.printlevel     = SH_ERR_NOT;
910      errFlags.exportlevel    = SH_ERR_NOT;
911      errFlags.externallevel  = SH_ERR_NOT;
912      errFlags.databaselevel  = SH_ERR_NOT;
913      errFlags.preludelevel   = SH_ERR_NOT;
914
915      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY_MAIL,
916                       sh.prg_name, crypto, 
917                       crypto, log_msg.timestamp);
918
919      /* send to other allowed channels
920       */
921      errFlags.maillevel      = SH_ERR_NOT;
922      /* errFlags.printlevel     = store3; */
923      errFlags.exportlevel    = store4;
924      errFlags.externallevel  = store6;
925      errFlags.databaselevel  = store7;
926      errFlags.preludelevel   = store8;
927
928      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY,
929                       sh.prg_name, crypto);
930
931      /* Cleanup.
932       */
933      errFlags.loglevel       = store1;
934      errFlags.sysloglevel    = store2;
935      errFlags.printlevel     = store3;
936      errFlags.exportlevel    = store4;
937      errFlags.maillevel      = store5;
938      errFlags.externallevel  = store6;
939      errFlags.databaselevel  = store7;
940
941
942      memset (crypto, (int) '\0', KEY_LEN);
943      sh.flag.log_start    = S_FALSE; 
944      current->log_start   = S_FALSE;
945    } 
946  else 
947    {
948      log_msg.timestamp[0] = '\0';
949      (void) sl_strlcpy (sigkey_new, 
950                         sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN),
951                         KEY_LEN+1);
952    }
953
954  /* --- Sign the message with the signature key. ---
955   */
956
957  (void) sl_strlcat (log_msg.msg, sigkey_new, (size_t)(status + KEY_LEN + 2));
958 
959  (void) sl_strlcpy (log_msg.signature,
960                     sh_tiger_hash (log_msg.msg, TIGER_DATA, 
961                                    (unsigned long)(status + KEY_LEN)), 
962                     KEY_LEN+1);
963  (void) sl_strlcpy (sigkey_old, sigkey_new, KEY_LEN+1); 
964
965  /*@-usedef@*/
966#ifdef SH_USE_XML
967  if (log_msg.timestamp[0] != '\0')
968    sl_snprintf(log_msg.sig, sizeof(log_msg.sig),
969#ifdef FIX_XML
970                _("\n<sig>%s%s</sig></log>\n"),          /* <sig> FIX XML */
971#else
972                _("\nsig>%s%s</sig></log>\n"),          /* <sig> FIX XML */
973#endif
974                log_msg.signature, log_msg.timestamp);
975  else
976    sl_snprintf(log_msg.sig, sizeof(log_msg.sig),
977#ifdef FIX_XML
978                _("\n<sig>%s</sig></log>\n"),            /* <sig> FIX XML */
979#else
980                _("\nsig>%s</sig></log>\n"),            /* <sig> FIX XML */
981#endif
982                log_msg.signature);
983  /*@+usedef@*/
984
985#ifdef SH_STEALTH
986  /* don't encode the line breaks (0 + last char)
987   */
988  sh_do_encode (&log_msg.sig[1], (sl_strlen(log_msg.sig)-2) );
989#endif
990#else
991#ifdef SH_STEALTH
992  sh_do_encode (log_msg.signature, KEY_LEN);
993  sh_do_encode (log_msg.timestamp, sl_strlen(log_msg.timestamp));
994#endif
995#endif
996 
997#ifdef SH_USE_XML
998  log_msg.msg[status] = '\0';
999  (void) sl_strlcat (log_msg.msg,   log_msg.sig, 
1000                     (size_t)(status + 2*KEY_LEN + 32));
1001#ifdef SH_STEALTH
1002  if (NULL != sl_strstr(log_msg.msg, N_("EXIT")) &&
1003      NULL == sl_strstr(log_msg.msg, N_("remote_host")))
1004    {
1005      (void) sl_strlcat (log_msg.msg,  N_("</trail>"), 
1006                         (size_t)(status + 2*KEY_LEN + 32)); 
1007#else
1008  if (NULL != sl_strstr(log_msg.msg,  _("msg=\"EXIT\"")) &&
1009      NULL == sl_strstr(log_msg.msg,  _("remote_host")))
1010    {
1011      (void) sl_strlcat (log_msg.msg,   _("</trail>"), 
1012                         (size_t)(status + 2*KEY_LEN + 32)); 
1013#endif
1014     
1015      (void) sl_strlcat (log_msg.msg,   _("\n"), 
1016                         (size_t)(status + 2*KEY_LEN + 32)); 
1017      current->log_start = S_TRUE;
1018    }
1019#else
1020  log_msg.msg[status] = '\0';
1021  (void) sl_strlcat (log_msg.msg,              "\n", 
1022                     (size_t)(status + KEY_LEN + 2));
1023  (void) sl_strlcat (log_msg.msg, log_msg.signature, 
1024                     (size_t)(status + KEY_LEN + 2));
1025  if (log_msg.timestamp[0] != '\0')
1026    (void) sl_strlcat (log_msg.msg, log_msg.timestamp, 
1027                       (size_t)(status + 2*KEY_LEN + 2));
1028  (void) sl_strlcat (log_msg.msg,              "\n", 
1029                     (size_t)(status + 2*KEY_LEN + 3));
1030#endif
1031 
1032  /* --- Write out the record. ---
1033   */
1034  (void) sl_write (fd, log_msg.msg, (long) strlen(log_msg.msg));
1035  (void) sl_sync  (fd);
1036  (void) sl_close (fd);
1037
1038  /* --- Clean up and free record. ---
1039   */
1040  memset (log_msg.msg,       (int)'\0', (size_t)(status + 2*KEY_LEN + 32));
1041  memset (log_msg.signature, (int)'\0', KEY_LEN);
1042  (void) sh_unix_munlock (log_msg.msg, 
1043                          (size_t)(status + 2*KEY_LEN + 32));
1044  SH_FREE(log_msg.msg);
1045
1046  SL_RETURN (0, _("sh_log_file"));
1047}
1048
Note: See TracBrowser for help on using the repository browser.