Logo Search packages:      
Sourcecode: samhain version File versions  Download package

sh_err_log.c

/* SAMHAIN file system integrity testing                                   */
/* Copyright (C) 2000 Rainer Wichmann                                      */
/*                                                                         */
/*  This program is free software; you can redistribute it                 */
/*  and/or modify                                                          */
/*  it under the terms of the GNU General Public License as                */
/*  published by                                                           */
/*  the Free Software Foundation; either version 2 of the License, or      */
/*  (at your option) any later version.                                    */
/*                                                                         */
/*  This program is distributed in the hope that it will be useful,        */
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of         */
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
/*  GNU General Public License for more details.                           */
/*                                                                         */
/*  You should have received a copy of the GNU General Public License      */
/*  along with this program; if not, write to the Free Software            */
/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */

#include "config_xor.h"

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include "samhain.h"
#include "sh_error.h"
#include "sh_utils.h"
#include "sh_tiger.h"

#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
#include <sys/mman.h>
#endif


#undef  FIL__
#define FIL__  _("sh_err_log.c")

#undef  FIX_XML
#define FIX_XML 1 

#define MYSIGLEN (2*KEY_LEN + 32)

typedef struct _sh_log_buf {
  char   signature[KEY_LEN+1];
  char   timestamp[KEY_LEN+1];
#ifdef SH_USE_XML
  char   sig[MYSIGLEN];
#endif
  char * msg;
} sh_sh_log_buf;

extern struct  _errFlags  errFlags;

#define CHK_KEY 0
#define CHK_FIL 1
#define CHK_NON 2

static int get_key_from_file(char * path, char * keyid, char * key)
{
  SL_TICKET  fd;
  char * buf;
  char * bufc;

  if (path[strlen(path)-1] == '\n')
    path[strlen(path)-1] = '\0';

  /* open the file, then check it 
   */
  if ( SL_ISERROR(fd = sl_open_read (path, SL_NOPRIV)))
    {
      fprintf(stderr, _("Could not open file <%s>\n"), path);
      _exit (EXIT_FAILURE);
    }

  buf     = SH_ALLOC( (size_t)(SH_BUFSIZE+1));
  bufc    = SH_ALLOC( (size_t)(SH_MAXBUF+1));

  while (1 == 1)
    {
      buf[0]  = '\0';
      bufc[0] = '\0';

      /* find start of next key
       */
      while (0 != sl_strncmp(buf, _("-----BEGIN LOGKEY-----"),
                       sizeof("-----BEGIN LOGKEY-----")-1)) 
      {
        (void) sh_unix_getline (fd, buf, SH_BUFSIZE);
        if (buf[0] == '\0')
          {
            /* End of file reached, return. 
             */
            (void) fflush(stdout);
            (void) sl_close(fd);
            return -1; 
          }
      }

      /* read key
       */
      (void) sh_unix_getline (fd, buf, SH_BUFSIZE);

      if (0 == sl_strncmp(keyid, &buf[KEY_LEN], strlen(keyid)))
      {
        (void) sl_strlcpy(key, buf, KEY_LEN+1);
        (void) sl_close(fd);
        return 0;
      }
    }
        
  /*@notreached@*/
}

static int just_list = S_FALSE;

int sh_error_logverify_mod (char * s)
{
  just_list = S_TRUE;
  if (s)      /* compiler warning (unused var) fix */
    return 0;
  else
    return 0;
} 

