source: trunk/src/sh_err_log.c@ 19

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

Rewrite of test suite, checksum for growing logs, fix for minor bug with dead client detection.

File size: 25.4 KB
RevLine 
[1]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 (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 (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, KEY_LEN+2, 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 = 6 + sl_strlen(tmp);
556 lockfile = SH_ALLOC(len);
557 (void) sl_strlcpy(lockfile, tmp, len);
558 (void) sl_strlcat(lockfile, _(".lock"), len);
559 (void) sl_get_euid(&uid);
560 if ((*service_failure) == 0)
561 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_LOCKED,
562 (long) uid, tmp, lockfile);
563 status = -1;
564 SH_FREE(lockfile);
565 (void) sl_close(fd);
566 }
567 }
568
569 if (status == 0)
570 {
571 status = sl_forward(fd);
572 if (SL_ISERROR(status))
573 {
574 tmp = sh_util_safe_name (logfile);
575 (void) sl_get_euid(&uid);
576 if ((*service_failure) == 0)
577 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_ACCESS,
578 (long) uid, tmp);
579 status = -1;
580 (void) sl_close(fd);
581 }
582 }
583
584 if (status < 0)
585 {
586 if ((*service_failure) == 0) {
587 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_SRV_FAIL,
588 _("logfile"), tmp);
589 (*service_failure) = 1;
590 }
591 SH_FREE(tmp);
592 SL_RETURN(-1, _("sh_log_open"));
593 }
594
595 *fildesc = fd;
596 *service_failure = 0;
597 SL_RETURN(0, _("sh_log_open"));
598}
599
600typedef struct lfstc {
601 char * logfile;
602 int service_failure;
603 int log_start;
604 char sigkey_old[KEY_LEN+1];
605 char sigkey_new[KEY_LEN+1];
606 char crypt[KEY_LEN+1];
607 struct lfstc * next;
608} open_logfile;
609
610static open_logfile * logfile_list = NULL;
611
612static int flag_sep_log = S_FALSE;
613
614#ifdef SH_WITH_SERVER
615int set_flag_sep_log (char * str)
616{
617 return sh_util_flagval(str, &flag_sep_log);
618}
619#endif
620
621/*
622 * --- Log error message to log file. ---
623 */
624int sh_log_file (/*@null@*/char *errmsg, /*@null@*/char * inet_peer)
625{
626 int store1;
627 int store2;
628 int store3;
629 int store4;
630 int store5;
631 int store6;
632 int store7;
633 int store8;
634
635 SL_TICKET fd = -1;
636 long int status;
637 struct _sh_log_buf log_msg;
638
639 char logfile[SH_PATHBUF+SH_MINIBUF+2];
640 open_logfile * current = logfile_list;
641 open_logfile * next = NULL;
642 char * sigkey_new;
643 char * sigkey_old;
644 char * crypt;
645
646 SL_ENTER(_("sh_log_file"));
647
648 if (errFlags.HaveLog == BAD) /* paranoia */
649 SL_RETURN((-1), _("sh_log_file"));
650
651#ifdef SH_USE_XML
652 if (NULL == errmsg)
653 {
654 while (current != NULL)
655 {
656 /* don't write second EOF mark
657 */
658 if (current->log_start != S_TRUE)
659 {
660 /* Don't use inet_peer == NULL, userwise a lock file will
661 * be created.
662 */
663 (void) sh_log_open ("\0",
664 current->logfile,
665 &(current->service_failure), &fd);
666
667#ifdef SH_STEALTH
668 (void) sl_write_line (fd, N_("</trail>"), 7);
669 (void) sl_write (fd, "\n", 1);
670 (void) sl_sync(fd);
671#else
672 (void) sl_write_line (fd, _("</trail>\n"), 8);
673 (void) sl_sync(fd);
674#endif
675 (void) sl_close(fd);
676 /* sh_unix_rm_lock_file (current->logfile); */
677 }
678 next = current->next;
679 SH_FREE(current->logfile);
680 SH_FREE(current);
681 current = next;
682 }
683 logfile_list = NULL;
684 SL_RETURN( 0, _("sh_log_file"));
685 }
686#else
687 if (NULL == errmsg)
688 {
689 while (current != NULL)
690 {
691 /* sh_unix_rm_lock_file (current->logfile); */
692 next = current->next;
693 SH_FREE(current->logfile);
694 SH_FREE(current);
695 current = next;
696 }
697 logfile_list = NULL;
698 SL_RETURN( 0, _("sh_log_file"));
699 }
700#endif
701
702 (void) sl_strlcpy (logfile, sh.srvlog.name, sizeof(logfile));
703 if (inet_peer != NULL && flag_sep_log == S_TRUE)
704 {
705 (void) sl_strlcat (logfile, ".", sizeof(logfile));
706 (void) sl_strlcat (logfile, inet_peer, sizeof(logfile));
707 }
708
709 if (sh.flag.log_start == S_TRUE)
710 {
711 while (current != NULL)
712 {
713 current->log_start = S_TRUE;
714 current = current->next;
715 }
716 sh.flag.log_start = S_FALSE;
717 current = logfile_list;
718 }
719
720 while (current != NULL)
721 {
722 if (strcmp(logfile, current->logfile) == 0)
723 break;
724 current = current->next;
725 }
726
727 if (current == NULL)
728 {
729 current = SH_ALLOC(sizeof(open_logfile));
730 current->logfile = SH_ALLOC(strlen(logfile) + 1);
731 (void) sl_strlcpy(current->logfile, logfile, strlen(logfile) + 1);
732 current->service_failure = 0;
733 current->log_start = S_TRUE;
734 memset(current->sigkey_old, (int)'\0', KEY_LEN+1);
735 memset(current->sigkey_new, (int)'\0', KEY_LEN+1);
736 memset(current->crypt, (int)'\0', KEY_LEN+1);
737 current->next = logfile_list;
738 logfile_list = current;
739 }
740
741 if (0 != sh_log_open (inet_peer, current->logfile,
742 &(current->service_failure), &fd))
743 {
744 SL_RETURN ((-1), _("sh_log_file"));
745 }
746
747
748 /* --- Allocate storage and mlock it. ---
749 */
750
751 status = (long) sl_strlen (errmsg);
752 log_msg.msg = (char *) SH_ALLOC ((size_t) (2*KEY_LEN + status + 32));
753
754#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
755 if (skey->mlock_failed == SL_FALSE)
756 {
[19]757 if ( (-1) == sh_unix_mlock( FIL__, __LINE__, log_msg.msg,
[1]758 (size_t)(2*KEY_LEN + status + 32) ) )
759 {
760 skey->mlock_failed = SL_TRUE;
761#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
762 sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK);
763#endif
764 }
765 }
766#else
767 if (skey->mlock_failed == SL_FALSE)
768 {
769 skey->mlock_failed = SL_TRUE;
770#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
771 sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK);
772#endif
773 }
774#endif
775
776 /* --- Write the start marker. ---
777 */
778
779 if (current->log_start == S_TRUE)
780 {
781#ifdef SH_USE_XML
782#ifdef SH_STEALTH
783 (void) sl_write (fd, "\n", 1);
784 (void) sl_write_line (fd, N_("<trail>"), 7);
785 (void) sl_sync(fd);
786#else
787 (void) sl_write_line (fd, _("\n<trail>"), 8);
788 (void) sl_sync(fd);
789#endif
790#else
791#ifdef SH_STEALTH
792 (void) sl_write (fd, "\n", 1);
793 (void) sl_write_line (fd, N_("[SOF]"), 5);
794 (void) sl_sync(fd);
795#else
796 (void) sl_write_line (fd, _("\n[SOF]"), 6);
797 (void) sl_sync(fd);
798#endif
799#endif
800 }
801
802 /* reserve KEY_LEN chars at end for key
803 */
804 (void) sl_strlcpy (log_msg.msg, errmsg, (size_t) status+1 );
805
806
807#ifdef SH_USE_XML
808 /* cut the trailing "/>"
809 */
810 if (log_msg.msg[status-2] == '/')
811 {
812#ifdef FIX_XML
813 log_msg.msg[status-2] = ' '; /* ' ' FIX XML */
814 log_msg.msg[status-1] = '>'; /* '>' FIX XML */
815#else
816 log_msg.msg[status-2] = '>'; /* ' ' FIX XML */
817 log_msg.msg[status-1] = '<'; /* '>' FIX XML */
818#endif
819 log_msg.msg[status] = '\0';
820 }
821 else if (status >= 6 && log_msg.msg[status-5] == '/' &&
822 log_msg.msg[status-6] == '<')
823 {
824#ifdef FIX_XML
825 log_msg.msg[status-6] = '\0';
826 status -= 6;
827#else
828 log_msg.msg[status-5] = '\0';
829 status -= 5;
830#endif
831 }
832#endif
833
834
835#ifdef SH_STEALTH
836 sh_do_encode (log_msg.msg, status);
837#endif
838
839 if (flag_sep_log == S_TRUE && inet_peer != NULL)
840 {
841 sigkey_old = current->sigkey_old;
842 sigkey_new = current->sigkey_new;
843 crypt = current->crypt;
844 }
845 else
846 {
847 sigkey_old = skey->sigkey_old;
848 sigkey_new = skey->sigkey_new;
849 crypt = skey->crypt;
850 }
851
852 /* write the signature
853 */
854 if (current->log_start == S_TRUE)
855 {
856 if (sh.real.user[0] == '\0')
857 (void) sh_unix_getUser();
858
859 /* Initialize the key.
860 */
861 (void) sh_util_keyinit(sigkey_old, KEY_LEN+1);
862
863 /* Hash the key to make sure it has the correct format.
864 */
865 (void) sl_strlcpy(sigkey_new,
866 sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN),
867 KEY_LEN+1);
868
869 /* Copy it to 'crypt' for encryption.
870 */
871 (void) sl_strlcpy(crypt, sigkey_new, KEY_LEN+1);
872
873 /* Use message and compiled-in key to encrypt.
874 */
875 BREAKEXIT(sh_util_encode);
876 sh_util_encode(crypt, log_msg.msg, 0, 'B');
877
878 /* Send out the key.
879 */
880 (void) sl_strlcpy(log_msg.timestamp, sh_unix_time(0), KEY_LEN+1);
881
882 store1 = errFlags.loglevel;
883 store2 = errFlags.sysloglevel;
884 store3 = errFlags.printlevel;
885 store4 = errFlags.exportlevel;
886 store5 = errFlags.maillevel;
887 store6 = errFlags.externallevel;
888 store7 = errFlags.databaselevel;
889 store8 = errFlags.preludelevel;
890
891 /* mail the key
892 */
893 errFlags.loglevel = SH_ERR_NOT;
894 errFlags.sysloglevel = SH_ERR_NOT;
895 errFlags.printlevel = SH_ERR_NOT;
896 errFlags.exportlevel = SH_ERR_NOT;
897 errFlags.externallevel = SH_ERR_NOT;
898 errFlags.databaselevel = SH_ERR_NOT;
899 errFlags.preludelevel = SH_ERR_NOT;
900
901 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY_MAIL,
902 sh.prg_name, crypt,
903 crypt, log_msg.timestamp);
904
905 /* send to other allowed channels
906 */
907 errFlags.maillevel = SH_ERR_NOT;
908 /* errFlags.printlevel = store3; */
909 errFlags.exportlevel = store4;
910 errFlags.externallevel = store6;
911 errFlags.databaselevel = store7;
912 errFlags.preludelevel = store8;
913
914 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY,
915 sh.prg_name, crypt);
916
917 /* Cleanup.
918 */
919 errFlags.loglevel = store1;
920 errFlags.sysloglevel = store2;
921 errFlags.printlevel = store3;
922 errFlags.exportlevel = store4;
923 errFlags.maillevel = store5;
924 errFlags.externallevel = store6;
925 errFlags.databaselevel = store7;
926
927
928 memset (crypt, (int) '\0', KEY_LEN);
929 sh.flag.log_start = S_FALSE;
930 current->log_start = S_FALSE;
931 }
932 else
933 {
934 log_msg.timestamp[0] = '\0';
935 (void) sl_strlcpy (sigkey_new,
936 sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN),
937 KEY_LEN+1);
938 }
939
940 /* --- Sign the message with the signature key. ---
941 */
942
943 (void) sl_strlcat (log_msg.msg, sigkey_new, (size_t)(status + KEY_LEN + 2));
944
945 (void) sl_strlcpy (log_msg.signature,
946 sh_tiger_hash (log_msg.msg, TIGER_DATA,
947 (unsigned long)(status + KEY_LEN)),
948 KEY_LEN+1);
949 (void) sl_strlcpy (sigkey_old, sigkey_new, KEY_LEN+1);
950
951 /*@-bufferoverflowhigh -usedef@*/
952#ifdef SH_USE_XML
953 if (log_msg.timestamp[0] != '\0')
954 sprintf(log_msg.sig, /* known to fit */
955#ifdef FIX_XML
956 _("\n<sig>%s%s</sig></log>\n"), /* <sig> FIX XML */
957#else
958 _("\nsig>%s%s</sig></log>\n"), /* <sig> FIX XML */
959#endif
960 log_msg.signature, log_msg.timestamp);
961 else
962 sprintf(log_msg.sig, /* known to fit */
963#ifdef FIX_XML
964 _("\n<sig>%s</sig></log>\n"), /* <sig> FIX XML */
965#else
966 _("\nsig>%s</sig></log>\n"), /* <sig> FIX XML */
967#endif
968 log_msg.signature);
969 /*@+bufferoverflowhigh +usedef@*/
970
971#ifdef SH_STEALTH
972 /* don't encode the line breaks (0 + last char)
973 */
974 sh_do_encode (&log_msg.sig[1], (sl_strlen(log_msg.sig)-2) );
975#endif
976#else
977#ifdef SH_STEALTH
978 sh_do_encode (log_msg.signature, KEY_LEN);
979 sh_do_encode (log_msg.timestamp, sl_strlen(log_msg.timestamp));
980#endif
981#endif
982
983#ifdef SH_USE_XML
984 log_msg.msg[status] = '\0';
985 (void) sl_strlcat (log_msg.msg, log_msg.sig,
986 (size_t)(status + 2*KEY_LEN + 32));
987#ifdef SH_STEALTH
988 if (NULL != sl_strstr(log_msg.msg, N_("EXIT")) &&
989 NULL == sl_strstr(log_msg.msg, N_("remote_host")))
990 {
991 (void) sl_strlcat (log_msg.msg, N_("</trail>"),
992 (size_t)(status + 2*KEY_LEN + 32));
993#else
994 if (NULL != sl_strstr(log_msg.msg, _("msg=\"EXIT\"")) &&
995 NULL == sl_strstr(log_msg.msg, _("remote_host")))
996 {
997 (void) sl_strlcat (log_msg.msg, _("</trail>"),
998 (size_t)(status + 2*KEY_LEN + 32));
999#endif
1000
1001 (void) sl_strlcat (log_msg.msg, _("\n"),
1002 (size_t)(status + 2*KEY_LEN + 32));
1003 current->log_start = S_TRUE;
1004 }
1005#else
1006 log_msg.msg[status] = '\0';
1007 (void) sl_strlcat (log_msg.msg, "\n",
1008 (size_t)(status + KEY_LEN + 2));
1009 (void) sl_strlcat (log_msg.msg, log_msg.signature,
1010 (size_t)(status + KEY_LEN + 2));
1011 if (log_msg.timestamp[0] != '\0')
1012 (void) sl_strlcat (log_msg.msg, log_msg.timestamp,
1013 (size_t)(status + 2*KEY_LEN + 2));
1014 (void) sl_strlcat (log_msg.msg, "\n",
1015 (size_t)(status + 2*KEY_LEN + 3));
1016#endif
1017
1018 /* --- Write out the record. ---
1019 */
1020 (void) sl_write (fd, log_msg.msg, (long) strlen(log_msg.msg));
1021 (void) sl_sync (fd);
1022 (void) sl_close (fd);
1023
1024 /* --- Clean up and free record. ---
1025 */
1026 memset (log_msg.msg, (int)'\0', (size_t)(status + 2*KEY_LEN + 32));
1027 memset (log_msg.signature, (int)'\0', KEY_LEN);
1028 (void) sh_unix_munlock (log_msg.msg,
1029 (size_t)(status + 2*KEY_LEN + 32));
1030 SH_FREE(log_msg.msg);
1031
1032 SL_RETURN (0, _("sh_log_file"));
1033}
1034
Note: See TracBrowser for help on using the repository browser.