source: trunk/src/sh_err_log.c @ 132

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

Make utility functions thread-safe.

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