int sh_error_logverify (char * s)
{
  SL_TICKET fd;
  int len;
  int status;
  int count =  0;
  int start = -1;
  char * buf;
  char * bufc;
#ifdef SH_USE_XML
  char * ptr;
  int fixed_xml = S_TRUE;
  char c_start;
#endif
  char signature[64];
  char key[KEY_LEN+2];
  char path[KEY_LEN+1];
  char timestamp[64];
  char c_cont;
  int  chk_mode = CHK_KEY;

  sh_error_logoff();

  if (s == NULL || sl_strlen(s) >= PATH_MAX)
    {
      fprintf(stderr, _("FAIL: msg=\"Invalid input\", path=\"%s\"\n"), s);
      _exit (EXIT_FAILURE);
    }

  /* Open the file, then check it. 
   */
  if (0 != sl_is_suid())
    {
      fprintf(stderr, _("Cannot open file %s in suid mode\n"), s);
      _exit (EXIT_FAILURE);
    }

  if ( SL_ISERROR(fd = sl_open_read (s, SL_NOPRIV)) )
    {
      fprintf(stderr, 
            _("FAIL: msg=\"File not accessible\", path=\"%s\"\n"), s);
      _exit (EXIT_FAILURE);
    }

  /* Find space value.
   */
  c_cont  = ' ';
#ifdef SH_STEALTH
  c_cont ^= XOR_CODE;
#endif

#ifdef SH_USE_XML
  c_start  = '<';
#ifdef SH_STEALTH
  c_start ^= XOR_CODE;
#endif
#endif

  buf  = (char *) SH_ALLOC( 2*SH_BUFSIZE+1 );
  bufc = (char *) SH_ALLOC( 2*SH_BUFSIZE+1 );

  while (1 == 1) 
    {
      /* get the log message
       */
      if (sh_unix_getline (fd, buf, (2*SH_BUFSIZE)) < 0) 
      break;

      len = (int) sl_strlen(buf);

#ifdef SH_USE_XML
#ifdef SH_STEALTH
      if (0 == sl_strncmp (buf, N_("<trail>"), 7)) 
#else
      if (0 == sl_strncmp (buf, _("<trail>"),  7)) 
#endif
#else 
#ifdef SH_STEALTH
      if (0 == sl_strncmp (buf, N_("[SOF]"), 5)) 
#else
      if (0 == sl_strncmp (buf, _("[SOF]"),  5)) 
#endif
#endif
      {
        if (just_list == S_TRUE)
          {
#ifdef SH_STEALTH
            sh_do_decode (buf, sl_strlen(buf));
#endif
            fprintf (stdout, _("%s\n"), buf);
          }

        /* Found start of audit trail, read first line. 
         */
        start = 1;
        do {
          if ( sh_unix_getline (fd, buf, (2*SH_BUFSIZE)) < 0)
            break;
        } while (buf[0] == '\0' || buf[0] == '\n');
        len = (int) sl_strlen(buf);

        if (just_list == S_TRUE)
          {
#ifdef SH_STEALTH
            if (buf[0] != '\n') 
            sh_do_decode (buf, sl_strlen(buf));
#endif
            fprintf (stdout, _("%s\n"), buf);
            start = 0;
          }

        ++count;
      }
      else if (buf[0] == '\n'
#ifdef SH_USE_XML
             ||
#ifdef SH_STEALTH
             0 == sl_strncmp(buf, N_("</trail>"), 7)
#else
             0 == sl_strncmp(buf,  _("</trail>"), 7)
#endif
#endif
             )
      {
        if (just_list == S_TRUE)
          {
#ifdef SH_STEALTH
            if (buf[0] != '\n') 
            sh_do_decode (buf, sl_strlen(buf));
#endif
            fprintf (stdout, _("%s\n"), buf);
          }

        /* A newline.
         */
        ++count;
        continue;
      }
      else if (start == 0)
      {
        /* We are inside an audit trail. 
         */
        ++count;
        if (just_list == S_TRUE)
          {
#ifdef SH_STEALTH
            sh_do_decode (buf, sl_strlen(buf));
#endif
            fprintf (stdout, _("%s\n"), buf);
            continue;
          }
      }
      else
      {
        /* No start-of-file found yet. 
         */
        continue;
      }

      if (just_list == S_TRUE)
      continue;

      /* Check for a continuation line.
       */
      while (1 == 1)
      {
        do {
          if ( sh_unix_getline (fd, bufc, (2*SH_BUFSIZE)) < 0)
            break;
        } while (bufc[0] == '\0' || bufc[0] == '\n');
        ++count;
        if (bufc[0] == c_cont) 
          {
            /* A continuation line. Add the newline. 
             */
            (void) sl_strlcat(buf, "\n", 2*SH_BUFSIZE+1);
            ++len;
            (void) sl_strlcat(buf, bufc, 2*SH_BUFSIZE+1);
            len += (int) sl_strlen(bufc);
          }
        else
          {
            /* No continuation line. Use it as signature. 
             * A48014C05604EF7C9472330E85453E704024943E556163C2
             */
#ifdef SH_USE_XML
#ifdef SH_STEALTH
            if (bufc[0] == c_start) /* FIX XML */
#else
            if (bufc[0] == c_start)
#endif
            {
              (void) sl_strlcpy(signature, &bufc[5], KEY_LEN+1);
              fixed_xml = S_TRUE;
            }
            else
            {
              (void) sl_strlcpy(signature, &bufc[4], KEY_LEN+1);
              fixed_xml = S_FALSE;
            }
            if (sl_strlen(bufc) > (KEY_LEN+18))
            {
#ifdef SH_STEALTH
              if (bufc[0] == c_start) /* FIX XML */
#else
              if (bufc[0] == c_start)
#endif
                (void) sl_strlcpy(timestamp, &bufc[KEY_LEN+5], 64);
              else
                (void) sl_strlcpy(timestamp, &bufc[KEY_LEN+4], 64);
#ifdef SH_STEALTH
              ptr = strchr(timestamp, c_start);
#else
              ptr = strchr(timestamp, c_start);
#endif
              if (ptr) *ptr = '\0';
            }
            break;
#else
            sl_strlcpy(signature, bufc, KEY_LEN+1);
            if (sl_strlen(bufc) > KEY_LEN)
            sl_strlcpy(timestamp, &bufc[KEY_LEN], 64);
            break;
#endif
          }
      }
      
      /* Get starting key from command line. 
       */    
      if (start == 1) 
      {
        
        /* Get the timestamp.
         */
        
#ifdef SH_STEALTH
        sh_do_decode (timestamp, sl_strlen(timestamp));
#endif
        key[0] = '\0';
        
      findKey:
        
        if (chk_mode != CHK_FIL)
          {
            /* Ask for the key.
             */
            chk_mode = CHK_KEY;
            fprintf(stdout, _("\nNew audit trail (%s), enter key|keyfile: "),
                  /*@-usedef@*/timestamp/*@+usedef@*/);
            key[0] = '\0';
            
            while (sl_strlen(key) < KEY_LEN ) 
            { 
              if (key[0] != '\n' && key[0] != '\0')
                fprintf(stdout, _("New audit trail, enter key: "));
              else if (key[0] == '\n')
                {
                  (void) sl_strlcpy(key, 
                              sh_tiger_hash(NULL, TIGER_DATA, 0), 
                              KEY_LEN+1);
                  chk_mode = CHK_NON;
                  break;
                }
              (void) fflush(stdout); 
              key[0] = '\0';
              (void) fgets(key, KEY_LEN+2, stdin);
              if (key[0] != '\n') 
                {
                  if (key[strlen(key) - 1] == '\n')
                  key[strlen(key) - 1] = '\0';
                }
              if (key[0] == '/')
                {
                  chk_mode = CHK_FIL;
                  (void) sl_strlcpy(path, key, KEY_LEN+1); 
                  break;
                }
            }
          }
        /* we now have either a key (chk_mode == CHK_NON|CHK_KEY)
         * or a file (chk_mode == CHK_FIL)
         */
        if (chk_mode == CHK_FIL)
          {
            fprintf(stdout, _("\nAudit trail (%s), searching file %s\n"), 
                  /*@-usedef@*/timestamp, path/*@+usedef@*/);
            if (-1 == get_key_from_file(path, timestamp, key))
            {
              chk_mode = CHK_KEY;
              fprintf(stdout, _("Key not found in file\n"));
              goto findKey;
            }
          }
        
        
        sh_util_encode(key, buf, 1, 'B');
        start = 0;
      } 
      else
      { 
        /* Iterate the key.
         */
        (void) sl_strlcpy (key, 
                       sh_tiger_hash (key, TIGER_DATA, KEY_LEN), 
                       KEY_LEN+1);
      }
      
      (void) sl_strlcat ( buf, key, 2*SH_BUFSIZE + 1);
      
#ifdef SH_STEALTH
      sh_do_decode (signature, sl_strlen(signature));
#endif
      
      status = sl_strncmp (signature, 
                     sh_tiger_hash (buf, TIGER_DATA, 
                                (unsigned long) sl_strlen(buf)),
                     KEY_LEN);
      
      buf[len] = '\0';    /* do not print out the key */
#ifdef SH_STEALTH
      sh_do_decode (buf, sl_strlen(buf));
#endif
      
      if (status != 0) 
      {
#ifdef SH_USE_XML
        if (chk_mode == CHK_NON)
          {
            if (fixed_xml == S_FALSE)
            fprintf (stdout, _("XFAIL: line=%05d %s/log>\n"), 
                   count-1, buf);
            else
            fprintf (stdout, _("XFAIL: line=%05d %s</log>\n"), 
                   count-1, buf);
          }
        else
          {
            if (fixed_xml == S_FALSE)
            fprintf (stdout, _("FAIL:  line=%05d %s/log>\n"), 
                   count-1, buf);
            else
            fprintf (stdout, _("FAIL:  line=%05d %s</log>\n"), 
                   count-1, buf);
          }
#else
        if (chk_mode == CHK_NON)
          fprintf (stdout, _("XFAIL: line=%5d %s\n"), count-1, buf);
        else
          fprintf (stdout, _("FAIL:  line=%5d %s\n"), count-1, buf);
#endif
      }
      else
      {
#ifdef SH_USE_XML 
        if (fixed_xml == S_FALSE)
          fprintf (stdout, _("PASS:  line=%05d %s/log>\n"),  count-1, buf);
        else
          fprintf (stdout, _("PASS:  line=%05d %s</log>\n"), count-1, buf);
#else
        fprintf (stdout, _("PASS:  line=%5d %s\n"), count-1, buf);
#endif    
      }
    }

  /* Cleanup and exit.
   */
  (void) sl_close (fd);
  SH_FREE  (buf);
  SH_FREE  (bufc);
  (void) fflush   (stdout);
  _exit    (EXIT_SUCCESS);

  /* Make compilers happy. 
   */
  /*@notreached@*/
  return 0; 
}

