source: branches/samhain-2_2-branch/src/sh_err_log.c@ 209

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

Code cleanup and minor fixes

File size: 25.6 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) sl_strlcpy(log_msg.timestamp, sh_unix_time(0), 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.