source: trunk/src/sh_err_log.c@ 134

Last change on this file since 134 was 133, checked in by rainer, 17 years ago

Reentrant checksum/hash functions.

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