/********************************************************************
 *
 *  Runtime code
 *
 ********************************************************************/
static
int sh_log_open (char * inet_peer, 
                 char * logfile, int * service_failure, SL_TICKET * fildesc)
{
  SL_TICKET            fd = -1;
  long int             status;
  char               * tmp = NULL;
  uid_t                uid;
  size_t               len;
  char               * lockfile = NULL;

  SL_ENTER(_("sh_log_open"));

  /* open/create the file, then check it 
   */

  if (  0 !=  (status = tf_trust_check (logfile, SL_YESPRIV))
        && (*service_failure) == 0)
    {
      tmp  = sh_util_safe_name (logfile);
      sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_TRUST,
                      (long) sh.effective.uid, tmp);
    }

  if (status == 0)
    {
      fd = sl_open_write (logfile, SL_YESPRIV);
      if (SL_ISERROR(fd))
        {
        tmp  = sh_util_safe_name (logfile);
        (void) sl_get_euid(&uid);
          if ((*service_failure) == 0)
            sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_ACCESS,
                             (long) uid, tmp);
          status = -1;
        }
    }


  if (status == 0 && inet_peer == NULL )
    {
      status = sh_unix_write_lock_file(logfile);
      if (status < 0)
        {
        tmp  = sh_util_safe_name (logfile);
        len      = 6 + sl_strlen(tmp);
        lockfile = SH_ALLOC(len);
        (void) sl_strlcpy(lockfile,        tmp, len);
        (void) sl_strlcat(lockfile, _(".lock"), len);
          (void) sl_get_euid(&uid);
          if ((*service_failure) == 0)
            sh_error_handle ((-1), FIL__, __LINE__, status, MSG_LOCKED,
                             (long) uid, tmp, lockfile);
          status = -1;
        SH_FREE(lockfile);
          (void) sl_close(fd);
        }
    }

  if (status == 0)
    {
      status = (long) SL_ISERROR(sl_forward(fd) ); 
      if (status < 0)
        {
        tmp  = sh_util_safe_name (logfile);
          (void) sl_get_euid(&uid);
          if ((*service_failure) == 0)
            sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_ACCESS,
                             (long) uid, tmp);
          status = -1;
          (void) sl_close(fd);
        }
    }
  
  if (status < 0)
    {
      if ((*service_failure) == 0) {
        sh_error_handle ((-1), FIL__, __LINE__, status, MSG_SRV_FAIL,
                         _("logfile"), tmp);
        (*service_failure) = 1;
      }
      SH_FREE(tmp);
      SL_RETURN(-1, _("sh_log_open"));
    }

  *fildesc         = fd;
  *service_failure = 0;
  SL_RETURN(0, _("sh_log_open"));
}

