source: trunk/src/sh_err_log.c@ 20

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

Enable command-line parsing for prelude, and make prelude regression test safer.

File size: 25.4 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, 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 {
757 if ( (-1) == sh_unix_mlock( FIL__, __LINE__, log_msg.msg,
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.