typedef struct lfstc {
  char          * logfile;
  int             service_failure;
  int             log_start;
  char            sigkey_old[KEY_LEN+1];
  char            sigkey_new[KEY_LEN+1];
  char            crypt[KEY_LEN+1]; 
  struct  lfstc * next;
} open_logfile;

static open_logfile * logfile_list = NULL;

static int flag_sep_log = S_FALSE;

#ifdef SH_WITH_SERVER
int set_flag_sep_log (char * str)
{
  return sh_util_flagval(str, &flag_sep_log);
}
#endif

/*
 *   --- Log error message to log file. ---
 */
int  sh_log_file (/*@null@*/char *errmsg, /*@null@*/char * inet_peer)
{
  int                  store1;
  int                  store2;
  int                  store3;
  int                  store4;
  int                  store5;
  int                  store6;
  int                  store7;
  int                  store8;

  SL_TICKET            fd = -1;
  long int             status;
  struct _sh_log_buf   log_msg;

  char                 logfile[SH_PATHBUF+SH_MINIBUF+2];
  open_logfile       * current = logfile_list;  
  open_logfile       * next    = NULL;
  char               * sigkey_new;
  char               * sigkey_old;
  char               * crypt;

  SL_ENTER(_("sh_log_file"));

  if (errFlags.HaveLog == BAD)  /* paranoia */ 
    SL_RETURN((-1), _("sh_log_file"));

#ifdef SH_USE_XML
  if (NULL == errmsg)
    {
      while (current != NULL)
        {
        /* don't write second EOF mark
         */
        if (current->log_start != S_TRUE)
          {
            /* Don't use inet_peer == NULL, userwise a lock file will
             * be created.
             */
            (void) sh_log_open ("\0", 
                          current->logfile, 
                          &(current->service_failure), &fd);
          
#ifdef SH_STEALTH
            (void) sl_write_line (fd, N_("</trail>"), 7);
            (void) sl_write (fd, "\n", 1);
            (void) sl_sync(fd);
#else
            (void) sl_write_line (fd, _("</trail>\n"),  8);
            (void) sl_sync(fd);
#endif
            (void) sl_close(fd);
            /* sh_unix_rm_lock_file (current->logfile); */
          }
        next    = current->next;
        SH_FREE(current->logfile);
        SH_FREE(current);
        current = next;
      }
      logfile_list = NULL;
      SL_RETURN( 0, _("sh_log_file"));
    }
#else
  if (NULL == errmsg)
    {
      while (current != NULL)
        {
        /* sh_unix_rm_lock_file (current->logfile); */
        next    = current->next;
          SH_FREE(current->logfile);
          SH_FREE(current);
          current = next;
        }
      logfile_list = NULL;
      SL_RETURN( 0, _("sh_log_file"));
    }
#endif

  (void) sl_strlcpy (logfile, sh.srvlog.name, sizeof(logfile));
  if (inet_peer != NULL && flag_sep_log == S_TRUE)
    {
      (void) sl_strlcat (logfile, ".",       sizeof(logfile));
      (void) sl_strlcat (logfile, inet_peer, sizeof(logfile));
    }

  if (sh.flag.log_start == S_TRUE)
    {
      while (current != NULL)
        {
          current->log_start = S_TRUE;
          current = current->next;
        }
      sh.flag.log_start    = S_FALSE;
      current = logfile_list;
    }

  while (current != NULL)
    {
      if (strcmp(logfile, current->logfile) == 0)
        break;
      current = current->next;
    }

  if (current == NULL)
    {
      current                  = SH_ALLOC(sizeof(open_logfile));
      current->logfile         = SH_ALLOC(strlen(logfile) + 1);
      (void) sl_strlcpy(current->logfile, logfile, strlen(logfile) + 1);
      current->service_failure = 0;
      current->log_start       = S_TRUE;
      memset(current->sigkey_old, (int)'\0', KEY_LEN+1);
      memset(current->sigkey_new, (int)'\0', KEY_LEN+1);
      memset(current->crypt,      (int)'\0', KEY_LEN+1);
      current->next            = logfile_list;
      logfile_list             = current;
    }

  if (0 != sh_log_open (inet_peer, current->logfile, 
                        &(current->service_failure), &fd))
    {
      SL_RETURN ((-1), _("sh_log_file"));
    }


  /* --- Allocate storage and mlock it. ---
   */

  status      = (long) sl_strlen (errmsg);
  log_msg.msg = (char *) SH_ALLOC ((size_t) (2*KEY_LEN + status + 32)); 

#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
  if (skey->mlock_failed == SL_FALSE) 
    {
      if ( (-1) == sh_unix_mlock( log_msg.msg, 
                          (size_t)(2*KEY_LEN + status + 32) ) ) 
      {
        skey->mlock_failed = SL_TRUE;
#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
        sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK); 
#endif
      }
    }
#else
  if (skey->mlock_failed == SL_FALSE) 
    {
      skey->mlock_failed = SL_TRUE;
#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
      sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK);
#endif
    }
#endif

  /* --- Write the start marker. --- 
   */

  if (current->log_start == S_TRUE) 
    {
#ifdef SH_USE_XML
#ifdef SH_STEALTH
      (void) sl_write (fd, "\n", 1);
      (void) sl_write_line (fd, N_("<trail>"), 7);
      (void) sl_sync(fd);
#else
      (void) sl_write_line (fd, _("\n<trail>"),  8);
      (void) sl_sync(fd);
#endif
#else
#ifdef SH_STEALTH
      (void) sl_write (fd, "\n", 1);
      (void) sl_write_line (fd, N_("[SOF]"), 5);
      (void) sl_sync(fd);
#else
      (void) sl_write_line (fd, _("\n[SOF]"),  6);
      (void) sl_sync(fd);
#endif
#endif
    }

  /* reserve KEY_LEN chars at end for key 
   */
  (void) sl_strlcpy (log_msg.msg, errmsg, (size_t) status+1 );


#ifdef SH_USE_XML
  /* cut the trailing "/>"
   */
  if (log_msg.msg[status-2] == '/')
    {
#ifdef FIX_XML
      log_msg.msg[status-2] = ' '; /* ' ' FIX XML */
      log_msg.msg[status-1] = '>'; /* '>' FIX XML */
#else
      log_msg.msg[status-2] = '>'; /* ' ' FIX XML */
      log_msg.msg[status-1] = '<'; /* '>' FIX XML */
#endif
      log_msg.msg[status]   = '\0';
    }
  else if (status >= 6 && log_msg.msg[status-5] == '/' && 
         log_msg.msg[status-6] == '<')
    {
#ifdef FIX_XML
      log_msg.msg[status-6]   = '\0';
      status -= 6;
#else
      log_msg.msg[status-5]   = '\0';
      status -= 5;
#endif
    }
#endif


#ifdef SH_STEALTH
  sh_do_encode (log_msg.msg, status);
#endif

  if (flag_sep_log == S_TRUE && inet_peer != NULL)
    {
      sigkey_old = current->sigkey_old;
      sigkey_new = current->sigkey_new;
      crypt      = current->crypt;
    }
  else
    {
      sigkey_old = skey->sigkey_old;
      sigkey_new = skey->sigkey_new;
      crypt      = skey->crypt;
    }

  /* write the signature 
   */
  if (current->log_start == S_TRUE) 
    {
      if (sh.real.user[0] == '\0') 
      (void) sh_unix_getUser();

      /* Initialize the key.
       */
      (void) sh_util_keyinit(sigkey_old, KEY_LEN+1);

      /* Hash the key to make sure it has the correct format.
       */
      (void) sl_strlcpy(sigkey_new, 
                  sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN), 
                  KEY_LEN+1);

      /* Copy it to 'crypt' for encryption.
       */
      (void) sl_strlcpy(crypt, sigkey_new, KEY_LEN+1);

      /* Use message and compiled-in key to encrypt.
       */
      BREAKEXIT(sh_util_encode);
      sh_util_encode(crypt, log_msg.msg, 0, 'B');

      /* Send out the key.
       */
      (void) sl_strlcpy(log_msg.timestamp, sh_unix_time(0), KEY_LEN+1); 

      store1               = errFlags.loglevel;
      store2               = errFlags.sysloglevel;
      store3               = errFlags.printlevel;
      store4               = errFlags.exportlevel;
      store5               = errFlags.maillevel;
      store6               = errFlags.externallevel;
      store7               = errFlags.databaselevel;
      store8               = errFlags.preludelevel;

      /* mail the key
       */
      errFlags.loglevel       = SH_ERR_NOT;
      errFlags.sysloglevel    = SH_ERR_NOT;
      errFlags.printlevel     = SH_ERR_NOT;
      errFlags.exportlevel    = SH_ERR_NOT;
      errFlags.externallevel  = SH_ERR_NOT;
      errFlags.databaselevel  = SH_ERR_NOT;
      errFlags.preludelevel   = SH_ERR_NOT;

      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY_MAIL,
                   sh.prg_name, crypt, 
                   crypt, log_msg.timestamp);

      /* send to other allowed channels
       */
      errFlags.maillevel      = SH_ERR_NOT;
      /* errFlags.printlevel     = store3; */
      errFlags.exportlevel    = store4;
      errFlags.externallevel  = store6;
      errFlags.databaselevel  = store7;
      errFlags.preludelevel   = store8;

      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY,
                   sh.prg_name, crypt);

      /* Cleanup.
       */
      errFlags.loglevel       = store1;
      errFlags.sysloglevel    = store2;
      errFlags.printlevel     = store3;
      errFlags.exportlevel    = store4;
      errFlags.maillevel      = store5;
      errFlags.externallevel  = store6;
      errFlags.databaselevel  = store7;


      memset (crypt, (int) '\0', KEY_LEN);
      sh.flag.log_start    = S_FALSE;  
      current->log_start   = S_FALSE;
    } 
  else 
    {
      log_msg.timestamp[0] = '\0';
      (void) sl_strlcpy (sigkey_new, 
                   sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN),
                   KEY_LEN+1);
    }

  /* --- Sign the message with the signature key. ---
   */

  (void) sl_strlcat (log_msg.msg, sigkey_new, (size_t)(status + KEY_LEN + 2));
  
  (void) sl_strlcpy (log_msg.signature,
                 sh_tiger_hash (log_msg.msg, TIGER_DATA, 
                            (unsigned long)(status + KEY_LEN)), 
                 KEY_LEN+1);
  (void) sl_strlcpy (sigkey_old, sigkey_new, KEY_LEN+1); 

  /*@-bufferoverflowhigh -usedef@*/
#ifdef SH_USE_XML
  if (log_msg.timestamp[0] != '\0')
    sprintf(log_msg.sig,                            /* known to fit  */
#ifdef FIX_XML
          _("\n<sig>%s%s</sig></log>\n"),          /* <sig> FIX XML */
#else
          _("\nsig>%s%s</sig></log>\n"),          /* <sig> FIX XML */
#endif
          log_msg.signature, log_msg.timestamp);
  else
    sprintf(log_msg.sig,                            /* known to fit  */
#ifdef FIX_XML
          _("\n<sig>%s</sig></log>\n"),            /* <sig> FIX XML */
#else
          _("\nsig>%s</sig></log>\n"),            /* <sig> FIX XML */
#endif
          log_msg.signature);
  /*@+bufferoverflowhigh +usedef@*/

#ifdef SH_STEALTH
  /* don't encode the line breaks (0 + last char)
   */
  sh_do_encode (&log_msg.sig[1], (sl_strlen(log_msg.sig)-2) );
#endif
#else
#ifdef SH_STEALTH
  sh_do_encode (log_msg.signature, KEY_LEN);
  sh_do_encode (log_msg.timestamp, sl_strlen(log_msg.timestamp));
#endif
#endif
  
#ifdef SH_USE_XML
  log_msg.msg[status] = '\0';
  (void) sl_strlcat (log_msg.msg,   log_msg.sig, 
                 (size_t)(status + 2*KEY_LEN + 32));
#ifdef SH_STEALTH
  if (NULL != sl_strstr(log_msg.msg, N_("EXIT")) &&
      NULL == sl_strstr(log_msg.msg, N_("remote_host")))
    {
      (void) sl_strlcat (log_msg.msg,  N_("</trail>"), 
                   (size_t)(status + 2*KEY_LEN + 32)); 
#else
  if (NULL != sl_strstr(log_msg.msg,  _("msg=\"EXIT\"")) &&
      NULL == sl_strstr(log_msg.msg,  _("remote_host")))
    {
      (void) sl_strlcat (log_msg.msg,   _("</trail>"), 
                   (size_t)(status + 2*KEY_LEN + 32)); 
#endif
      
      (void) sl_strlcat (log_msg.msg,   _("\n"), 
                   (size_t)(status + 2*KEY_LEN + 32)); 
      current->log_start = S_TRUE;
    }
#else
  log_msg.msg[status] = '\0';
  (void) sl_strlcat (log_msg.msg,              "\n", 
                 (size_t)(status + KEY_LEN + 2));
  (void) sl_strlcat (log_msg.msg, log_msg.signature, 
                 (size_t)(status + KEY_LEN + 2));
  if (log_msg.timestamp[0] != '\0')
    (void) sl_strlcat (log_msg.msg, log_msg.timestamp, 
                   (size_t)(status + 2*KEY_LEN + 2));
  (void) sl_strlcat (log_msg.msg,              "\n", 
                 (size_t)(status + 2*KEY_LEN + 3));
#endif
  
  /* --- Write out the record. ---
   */
  (void) sl_write (fd, log_msg.msg, (long) strlen(log_msg.msg));
  (void) sl_sync  (fd);
  (void) sl_close (fd);

  /* --- Clean up and free record. ---
   */
  memset (log_msg.msg,       (int)'\0', (size_t)(status + 2*KEY_LEN + 32));
  memset (log_msg.signature, (int)'\0', KEY_LEN);
  (void) sh_unix_munlock (log_msg.msg,  
                    (size_t)(status + 2*KEY_LEN + 32));
  SH_FREE(log_msg.msg);

  SL_RETURN (0, _("sh_log_file"));
}


Generated by  Doxygen 1.6.0   Back to index